On Tue, Jun 27, 2023 at 8:36 PM Adrian Vovk <adrianv...@gmail.com> wrote:
> Hello! > > I'm working on passing sd_notify events from systemd-{pull,import} through > sysupdate. > > All services that consume sd_notify events (systemd itself, importd, > machined, homed, etc) act as daemons and own a directory in /run. Thus, > they can open a notification socket at, say, /run/SERVICENAME/notify and > set NOTIFY_SOCKET to that. Also, there's no cleanup involved: if the > service goes away the file sticks around until the service is restarted. > > sysupdate, however, is the first instance of a worker process forking off > another worker process. Thus, we cannot bind the notify socket to some > stable name. Here are potential approaches I've explored to solve this: > > - Simply pass through the NOTIFY_SOCKET environment variable. That's not > suitable because we want to export an overall progress value (smoothly from > 0 to 100), but systemd-import is forked off multiple times so we'd instead > export a progress value that bounces around from 0 to 100 and back to 0. > Also progress messages would come from different PIDs for a single > invocation of sysupdate > > - Create a temporary file and use that as the socket. Problem: What > happens if systemd-sysupdate crashes and we don't get to clean up that > file? Over time that potentially clutters up /tmp! Is this a concern? > I assume you meant named sockets (like one would usually find in /run), not actually regular temporary files? systemd-tmpfiles should correctly clean up broken sockets in /tmp, IIRC it supports checking whether the socket is bound or stale (though maybe /run is still a better place, even for temporary sockets). Personally my concern would be the crash itself, not the lack of cleanup. But if the sockets are kept in a single place, say, /run/sysupdate/notify/, then the subsequent restart could clean out all of them? > > - Use socketpair to open an anonymous socket and pass it into the child. > This one seems ideal on paper but it doesn't actually work. I can modify > sd_notify to just use an open file descriptor instead of tying to open its > own, and that does work except for some reason process credentials aren't > sent over. Also using the socket pair method doesn't work all that well > with CLOEXEC, though maybe we don't want to CLOEXEC (We'd only close the > socket when sd_notify is called with unset_env=true) > > - Create an abstract socket, named after the PID of the parent sysupdate. > i.e. @/run/sysupdate/PID/notify. I'm not super familiar with abstract > sockets so I'm not sure of the downsides > Abstract sockets are tied to the network namespace, instead of the filesystem (mount namespace). That's the main difference, as far as I know. -- Mantas Mikulėnas