1

https://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons/

...these storage daemons are started from the initramfs, stay running all the time during normal operation and are terminated only after we returned control back to the initramfs and by the initramfs. As such, storage daemons involved with maintaining the root file system storage conceptually are more like kernel threads than like normal system services: from the perspective of the init system (i.e. systemd) these services have been started before systemd got initialized and stay around until after systemd is already gone.

But, isn't the initramfs unmounted once systemd starts? I can't see the initramfs mounted anywhere on my Fedora 28 system.[*]

Where is the filesystem that "Root Storage Daemons" run from?

And what does it look like from their point of view? For example, can they access a fully-featured /dev during runtime?


[*] There is a directory /run/initramfs, but it is not a separate ram filesystem (tmpfs mount). It is empty except for a couple of directories with no files, and one file rwtab which lists the directory names.

$ findmnt -T /run/initramfs
TARGET SOURCE FSTYPE OPTIONS
/run   tmpfs  tmpfs  rw,nosuid,nodev,seclabel,mode=755
$ find /run/initramfs -type d
/run/initramfs
/run/initramfs/state
/run/initramfs/state/var
/run/initramfs/state/var/lib
/run/initramfs/state/var/lib/dhclient
/run/initramfs/state/etc
/run/initramfs/state/etc/sysconfig
/run/initramfs/state/etc/sysconfig/network-scripts
/run/initramfs/log
$ find /run/initramfs -not -type d
/run/initramfs/rwtab
/run/initramfs/.need_shutdown
$ cat /run/initramfs/rwtab
files /etc/sysconfig/network-scripts
files /var/lib/dhclient
$ cat /run/initramfs/.need_shutdown
$
1

But, isn't the initramfs unmounted once systemd starts?

No. The initramfs filesystem actually can't be unmounted.


At least if the initramfs is implemented using systemd, it does calls umount(), but it passes the flag MNT_DETACH. See also umount -l.

(This mode of umount() is not prevented when there are open files. It only "detaches" the initramfs filesystem from its mount point, removing it from the mount table (/proc/mounts etc). Any open files can continue to be used. Once all open files are closed, then the kernel will finish unmounting the filesystem).

Where is the filesystem that "Root Storage Daemons" run from? And what does it look like from their point of view?

The spirit of "RootStorageDaemons" says that they continue running inside the detached initramfs.

In addition to detaching the mount, MNT_DETACH detaches any child mounts. So Root Storage Daemons would not see critical API filesystems including /dev and /proc mounts. This is pretty brutal:

# unshare -m
\# umount -l /
\# findmnt
findmnt: can't read /proc/mounts: No such file or directory
\# ls /dev
\#

After using MNT_DETACH, systemd in the initramfs continues to match the more traditional switch_root command, by deleting unlink()ing every file from the initramfs. (The systemd function is called rm_rf_children() - it effectively does rm -rf *. As usual, any open files - including the executable and library files of running daemons - will keep working. When the last reference to the file is closed, their storage will be freed by the kernel).

If true this would be quite interesting; it would be a nice protection against a bug in a RootStorageDaemon which opened a file on the root filesystem. It could also be a partial protection against making RPC calls through sockets in /run, and becoming dependent on daemons running from the root filesystem. Doing either of these things would be liable to cause a deadlock (circular dependency).


However in fact, if you look at /proc/$PID/root of a Root Storage Daemon, it will most likely point to the main root filesystem, not the initramfs. So why would this happen, and how does the system work in face of this?

It happens because the initramfs uses pivot_root() to switch to the root filesystem. As well as modifying the mount table, pivot_root() currently scans the root and current working directory (/proc/$PID/root and /proc/$PID/cwd) of all processes. If either of these match the root directory of the old root filesystem (initramfs), they are replaced with the new one. This is documented as an implementation detail of pivot_root(), which programs are not supposed to rely on.

<del>The system works because pivot_root() is also how systemd is able to switch back to an initramfs. So the references to the root filesystem are replaced again, with references to the shiny new initramfs. </del>


(It is also likely that the /run tmpfs in the shiny new initramfs, is passed down from /run on the root filesystem. Which in turn was passed down from the initramfs. In this case, I think it would allow the shutdown initramfs to communicate with the RootStorageDaemon, if the daemon opened a socket in /run as part of its startup sequence.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.