Home » Linux » User Mode Linux and Gentoo

Linux : User Mode Linux and Gentoo

A brief primer on getting started with User Mode Linux and Gentoo. Includes init scripts for UML management.

Purpose

These modifications were made to better integrate our User Mode Linux infrastructure with Gentoo. Our use of UMLs began as a small, manually configured experiment, but the need for some basic management quickly became apparent. Several management tools such as UMLazi were considered, but eventually deemed far too feature packed for our purposes. We don't frequently need to create or modify our UMLs and thus the effort of configuring any of these tools exceeded that of managing them manually. Furthermore, the level of integration desired was still not met. Our goals were rather simple:

  • Integrated configuration of network: tap/tun devices and bridging
  • Integrated configuration/basic management of UML instances

Related Documentation

Required Components

  • Host kernel with skas3 support and a UML child kernel
  • UML root and swap loopback filesystems
  • Bridged networking of tun/tap devices on the host
  • Init scripts and configuration to control the UML instance

Basic Steps

The user-mode-linux Sourceforge project is the primary source of UML documentation. The UML Wiki Site is also quite useful. Even with these pages, I found a number of details to be neglected, or at least not obvious. Rather than reproducing a great amount of background information, I aim here only to hit the necessary details. As such, I'm likely to leave out some details you find important. Feel free to send an email if in doubt.

Root filesystem

You'll need to create the UML filesystems as loopback devices. I typically create the filesystem by the same chroot method as standard Gentoo installations. To get started, the following will create root and swap filesystems. Then go ahead with a standard gentoo installation in uml-root/.

dd if=/dev/zero of=uml.root bs=1M count=3072
dd if=/dev/zero of=uml.swap bs=1M count=512
mke2fs -j uml.root
mkswap uml.swap
mkdir uml-root; mount -o loop uml.root uml-root

The client /etc/inittab requires a few changes. The default console device inside the UML must be connected to stdin, stdout, and stderr when started. By default, these are connected to /dev/tty0 inside the child, though Gentoo starts agetty on only tty{1-6}. The other agetty instances may be commented, as follows:

# TERMINALS
c0:12345:respawn:/sbin/agetty 38400 tty0 linux
#c1:12345:respawn:/sbin/agetty 38400 tty1 linux
...

uml_mconsole is used by the init script(below) to send various signals to the running UML kernel. The options available are just about what you get with alt-sysrq for a real kernel. I take advantage of the ctrl-alt-delete signal to request a clean shutdown. After a 60 second timeout, I proceed with a sync, try to remount, and halt the UML. There's only one change required to the UML child /etc/inittab:

# What to do at the "Three Finger Salute".
#ca:12345:ctrlaltdel:/sbin/shutdown -r now
# Shut down, rather than reboot
ca:12345:ctrlaltdel:/sbin/shutdown -h now
Host Kernel

A bit of research on the various UML mailing lists will show that you'll need skas support in your host kernel. Sparing the details, it will result in a several fold performance increase. Processes running in the UML will no longer be visible with 'ps' on the host and only a few kernel processes will be observed. This alone has several benefits in observing the performance of multiple running UMLs. See http://user-mode-linux.sourceforge.net/skas.html for details.

As the patches on http://user-mode-linux.sourceforge.net seem to be consistently outdated, you'll need to look elsewhere. The author of the skas3 patch, BlaisorBlade (Paolo Giarrusso), provides all of the patches at his UML website: http://www.user-mode-linux.org/~blaisorblade/. If you don't find patches for the kernel you need there, also take a look at Suse's patches at http://www.suse.de/~kraxel/uml/patches/. The host-skas patch should apply cleanly to a vanilla kernel.org kernel.

Once you're patched, configure and compile the kernel as you normally would. Be sure to select 'Y' to /proc/mm in Processor type and features. Additionally, you will want tun/tap device support under Network Devices.

UML Kernel

Compilation of the UML kernel is only slightly more involved than the host kernel. Specifically, you'll need kernel sources patched with the uml-patch, available at http://user-mode-linux.sourceforge.net. I do recommend starting with freshly extracted kernel sources, separate from your host kernel. Under Gentoo, I use the usermode-sources. Currently, I do use kernel 2.4 for the UML kernel due to some performance issues with kernel 2.6. It is possible that some of these have been resolved, but the 2.4 patches do seem to be the mainstream method.

Once you've got the sources, they can be configured with make ARCH=um menuconfig. If they better suit your tastes, config and xconfig may also be used. Be sure to include the ARCH=um in any case. You'll see significant changes from the normal configuration options in General Setup. You will want 'Y' to Management Console and /proc/mm. The default options in Character Devices and Block Devices seem to be reasonable. You can also take a look at my configuration for 2.4.24. Compile with make ARCH=um linux and use the resulting linux executable.

Init Script and Configuration

Update: These files are now included in the Gentoo usermode-utilities package. See Bug 55749.

Rather than going into great deal paraphrasing my implementation of the above configuration options, I'll just provide the code and configuration here. See the UML Management section below for configuration details.

Host /dev/shm

