据我了解(如果我错了,请纠正我),这些命令的语义是:
- 每个进程都有一个根文件系统(即安装在上的文件系统
/
)。 - 子进程继承其父进程的根文件系统。
chroot
使用新的根文件系统启动一个新进程(而不是从父进程继承)。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
请注意,这
exec chroot
会改变正在运行的可执行文件,如果之后要卸载旧的根目录,那么这是必需的。
正如后面提到的,其他一些资源也是如此。
没有chroot迁移到较新的文件系统时,该umount
命令将失败并显示 EBUSY,因为 shell 的进程仍在使用前一个文件系统中的资源:shell 的二进制文件本身(以及可能关联的库)。exec chroot
除了实际的chroot操作,用新文件系统上存在的不同 shell 替换该 shell,从而释放前一个 shell 并允许将其卸载。
更新:为什么exec
(没有chroot
)还不够?
手册页还告诉:
注意,根据的实现
pivot_root
,调用者的root和cwd可能会改变也可能不会改变。以下是调用pivot_root的序列,在任何一种情况下都可以工作,假设pivot_root
和chroot
处于当前PATH
:cd new_root pivot_root . put_old exec chroot . command
这里指的root
是/
枢轴根。因此,不使用exec chroot
会导致未定义的行为,而使用它将适用于所有实现。
例如(但我没有检查),它可能取决于内核版本或确切的系统调用及其在命令中的顺序pivot_root(8)
旁枢轴根(2),具体取决于其具体版本。