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 upand 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.