Chroot

From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a translated version of the page Chroot and the translation is 8% complete.
Outdated translations are marked like this.
Resources

Chroot(Change root - Kökü değiştir), var olan kök dizinden farklı bir dizini kök dizin kabul ederek, ana sistemden mantıken bağımsız bir izole ortama geçiş yapmayı sağlayan bir Unix sistem aracıdır. Bu ortam "chroot hapishanesi" diye de anılır. Bu hapishanede çalışan kullanıcı, kendisine kök olarak tanımlanmış dizinin dışarısını göremez.

Chroot'un ana kullanım alanlarından birisi Linux sistemi içerisinde test veya uyumluluk amaçlı farklı bir sistem ortamı yaratmaktır. Sanallaştırma yazılımı gerektirmediği için genelde sanallaştırmaya hafif bir alternatif olarak görülür.

Prerequisites

Ortamın ayarlanması

Yeni bir kuruluma başlarken ilk olarak yapmanız gereken işlem chroot olarak kullanılacak dizinin oluşturulmasıdır, örneğin /mnt/chrootdizini

user $mkdir /mnt/chrootdizini
user $cd /mnt/chrootdizini

Farklı bir disk bölümünde zaten var olan bir kurulumu bağlamak isterseniz aşağıdaki komutu çalıştırabilirsiniz. <AYGIT> yerine kurulumun yapıldığı disk bölümün girdiğinize emin olun:

user $mkdir /mnt/chrootdizini
user $mount /dev/AYGIT /mnt/chrootdizini

Zaten bulunduğunuz kök dizinin altında bir kurulum var ise, yukarıdaki adımları uygulamanıza gerek yok.

Yeni kurulum için sistem ve Portage dosyalarını açma

Yeni bir kurulum yapıyorsanız, sonraki adım stage3 ve Portage sıkıştırılmış dosyalarını indirip chroot dizini içerisine açmaktır. Detaylı bilgi için kurulum dökümanının 5a ve 5b bölümlerine göz atınız.

root #tar xvjpf stage3-*.tar.bz2 -C /mnt/chrotdizini
root #tar xvjf portage-*.tar.bz2 -C /mnt/chrotdizini/usr

Yapılandırma

Chroot'a giriş yapmadan önce bazı dizinleri bağlamamız (mount etmemiz) gerekmekte:

root #mount -o bind /dev /mnt/chrootdizini/dev
root #mount -t proc none /mnt/chrootdizini/proc
root #mount -o bind /sys /mnt/chrootdizini/sys
root #mount -o bind /tmp /mnt/chrootdizini/tmp

Ayrıca ana sistemden bazı temel yapılandırma dosyalarını da kopyalamalısınız. Bu aşamada yeni kurulum değilse make.conf dosyasını kopyalamayın:

user $cp /etc/portage/make.conf /mnt/chrootdizini/etc/portage # Yeni kurulum değilse bu adımı es geçin.
user $cp /etc/resolv.conf /mnt/chrootdizini/etc

Usage

Artık chroot ortamına giriş yapabiliriz:

root #chroot /mnt/chrootdizini /bin/bash
root #env-update
root #source /etc/profile
root #export PS1="(chroot) $PS1"

Yeni kurulum sırasında Pportage'ı senkronize edip herşeyin güncel olduğuna emin olun.

root #emerge --sync

Sistem artık hazır. Yeni yazılım kurabilir, yapılandırma değişiklikleri yapabilir ve dilediğiniz paketleri test edebilirsiniz. Chroot altında yaptığınız işlemlerin ana sisteme herhangi bir etkisi olmayacaktır. Ortamdan çıkıp ana sisteme dönmek için exit komutu verebilir veya Ctrl+D kombinasyonunu kullanabilirsiniz. Bağladığınız dizinleri ayırmayı (umount) unutmayın.

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 betikleri

Eğer bu işlemi sık yapıyorsanız, chroot için gerekli dizinlerin bağlanmasını init betiği kullanarak hızlandırabilirsiniz:

Dosya /etc/init.d/chrootbagla
#!/sbin/runscript
 
depend() {
   need localmount
   need bootmisc
}
 
start() {
     ebegin "Chroot dizinleri baglaniyor"
     mount -o rbind /dev /mnt/chrootdizini/dev > /dev/null &
     mount -t proc none /mnt/chrootdizini/proc > /dev/null &
     mount -o bind /sys /mnt/chrootdizini/sys > /dev/null &
     mount -o bind /tmp /mnt/chrootdizini/tmp > /dev/null &
     eend $? "Chroot dizinleri baglanirken hata olustu"
}
 
stop() {
     ebegin "Chroot dizinleri ayriliyor"
     umount -f /mnt/chrootdizini/dev > /dev/null &
     umount -f /mnt/chrootdizini/proc > /dev/null &
     umount -f /mnt/chrootdizini/sys > /dev/null &
     umount -f /mnt/chrootdizini/tmp > /dev/null &
     eend $? "Chroot dizinleri ayrilirken hata olustu"
}

Eğer farklı bir dizin veya disk bölümü kullanıyorsanız gerekli değişiklikleri yapmayı unutmayın.

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]

  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.
  2. If WAYLAND_DISPLAY is set, concat with XDG_RUNTIME_DIR to form the path to the Unix socket.
  3. 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 /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:

Ayrıca bkz.

External resources

References

  1. https://wayland-book.com/protocol-design/wire-protocol.html
  2. So if DISPLAY=:12, then Xorg will listen on localhost TCP port 6012