在pivot_root之后使用chroot

在pivot_root之后使用chroot

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

  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

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

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

足够?

答案1

man pivot_root告诉:

请注意,这exec chroot会改变正在运行的可执行文件,如果之后要卸载旧的根目录,那么这是必需的。

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

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

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

手册页还告诉:

注意,根据的实现pivot_root,调用者的root和cwd可能会改变也可能不会改变。以下是调用pivot_root的序列,在任何一种情况下都可以工作,假设 pivot_rootchroot处于当前PATH

cd new_root
pivot_root . put_old
exec chroot . command

这里指的root/枢轴根。因此,不使用exec chroot会导致未定义的行为,而使用它将适用于所有实现。

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

相关内容