My Ubuntu UML Installation

Last updated $Date: 2008-06-05 12:50:40 $

Martti Kuparinen <martti.kuparinen@iki.fi>

http://www.iki.fi/kuparine/comp/ubuntu/en/uml.html

Abstract

This is how I installed and configured User Mode Linux (UML) on my Ubuntu 8.04 workstation.


[ See also My Ubuntu Installation and My Ubuntu Server Installation with VMware Server ]

Table of Contents

1. Introduction
2. Creating disk images for guests
3. Building a guest kernel
4. Starting and stopping virtual network
5. Starting and stopping guests
6. Accessing host's filesystem from guests
7. Debugging the guest kernel with DDD
8. Useful links

1. Introduction

This article describes how I installed a small UML guest to perform some kernel debugging at work. I'm running 64-bit Ubuntu 8.04 on my workstation so the guest must also be 64-bit. This is important to remember if you use some previously created disk image.

The following packages are needed in this document. The libpcap-dev package is only needed if you activate pcap transport (UML Network Devices > pcap transport) in the kernel configuration phase.

sudo aptitude -y install debootstrap
sudo aptitude -y install uml-utilities
sudo aptitude -y install bridge-utils
sudo aptitude -y install libpcap-dev

2. Creating disk images for guests

Please note that every guest needs its own disk image!

# Some directory on the local disk
export DSTDIR=/var/tmp

# Create 2 GB virtual disk
dd if=/dev/zero of=${DSTDIR}/imagefile seek=2 count=0 bs=1G
mkfs.ext3 -F ${DSTDIR}/imagefile
sudo mount -o loop ${DSTDIR}/imagefile /mnt

# Bootstrap a new Ubuntu host (for Debian, click here)
sudo debootstrap --verbose hardy /mnt http://archive.ubuntu.com/ubuntu

# Go into chroot and perform some configuration
sudo mount -t proc none /mnt/proc
sudo chroot /mnt /bin/bash

export LANG=C

cd /dev
mknod ubd0 b 98 0

# Ubuntu repositories (for Debian repositories, click here)
cat > /etc/apt/sources.list << EOF
deb http://archive.ubuntu.com/ubuntu hardy main restricted
deb http://archive.ubuntu.com/ubuntu hardy-updates main restricted universe
deb http://archive.ubuntu.com/ubuntu hardy-security main restricted
deb http://archive.ubuntu.com/ubuntu hardy universe multiverse
deb http://archive.ubuntu.com/ubuntu hardy-security universe multiverse
EOF

aptitude update && aptitude -y dist-upgrade
echo localhost > /etc/hostname

cat > /etc/hosts << EOF
127.0.0.1       localhost
EOF

cat > /etc/fstab << EOF
/dev/ubd0       /               ext3    defaults        0       1
proc            /proc           proc    defaults        0       0
tmpfs           /tmp            tmpfs   defaults        0       0
none            /host           hostfs  defaults,noauto 0       0
EOF

mkdir -p /host

cat > /etc/network/interfaces << EOF

# We always want the loopback interface.
#
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
EOF

sed -i '/ACTIVE_CONSOLES/s/.-./1-2/' /etc/default/console-setup
for i in /etc/event.d/tty[3-9]
do
  sed -i 's/start/stop/' ${i}
done

ln -sf /usr/share/zoneinfo/Europe/Helsinki /etc/localtime

aptitude -y install less locales console-data
update-locale LANG=C

aptitude -y install tcpdump telnet openssh-client

# Prepare for optional image compression
apt-get clean
dd if=/dev/zero of=remove-this bs=8k
rm -f remove-this 

exit
sudo umount /mnt/proc
sudo umount /mnt

# Optional image compression (backup to DVD, move to another host, ...)
bzip2 -9 -c ${DSTDIR}/imagefile > ${DSTDIR}/imagefile.bz2
ls -lh ${DSTDIR}/imagefile*

-rw-r--r-- 1 martti users 2.0G 2008-04-30 14:23 /var/tmp/imagefile
-rw-r--r-- 1 martti users 100M 2008-04-30 14:40 /var/tmp/imagefile.bz2

Please note how compressing the image before moving it to another host over network really makes sense, the size dropped from 2 GB to 100 MB!

3. Building a guest kernel

export DSTDIR=/var/tmp
export KVER=2.6.24.3

cd ${DSTDIR}
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-${KVER}.tar.bz2
tar xjf linux-${KVER}.tar.bz2

