https://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons/
...这些存储守护进程从 initramfs 启动,在正常操作期间始终保持运行,并且仅在我们将控制权返回给 initramfs 并由 initramfs 终止后才终止。因此,从概念上讲,涉及维护根文件系统存储的存储守护进程更像是内核线程,而不是普通的系统服务:从 init 系统(即 systemd)的角度来看,这些服务已在 systemd 初始化之前启动,并一直保留到之后systemd 已经消失了。
但是,systemd启动后initramfs不是就被卸载了吗?我在 Fedora 28 系统上的任何位置都看不到安装的 initramfs。[*]
“根存储守护进程”运行的文件系统在哪里?
从他们的角度来看,这是什么样的?例如,他们可以/dev
在运行时访问全功能的吗?
[*] 有一个目录/run/initramfs
,但它不是一个单独的ram文件系统(tmpfs挂载)。除了几个没有文件的目录和一个rwtab
列出目录名称的文件外,它是空的。
$ 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
但是,systemd启动后initramfs不是就被卸载了吗?
否。initramfs 文件系统实际上无法卸载。
至少如果 initramfs 是使用 实现的systemd
,它会调用umount()
,但会传递标志MNT_DETACH
。也可以看看umount -l
。
(这种模式umount()
是不是当有打开的文件时被阻止。它仅将 initramfs 文件系统与其挂载点“分离”,将其从挂载表(/proc/mounts
等)中删除。任何打开的文件都可以继续使用。关闭所有打开的文件后,然后内核将完成卸载文件系统)。
“根存储守护进程”运行的文件系统在哪里?从他们的角度来看,这是什么样的?
这精神“RootStorageDaemons”表示它们继续在超然的initramfs。
除了分离安装座之外,还MNT_DETACH
分离所有子安装座。因此根存储守护进程不会看到关键的 API 文件系统,包括 /dev 和 /proc 挂载。这实在是太残酷了:
# unshare -m
\# umount -l /
\# findmnt
findmnt: can't read /proc/mounts: No such file or directory
\# ls /dev
\#
使用MNT_DETACH后, systemd
在 initramfs 中继续匹配更传统的switch_root
命令,通过删除从 initramfs 中 unlink()ing 每个文件。 (该systemd
函数被调用rm_rf_children()
- 它实际上是这样做的rm -rf *
。像往常一样,任何打开的文件 - 包括正在运行的守护程序的可执行文件和库文件 - 将继续工作。当对文件的最后一个引用被关闭时,它们的存储将被内核释放) 。
如果这是真的,这将非常有趣;这将是一个很好的保护措施,防止 RootStorageDaemon 中打开根文件系统上的文件的错误。它还可以部分保护,防止通过 中的套接字进行 RPC 调用/run
,并防止依赖于从根文件系统运行的守护进程。执行这些操作中的任何一个都可能导致死锁(循环依赖)。
然而在事实,如果您查看/proc/$PID/root
根存储守护进程,它很可能会指向主根文件系统,而不是 initramfs。那么为什么会发生这种情况,系统在这种情况下如何工作呢?
发生这种情况是因为 initramfs 用于pivot_root()
切换到根文件系统。除了修改挂载表之外,当前还会扫描所有进程的pivot_root()
根目录和当前工作目录(/proc/$PID/root
和)。/proc/$PID/cwd
如果其中任何一个与旧根文件系统 (initramfs) 的根目录匹配,它们将被替换为新根文件系统。这被记录为 的实现细节pivot_root()
,程序不应依赖该细节。
<del>
该系统之所以有效,是因为pivot_root()
它也是如何systemd
能够切换的后退到 initramfs。因此,对根文件系统的引用再次被替换为对闪亮的新 initramfs 的引用。</del>
(也有可能/run
闪亮的新 initramfs 中的 tmpfs 是从/run
根文件系统传递下来的。而根文件系统又是从 initramfs 传递下来的。在这种情况下,我认为它将允许关闭 initramfs 与 RootStorageDaemon 进行通信,如果守护进程/run
在其启动序列中打开一个套接字。)