Run Linux on Linux

If you need to run multiple distros at the same time, test out new kernels, or just want to test new software in a 'sandbox,' User Mode Linux is perfect for the job. Here's how to get started.

User Mode Linux (UML) is a Linux kernel that runs as an application. To the host system — the underlying hardware and booted kernel — UML is just like ls, grep, Apache, Emacs, or vi: UML runs in user-space; it runs with user privileges; and multiple instances of UML can run simultaneously, where each instance gets its share of resources, such as memory and CPU time.

Of course, while UML looks like any other application to the host, it’s an unusually powerful one because each UML instance represents an entire, self-contained GNU/Linux system. Indeed, that’s often what UML is used for — to run one or more virtual Linuxes, or guest hosts, on top of a host system. (If you’re wondering if it’s possible to run a guest system on top of a guest system, running on a host system, the answer is yes, you can do that.) In fact, UML has rapidly become a popular way to test Linux kernels and distributions and a favorite way to run multiple, virtual Linux hosts on a single machine. Using UML, you can easily run multiple Linux distros on one x86-compatible machine at no additional cost except the time it takes to install and configure UML and create or install the guest hosts.

The UML project provides some pre-built guest host images — called filesystems in UML parlance — but you can also create your own with a modicum of difficulty, particularly if you have the right tool. Here, you can learn how to build a UML host system and how to build guests hosts using one of the best tools for the task, UML Builder. (If you want to know more about UML, read Jeff Dike’s “User Mode Linux” feature in the April 2001 issues of Linux Magazine, available online at http://www.linux-mag.com/2001-04/user_mode_01.html.)

It’s Linux on Linux on Linux on…

All you need to run User Mode Linux is the right kernel, the UML utilities, and a filesystem to boot from. The UML web site is hosted on SourceForge at http://user-mode-linux.sourceforge.net. Head over to the Downloads page to find the latest UML package.

If you use Debian, you can simply use apt to grab a UML kernel and the necessary utilities. Using apt, just run…

$ apt-get install user-mode-linux

… which downloads and installs UML for you. (The UML package in Debian stable is a bit long in the tooth, at least as we go to press. You may wish to grab UML from testing or unstable instead.)

If you use Red Hat or another RPM-based distro and don’t mind using an older kernel (the UML web site is a bit out of date at the moment), you can download the latest RPM and run…

$ rpm -Uvh user_mode_linux-X.X.X.um-0.i386.rpm

… where X.X.X is a kernel version number that corresponds with the stock kernel used to create the UML kernel.

Or, you can compile your own UML kernel and utilities. To do this, you’ll need to grab several pieces of code from the UML website download page.

1. First, download the stock Linux kernel you want to work with from one of the Linux Kernel Archives (http://www.kernel.org) mirrors. Make sure that there is a corresponding patch for that kernel release on the UML site.

For example, if you want to work with the 2.6.0-test8 kernel, grab the file uml-patch-2.6.0-test8.bz2 from the UML web site.

2. Next, patch the kernel and compile it. Uncompress the kernel source and the UML patch, and copy the UML patch into the top-level directory with the Linux source.

For example, if you grab the 2.6.0-test8 kernel and uncompress your kernel source in /usr/src/uml, that kernel source is uncompressed into /usr/src/uml/linux-2.6.0-test8/. Copy the patch source into that directory and run…

$ cat uml-patch-2.6.0-test8 | patch -p1

… to patch the source. You should see a bunch of messages printed to the console. If you encounter errors, it’s likely you have mismatched the UML patch and kernel source.

3. Now configure the kernel using…

$ make xconfig ARCH=um

… or …

$ make menuconfig ARCH=um

Choose the options you want to enable or disable, and then compile your UML kernel with:

$ make linux ARCH=um

This creates an executable called linux (no shocker that). If you want to use this kernel for debugging, it’s fine to go as it is. However, you might notice that this kernel is a bit larger than the average kernel image. This is because it contains a lot of symbol information, which can be safely stripped to reduce the size of the binary. To remove the symbol information run strip linux.

Once you’ve finished compiling your UML kernel, copy it to /usr/bin/.

4. Finally, grab the most recent release of the UML utilities. At the moment, the most recent release is uml_utilities_20030903.tar.bz2. The release number corresponds to the date of release, in this case, September 3, 2003. The UML utilities don’t have to correspond to a specific kernel release (unlike the UML kernel patches), so you should grab the most recent package available.

Uncompress the tarball and then run…

# make all; make install DESTDIR=/

… from the top-level directory of the package. This builds and installs the utilities for you.

If you want to try out your new UML kernel before you start making filesystems, download one of the smaller filesystems from the UML website and test it out. Or, you can make your own.

About UML Builder

UML Builder is designed to simplify the process of building UML filesystems from RPM-based distributions. (Unfortunately, UML Builder can’t be used to build filesystems to run Slackware, Debian GNU/Linux, and a number of other popular distros. There are tools or methods to build filesystems for those distros, but they are a little less polished than UML Builder.)

UML Builder “automagically” sets up TUN/TAP networking, and creates a handy script for managing your UML guest host, and more. UML Builder has two modes: a GUI mode and a console mode that doesn’t require the X Window System. The GUI mode lets you point-and-click your way through building filesystems; the console mode is perfect for dial-up access or for those who think that GUIs are for sissies (Are not! Are too! Are not!)

UML Builder is written mostly in Python, though it also depends on a few bash scripts to work its magic.

Naturally, you’ll need to install UML Builder before you start using it. UML Builder has a few dependencies: it needs Tcl/Tk, Tkinter, Python, and a UML-capable kernel. Once those packages are installed, grab the UML Builder RPM from the UML Builder page on SourceForge at http://umlbuilder.sourceforge.net/download.shtml. Right now, the most recent stable release is 1.40-5, though there’s also a test release of 1.5 that seems to work just fine.

After you’ve fetched the most recent UML Builder release, log in as root and run…

# rpm -Uvh umlbuilder-x.xx-x.i386.rpm

… where x.xx-x is the version number of UML Builder. This is the only step that requires root priveleges. After UML Builder is installed, you can run the rest of the steps as a normal user.

Using UML Builder

Before you fire up UML Builder, there’s a little grunt work to do.

1. First, copy all of the RPMs from your distribution to a directory on your hard disk. Depending on your distribution, you may need anywhere from 500 MB to 3 GB. SUSE 8.1 Pro, for example, consumes 2.8 GB or so; the first Fedora release, Core 1, takes up about 1.8 GB. You can find all of the necessary RPMs on your installation media. Usually the RPMs are located on the CD-ROM or DVD-ROM under distroname/rpms, where distroname is the name of your distribution. Copy all of the RPMs used by the installer, except for source code RPMs.

For example, if you’re working with Fedora Linux, copy only those RPMs found on the first three CDs or ISO images. Mount each piece of media and copy all of the RPMs to a writeable directory, like this:

$ mkdir ~/umlrpms
$ cp /mnt/cdrom/Fedora/RPMS/*rpm ~/umlrpms

Some distributions, like SUSE, have several subdirectories for RPMs. Be sure to copy all of the RPMs from your installation media. Of course, you should also have enough free space for the filesystems that you create.

(If disk space is an issue, you can delete the RPMs directly afterwards. However, leaving the RPMs on the drive is convenient in case you want to build a new filesystem. It can take quite a while to copy all of the RPMs, even on a fast machine with a speedy DVD or CD drive and a fast hard drive. And since UML Builder reads and indexes the RPMs before creating the filesystem you can’t use RPMs stored on removable media like a CD-ROM or DVD-ROM, even if all the RPMs are contained in one directory on your CD or DVD.)

2. Next, verify that UML Builder supports the distribution you want to build a filesystem for. UML Builder uses profile scripts (found in /usr/lib/uml/umlbuilder/profiles) to support a particular distribution. You can find out what distros are supported by typing:

$ umlbuilder –distro list

This yields a list of supported distributions, including version numbers. This list is important because there are often significant changes between versions that are incompatible with earlier versions. For example, UML Builder 1.5 supports Red Hat 6.2 through Red Hat 9. However, when newer versions of Red Hat are released, they may be incompatible with the profile for Red Hat 9.

(You may, however, get lucky. If you want to try the latest and greatest of your favorite distribution, but there’s not a profile available for it yet, give the last version’s profile a shot. If the two releases are similar enough — which sometimes happens with point releases — it may work anyway. If not, you can try your hand at editing the profiles to work with the new release.)

3. Assuming your distribution is supported, run umlbuilder_gui. The GUI, shown in Figure One, is pretty straightforward and mostly self-explanatory.

Figure One: UML Builder’s filesystem wizard

The first step is to select the distribution you want to use. After you do that, show UML Builder where you’ve saved your RPMs. After that, UML Builder indexes the RPMs. Indexing can take quite a while, depending on the number of RPMs you have and the speed of your system. On a system with 1 GB of RAM and an Athlon 2000+ XP processor, it took about five minutes to index all of the RPMs from SUSE Pro 8.1. Once you’ve indexed the RPMs, GUI Builder saves the index, making it faster to build the same filesystem in the future.

4.. After GUI Builder finishes, you can now select modules. Modules are groups of packages that you can install. (If you’re trying to use UML Builder with a newer distribution that’s not yet supported, choose a minimal install because it’s less likely to fail. Once the system is running, you can install the other packages you want to use by hand.)

After you’ve chosen the modules you want to install, you can specify what filesystems to create. The default is to create a single Ext2 root filesystem with a maximum size of one gigabyte. The filesystem that’s created only occupies as much space on disk as necessary.

For example, if you tell UML Builder that you want a one gigabyte disk, but only fill 255 MB, the file should only occupy 255 MB on the host system’s hard drive until you consume additional space on the guest host.

Just as you may create multiple partitions for a regular Linux installation to put /home or /usr on their own partition, you can create multiple filesystems for UML guest hosts. You can create up to seven separate filesystems using UML Builder, not including a swap filesystem, which is created by default.

5. After you’ve created your filesystems, you should specify your network settings, hostname, swap size, number of terminals, the root password and so on. Figure Two shows the dialog box used to set those parameters.

Figure Two: Setting machine configuration options in UML Builder

If you don’t change the root password, it defaults to “root,” so it’s best to set a more secure password or change the password as soon as you’ve fired up your new guest host.

6. Finally, choose where you want the UML filesystem to be created. UML Builder then presents a summary of the settings you’ve chosen, and if it all looks good, click “Finish” to create your filesystem.

After UML Builder finishes, you can start your guest host by using the control script created by UML Builder (instead of just typing linux in the directory with the root filesystem). Enter the directory where UML Builder placed your filesystems and run…

$ ./control start

… to fire up your new UML guest host. You can also use control to stop or kill the guest host, get the status of the guest host, and so on.

Also, if you decide later that 64 MB of RAM is not sufficent and you want to give your guest host 128 MB of RAM or more, you can change the amount of RAM allocated by editing control. You can also change the networking values, add filesystems, and so on, without creating an entirely new filesystem.

UML Builder at the Command Line

If GUI’s don’t do it for you, you can use UML Builder at the console instead. It’s almost as easy as the GUI, perhaps even easier.

To create a UML filesystem using the command line interface, use umlbuilder instead of umlbuilder_gui. There are several mandatory arguments that umlbuilder needs to create the filesystem, and a number of optional arguments that you may wish to specify (but otherwise have reasonable defaults).

You must specify: a hostname for the guest host (–hostname); the destination directory for the UML filesystem (–dir); the directory that contains the RPMs (–rpmdir); and the distribution you’re using (–distro). Again, you can get a full list of distributions by running umlbuilder –distro list. All names are case-sensitive.

And even though it’s not a mandatory argument, you should specify the modules you want installed as well. To get a list of available modules, run…

$ umbuilder –distro Redhat9.0 –modules list

… assuming that you want to know what modules are available for Red Hat 9, of course.

You may also want to specify the IP address for the new guest host as well, using the –ipaddr option. You can increase the size of the swap file using –swapsize. To manually set the memory size for the guest host, use –memsize. To get a full list of options, run umlbuilder without any options.

As an example, let’s say you want to create a Red Hat 9 filesystem, using the core module set of packages, an IP address of, a 256 MB swap file, and 512 MB of RAM. The hostname is gonzo.dissociatedpress.org and the directory to hold the new filesystem is gonzo_uml. Using those values, you’d run:

$ umlbuilder –hostname gonzo –dir \
gonzo_uml \
–rpmdir umlrpms –ipaddr \
–distro Redhat9.0 \
–swapsize 256 –memsize 512

Arguments and their corresponding values are separated by a space and do not require an =. The order of the options does not matter. Providing everything was OK, a bunch of messages appear as umlbuilder creates the new filesystem.

That’s really all there is to it. It’s even easier to use the command line tool if you’ve used the GUI a few times, because you’ll understand the information that UML Builder needs.

Final Thoughts

That’s pretty much all there is to creating a filesystem using UML Builder. Anyone with just a little Linux knowledge should have no problem creating a filesystem in just an hour or two. Probably the most time-consuming part of creating a new filesystem is copying the RPMs to the hard drive.

UML is a great tool for testing and running multiple Linux hosts on one box. With UML Builder, you can exploit the full potential of UML by rolling your own filesystems.

Joe “Zonker” Brockmeier is a freelance technology journalist. Contact him at http://www.dissociatedpress.net.

Comments are closed.