openroot is now called xchroot:

Tux at his computer freebsd devil


chroot for users with Xorg/X11 forwarding and automatic mounting + aufs/unionfs read only root support.

This page can be viewed online at

Table of Contents

JavaScript error


Chroot allows you to run commands from a different system installation without having to boot into that system. You do not even need a separate partition for the alternate system installation or root file system. This does of course only work if both systems are Linux installations or both systems are BSD derivates since they will always need a compatible kernel to be in operation. Just shared libraries (*.so, Windows: dll) are loaded from the new root on program invocation out of the chroot environment. Newer kernels use to be backward compatible. Thus chrooting into an elder system installation would always be possible. There are a few exceptions like the old ddrescue program using a deprecated kernel api which is no more supported. Backward compatibility of kernels is also the reason why statically linked programs use to continue to run even without preserving a full chroot environment for them.

Chroot is particularely useful if you have installed more than one Linux distro and want to run programs from another distro than you have actually booted to. Chroot is also widely in use for program development and packaging as it can simulate another environment very well allowing to test on multiple systems at the same time. It can also be used to run programs that are no more available for recent Linux distros.

Chroot works immediately and guarantees minimal effort. You do not have to wait until another system is booted. Memory usage is as little as possible. Under Linux it is possible for a cracker to escape from a chroot environment while chroot-jails are also considered a security feature in FreeBSD.

The only thing you basically have to do in order to change to another chroot environment (i.e. another installed system) is to issue a chroot command as root on the directory that should become the new root of the file system. Use exit to get back to your boot-root.

> chroot /dst/other-linux-system

problems with a pure chroot

Nonetheless you may find out soon that this does not work for many many programs; f.i. you are not able to run any GUI applications as you can not connect to a running X server inside a chroot environment without special provisions even under Linux which allows programs to 'escape' from chroot environments.

For further instructions on how to secure a chroot environment under Linux that does not need X access you may want to have a look at Grsecurity (though booting the system in a virtual machine is the best option for means of security.). Be aware that allowing compromized programs to connect to the same X server (the program that is responsible for graphics output under unixoid systems) together with uncompromized programs will compromize the rest of your system at least as long as no MAC (Mandatory Access System) is in place that is able to controlle your X server and adherent programs like DBUS; be it a 'secured' chroot environment or not. That can be as simple as pasting text into a root console and letting it disappear by appropriate escape sequences fractions of milliseconds thereafter!

There are even more restrictions: you can not run programs such as grub that need access to either /dev, /sys or your /proc filesystem as long as these systems are not mounted properly (i.e. recursively) into the new chroot environment. If you have installed a fresh system and want to access your old installation via xchroot you may want to verify your old installation with a tool like debcheckroot first in order not to infect your new system.

trying to resolve these problems by hand

As far as now you may already know that a pure chroot is very restricted. f.i. You can not run any GUI-applications. A workaround for this is to redirect all Xorg drawing operations through localhost: > xhost +localhost > DISPLAY=localhost:0 chroot /dst/debian;

However this does not work if your X server (being responsible for all graphical output) has been startet with the -nolisten tcp option which is on by default now for reasons of security in most modern distributions. In this case you would have to replicate the socket file /tmp/.X11-unix/X0 to /dst/debian/tmp/.X11-unix/X0 which can be done by a proper socat rather than a pure symbolic link. Pure symbolic links do not work since a link equals to the character string of the referenced file which points to something different after the chroot. Find out about the command line X has been started with by the following command:

> ps ax|grep "X[^/]* " 1959 tty7 Ss+ 75:16 /usr/bin/Xorg -br -nolisten tcp :0 vt7 -auth /var/lib/xdm/authdir/authfiles/A:0-EgqjEQ

Replicating the appropriate socket and setting $DISPLAY to the socket/display number is not the only thing you will have to do. X servers use to use an additional authentication mechanism based on cookies. The cookies are transmitted unencrypted to the X server so that they can be eavesdropped by anyone listening on the local network. Thus you may want to establish an ssh or vpn tunnel whenever you connect to a remote X server in order not to allow any other user access to the same X server who listens on the same net. Nonetheless this authentication mechanism can be used securely for different users on the same machine and whenever you do only interconnect two machines mutually by a non-eavesdroppable point to point connection.