The host device /dev/shm must not be mounted with noexec. The Gentoo default (of noexec) causes the following error to be printed by the UML child kernel.

...
Checking advanced syscall emulation patch for ptrace...OK
Checking for tmpfs mount on /dev/shm...OK
Checking PROT_EXEC mmap in /dev/shm/...failed: Operation not permitted
/dev/shm/ must be not mounted noexec
Simply remove the noexec option from /etc/fstab on the host:
#shm   /dev/shm        tmpfs           nodev,nosuid,noexec     0 0
shm    /dev/shm        tmpfs           nodev,nosuid            0 0

Networking

Recent releases of baselayout have eliminated the necessity of custom network initialization scripts. It is now hassle-free to configure the necessary tun/tap devices, and bridges to the physical host interfaces. In the below example, for a single UML child, the host IP is 192.168.99.2, assigned to br0, which is attached to the physical device eth0. eth1 and wlan0 are additional physical devices to be used only inside the child. The host has no IP associated with these devices, or their bridges. Note that you might only need one of these interfaces; I use this UML child as a router. Here is my /etc/conf.d/net:

#################################
# UML tun configuration
# requires sys-apps/usermode-utilities
#################################
# local network
tuntap_uml0='tun'
# Internet
tuntap_uml1='tun'
# wireless
tuntap_uml2='tun'
#tunctl_tun1="-u adm"


#################################
# Bridge configuration
# requires
#################################
bridge_br0="eth0"
bridge_add_uml0="br0"
config_br0=( "192.168.99.2/24" )
routes_br0=("default via 192.168.99.1")

bridge_br1="eth1"
bridge_add_uml1="br1"
config_br1=( "0.0.0.0/0" )

bridge_br2="wlan0"
bridge_add_uml2="br2"
config_br2=( "0.0.0.0/0" )

UML Management

This section is an order of magnitude less intrusive than the networking changes into the Gentoo core. No modifications are made to the existing configuration or scripts. An init script and configuration file must be provided for each UML instance. This allows starting, stopping, and reconfiguration of each UML independently. Again, I've not provided much in terms of full-fledged UML management suite. My needs are rather simple, and these scripts meet them. More features could come later.

Configuration

Following the traditional Gentoo way, an init script in /etc/init.d/ will source the corresponding file in /etc/conf.d/. (The network scripts are hard coded to source /etc/conf.d/net from /sbin/runscript.) As such, I've named my init script uml.<machine> and configured it with the following variables:

  • UMLDIR="/uml": This directory must contain a directory for this specific machine. In it, there must be root.loop and swap.loop filesystems, and a kernel named linux. I generally create them by mounting and using the standard Gentoo chroot installation methods(or a copy of another).
  • USER="umluser": Despite the "impossibility" of breaking out of a UML, it's still wise to run the UML as a non-root user. Be sure the UMLDIR permissions are correct if the user is not root.
  • MEMORY="128MB": specify the amount of ram to be allocated for this UML instance.
  • NET="<interface>": This interface will probably be one of the tun/tap devices configured and bridged as above. Of course, it can also be a real physical interface.

(Outdated) Networking

Update: As baselayout has changed significantly, these modifications are not longer needed. They will remain here for reference.

The Gentoo init scripts currently have no method for handling tap/tun devices or the bridging typically required for our UML instances. That is, we need a generic way to create the tap devices and bridge them with other interfaces before starting the UMLs. I have made an effort to not make any of this configuration specific to the UML configuration. Whenever possible, I've errored on the side of fewer modifications to the Gentoo scripts and have integrated tightly with the standard network configuration in /etc/conf.d/net.

Tun/Tap Devices

To facilitate configuration of tap/tun devices, three configuration directives were added:

  • iface_="tuntap": The device type "tuntap" was added. It can be used where "dhcp", for example, would be used for a device. This allows similar code to the dhcp work in the init script.
  • ifconfig_="0.0.0.0": Allows an alternate method for specifying ifconfig options when iface is used for another purpose. Generally, with regular interfaces, dhcp would handle this portion for you. In future revisions, this addition may change, but I would prefer to not combine this with other iface directives so it may remain generic.
  • user_="user": As tuntap devices must be assigned to a user, and a UML may often run as something other than root, this option is passed along to tunctl for the correct permissions to be assigned.
Bridging

Similar to the Tun/Tap modifications, a few configurations directives were added. With exception of the ports_xxx, they are nearly identical both in configuration and init scripts:

  • iface_="bridge": Same as tuntap, above.
  • ifconfig_="x.x.x.x netmask x.x.x.x": Again, this is used to run ifconfig for the created brige interface. If you still want the local machine to be able to talk over this interface, this IP will be what you normally specified for iface_eth0. You'll want to set it to "0.0.0.0". Otherwise, set this value to "0.0.0.0".
  • ports_="if1 if2 if3": Here, you specify the interfaces to be added to the created bridge interface. Be sure they actually exist, whether as taptun devices or real interfaces.

Network init scripts for the above changs can be found here:



Created: 07 Jul 2005
Last Modified: 17 Nov 2009