[systemd-devel] Questions about systemd's "root storage daemon" concept

Martin Wilck mwilck at suse.com
Sat Jan 23 01:44:05 UTC 2021


Hi

I'm experimenting with systemd's root storage daemon concept
(https://systemd.io/ROOT_STORAGE_DAEMONS/).

I'm starting my daemon from a service unit in the initrd, and
I set argv[0][0] to '@', as suggested in the text.

So far so good, the daemon isn't killed. 

But a lot more is necessary to make this actually *work*. Here's a list
of issues I found, and what ideas I've had so far how to deal with
them. I'd appreciate some guidance.

1) Even if a daemon is exempted from being killed by killall(), the
unit it belongs to will be stopped when initrd-switch-root.target is
isolated, and that will normally cause the daemon to be stopped, too. 
AFAICS, the only way to ensure the daemon is not killed is by setting
"KillMode=none" in the unit file. Right? Any other mode would send
SIGKILL sooner or later even if my daemon was smart enough to ignore
SIGTERM when running in the intird.

2) KillMode=none will make systemd consider the respective unit
stopped, even if the daemon is still running. That feels wrong. Are
there better options?

3) The daemon that has been started in the initrd's root file system is
unable to access e.g. the /dev file system after switching root. I
haven't yet systematically analyzed which file systems are available. 
I suppose this must be handled by creating bind mounts, but I need
guidance how to do this. Or would it be possible/advisable for the
daemon to also re-execute itself under the real root, like systemd
itself? I thought the root storage daemon idea was developed to prevent
exactly that.

4) Most daemons that might qualify as "root storage daemon" also have
a "normal" mode, when the storage they serve is _not_ used as root FS,
just for data storage. In that case, it's probably preferrable to run
them from inside the root FS rather than as root storage daemon. That
has various advantages, e.g. the possibility to update the sofware
without rebooting. It's not clear to me yet how to handle the two
options (root and non-root) cleanly with unit files. 

 - if (for "root storage daemon" mode) I simply put the enabled unit
file in the initrd, systemd will start the daemon twice, at least if
it's a "simple" service. I considered working with conditions, such as 

   ConditionPathExists=!/run/my-daemon/my-pidfile

(where the pidfile would have been created by the initrd-based daemon)
but that would cause the unit in the root FS to fail, which is ugly.

 - I could (for root mode) add the enabled unit file to the intird
and afterwards disable it in the root fs, thus avoiding two copies to
be started. But that would cause issues whenever the intird must be
rebuilt. I suppose it could be handled with a dracut module.

- I could create two different unit files mydaemon.service and
mydaemon-initrd.service and have them conflict. dracut doesn't support
this out of the box. A separate dracut module would be necessary, too.

- Some settings such as KillMode=none make sense for the service in the
intird environment, but not for the one running in the root FS, and
vice versa. This is another argument for having separate unit files, or
initrd-specific drop-ins.

Bottom line for 4) is that a dracut module specific to the daemon at
hand must be written. That dracut module would need to figure out
whether the service is required for mounting root, and activate "root-
storage-daemon" mode by adding the service to the intird. The instance
in the root FS would then either need be disabled, or be smart enough
to detect situation and exit gracefully. Ideally, "systemctl status"
would show the service as running even thought the instance inside the
root FS isn't actually running. I am unsure if all this can be achieved
easily with the current sytemd functionality, please advise.

I hope this makes at least some sense.

Suggestions and Feedback welcome.

Regards
Martin






More information about the systemd-devel mailing list