Chroot

From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a translated version of the page Chroot and the translation is 100% complete.
Resources

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 xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner -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

システムが systemd を使用している場合は、systemd-nspawn を使用することで、chroot 環境を管理するのに必要なボイラープレートの多くを自動的に扱うことができます。例えば、systemd-nspawn を利用して設定の節で指定したものと同じ設定を持つ chroot 環境に入るには、単に以下を実行してください:

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を適切な名前に変更してください。

音声と映像

chroot 内で実行しているソフトウェアは、デフォルトではシステムのサウンドおよびディスプレイのドライバへのアクセス権限を持たないでしょう。これは、ソケットを共有するか、localhost 上で TCP 通信を行うことで修正されます。

Wayland

Wayland はクライアントをコンポジタと接続するためにソケットを使用します。グラフィカルアプリケーションを動作させるには、このソケットを chroot 環境と共有する必要があります。このソケットを見つけるための一般的な手順は以下の通りです:[1]

  1. WAYLAND_SOCKET が設定されている場合は、親プロセスがクライアントのために接続を構成しているとして、その接続が確立されたファイルディスクリプタの番号としてその値を解釈してください。
  2. WAYLAND_DISPLAY が設定されている場合は、XDG_RUNTIME_DIR と結合して Unix ソケットへのパスとしてください。
  3. ソケット名は wayland-0 であるとみなして、XDG_RUNTIME_DIR と結合して Unix ソケットへのパスとしてください。

多くの場合は WAYLAND_DISPLAY および XDG_RUNTIME_DIR を使用するのが良い方法で、ここでもそれを使用します。デフォルトでは XDG_RUNTIME_DIR/run/user/$(uid) に設定されています。#Configuration の指示は /run を非再帰的にバインドマウントするので、このディレクトリは chroot 内からは利用できないでしょう。ユーザの uid が 1000 であると仮定して、これは次のように /run/user/1000 をバインドマウントすることで解決できます:

root #mkdir -p /mnt/mychroot/run/user/1000
root #mount --bind /run/user/1000 /mnt/mychroot/run/user/1000

あるいは次のように、単に /run を再帰的にバインドマウントすることでも解決できます:

root #mount --rbind /run /mnt/mychroot/run

Wayland ライブラリ dev-libs/wayland はソケットを見つけるために、上に示したのと同じ手続きを使用します。そのため chroot とソケットを共有するために必要なのは、XDG_RUNTIME_DIRWAYLAND_DISPLAY を定義することだけです。ここで Wayland ソケット名 WAYLAND_DISPLAYwayland-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

chroot 内のユーザが Wayland ソケットにアクセスする権限を持っていないと、権限エラーが発生するでしょう。これは、ユーザ名前空間再マッピングまたは ACL を使用することで解決できます。最も簡単な解決策はユーザ ID が一致するようにすることです。ユーザを作成するときに、useradd -u, --uid UID オプションを使用することができます。

PipeWire

Wayland と同様に、PipeWire ではクライアントを PipeWire デーモンと接続させるためにソケットを使用します。

アプリケーションは PipeWire ソケットが ${XDG_RUNTIME_DIR}/pipewire-0 に置かれていると仮定するので、PipeWire クライアントをホストのデーモンに接続させるために必要なことは XDG_RUNTIME_DIR を chroot に公開することだけです。このプロセスは #Wayland で説明したのとまったく同じです。 XDG_RUNTIME_DIR は /run/user/$(uid) であることが多いですが、これを公開するには以下のコマンドを使用します:

root #mkdir -p /mnt/mychroot/run/user/1000
root #mount --bind /run/user/1000 /mnt/mychroot/run/user/1000

chroot 環境にログインしたときに XDG_RUNTIME_DIR は設定されないでしょうから、PipeWire クライアントがソケットを見つけられるように、XDG_RUNTIME_DIR を export する必要があります:

(chroot) user $export XDG_RUNTIME_DIR=/run/user/1000
(chroot) user $pw-cli

Xorg

Xorg はデフォルトでは、/tmp/.X11-unix/X${DISPLAY} に置かれているソケットと、localhost の TCP ポート 6000 + ${DISPLAY}[2] で待ち受けます。#Configuration の指示で /tmp をバインドマウントしているので、グラフィカルアプリケーションを起動する前に DISPLAY 変数を設定することを除いて、追加の設定は不要です:

(chroot) user $DISPLAY=:0 firefox-bin

chroot 環境内のユーザの uid が chroot 環境の外のユーザの uid とマッチしない場合は、xhost でパーミッションを設定する必要があるでしょう。すべてのローカル接続を許可するには、chroot 環境の外で次を実行してください:

user $xhost +local:

関連項目

外部資料

参照

  1. https://wayland-book.com/protocol-design/wire-protocol.html
  2. つまり DISPLAY=:12 なら、Xorg は localhost の TCP ポート 6012 で待ち受けるでしょう