HowTo.Gumph.Org

Step by step solutions to IT problems

Get Started with User-Mode-Linux

UML (User-Mode-Linux) is probably the easiest of the current virtualization sytems to use on Linux. We walk through step by step to running your first UML client.

To run UML we need a disk image of an installed linux filesystem, a kernel to boot the disk image with, and some tools to handle the networking.

Getting Started

To get started with UML I'd recommend using a separate test pc, rather than your desktop pc, as it makes the building and testing much easier. The PC doesn't need to be that powerful - I used a 500Mhz P3 with 256MB RAM and 20GB Disk.

First up, install your favourite flavour of linux on the pc, I'd recommend slackware or debian, as these both offer lightweight installations. You don't need to install X/KDE/Gnome etc, infact I'd recommend you don't bother initally, as it's easier to build the UML disk images from a lightweight setup first.

Building an Image

The easiest way by far to build a UML is to simply take a copy of an already working (and lightweight) linux installation. This solves most of the installation problems, and gives you an UML node that is running a flavour of linux you are already familiar with.

To build a disk image, look to see how much space you are using

root@testpc:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/hda1             7.6G  285M  6.9G   4% /

As we are using just 258MB, I'll create a 1024MB disk image and format it. I'd recommend you always create at least a 1GB (1024MB) disk image, otherwise it's easy to run out of inodes when copying all the files across. If you want to create a small image, then decrease the block size of the image (from 4k to 2k or 1k) so there are enough inodes created.

root@testpc:~# dd if=/dev/zero of=root_fs bs=1M count=1024
1024+0 records in
1024+0 records out
root@testpc:~# mkfs.ext2 root_fs
mke2fs 1.35 (28-Feb-2004)
root_fs is not a block special device.
Proceed anyway? (y,n) y

Now mount the drive image as a loop device, and copy across all the files from your current working installation. Because we need to exclude trying to copy the drive image into itself, use rsync to do the copy rather than cp

root@testpc:~# mkdir mounted_root_fs
root@testpc:~# mount root_fs mounted_root_fs -o loop
root@testpc:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/hda1             7.6G  786M  6.5G  11% /
/root/root_fs        1008M   20K  957M   1% /root/mounted_root_fs
root@testpc:~# rsync -ax --exclude=root_fs / mounted_root_fs

Now we need to make a few changes to the disk image, such as changing its name, and editing the fstab file. Change the hostname to something UML-ish

root@testpc:~# vi mounted_root_fs/etc/HOSTNAME
umlnode1.localnet

and change the first line of the fstab file from /dev/hda1 to /dev/ubd/0

root@testpc:~# vi mounted_root_fs/etc/fstab
/dev/ubd/0   /   ext2   defaults   1   1

Now we need to change the logon from a tty to a virtual console, so edit the inittab file, commenting out the tty console lines, and adding a vc line.

root@testpc:~# vi mounted_root_fs/etc/inittab
# These are the standard console login getties in multiuser mode:
c0:1235:respawn:/sbin/agetty 38400 vc/0 linux
#c1:1235:respawn:/sbin/agetty 38400 tty1 linux
#c2:1235:respawn:/sbin/agetty 38400 tty2 linux
#c3:1235:respawn:/sbin/agetty 38400 tty3 linux
#c4:1235:respawn:/sbin/agetty 38400 tty4 linux
#c5:1235:respawn:/sbin/agetty 38400 tty5 linux
#c6:12345:respawn:/sbin/agetty 38400 tty6 linux

and add the vc/0 to securetty

root@testpc:~# vi mounted_root_fs/etc/securetty
# This file defines which devices root can log in on.

# These are the ttys on the physical console: console vc/0 tty1 tty2 tty3

Now unmount the image

umount mounted_root_fs

The UML Kernel

If the linux distribution you are running uses a 2.4.x kernel, then the easiest solution is to just download the latest uml client kernel from the UML kernel download page.

In this example I downloaded the linux-2.4.19-5.bz2 kernel. Uncompress the downloaded kernel, and make it executable.

root@testpc:~# bunzip2 linux-2.4.19-5.bz2
root@testpc:~# chmod +x linux-2.4.19-5

For a 2.6.x kernel, either download one of Bill Stearns UML kernels or compile your own UML client kernel.

Give it a Run

Now is a good a time as any to see if your uml will run, so to fire it up, with just 64M of memory allocated, run

 root@testpc:~# ./linux-2.4.19-5 mem=64M 

You should see an normal linux boot process start up, though there are bound to be some module errors, as the modules are no longer compatible with your uml kernel, and it should arrive at a boot prompt for your uml node

Welcome to Linux 2.4.19-5um (vc/0)

umlnode1 login:

Login as normal, using the same password as you used for the host login

Linux 2.4.19-5um.
Last login: Thu Jul 20 11:51:38 +0100 2006 on vc/0.
You have mail.
root@umlnode1:~#

You can run as many as you want (depending on how much memory and disk you have) , each one needs its own disk image to boot from, so copy the original disk image, change its hostname, and start up more

root@testpc:~# ./linux-2.4.19-5 mem=64M ubd0=root_fs_node2

Networking

Now you have a working UML client, we just need to add networking support to finish it off. Download the latest uml utilities, I used uml_utilities_20040406.tar.bz2

Extract the files, which should extract into a tools directory

root@testpc:~# tar -xjf uml_utilities_20040406.tar.bz2

The only utility we need at this stage is the tunctl so

root@testpc:~# cd tools/tunctl/
root@testpc:~/tools/tunctl# make
cc -g -Wall   -c -o tunctl.o tunctl.c
cc -g -Wall -o tunctl tunctl.o
root@testpc:~/tools/tunctl# ls
CVS  Makefile  tunctl  tunctl.c  tunctl.o
root@testpc:~/tools# cd ../..

Now initialise the tunctl, so it automatically creates the tap/tun devices as needed. Replace root with whatever user will be starting the uml clients.

root@testpc:~# /tools/tunctl/tunctl -u root
Set 'tap0' persistent and owned by uid 0

Now initialise the host side of the networking

root@testpc:~# ifconfig tap0 192.168.0.254 up
root@testpc:~# echo 1 > /proc/sys/net/ipv4/ip_forward
root@testpc:~# route add -host 192.168.0.253 dev tap0
root@testpc:~# echo 1 > /proc/sys/net/ipv4/conf/tap0/proxy_arp
root@testpc:~# arp -Ds 192.168.0.253 eth0 pub

And finally, fire up your uml client, passing in the tap number to use. Remember to turn off DHCP for the client first. Each client needs it's own tap/tun pair, so adjust the above lines for each client.

./linux-2.4.19-5 mem=64M  eth0=tuntap,tap0

Once the client has started if eth0 does not start straight away, kick it up

root@umlnode1:~# ifconfig eth0 192.168.0.253 up
and you should now be able to access the network as normal from your UML node.

More Information

Once you are happy running UML, you'll probably want to start compiling your own host and client kernels, and moving onto more advanced configuration, use the User Mode Linux website for information on more advanced setups, and compiling your own UML kernels.

Submit to     del.icio.us    digg    reddit    simpy