Now in practice the file that stores the cookie for authentication with the X-server defaults either to ~/.Xauthority or whenever the $XAUTHORITY variable is set then it holds the path and file name of the Xauthority file. The access rights of these files need to be chosen in a way so that other users can not read or write to them. You may simply copy these files though the correct way for adding entries to these files goes via an xauth extract and xauth merge.

Furthermore as already discuessed programs like grub or gparted need direct access to your disk devices at /dev. You may simply mirror your /dev to /dst/my-distro/dev in this example before you issue a chroot which can be accomplished by mount --bind /dev /dst/my-distro/dev. Proceed the same way for your /sys and /proc directory which are required by many programs as an additional interface to expose and set kernel data. Note that also subdirectories may require their own mounts as /dev/pts/* for terminals.

xchroot - an extended version of chroot

Simply use xchroot instead to accomplish all these tasks automatically:

> xchroot /dst/debian

In a fact xchroot will do a whole lot more than the minimal provisions we have just discussed. Here is an overview of what xchroot can do for you:

xchroot will mount your new root filesystem and all sub-partitions as for /var /tmp /usr automatically, provided that they are listed in your /etc/fstab (you may want to specify the noauto option if a partition should not be mounted unless an xchroot is issued upon its root.). Mounting an alternative distro not before actually using it may f.i. safe you from unnecessary checkdisks after crashes on bootup or will facilitate the usage of roots on removable media. xchroot will mirror /sys, /proc and /dev and most important it will leverage the usage of GUI applications (DISPLAY=:X). Furthermore unlike with chroot you may specify any program in the chroot environment if you do not just wish to execute the bash standard shell:

> xchroot /dst/debian xterm

xchroot unmounts the helper dirs (sys,proc,dev) automatically on exit independent of the mount state at invocation time. Since version 2.0 it uses furthermore tmp-mirroring by default instead of socat-ing so that socat is no more required. Nonetheless the somewhat more secure -socat option is still available. Socat will definitely be more secure if you choose to run an own X-server for the new chroot enviroment as allowing to connect clients with different privileges to the same X-server is not recommended.

If any program in the chroot is still running on exit you are prompted to terminate it but you can also choose to leave all programs running. In this case you need to quit these programs and umount later on by invoking chroot cleanup with exactly the same parameters as before. If an xchroot/openroot is already running a normal chroot should also suffice as long as you terminate the openroot/xchroot last. On the contrary there should nothing speak against invoking multiple xchroots leaving the cleanup to the xchroot terminated last (select Leave in the menu.).

xchroot and users: the background

If you have xchroot forget all the other *chroot-s! You do not even need it to chroot as user. The --user option and sudo will serve this purpose. A simple

> xchroot -u usr /dst/debian

will do what you want provided that you execute it as root.
A simple entry in your /etc/sudoers leverages the use directly as user usr or via /etc/sudoers:

usr ALL=(root) NOPASSWD: /usr/sbin/xchroot [-]u usr /dst/* usr ALL=(root) NOPASSWD: /usr/sbin/xchroot [-]u usr [-]t /dst/*

letting you open any root under /dst as user usr. (instead of 'ALL' a host name may be stated in case that the /etc/sudoers is distributed to many hosts but should not be allowed on all of them.) You will have to be extremely careful when adding sudoer entries on your own. /etc/sudoers does not use regular expressions but shell pattern globbing which means that an asterisk "*" can stand for any combination of characters including spaces. It thus does usually only make sense to use one star per line in sudoers.

Now we do also want to pass user parameters to xchroot. Unfortunately we can not put these parameters in front of our root /dst/* (which stands for 'distribution') because otherwise we could also wildcard our root which is likely not what we want. By this reason the developers of xchroot have invented a little trick: put the -t option in front and put any option after a '--' at the end right after your root and program specification. We will show you by the following example how it works:

elm:~> sudo -E xchroot -u elm -t /dst/debchroot/ -- --unionfs (does not make use of our sudoers entry yet; just have a quick test now.) ----------------------------------------------------------- unionfs -o cow,max_files=32768,allow_other,suid,dev /tmp/xchroot/unionfs-debchroot-13653=RW:/dst/debchroot=RO /tmp/xchroot/mount-debchroot-13653 chroot /tmp/xchroot/mount-debchroot-13653 /tmp/xchroot/startup-13653 Debian GNU/Linux 7 \n \l debian_elm:~> goldendict &

Note that we have used the unsecure -E option which is disallowed by /etc/sudoers which passes all the environment variables along to the new chroot environment. In a fact the only environment variables we need to keep in order for xchroot to function are $DISPLAY, $XAUTHORITY and $XCHROOT_MYROOT. Now let us drop the -E option and merely pass along the variables we need:

elm:~> sudo xchroot -u elm /dst/debchroot/ --env DISPLAY=:0 --env XAUTHORITY=$XAUTHORITY --env XCHROOT_MYROOT=$XCHROOT_MYROOT

That`s it.

Oops?! Haven`t we forgotten about -- before the trailing options and the -t in front? These options are not required as long as you do only use --env as tail option. Note that the --user option can not be used as tail option because that would compromize our security needs.

Rather complicated?
Yes it is. This is why we have invented a macro called openroot in order to xchroots more easily as user (Well we could also have called the user macro xchroot but that might have been subject to further confusion.). Get it installed into your .bashrc which executes automatically on any bash login:

elm:~> xchroot bashrclines openroot() { sudo /usr/sbin/xchroot -u $(whoami) "$@" --env XCHROOT_MYROOT="$XCHROOT_MYROOT" --env XAUTHORITY="$XAUTHORITY" --env DISPLAY="$DISPLAY"; } elm:~> mv ~/.bashrc ~/.oldbashrc elm:~> xchroot bashrclines >>~/.bashrc elm:~> cat ~/.oldbashrc >>~/.bashrc elm:~> source ~/.bashrc

Now just have a little time to disfruit our new macro:

elm:~> openroot /dst/debchroot elm:~> openroot -t /dst/debchroot -- --aufs

xchroot and users: the easy way

xchroot has a user wrapper called openroot: It can invoke xchroot via sudo as user.

Now before we can use openroot we need to execute some administration commands as root to set up proper access rights for users.

root:~> xchroot --dirpfx /dst/ addsudoers elm adding elm with directory praefix /dst/ to /etc/sudoers ... root:~> xchroot --dir /dst/debchroot/ addsudoers shell adding shell with directory /dst/debchroot/ to /etc/sudoers ... root:~> xchroot listsudoers xchroot entries in /etc/sudoers: /usr/sbin/xchroot: elm /dst/* /usr/sbin/xchroot: elm [-]t /dst/* /usr/sbin/xchroot: elm cleanup /dst/* /usr/sbin/xchroot: elm [-]t cleanup /dst/* /usr/sbin/xchroot: shell /dst/debchroot/ * /usr/sbin/xchroot: shell [-]t /dst/debchroot/ * /usr/sbin/xchroot: shell cleanup /dst/debchroot/ * /usr/sbin/xchroot: shell [-]t cleanup /dst/debchroot/ *

Now let us have a look at the preceding commands. The first addsudoers allows the user elm to xchroot to any directory below /dst/. Note the trailing slash: It is necessary in order not to allow xchrooting to any directory name that starts with /dst. Then we allow the user shell to issue an openroot upon /dst/debchroot and only upon this directory. Finally we list all sudoer entries: addsudoers adds four sudoer entries for every access record: Allowing to invoke openroot with and without tail opts ([-]t) and finally allowing to issue cleanups for whenever you have invoked openroot with --noask, killed it or chosen to leave some programs running. Use delsudoers to delete a given group of sudoer entries. You may furthermore remove the lines with [-]t manually to disable tail option parsing for the given user.

Now what is tail option parsing? Tail option parsing allows you to put options at the end rather than letting the options precede your chroot directory and the command to execute in the new chroot. Tail options work like the following: Put the [-]t option in front and all other options at the end after an "--". This has become necessary because of the wildcarding feature of sudoers: A wildcard can stand for any combination of letters. That is why we may only wildcard after specifying user and root filesystem. Have a look at the following examples:

elm:~> openroot /dst/debchroot/ elm:~> openroot -t /dst/debchroot/ -- --aufs

The first one does not need any option, the second one needs -t in front because we have -- --aufs at the back. Note that you may add any number of options after the --. Now to make this work you need to add the openroot macro to your ~/.bashrc first:

elm:~> xchroot bashrclines >>~/.bashrc elm:~> source ~/.bashrc

The first line installs the openroot macro in your basrc (do a grep openroot ~/.bashrc to see whether it is already installed), the second line fetches the changes of your bashrc for the current session.

Now to keep things clear and to see which chroot environment you are currently working in a goodie for colorful user prompts designed especially for use with xchroot (put it in your .bashrc);

export PS1="\[\e[0;32m\]$XCHROOT_NAME${XCHROOT_NAME:+_}\[\e[0;31m\]\u:\[\e[0;33m\]\w> \[\e[0m\]"
elm:~> openroot /dst/debchroot/
xchroot - visit us on
----------------------------------------------------------- chroot /dst/debchroot /tmp/xchroot/startup-15842 Debian GNU/Linux 7 \n \l debchroot_elm:~> goldendict & ...

establishing users for a chroot environment

Now it may be the case that you have already set up openroot correctly for users but that your target chroot environment does not have the same users from which you want to issue an openroot. Simply do the following for the user elm:

root:~> grep ^elm: /etc/passwd >>/dst/debchroot/etc/passwd root:~> grep ^elm: /etc/shadow >>/dst/debchroot/etc/shadow root:~> grep ^elm /etc/passwd elm:x:1000:100:Elmar Stellnberger:/home/elm:/bin/bash root:~> grep 100 /etc/group users:x:100: root:~> grep 100 /dst/debchroot/etc/group users:x:100:

If desired you may add additional groups with usermod when xchrooting to the new root.

root:~> usermod --groups video,vboxusers elm root:~> grep elm /etc/group video:x:33:gdm,elm vboxusers:x:477:elm

Xorg/X11 access as root

Now it may be the case that you have Xorg access by issuing an openroot but not after a su or sudo su whenever you wanna become root for some purpose. Your distro should normally automatically complete this task by an adequate bash startup. However you can also establish this yourself; a topic which is not directly related to xchroot/openroot but which may be very useful in the context of openroot. The bash environment variable XAUTHORITY points to a file which is by default called ~/.Xauthority and which contains a cookie the client needs to obtain access from the Xorg/X11 server. To move the cookie from /home/usr/.Xauthority to /root/.Xauthority do an xauth extract myfile as user and an xauth merge myfile as root. Myfile may be '-' for stdin/stdout.

Now let the following code in my .bashrc slowly melt on your tongue:

if logname &>/dev/null && [ "$(logname)" != "$(id --name -u )" ] && [ -z "$XCHROOT_MYROOT" ]; then if [ -n "$XAUTH" ]; # matters whether environment variable is unset or empty; not set: should not exist. then sudo -n -u $(logname) env XAUTHORITY="$XAUTH" /usr/bin/xauth extract - $DISPLAY | xauth merge - else sudo -n -u $(logname) /usr/bin/xauth extract - $DISPLAY | xauth merge - fi else if [ -z "$XAUTH" ]; then export XAUTH="$XAUTHORITY" elif [ -z "$XAUTHORITY" ]; then export XAUTHORITY="$XAUTH" fi fi
by Elm.Stb.(c); usable under C-FSL v1.0 under

xchroot and read only roots (aufs,unionfs)

xchroot is also handy if you wanna leave your target chroot environment untouched for any kind of reason. This may be a necessity if your chroot environment is located on a read only media like your cdrom drive. Simply use the --aufs/-a or --unionfs option and be sure that either aufs or unionfs is installed.

> xchroot --aufs /dst/debian

Readonly access is established like this: Changed files are copied to /tmp/xchroot/{aufs/unionfs}-$rootname-$$ where $$ is the pid of the invoker and $rootname the name of the directory you are chrooting-into. The mount point of the two combined directories (ro+rw) is /tmp/xchroot/mount-$rootname-$$.

It is a totally new feature of xchroot-2.3 that you can also save the temporary changes you have made to your chroot-environment into a squashfs-image. Squashfs images for unionfs and aufs will differ in the naming and storage of whiteout files. Whiteout files are hidden files that make a file of the ro-root appear deleted. xchroot will ask you for unsafed changes on exit; optionally you can specify the --save my-unionfs.squashfs --noask options to make that automatically and prevent any direct user interactions (keyboard usage). Use the --restore option on a saved image:

> xchroot --aufs --restore my-aufs.squashfs /dst/debian

When restoring elder changes an additional ro-branch mounted under /tmp/xchroot/squashfs-$rootname-$$ will be established. You may need to know about /tmp/xchroot whenever you issue a killall xchroot because then it will terminate immediately after listing the processes still running in the chroot-environment without performing the standard cleanup tasks. Do not kill these processes manually; use xchroot [--aufs/--unionfs [--restore xy]] cleanup $rootdir instead. It is recommended to specify the same options as before by only adding the keyword 'cleanup' before your root directory.

When using aufs you may want to mount /tmp or /tmp/xchroot to a tmpfs in ram especially when you are using a SSD or flashdisk because aufs needs some volatile files like the inode translation table. If you do not want to pack your changes into ram then you may want to use --unionopts xino=.. to relocate the inode translation table to a proper ramfs. Caution should be given with tmpfs. It makes the inode numbers wrap around if many files are created and deleted which can make aufs err. At the time of publishing xchroot it was not known if ramfs was affected by a similar problem.

> mount -t ramfs /dev/ram7 /tmp/xchroot
> mount -t tmpfs none /tmp (not so recommended)

If you wanna be absolutely sure not to confuse aufs you may also create an ext2 image in ram and mount it to /tmp/xchroot.

Note that some kind of partitions like ext4 partitions are not mountable if burnt to read only media because they seem only having been designed for rw-media always writing the last mount time. If you want to burn a root to blue ray in order to access it later on with xchroot use ext2 or JFS a fully fast and compatible filesystem also supported by OS/2 and eComstation

xchroot and changeable media

xchroot does also mount changeable media under /media into your chroot environment. While this has proven to be practical in many situations you have to take special care when removing your changeable media during an xchroot session. Make sure that all mount points are unmounted i.e. /media/xx, /chroot/media/xxx etc.. You can check for all removable media mounts by issuing sth. like mount | grep sd[^ab] given that you have two non-removable disks called sda and sdb. Note that /media-mounting is currently only done on startup.

How to create a chroot environment

You may simply use an old system installation as chroot environment instead of booting into it via qemu-kvm, VMWare or VirtualBox. On the other hand it is not difficult to create an own minimal chroot environment that does only contain the necessary packages to run a certain software or to compile a certain package

In Debian use debootstrap to initialize a new root

> debootstrap lenny /var/xchroot/suse11.2

In Suse use zypper with the --root option to add repositories and install software:

> mkdir /var/xchroot/suse11.2 > mount /dev/sr0 /media/dvd > zypper --root /xchroot/suse11.2 ar /media/dvd/ dvd Repository 'dvd' wird hinzugefügt [fertig] Repository 'dvd' erfolgreich hinzugefügt Aktiviert: Ja Autoaktualisierung: Nein URI: dir:///media/dvd > zypper --root /xchroot/suse11.2 lr # | Alias | Name | Aktiviert | Aktualisieren --+-------+------+-----------+-------------- 1 | dvd | dvd | Ja | Nein > zypper --root /xchroot/suse11.2 in rpm zypper xterm

Making audio support work

For audio under Linux alsa is usually used for the hardware layer and pulseaudio as a software daemon. You may not hear any audio if the volume for the specified source is set to zero or if the wrong output target is selected for your application. Use alsamixer and pavucontrol to fix such issues. pavucontrol is for pulseaudio and additionally lets you select the audio sink for your application. If /run/user/1000/pulse has wrong permissions the volume utilities may not start. However this is fixed automatically by xchroot for the guest system.

Now the pulseaudio client starts the pulseaudio daemon for sound output on demand. It is started as user. Have a look at /dst/yourchroot/etc/pulse/client.conf for this purpose:

default-sink = alsa_output.pci-0000_04_07.0.analog-stereo default-source = alsa_output.pci-0000_04_07.0.analog-stereo.monitor default-server = /run/user/1000/pulse/native autospawn = yes extra-arguments = --log-target=syslog --realtime=true --high-priorty=true

Important are the default-server and the autospawn lines. The default-server directory is mounted automatically by xchroot/openroot unless --no-audio is given. The autospawn line is important to start the pulseaudio daemon when needed. Make sure that it is not overrided by an /etc/pulse/client.conf.d/00-disable-autospawn.conf file and delete this file if necessary. The default-source and default-sink parameters can be used to override the default output sink and source for the pulseaudio applications you start. That can make sense as normally you will only use one output device and you do not want to set it with pavucontrol manually all the time. The extra-arguments line is here to add the --realtime=true and --high-priorty=true parameters which we have stated for better sound quality. However the right volume level is much more important to get a good sound quality. We have found that for our setting it was necessary to reduce the volume of the xine input stream at replay while the volume level at the output device did not cause quality issues. This is somewhat contraintuitive. However we suppose that there is a maximum volume which is cropped when being transgressed at the audio stream generation. You can see the extra-arguments parameters from before if you ps the pulseaudio daemon:

> ps ax | grep pulse 708 ? S<l 1:42 /usr/bin/pulseaudio --start --log-target=syslog --realtime=true --high-priority=true 10387 pts/3 S+ 0:00 grep pulse

Now how to find out about the correct name of audio sink and source. At first you can query for them in the host system:

elm:~> /usr/bin/pactl info Failed to create secure directory (/run/user/1000/pulse): insufficient access rights #connection error: connection refused pa_context_new() failed: connection refused elm:~> sudo chown 1000 /run/user/1000/pulse elm:~> /usr/bin/pactl info Server String: /run/user/1000/pulse/native Library Protocol Version: 29 Server Protocol Version: 29 Is Local: yes Client Index: 34 Tile Size: 65472 User Name: elm Host Name: debian8 Server Name: pulseaudio Server Version: 5.0 Default Sample Specification: s16le 2ch 44100Hz Default Channel Map: front-left,front-right Default Sink: alsa_output.pci-0000_01_00.1.hdmi-stereo Default Source: alsa_output.pci-0000_01_00.1.hdmi-stereo.monitor Cookie: 4b9b:ab79

The problem with pactl and any other pusleaudio client from above can only arise in the host system as in the chroot xchroot will take care of the correct access privileges. Here you can see that the HDMI cable, i.e. the monitor cable for your display is used as default sound output which is from the graphics card. If you have another sound output, you would usually prefer this one as your monitor may either give no sound or sound output at a low quality. So how to find out about the correct audio sink and source names? Have a look at the following command:

elm:~> pactl list | grep alsa_output Name: alsa_output.pci-0000_01_00.1.hdmi-stereo Monitor Source: alsa_output.pci-0000_01_00.1.hdmi-stereo.monitor Name: alsa_output.pci-0000_04_07.0.analog-stereo Monitor Source: alsa_output.pci-0000_04_07.0.analog-stereo.monitor Name: alsa_output.pci-0000_01_00.1.hdmi-stereo.monitor Monitor of Sink: alsa_output.pci-0000_01_00.1.hdmi-stereo Name: alsa_output.pci-0000_04_07.0.analog-stereo.monitor Monitor of Sink: alsa_output.pci-0000_04_07.0.analog-stereo

general issues with audio support under Linux

At first you will of course need to make audio work for your host system. Here are some additional hints on this in addition to the hints from the last section. However the description here is completely independent from xchroot and can be used for any Linux system.

First of all note that viewing cotrols with pavucontrol and alsamixer may be insufficient. At me there was a hidden control for the SPDIF/IEC958 digital audio output:

> amixer controls numid=31,iface=MIXER,name='IEC958 Output Switch' … > amixer get 'IEC958 Output' Simple mixer control 'IEC958 Output',0 Capabilities: pswitch pswitch-joined Playback channels: Mono Mono: Playback [off] > amixer set 'IEC958 Output' unmute Simple mixer control 'IEC958 Output',0 Capabilities: pswitch pswitch-joined Playback channels: Mono Mono: Playback [on]

It may be handy to directly test and configure sound output at the alsa level. To do so set autospawn to no in /etc/pulse/client.conf and do a killall pulseaudio. Otherwise the alsa sources and sinks may be occupied and not free for use by aplay. Now you can test hardware devices like this: aplay -D hw:0,2 Track03.wav. But how to find out about the right output device? I knew from pavucontrol that IEC958 named my digital SPDIF output.

> cat /proc/asound/cards 0 [CMI8738 ]: CMI8738-MC6 - C-Media CMI8738 C-Media CMI8738 (model 55) at 0x3000, irq 21 2 [HDMI ]: HDA-Intel - HDA ATI HDMI HDA ATI HDMI at 0xfc220000 irq 35 > cat /proc/asound/devices 2: [ 0- 0]: digital audio playback 3: [ 0- 0]: digital audio capture 4: [ 0- 1]: digital audio playback 5: [ 0- 2]: digital audio playback 6: [ 0- 2]: digital audio capture 7: [ 0- 0]: raw midi 8: [ 0- 0]: hardware dependent 9: [ 0] : control 10: [ 2- 3]: digital audio playback 11: [ 2- 0]: hardware dependent 12: [ 2] : control 33: : timer > cat /proc/asound/card0/pcm2c/info card: 0 device: 2 subdevice: 0 stream: CAPTURE id: CMI8738-MC6 name: C-Media PCI IEC958 subname: subdevice #0 class: 0 subclass: 0 subdevices_count: 1 subdevices_avail: 1

Now not all output devices support all sampling rates. My Bose sound bar does f.i. work well at 48kHz or 96kHz but not at 192kHz. You may define rate settings in a file often called /etc/asound.conf. However at me I had to create such a file /usr/share/alsa/alsa.conf.d. ~/.asoundrc should also do it. There you can define aliases used with aplay -D instead of hw0,1.

pcm.raw3 { type hw card 0 device 2 }

Test with aplay whether the target is avaiable and the config file has been parsed correctly. Here is a way to define a default sampling rate for such a device:

pcm_slave.slout3 { pcm "hw:0,2" rate 96000 } pcm.out3 { type rate slave slout3 }

If you do not have a .wav file handy for testing, speaker-test is what you want: speaker-test -c2 --device out3 [--rate 48000]. The tool is said to also initialize some parameters so playback may work better/ start to work after an invocation.

Finally make sure whether your sound card requires some additional firmware support. For Debian the usually proprietary firmware does not get installed automatically. However it can be downloaded from Then you can query for sound support by the Linux kernel via ls /sys/class/sound/. In our case we have two sound cards card0 and card2. The kernel driver for a sound card can be obtained like this:

> cat /sys/class/sound/card0/device/uevent DRIVER=snd_ens1371 PCI_CLASS=40100 PCI_ID=1274:1371 PCI_SUBSYS_ID=1274:1371 PCI_SLOT_NAME=0000:04:07.0 MODALIAS=pci:v00001274d00001371sv00001274sd00001371bc04sc01i00 > lspci | grep 04:07.0 04:07.0 Multimedia audio controller: Ensoniq ES1371 / Creative Labs CT2518 [AudioPCI-97] (rev 08) > modinfo snd_ens1371 filename: /lib/modules/4.19.67-rt24/kernel/sound/pci/snd-ens1371.ko description: Ensoniq/Creative AudioPCI ES1371+ license: GPL author: Jaroslav Kysela , Thomas Sailer alias: pci:v00001102d00008938sv*sd*bc*sc*i* alias: pci:v00001274d00005880sv*sd*bc*sc*i* alias: pci:v00001274d00001371sv*sd*bc*sc*i* depends: snd-pcm,snd,snd-rawmidi,gameport,snd-ac97-codec retpoline: Y intree: Y name: snd_ens1371 vermagic: 4.19.67-rt24 SMP preempt mod_unload modversions parm: index:Index value for Ensoniq AudioPCI soundcard. (array of int) parm: id:ID string for Ensoniq AudioPCI soundcard. (array of charp) parm: enable:Enable Ensoniq AudioPCI soundcard. (array of bool) parm: joystick_port:Joystick port address. (array of int) parm: spdif:S/PDIF output (-1 = none, 0 = auto, 1 = force). (array of int) parm: lineio:Line In to Rear Out (0 = auto, 1 = force). (array of int)

The actual model parameters can be queried via /sys/class/sound/card2/device/driver/module/parameters/ and stated at modprobe time. Before you can actually re-insert a kernel module you may need to remove it with rmmod -f. Query with lsmod | grep name whether it is loaded. Set boot time module parameters in /etc/modprobe.d/:

> cat /etc/modprobe.d/modesetting.conf options cirrus modeset=1 options mgag200 modeset=1

The lines from above show module parameters for some graphics cards. Similarely to audio graphics cards may require the right firmware to be installed.

Things that are new in version v2.4


get it!

xchroot v2.5.3 some important but yet not fully tested bugfixes towards v2.5
xchroot v2.5 mount-mirroring, cleanup: faster exit, message printing
xchroot v2.4.1 bugfix on unmounting, no spurious message on relative dir chroot, keep dir when already inside chroot
xchroot v2.4 + man page improved --quiet, added --genuine-retval, making use of chroot --userspec (changelog: see the first lines of the program)
xchroot v2.3.4 + man page improved --quiet, added --genuine-retval, making use of chroot --userspec (changelog: see the first lines of the program)
xchroot v2.3.3 + man page chroot: openroot between different users, security fix when users have same name but are different; cd into home directory; license update.
xchroot v2.3.2 + man page recommended security fixes; license update.
xchroot v2.3.1 + man page some minor bugfixes including XAUTHORITY handling for remote hosts; license allowing to distribute modified versions of xchroot
xchroot v2.3 renewed aufs & unionfs support; totally new features like --save & --restore
xchroot v2.25 several bugfixes towards v2.2; see changelog at beginning of file
xchroot v2.1 first completely reworked edition; without aufs support
openroot v2.0 xchroot as it was called before
openroot v1.1 ancient xchroot (usage descouraged)
*** new *** covered by our gpg-signed software/SHA512SUMS.signed.
online changelog:
ViewRSS: xchroot
Elmar Stellnberger


Since v2.3.4 xchroot is GPLv3. Please sign our Contributor License Agreement if you want to contribute code. Otherwise we can not assimilate and re-distribute your changes here at

Hint: Don`t forget to chmod +x xchroot; good place would be /usr/sbin and copy the man page renamed int xchroot.8.gz into /usr/share/doc/man/man8


Britten Kerin wrote:

I love it, I hope you keep maintaining it, help propagate it into distros, etc.

I wanted to debug a weird assertion violation in inkscape that I suspect
is due to my weird random stack of gnome libs, I asked on garnome
list and even the garnome enthusiasts said to run in fear and just use
a chroot...

But of course chroot with X isn't totally automatic these days, until you
find openchroot! Thanks so much for this handy little script, it succeeded
where all the old broken advice on how to get X going in a chroot either
failed or wasn't what I wanted (I have no desire to restart X every time I
test of run an extra GDM or anything like that).

Very sweet.