Mandatory warning: What follows is for testing only, and insecure (root all over the place, giving access to host devices from the container, etc.).

Problem of the day

  • It’d be nice to package Wayland. It’s been split in several repositories: one for the core protocol/library implementation; one for the demo compositor and clients.
  • Easy? Not quite, mesa needs to be rebuilt against the library. Doing so on a system running stable doesn’t seem too good: some newer libraries might be needed; and using make install could make it harder to remember additional bits installed all over the place ($DESTDIR is our friend but that might mean more work on the build system side to get everything detected).
  • What about having the whole development environment running in a Linux container? That’s what I investigated.

Giving Linux containers a try

  • Start from a squeeze system.
  • apt-get install lxc, read its README.Debian, get the mount point set up.
  • Copy the /usr/lib/lxc/templates/lxc-debian template somewhere as lxc-squeeze, and edit it:
    • Replace dhcp-client with dhcp3-client.
    • Replace lenny with squeeze.
    • Specify a better mirror than ftp.debian.org.
  • Create a lxc-test directory, and create a container: ./lxc-squeeze -p lxc-test.
  • Start the container, which gives access to a console: lxc-start -n test -f lxc-test/config (the test name passed through -n can be used to call lxc-stop -n test). Use root/root to get in.
  • Edit /etc/apt/sources.list to point to sid instead, and dist-upgrade (using squeeze to start with means fewer headaches while bootstrapping, in case sid breaks or gets into some transition).
  • Try lxc-stop and lxc-start to make sure the container can be stopped and restarted at will.

Getting devices

  • First things first (and unless I missed something), udev + LXC = fail. So let’s install it, note that it can’t be configured, edit /var/lib/dpkg/info/udev.postinst, add exit 0 at the top, and dpkg --configure udev.
  • Now, some devices are needed under /dev. Using mknod would be too easy, that’s called a container for a reason. So let’s edit the config file (the one passed to lxc-start earlier) to add a few devices (see below for an example).
  • Once that done, restart (lxc-stop/lxc-start) the container, mknod on those devices is now possible.
  • Input devices are not considered here, only video output is wanted for this test case. [This post might be edited if some examples get added later.]

Example, with a Radeon card, KMS enabled, let’s assume those devices are wanted:

crw-rw---- 1 root video 226, 0 Apr  5 02:34 /dev/dri/card0
crw-rw---- 1 root video  29, 0 Apr  5 02:34 /dev/fb0
crw------- 1 root root    4, 7 Apr  5 02:34 /dev/tty7
crw------- 1 root root    4, 8 Apr  5 02:34 /dev/tty8

Note the major, minor right between owner groups and dates, and edit the config file accordingly, adding those lines (watch the syntax, it doesn’t like extra whitespaces):

lxc.cgroup.devices.allow = c 226:0 rwm
lxc.cgroup.devices.allow = c 29:0 rwm
lxc.cgroup.devices.allow = c 4:7 rwm
lxc.cgroup.devices.allow = c 4:8 rwm

Once the container restarted, create the devices:

cd /dev
mkdir -p dri
mknod -m 666 dri/card0 c 226 0
mknod -m 666 fb0       c 29 0
mknod -m 666 tty7      c 4 7
mknod -m 666 tty8      c 4 8

Getting serious

  • apt-get install xorg
  • startx
  • strace -f can help diagnose issues. If /dev/dri/card0 shows up with ENODEV, an old libdrm could even remove that device, so running mknod is needed again (but not sufficient)
  • A likely cause of such issues might be that an X server already ran (or is still running) on the host system. Disabling the display manager on the host, rebooting, and trying startx from the container again should give better results (that’s what happened here).
  • If startx just works™, just use ^Z then bg to put it in the background.
  • Move on to installing a random window manager (e.g. awesome) and mesa-utils, and enjoy!

Enjoy:

export DISPLAY=:0
awesome &
# this is not a benchmark:
glxgears &
# direct rendering:
glxinfo|egrep '(direct|renderer)'

which printed here:

direct rendering: Yes
OpenGL renderer string: Gallium 0.4 on ATI RS690