Open Source

Set up virtual test and development machines with User Mode Linux

To allow admins and developers to troubleshoot configurations or debug code without bringing down your servers, check out User Mode Linux. Scott Lowe explains how to use this virtual machine.

Developers. You give them some space on a server to work with, say, a new C compiler, and a little while later, you’re getting paged because a development server just went down while other people were working on it. An administrator finds a perplexing networking issue and immediately starts making changes to the suspect server before doing any planning or research. The next thing you know, your entire network is strangled, and your company comes crashing down.

It doesn’t have to be this way.

With User Mode Linux (UML), you can provide developers or administrators with an entire virtual machine inside a single file on a Linux system, which accesses only the hardware that it is assigned. When set up properly, nothing that happens inside the UML virtual machine can do any harm to the actual system, which can save you the headache of repairing a downed server.

Get it
The current version of UML, 2.4.17, can be found on the UML Web site. I usually prefer to build software from source, but for this particular package, installing the RPM is a much easier route. So download the file user_mode_linux-

For this article, I'll assume you're running a Red Hat Linux 7.1 server with 128 MB of RAM and 4 GB of drive space. Save all downloaded files into your home directory (i.e. /home/slowe). UML will run with any 2.4 kernel; however, the kernel version I used for the examples in this article is 2.4.2-2. UML also supports 2.2.15 or later and 2.3.22 or later. If an earlier kernel is being used and it cannot be upgraded, UML can still be run if you install a patch from UML.

Included in the RPM package are the following components:
  • ·        The UML kernel
  • ·        User space tools
  • ·        Documentation

You must also download a file system image. The UML Web site has a number of prepackaged, common distribution images available for download, including Red Hat 7.1, Red Hat 7.2, Mandrake 8.0, and Debian 2.2. For this article, I used the Debian 2.2 image because it's the easiest distribution to get up and running. The file is named root_fs_debian2.2_small.bz2, and you should place it in your user directory (in my case, that would be /home/slowe). You can decompress the file with the Bunzip2 utility.

Install it
Installing an RPM package under Red Hat Linux 7.1 is easy. For this package, you just need to switch to your home directory using a command similar to the following:
cd /home/slowe

Then, install the RPM package that you downloaded from the UML Web site with this command:
rpm --install user_mode_linux-

Next, expand the Debian 2.2 bootable file system into your home directory with this command:
bunzip2 root_fs_debian2.2_small.bz2

The process can take awhile because the file system image is quite large. Expanding the file creates a file named root_fs_debian2.2_small. This filename is important because you’ll have to use this name when you want to run UML.

That’s the installation. There is nothing more to configure for a basic UML installation.

Run it
After downloading and installing UML and the supported file system, it’s time to run UML. The only major rule of thumb is this: You need to know the name of the file system file that is to be run.

UML runs an entire virtual machine from inside one single file on a Linux server. This file is a "bootable” file system file. Any kernel can be made to work with UML with the right tools, which are included with the package.

To run UML, one needs to use the linux command from the command prompt. This executable command has a number of command-line options used to tweak its behavior.

Here are some of the common command-line parameters and their descriptions:
  • ·        mem= controls how much RAM is allocated to the virtual machine. The size is specified by a number followed by K or M. This number can be greater than the RAM available in the host machine. In the event that it is, swapping will take place.
  • ·        honeypot allows the UML machine to be exploitable via stack attacks.
  • ·        --version prints out the kernel version.
  • ·        ubd0= is probably the most important. By default, UML looks for a file called ‘root.fs’ to use as the virtual machine. Multiple virtual machines can be stored in the same directory by changing the name and using this parameter to point to the right boot file.
  • ·        umid= specifies a unique name for the virtual machine.
  • ·        eth(x)= is used with ethertap or TUN/TAP.
  • ·        ethertap is used with a 2.2 kernel host.
  • ·        TUN/TAP is used with a 2.4 kernel host.

For this example, start UML with the downloaded Debian 2.2 file system and name deb22 using this command:

The con=pty con0=fd:0,fd:1 disables the X-session inside the UML so you can boot to a clean command-line interface.

The eth0=ethertap,tap0,fe:fd:0:0:0:1, line tells UML to act as a gateway using the address and the MAC address of fe:fd:0:0:0:1.

This command will start UML with a networked configuration named deb22. There is no networking support, so you must do everything from the console command line; you will not be able to log in remotely. The console command line is the command prompt presented upon first boot.

As UML starts, all of the usual Debian 2.2 checks take place because it’s a Debian 2.2 kernel that's booting.

