在pivot_root之后使用chroot

sam*_*122 5 linux mount filesystems command-line

据我了解(如果我错了,请纠正我)这些命令的语义是:

  1. 每个进程都有一个根文件系统(即安装在 上的文件系统/)。
  2. 子进程继承其父进程的根文件系统。
  3. chroot使用新的根文件系统启动新进程(而不是从父进程继承)。
  4. pivot_root更改当前进程的根文件系统,同时保持旧根可访问。

现在考虑下面的例子(来自 linux 手册pivot_root

mount /dev/hda1 /new-root
cd /new-root
pivot_root . old-root
exec chroot . sh <dev/console >dev/console 2>&1
umount /old-root
Run Code Online (Sandbox Code Playgroud)

为什么是chroot必要的?它是从已经是根目录的目录中调用的(因为前面的pivot_root)。不应该

sh <dev/console >dev/console 2>&1

足够?

A.B*_*A.B 3

man pivot_root告诉:

请注意,exec chroot更改正在运行的可执行文件,如果之后应卸载旧根目录,则这是必要的。

后面提到的其他一些资源也是如此。

如果没有chroot到较新的文件系统,该umount命令将因 EBUSY 而失败,因为 shell 的进程仍在以前的文件系统中保留资源使用:shell 的二进制文件本身(以及可能的关联库)。exec chroot除了实际的chroot操作之外,还将用新文件系统上存在的不同 shell 替换 shell,从而释放前一个 shell 并允许卸载它。

更新:为什么exec(没有chroot)还不够?

手册页还告诉我们:

请注意,根据 的实现pivot_root,调用者的 root 和 cwd 可能会也可能不会改变。以下是在任一情况下都适用的调用 hub_root 的序列,假设 pivot_rootchroot位于 current 中PATH

cd new_root
pivot_root . put_old
exec chroot . command
Run Code Online (Sandbox Code Playgroud)

这里指的是pivot_root之后的root新的。因此,不使用会导致未定义的行为,而使用它则适用于所有实现。/exec chroot

例如(但我没有检查),它可能取决于内核版本或确切的系统调用及其在ivot_root(2)pivot_root(8)旁边的命令中执行的顺序,具体取决于其特定版本。