chroot

来自 Arch Linux 中文维基

Chroot 是一种修改当前进程及其子进程的可见根目录的操作。修改后,进程将不能访问该环境目录树以外的任何文件和命令,这种修改后的环境叫作 chroot jail(直译为 chroot 监狱)。

原因[编辑 | 编辑源代码]

改变根目录通常是为了在无法启动或登录的系统上进行系统维护,例如:

另见 Wikipedia:Chroot#Limitations

必要条件[编辑 | 编辑源代码]

  • root 权限
  • 另一个 linux 环境,例如 liveCD、USB 闪存介质或者一个已经安装的另一个 linux 发行版。
  • 匹配的架构,chroot 前后的环境架构要一致(例如,都是 i686 或 x86_64)。可以用以下命令查看当前环境的架构
    uname -m
  • 提前加载 chroot 环境需要的内核模块
  • 如果需要 swap, chroot 前先启用 swap (swapon /dev/sdxY
  • 如果需要网络,chroot 之前先建立好网络连接。

用法[编辑 | 编辑源代码]

注意:
  • 有些systemd 工具无法在 chroot 中运行,例如 hostnamectllocalectltimedatectl,因为这些程序需要可用的 dbus 连接。 [1]
  • 新的 root (/) 所在的文件系统必须是可用访问的状态(提前解密、挂载)。

有两种使用 chroot 的方式:

使用 arch-chroot[编辑 | 编辑源代码]

arch-chroot bash 脚本是软件包 arch-install-scripts 的一部分,在运行 /usr/bin/chroot 前,这个脚本会挂载类似 /proc 的 API 文件系统,建立可用的 /etc/resolv.conf

进入 chroot

# arch-chroot /location/of/new/root

例如在安装指南中,chroot 到 /mnt:

# arch-chroot /mnt

退出 chroot:

# exit

运行一个命令并退出[编辑 | 编辑源代码]

用下面命令在 chroot 中运行一个命令并退出:

# arch-chroot /location/of/new/root mycommand

例如要在 /mnt/arch 中运行 mkinitcpio -p linux 并退出:

# arch-chroot /mnt/arch mkinitcpio -p linux

使用 chroot[编辑 | 编辑源代码]

警告: 使用 --rbind 选项时,将无法卸载某些 dev/sys/ 的子目录,用 umount -l 卸载将会破坏会话并需要重启,所以请尽可能使用 -o bind

在下面的例子中,/location/of/new/root 代指新的根目录所在的文件夹。 首先,临时挂载 API 文件系统:

# cd /location/of/new/root
# mount -t proc /proc proc/
# mount -t sysfs /sys sys/
# mount --rbind /dev dev/

可选挂载:

# mount --rbind /run run/

如果正运行在 UEFI 系统,则还需要能够访问 EFI 变量,不然在安装 GRUB 时会得到类似这样的消息:UEFI variables not supported on this machine

# mount --rbind /sys/firmware/efi/efivars sys/firmware/efi/efivars/

如果已经建立了一个网络连接并且想在 chroot 环境中继续使用,将 DNS 服务器配置复制到新环境:

# cp -L /etc/resolv.conf etc/resolv.conf

chroot 到新环境中并启用指定 shell

# chroot /mnt/arch /usr/bin/bash
注意:
  • 如果遇到错误 chroot: cannot run command '/bin/bash': Exec format error,很可能是因为两个环境架构不匹配。
  • 如果遇到错误 chroot: '/usr/bin/bash': permission denied,用执行权限重新挂载: mount -o remount,exec /location/of/new/root
    • 如果以上方式无效,那么请确保新环境的基础组件完整(如果是 Arch 根目录,请尝试 paccheck --root=/location/of/new/root --files --file-properties --md5sum glibc filesystem,来自 pacutils)。

(可选)加载 Bash 配置文件(~/.bashrc/etc/bash.bashrc),运行:

# source ~/.bashrc
# source /etc/profile

或创建一个独特的提示符来区别你的chroot环境:

# export PS1="(chroot) $PS1"

退出 chroot 环境:

# exit

然后卸载临时文件系统:

# cd /
# umount --recursive /location/of/new/root

如果出现 /mnt(或其它任何分区) is busy, 这可能意味着:

  • chroot环境中残留了一个运行的程序或者还有分区没有被卸载,退出程序并用 findmnt -R /location/of/new/root 查找然后卸载未卸载的分区。
  • 如果你仍然不能卸载分区,使用--force选项:
    # umount -f /mnt
    , 或使用 umount --lazy 直接释放挂载。这是,请立即重启系统以避免不一致的状态导致冲突。

在 chroot 中运行图形程序[编辑 | 编辑源代码]

如果系统上运行了X,可以在 chroot 环境启动图形应用。

为了chroot环境能连接到你的X服务器,在X服务器中打开一个终端(例如,在用户当前登录的桌面中),然后运行如下命令给任何人连接到用户X服务器的权限(另见 Xhost):

$ xhost +local:

然后,从chroot环境中将应用指向你的X服务器,将chroot中的DISPLAY环境变量设定成和拥有X服务器的用户DISPLAY变量相匹配。例如运行:

$ echo $DISPLAY

作为拥有X服务器的用户查看DISPLAY的值。如果是“:0”(例如是),然后在chroot环境中运行

# export DISPLAY=:0

现在就可以从chroot命令行启动图形界面应用

不使用 root 权限[编辑 | 编辑源代码]

Chroot 需要 root 权限,有时用户并没有这个权限,下面工具可用实现类似的功能:

PRoot[编辑 | 编辑源代码]

PRoot 可用在没有 root 权限的情况下,用 mount --bind 设置可见根目录,这样可用为不同的 CPU 架构编译程序。这个程序的缺点是文件属于主机系统。可用用 --root-id 选项解决一部分问题。

Fakechroot[编辑 | 编辑源代码]

fakechroot 是一个拦截 chroot 调用并伪造结果的程序。用 fakeroot 可用为普通用户伪造一个 chroot 环境:

$ fakechroot fakeroot chroot ~/my-chroot bash

Unshare[编辑 | 编辑源代码]

Unshare 是 util-linux 的一部分,可以用来创建新的内核命名空间。它使用常规的 chroot 命令运行,例如:

$ unshare --map-root-user chroot ~/namespace /bin/sh

疑难解答[编辑 | 编辑源代码]

arch-chroot: /location/of/new/root is not a mountpoint. This may have undesirable side effects.[编辑 | 编辑源代码]

执行 arch-chroot /location/of/new/root 命令后,出现以下警告:

==> WARNING: /location/of/new/root is not a mountpoint. This may have undesirable side effects.

arch-chroot(8) 中的解释和使用绑定挂载让 chroot 目录变成挂载点的例子。

另见[编辑 | 编辑源代码]