# Without any saved .config
cd linux-${KVER}
make mrproper
make ARCH=um mrproper
make ARCH=um menuconfig
make ARCH=um

# With saved .config
cd linux-${KVER}
make mrproper
make ARCH=um mrproper
cp somewhere/.config .
make ARCH=um oldconfig
make ARCH=um

4. Starting and stopping virtual network

# Fetch the helper script
cd /usr/bin
sudo wget http://www.iki.fi/kuparine/comp/ubuntu/en/umlnet
sudo chmod 755 umlnet

# Start 5 virtual networks
umlnet start 5

# Add internet connectivity (eth1) for the guests (tap0). Do NOT add eth0
# to the bridge or your host will be disconnected from the LAN...
sudo ifconfig eth1 up
sudo ifconfig eth1 promisc
sudo brctl addbr br0
sudo brctl stp br0 off
sudo brctl setfd br0 1
sudo brctl sethello br0 1
sudo brctl addif br0 eth1
sudo brctl addif br0 tap0
sudo ifconfig br0 up

# Remove internet connectivity
sudo ifconfig br0 down
sudo brctl delbr br0

# Stop all networks when all guests have been halted
umlnet stop

5. Starting and stopping guests

Guests are started after starting the virtual network (see above). As an example, to start a guest with 5 interfaces you need to execute the following commands. Please note how each interface is given a unique MAC address.

cd ${DSTDIR}/linux-${KVER}
xterm -T "Host 123"					\
    -e ${DSTDIR}/linux-${KVER}/vmlinux			\
    ubd0="${DSTDIR}/imagefile"				\
    umid="Host 123"					\
    eth0=daemon,ca:fe:ab:ba:00:00,,/tmp/link0		\
    eth1=daemon,ca:fe:ab:ba:00:01,,/tmp/link1		\
    eth2=daemon,ca:fe:ab:ba:00:02,,/tmp/link2		\
    eth3=daemon,ca:fe:ab:ba:00:03,,/tmp/link3		\
    eth4=daemon,ca:fe:ab:ba:00:04,,/tmp/link4		\
    mem=128M &

These MAC addresses should be listed in the guest's /etc/udev/rules.d/70-persistent-net.rules to avoid weird-looking ethN_renamed interfaces. Please note that the MAC addresses are for some reason case sensitive!

sudo vi /etc/udev/rules.d/70-persistent-net.rules

SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="ca:fe:ab:ba:00:00", ATTR{type}=="1", NAME="eth0"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="ca:fe:ab:ba:00:01", ATTR{type}=="1", NAME="eth1"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="ca:fe:ab:ba:00:02", ATTR{type}=="1", NAME="eth2"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="ca:fe:ab:ba:00:03", ATTR{type}=="1", NAME="eth3"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="ca:fe:ab:ba:00:04", ATTR{type}=="1", NAME="eth4"

Guests are shut down by running "halt -p" inside each running guest.

In multi-UML scenario it's might be a good idea to use the umid and uml_dir options in addition to the ubdN, ethN and mem options used above. Execute the following command to see all available options.

${DSTDIR}/linux-${KVER}/vmlinux --help

6. Accessing host's filesystem from guests

You can mount the host's filesystems to be visible inside the guest by running

mount /host
cd /host
ls

7. Debugging the guest kernel with DDD

7.1. Starting guest from DDD

The debugger normally intercepts some signal (like SIGSEGV) which I don't want to receive at this time. As an example, the SIGSEGV is normally caused by applications running on the userspace within the guest. Since I'm now debugging the kernel I want the debugger to ignore these signals so I can focus on the kernel problems.

cd ${DSTDIR}/linux-${KVER}
cat > .gdbinit << EOF
handle SIGUSR1 noprint nostop
handle SIGSEGV noprint nostop

set args \
  ubd0=${DSTDIR}/imagefile \
  umid="Host 123" \
  eth0=daemon,ca:fe:ab:ba:00:00,,/tmp/link0 \
  eth1=daemon,ca:fe:ab:ba:00:01,,/tmp/link1 \
  eth2=daemon,ca:fe:ab:ba:00:02,,/tmp/link2 \
  eth3=daemon,ca:fe:ab:ba:00:03,,/tmp/link3 \
  eth4=daemon,ca:fe:ab:ba:00:04,,/tmp/link4 \
  mem=128M
EOF

ddd ./vmlinux

7.2. Attaching DDD to already running guest

TBD

8. Useful links