I'm giving it all she's got cap'n!
Keep in mind that booting this virtual machine may take some time on a machine with less horsepower. An entire server is being loaded from a file.

Once this small Debian kernel boots, you'll be greeted with a Debian log in, like this:

Post log in
Once you log in with the user name of root and the password of root, set up networking so that you can access other machines on the network. I will use the next host in the 192.168.100.x network, because is being used as the gateway interface from the UML command line. This host is assigned with the following two commands:
ifconfig eth0
route add default gw

Now, ping the host that is running UML with this command:
usermode:~# ping
PING ( 56 data bytes
64 bytes from icmp_seq=0 ttl=255 time=2.6 ms
64 bytes from icmp_seq=0 ttl=255 time=1.7 ms
64 bytes from icmp_seq=0 ttl=255 time=1.6 ms

--- ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.6/1.9/2.6 ms

You can verify that the gateway is actually passing data properly by pinging the address—which is the host that is running UML—with this command:
usermode:~# ping
PING ( 56 data bytes
64 bytes from icmp_seq=0 ttl=255 time=2.5 ms
64 bytes from icmp_seq=0 ttl=255 time=1.5 ms
64 bytes from icmp_seq=0 ttl=255 time=1.5 ms
64 bytes from icmp_seq=0 ttl=255 time=1.3 ms

--- ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 1.3/1.7/2.5 ms

If you run ipconfig on the server running the UML virtual machines, you'll get an output that looks like this:

You'll then have a working, networked UML space that you can let developers or admins work with without messing up the original file system.

Beyond a simple virtual machine
The great benefit of UML is the ability to have more than one person work with his or her own virtual machine. What would be even better is to have these users work from the same root file system and then just keep track of their changes. This way, the UML process would use less space because it would use the core file system and a change file, while all of the virtual machines would share the core file system. Additionally, if a user were to destroy a file system, break a kernel, or cause any other fatal error, the administrator could easily get it up and running with a clean file system.

UML can also do that. The ubd0 command-line option for the Linux executable can take two parameters. When only one parameter is specified, UML looks for that file as the virtual system and tries to boot. When a second parameter is specified, a file is created with a private file system. That second file also references the root file system. This second file is called a Copy on Write (COW) file.

Follow these steps to see how it works. In the ubd0 command-line switch, the first parameter is the name of the COW file, while the second parameter is the name of the root file system. Name your COW file root_fs_deb22_cow and use the same root file system as before, as in this example:

After the system comes up, go to the host system and do a directory listing of your home directory. You'll then have two files associated with this session, as in this example:

You'll also need to set up the networking as in the previous example again because you did the entire network configuration at the command line rather than by modifying the networking configuration files. To set up networking, use the following commands:
ifconfig eth0
route add default gw

Next, start a second UML machine named deb22b on the host system. From the host system, start a new SSH session, because your current one is tied up with the UML session.

A session by any other name…
Please note that the name of this second session is deb22b, while the first session is simply deb22.

After you've logged in, start a new UML session with this command:

Then, doing a directory listing of your home directory yields listings similar to this:

Notice that there are now two COW files, which will allow more than one person to use UML. When using COW files, all changes are saved in them, and the root file system stays intact for future use.

The next time UML starts, the command line can omit the root file system and point directly at the COW file. The COW file contains a pointer to the original file system file, so it does not need to be specified on the command line, as in this example:

Connecting to the UML machine
For this example, I have set a root password on the first running UML machine.

I will connect to the second machine with this command:

Since you never set a password on this machine, it will let us right in. However, you set a password on the first virtual machine, so you'll need to enter it (when prompted) to get in.
[root@redhat slowe]# ssh
root@'s password:
Last login: Mon Dec  3 20:26:44 2001
[root@debian /root]#

You're finished; the machine is visible to the Red Hat Linux host. To shut it down, type halt at the command line.

The potential for applications of UML is enormous. You can do more than just allow developers to each have their own test playground to play in. With a single server, an administrator can serve up multiple Web sites, each within their own memory space.

Other programs, such as VMware, are available and can support other operating systems besides Linux. However, VMware is not open source and costs $299 per license.

There is consistent development work happening on UML, with new releases and patches being put onto the Web site consistently, so check it frequently for updates.

A maze of OSs
For a lot of my testing and writing, I use VMware under Windows 2000 Professional on my laptop, because with it, I can run multiple OSs and have a virtual network between them. For this article, I tested installing UML inside a VMware partition running Red Hat Linux on top of Windows 2000. It worked.