Chroot
chroot (Change root) はメインシステムの root ディレクトリから論理的に分離された環境を作るために、見掛け上の root ディレクトリを変更する目的で使われる Unix システムのユーティリティです。この新しい環境は "chroot jail" (訳注:「chroot 監獄」) として知られています。jail の中にいるユーザーからは閉じこめられている環境の外側にあるファイルを見ることもアクセスすることもできません。
chrootの主な使い方の一つとして、ソフトウェアの互換性やテストの為に、現在のシステムの上に、分離されたLinuxシステムを作るものがあります。ハイパーバイザーのオーバーヘッドが無いので、これはしばしば軽量な仮想化の代替としてみられます。
前提条件
環境構築
新しく chroot 環境を作る時にはまず、chroot 環境をその中に置くためのディレクトリを作る必要があります。例えば chroot 環境を /mnt/mychroot に作成することができます:
root #
mkdir /mnt/mychroot
root #
cd /mnt/mychroot
既にインストールされたシステムをマウントしたい場合は、次のコマンドが使えるでしょう。例に書かれた <DEVICE>
は実際のドライブやパーティションに合わせて書き換えてください:
root #
mkdir /mnt/mychroot
root #
mount /dev/<DEVICE> /mnt/mychroot
もしあなたが今いるルートファイルシステムのサブディレクトリに既にシステムをインストールしてあれば、上のステップを繰り返し実行する必要はありません。
システムファイルを展開する
新しいシステムをインストール中であれば、次のステップは stage3 tarball をダウンロードして chroot の場所に展開することです。この手順についてのより詳しい情報は、Gentoo ハンドブックの stage tarball をダウンロードすると stage tarball を展開するを参照してください。
root #
links http://distfiles.gentoo.org/releases/amd64/autobuilds/
root #
tar xvjpf stage3-*.tar.bz2 -C /mnt/mychroot
設定
chroot に入る前にいくつかのディレクトリをマウントしておかなければなりません:
root #
mount --rbind /dev /mnt/mychroot/dev
root #
mount --make-rslave /mnt/mychroot/dev
root #
mount -t proc /proc /mnt/mychroot/proc
root #
mount --rbind /sys /mnt/mychroot/sys
root #
mount --make-rslave /mnt/mychroot/sys
root #
mount --rbind /tmp /mnt/mychroot/tmp
root #
mount --bind /run /mnt/mychroot/run
そして基本的な設定ファイルもホストからコピーしておく必要があります。既存のシステムを使っている場合は /etc/portage/make.conf をコピーしてはいけません:
root #
cp /etc/portage/make.conf /mnt/mychroot/etc/portage # 既存のシステムを使う場合、このコマンドは省いてください。
root #
cp /etc/resolv.conf /mnt/mychroot/etc
使い方
以上の作業が完了すれば、以下のコマンドで新しい chroot 環境に入ることができます:
root #
chroot /mnt/mychroot /bin/bash
root #
. /etc/profile
root #
export PS1="(chroot) $PS1"
新規インストールの場合は、全てを確実に最新にするために Portage を同期してください。
(chroot) root #
emerge-webrsync
(chroot) root #
emerge --sync
これでシステムは使用可能になりました。メインのシステムに何一つ影響を与えることなく、ソフトウェアをインストールしたり、メチャクチャな設定をしたり、実験的なパッケージや設定を試したり、自由にやってください。chroot 環境から抜けるには単に exit を入力するか、Ctrl + d を押してください。これで操作中のコンソールはいつもの環境に戻って来ます。マウントしたディレクトリをアンマウントするのを忘れないでください。
systemd-nspawn
If the system uses systemd, systemd-nspawn can be used, which can automatically handle much of the boilerplate required in administering chroots. For example, to enter a chroot via systemd-nspawn with the same configuration as specified in the Configuration section, simply run:
root #
cp /etc/portage/make.conf /mnt/mychroot/etc/portage
root #
systemd-nspawn -D /mnt/mychroot --bind=/tmp --resolv-conf=/etc/resolv.conf
Init スクリプト
頻繁に chroot の構築を行うのであれば、次の init script を使うことで chroot のためのマウントを速くできます。スクリプトはデフォルトのランレベルに追加することができ、システム起動時に自動的にセットアップされます:
/etc/init.d/mychroot
#!/sbin/openrc-run
depend() {
need localmount
need bootmisc
}
start() {
ebegin "Mounting chroot directories"
mount -o rbind /dev /mnt/mychroot/dev > /dev/null &
mount -t proc none /mnt/mychroot/proc > /dev/null &
mount -o bind /sys /mnt/mychroot/sys > /dev/null &
mount -o bind /tmp /mnt/mychroot/tmp > /dev/null &
eend $? "An error occurred while mounting chroot directories"
}
stop() {
ebegin "Unmounting chroot directories"
umount -f /mnt/mychroot/dev > /dev/null &
umount -f /mnt/mychroot/proc > /dev/null &
umount -f /mnt/mychroot/sys > /dev/null &
umount -f /mnt/mychroot/tmp > /dev/null &
eend $? "An error occurred while unmounting chroot directories"
}
異なったディレクトリやパーティションを使う場合は、必要なマウントコマンドをstart()
に追加して、異なる名前を使う場合は/mnt/chrootを適切な名前に変更してください。
Sound and graphics
The software running inside the chroot will by default not have access to the system sound- and display-server. Fixing this is done by either sharing a socket, or by running the communication with TCP over localhost.
Wayland
Wayland uses a socket to connect clients with the compositor. This socket needs to be shared with the chroot to make graphical applications work. The general procedure for finding this socket is:[1]
- If WAYLAND_SOCKET is set, interpret it as a file descriptor number on which the connection is already established, assuming that the parent process configured the connection for us.
- If WAYLAND_DISPLAY is set, concat with XDG_RUNTIME_DIR to form the path to the Unix socket.
- Assume the socket name is
wayland-0
and concat with XDG_RUNTIME_DIR to form the path to the Unix socket.
Using WAYLAND_DISPLAY and XDG_RUNTIME_DIR is fine in most cases and will be used here. By default XDG_RUNTIME_DIR is set to /run/user/$(uid). This directory will not be available in the chroot because the #Configuration instructions bind mounts /run non-recursively. Assuming the user's uid is 1000, this can be solved by either bind-mounting {{Path|/run/user/1000 with:
root #
mkdir -p /mnt/mychroot/run/user/1000
root #
mount --bind /run/user/1000 /mnt/mychroot/run/user/1000
or by simply recursively bind mounting /run with:
root #
mount --rbind /run /mnt/mychroot/run
The Wayland library dev-libs/wayland uses the same procedure for finding out the socket as listed above. So to share the socket with the chroot, the only thing that's needed to do is defining XDG_RUNTIME_DIR and WAYLAND_DISPLAY. Here it is assumed that the Wayland socket name WAYLAND_DISPLAY is wayland-0
.
(chroot) root #
useradd -m user
(chroot) root #
su -l user
(chroot) user $
export XDG_RUNTIME_DIR=/run/user/1000
(chroot) user $
export WAYLAND_DISPLAY=wayland-0
(chroot) user $
MOZ_ENABLE_WAYLAND=1 firefox-bin
Permission errors will occur if the user in the chroot does not have permissions to access the Wayland socket. This can be solved by using user namespace remapping or ACLs. The easiest solution is to just make sure that the user ids match. The useradd -u, --uid UID option can be used when creating a user.
PipeWire
Like Wayland, PipeWire uses a socket to connect clients to the PipeWire daemon.
Applications assume that the PipeWire socket will be located in ${XDG_RUNTIME_DIR}/pipewire-0
,
so the only thing that's needed to get PipeWire clients to connect to the host's daemon is to expose
XDG_RUNTIME_DIR to the chroot. This process is identical to the one described in #Wayland.
To expose XDG_RUNTIME_DIR, often /run/user/$(uid), the following commands are used:
root #
mkdir -p /mnt/mychroot/run/user/1000
root #
mount --bind /run/user/1000 /mnt/mychroot/run/user/1000
XDG_RUNTIME_DIR will not be set when logging in inside the chroot, therefore XDG_RUNTIME_DIR needs to exported so the PipeWire client can find the socket:
(chroot) user $
export XDG_RUNTIME_DIR=/run/user/1000
(chroot) user $
pw-cli
Xorg
Xorg by default listens on a socket located in /tmp/.X11-unix/X${DISPLAY}
, as well as on localhost TCP port 6000 + ${DISPLAY}
[2]. The instructions in #Configuration bind mounts /tmp, and therefore no additional configuration is needed except setting the DISPLAY variable before running a graphical application:
(chroot) user $
DISPLAY=:0 firefox-bin
If the uid of the user inside the chroot does not match the uid outside the chroot, then setting permissions with xhost will be needed. To allow all local connections, run outside the chroot:
user $
xhost +local:
関連項目
- Project:X86/Chroot Guide — provides instructions on how to create chroots to assist in testing Gentoo packages for stabilization.
- Knowledge Base:Chrooting returns exec format error
- Chrooting proxy services
- Chrooting and virtual servers
- PRoot — a user-space implementation of chroot, mount --bind, and binfmt_misc.
外部資料
- chroot on Archlinux's wiki
参照
- ↑ https://wayland-book.com/protocol-design/wire-protocol.html
- ↑ So if DISPLAY=:12, then Xorg will listen on localhost TCP port 6012