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 目錄變成掛載點的例子。

另見[編輯 | 編輯原始碼]