当 initrd 卸载时, initrd 挂载的目录中的文件会发生什么

Fra*_*anc 4 initrd linux-kernel

当 Linux 启动时,initrd会安装基本的支持文件和内核模块,这些是帮助进一步启动过程所必需的。随后在 Linux 操作系统中rootfs安装和initrd卸载。我的问题是,如果initrd已卸载,用户如何仍能看到 挂载的文件initrd

例如: 等中的一些/etc文件/lib

use*_*686 7

\n

随后,rootfs 被挂载,initrd 从 Linux 操作系统中卸载

\n
\n

它并不完全是“卸载”的;大多数 Linux 发行版已经很多年没有使用可安装的 initrd 了相反,他们使用“initramfs”,它是一个存档,被提取到最初安装在“/”的 RAM 文件系统 (tmpfs) 中。尽管仍然使用该initrd=选项指定,但其行为与原始 initrd 机制完全不同。

\n
\n

我的问题是,当卸载 initrd 时,为什么目录 /etc、/lib、/bin、/usr、.. 及其内容仍然存在?

\n
\n

因为从 initramfs 的角度来看,它们实际上并不是“/etc”或“/lib”。initramfs不会直接挂载“/” \xe2\x80\x93 initramfs本身是“/” \xe2\x80\x93 而是将真正的根文件系统挂载在“/mnt”或“/newroot”之类的位置,所以这些目录以“/newroot/lib”等开头。

\n

initramfs 完成的最后步骤之一是“pivot_root()”或“mount(MS_MOVE)”,该操作使“/newroot”成为新的“/”,本质上交换了两个挂载(旧的“/”) " 将 initramfs 移至子安装位置)。

\n

从 initramfs 中解压出来的最小的“/bin”、“/etc”和“/lib”在此过程中会消失。

\n

换句话说,这个过程大约是:

\n
    \n
  1. 内核在 挂载一个空的 tmpfs /
  2. \n
  3. 内核将 initramfs.cpio 存档解压到内存中/,其中包含 /bin、/lib 等中的一些最小文件。
  4. \n
  5. 内核运行的/init是initramfs的“核心”。
  6. \n
  7. initramfs /init 脚本从内核命令行读取“root=”(或使用其他方法)并将真正的根文件系统安装在/newroot或类似的位置。此时,您的文件位于 /newroot/lib、/newroot/home 等。
  8. \n
  9. initramfs 可以选择在 /newroot 下安装其他必要的东西,例如“/newroot/run”处的 tmpfs,或作为“/newroot/usr”的基于 NFS 的 /usr。
  10. \n
  11. 我相信initramfs /init 变成/newroot使用/以下两种方法之一:\n
      \n
    • 它删除所有解压到 initramfs“/”中的文件,然后将“/newroot”挂载移动到“/”上(覆盖现在为空的 tmpfs,它永远留在那里)并使用 chroot() 使其永久\xe2\ x80\x93 这是 Arch Linux 的 initramfs 使用 switch_root 工具完成的;
    • \n
    • 或者它调用pivot_root()来“交换”initramfs /与/newroot,将后者转换为新的/并将initramfs移动到类似/run/initramfs的位置,然后可以卸载\xe2\x80\x93不确定这是否方法仍沿用。
    • \n
    \n
  12. \n
  13. 最后,现在“/”是真正的根,/init(仍然从内存中运行)执行真正的根文件系统的/sbin/init.
  14. \n
\n

通常,initramfs /init 是一个简单的 shell 脚本(尽管并非总是如此;它甚至可能是 systemd 的完整副本)。您可以查看Arch mkinitcpio /init。这内部使用了“overlay using mount(MS_MOVE)”方法;请参见util-linux 中的switch_root

\n

  • 内核中的注释表明 rootfs 不能为“pivot_root”:https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/namespace.c# n3859。即 initramfs 必须执行列表中 6 下的第一个项目符号。Rootfs 无法卸载,因为 VFS 机制“自然”是非空的(“同样的原因你不能杀死 `init`”:https://git.kernel.org/pub/scm/linux/kernel/git/torvalds /linux.git/tree/Documentation/filesystems/ramfs-rootfs-initramfs.rst)。Rootfs *总是*附加到`/`,即使是空的或挂载的。这确保了 VFS 始终工作。 (2认同)