[pve-devel] [PATCH common v3 1/2] systemd: add sd_notify() helper
Fiona Ebner
f.ebner at proxmox.com
Wed Oct 29 10:16:55 CET 2025
Am 28.10.25 um 3:58 PM schrieb Wolfgang Bumiller:
> On Tue, Oct 07, 2025 at 02:25:00PM +0200, Fiona Ebner wrote:
>> @@ -282,4 +285,32 @@ sub write_ini {
>> file_set_contents($filename, $content);
>> }
>>
>> +# This is a pure Perl reimplementation of systemd's sd_notify() as defined in systemd/sd-daemon.h
>> +sub sd_notify {
>> + my ($unset_environment, $state) = @_;
>> +
>> + my $socket_path = $ENV{NOTIFY_SOCKET};
>
> Technically this could be an abstract socket. Should be enough to just
>
> $socket_path =~ s/^@/\0/;
Will do in v4!
>
>> +
>> + my $socket = IO::Socket::UNIX->new(
>> + Type => SOCK_DGRAM(),
>> + Peer => $socket_path,
>> + ) or die "unable to connect to socket $socket_path to notify systemd - $IO::Socket::errstr\n";
>> +
>> + # we won't be reading from the socket
>> + $socket->shutdown(SHUT_RD);
>> +
>> + my $sent = 0;
>> + my $total = length($state);
>> + while ($sent < $total) {
>> + my $res = $socket->send($state);
>> + die "sending to $socket_path failed - $!" if !$res && $! != EINTR;
>> + $sent += $res if $res;
>
> ^ This is a datagram socket. Systemd expects a single datagram.
> The code sort of makes it look like you're trying doing a `write_all()`
> style send (without actually changing what it sent in between calls
> which wouldn't return zero).
> Trying to continue sending in a fragmented way won't work anyway.
> (Otherwise it would be rather cumbersome, since the protocol also allows
> adding things like file descriptors to store in the fd registry; data
> and metadata need to come in one nice bundle)
>
> The example code in the referenced man page errors out with `-EPROTO` if
> the length does not match, so we could do that as well.
>
> So basically, only an EINTR loop makes sense here.
Yes, I messed that up. Thank you for the explanation and suggestions!
>
>> + }
>> + $socket->flush();
>
> This should not be necessary, this is not buffered I/O.
Ack!
>> +
>> + close($socket);
>> +
>> + delete($ENV{NOTIFY_SOCKET}) if $unset_environment;
>
> Why is this part of this function, though?
Because I wanted to match the signature of the original sd_notify(), but
actually it already doesn't match because of the return value. I guess
I'll drop it for now since the examples in 'man 3 sd_notify' also don't
have it. If a future caller needs it, it could also unset the variable
itself.
More information about the pve-devel
mailing list