User Mode Linux for Beginners - Setup and first VM

Why another UML tutorial?

This is not the first tutorial on UML — there are hundreds of them publicly available on the internet. However, none of them seems to fulfill my requirements:

What do you need?

Building UML

For extended information on building UML, refer to this great article. Keep in mind, however, the article compiles 32-bit UML, which basically does n

An alternative to building UML is to install the binary from your system maintainer instead (e.g. sudo apt-get install user-mode-linux on Ubuntu). The binaries are somewhat bloated, however (6.4 Megabytes versus 2.2 Megabytes in my case), and usually not up-to-date at all.

The User Mode Linux code has been merged into the mainline Linux kernel a few years ago, so we only need to compile the most recent kernel using the correct config options.

cat > mini.config << EOF &&
CONFIG_64BIT=y
CONFIG_X86_64=y
CONFIG_BINFMT_ELF=y
CONFIG_HOSTFS=y
CONFIG_LBD=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_STDERR_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_EXT2_FS=y
CONFIG_MODULES=y
CONFIG_INOTIFY_USER=y
CONFIG_NET=y
CONFIG_UNIX=y
CONFIG_EXT3_FS=m
CONFIG_EXT4_FS=m
EOF
make ARCH=um allnoconfig KCONFIG_ALLCONFIG=mini.config
make ARCH=um -j4 all modules

First basic UML VM

From now on, we assume you’re currently in the directory you want to create your first VM in. At the moment, this directory should only contain the linux executable.

The easiest thing you can do with UML is to use your host Linux installation for some first experiments. Execute this as normal user (not root!):

./linux rootfstype=hostfs rw init=/bin/bash quiet

You should get into a command prompt. UML is pretty verbose by default (even with the quiet kernel option), but the gist is the kernel doesn’t use any real initialization but just starts /bin/bash. You could now cd and ls around your system, but that would be pretty pointless after all, so press Ctrl+D to exit UML.

When exiting this way, UML fails and displays a kernel error. This is not abnormal, given the fact we didn’t properly startup the VM by using a real init etc. Some shells (e.g. zsh) screw up formatting after exiting UML, use the reset command to fix that.

Setup a VM using debootstrap

Now we can setup a proper minimal installation. This example uses Debian Wheezy. Modifying the distribution name and the mirror should be sufficient if you wish to use another distribution

  1. Ensure you have debootstrap installed (sudo apt-get install debootstrap on Ubuntu)
  2. Execute this command as root (debootstrap doesn’t run as non-root) to install a minimal Debian wheezy into the wheezy-uml directory
debootstrap --arch amd64 --variant minbase wheezy wheezy-uml http://mirror.switch.ch/ftp/mirror/debian
  1. It will take some time. Grab something like coffee to avoid getting bored.
  2. The file owner of the entire wheezy-uml tree is root, but UML should have write permissions when executing as non-root. Fix it with this command:
chown -R $USER:$USER wheezy-uml
  1. Start the UML VM
./linux rootfstype=hostfs rootflags=$(pwd)/wheezy-uml init=/bin/bash rw mem=128M

If you take a look at the FS tree in UML now, you can see that it isn’t your host filesystem. Besides that, you can also edit files anywhere.

The non-root hostfs method has some permission problems, however - the filesystem lists your user and group ID (usually 1000 for the first user created) as owner of the wheezy-uml tree,

Want more UML?

Originally this was planned as a multi-part series. However, since writing this, tools like Docker have emerged that make it mostly unneccesarry to build everything from scratch. LXC (which is used by Docker) also seems to have significant advantages. As for my usecases there seems to be no obvious advantage to others, I currently have no plans on continuing the series.