1. Setting up the host
    1. Kernel Options
      1. TUN/TAP
      2. bridging
      3. Skas Mode
      4. tmpfs
    2. Host configuration
  2. Running UML
    1. Get a root fs
    2. starting it up
    3. sans devfs
    4. /etc/init.d/uml
  3. Configuring Guest
    1. configuring guest's network
    2. basic stuff
  4. Issues
    1. HOSTFS
  5. Links

How to set up several User Mode Linux instances running on one box each with a real external ip and access to the internet.

  • host: the real machine which will host the virtual user mode linuxes. In our example the real machine is ibis.riseup.net (216.162.217.194)
  • guest: the user mode linux (uml) running on the host. In our example, the uml is stork.riseup.net (216.162.217.193).

Setting up the host

Kernel Options

Assumes you run "make menuconfig"

TUN/TAP

choose "Universal TUN/TAP device driver support" under "Network Device Support"

This is needed to get virtual network between host and uml. there are other ways, but this is easiest. If run as module, then insmod on startup. Also, this works best with devfs installed too (actually, I can't get it to work otherwise, need to mknod something something.).

bridging

Choose "802.1d Ethernet Bridging" (in "Networking options")

Skas Mode

Skas mode is much faster than normal tt mode, but requires a patch in the host's kernel. If the host has the patch installed, then the UML will go into skas mode automatically.

The patch can be downloaded from the UML website's download section.

tmpfs

User Mode Linux createas a tmp file as big as the RAM you allocate the UML instance. It's placed in your environment's TMPDIR path. One useful strategy is to use the tempfs filesystem for your TMPDIR.

For example:

> mkdir /tmp/uml
> mount -t tmpfs -o mode=1777,size=512M none /tmp/uml
> TMPDIR=/tmp/uml linux mem=512M ...<rest of linux command>

or

/etc/fstab
tmpfs  /tmp/uml    tmpfs   defaults,size=7168M 0 0

UML unlinks the tmp file right after creating it. So, an ls -al /tmp/uml is going to show an empty directory. Use "lsof" to check if it is used.

Host configuration

host> apt-get install bridge-utils uml-utilities user-mode-linux devfsd
host> useradd -m uml
host> chown root:uml /dev/net/tun
host> chmod 660 /dev/net/tun

note: do you need to add user 'uml' to group 'uml-net'?

create file host:/etc/init.d/bridge:

#!/bin/sh
 
# configuration
 
HOST_IP="216.162.217.194"
HOST_NETMASK="255.255.255.0"
HOST_GATEWAY="216.162.217.1"
HOST_IFACE="eth0"
 
case "$1" in
  start)
    echo -n "Setting up fancy dancy bridge networking"

    ifconfig $HOST_IFACE 0.0.0.0 promisc up
    brctl addbr umlbridge
    brctl setfd umlbridge 0
    brctl sethello umlbridge 0
    brctl stp umlbridge off
 
    ifconfig umlbridge $HOST_IP netmask $HOST_NETMASK up
    route add default gw $HOST_GATEWAY
    brctl addif umlbridge $HOST_IFACE
 
    # first UML instance
       tunctl -u uml -t tap0
       ifconfig tap0 0.0.0.0 promisc up
       brctl addif umlbridge tap0
    # second UML instance
#     tunctl -u uml -t tap1
#     ifconfig tap1 0.0.0.0 promisc up
#     brctl addif umlbridge tap1
    # and so on...
    echo "."
    ;;
  stop)
    echo -n "Stopping networking bridge"
    # add more tab1,tab2, etc as needed
    ifconfig umlbridge down
    brctl delif umlbridge $HOST_IFACE
    brctl delif umlbridge tab0
    brctl delbr umlbridge
    tunctl -d tab0
    ifconfig $HOST_IFACE $HOST_IP netmask $HOST_NETMASK up
    echo "."
    ;;
esac

exit 0

Do not put any networking stuff in host:/etc/network/interfaces. Instead, run this at startup (e.g. run rcconf to add this script to the boot sequence).

Running UML

Get a root fs

Here set up a folder for our virtual machine 'guest' and a root filesystem.

host> su uml
host> cd /home/uml
host> mkdir guest
host> cd guest
host> wget http://people.debian.org/~mdz/uml/Debian-3.0r0.ext2.bz2
host> bunzip2 Debian-3.0r0.ext2.bz2

make it bigger (512mb):
host> dd if=/dev/zero of=Debian-3.0r0.ext2 bs=1 count=0 seek=536870912
host> /sbin/e2fsck -f  Debian-3.0r0.ext2
host> /sbin/resize2fs -p Debian-3.0r0.ext2

starting it up

host> su uml
host> cd /home/uml/guest
host> linux ubd0=Debian-3.0r0.ext2 devfs=mount

If something goes wrong, you can pass boot options to the linux command, like this:

host> linux ubd0=Debian-3.0r0.ext2 devfs=mount single

which will boot in single user mode.

Once that is working, try it with networking:

host> linux ubd0=Debian-3.0r0.ext2 devfs=mount eth0=tuntap,tap0

tap0 is the name of the tap device created in the bridge script by the command "tunctl -u uml -t tap0". If you have multiple umls, then you would have a unique tap device for each one.

Here is an example startup script:

NAME="stork"
TAP="tap0"
MYOPTIONS="mem=128M ubd1=disk2"
OPTIONS="$MYOPTIONS     ubd0=root_fs devfs=mount eth0=tuntap,$TAP umid=$NAME"
 
case $1 in
  "-d")
        screen -S $NAME -d -m linux $OPTIONS con=null con0=fd:0,fd:1
        echo "Starting machine $NAME..."
        echo
        echo "management console:"
        echo "   uml> uml_mconsole $NAME"
        echo
        echo "terminal console:"
        echo "   uml> screen -r $NAME"
    ;;
  *)
        linux $OPTIONS
        ;;
esac

sans devfs

The debian root filesystem image that is available from the package maintainer of uml uses devfs. If, for whatever reason, you don't want devfs in your uml, you can build your own root filesystem or modify it to remove devfs naming from the config files. To do this, boot your uml in single user mode and then edit guest:/etc/inittab and guest:/etc/fstab to be the non devfs form (ie ttys/0 becomes tty0, /dev/ubd/0 becomes /dev/ubd0, etc).

/etc/init.d/uml

Here is an example uml startup script:

GUESTS='stork egret'
UML_USER='uml'
 
if [[ ! -z $2 ]]; then
        GUESTS=$2
fi
 
case "$1" in
  start)
    for host in $GUESTS; do
      if [[ ! -e /home/$UML_USER/.uml/$host ]]; then
                echo "Starting $host..."
        cd /home/$UML_USER/$host
        su $UML_USER -c "./start -d" > /dev/null
        echo "  done"
      else
        echo "$host is already running"
      fi
    done
  ;;
  stop)
   for host in $GUESTS; do
      echo "Stopping $host..."
      if [[ -e /home/$UML_USER/.uml/$host/mconsole ]]; then
        su $UML_USER -c "uml_mconsole $host sysrq s; uml_mconsole $host sysrq u; uml_mconsole $host sysrq e; uml_mconsole $host halt"
        echo "  done.";
      else
        echo "  error: file not found /home/$UML_USER/.uml/$host/mconsole"
      fi
    done
    sleep 4 # not sure if the uml_mconsole commands wait until completed before they return.
  ;;
  restart)
     echo "not supported";
  ;;
  *)
    echo "Usage: $0 {start|stop} {machine}" >&2
        exit 1
  ;;
esac
exit 0

Configuring Guest

When you boot up, things are pretty minimal. Login as root.

Guest sample configuration:
  • hostname: stork
  • ip address: 216.162.217.193

configuring guest's network

edit /etc/network/interfaces:

auto lo
iface lo inet loopback
 
# eth0
auto eth0
iface eth0 inet static
   address 216.162.217.193
   netmask 255.255.255.0
   network 216.162.217.0
   broadcast 216.162.217.255
   gateway 216.162.217.1

Then bring it up:

guest> ifup eth0

You should now be connected to the internet like any other machine. Note that this is funky, because the guest machine got to pick its own IP address. Supposedly, here is how to prevent this:
ebtables.sourceforge.net/br_fw_ia/br_fw_ia.html

basic stuff

Set a hostname:
guest> echo stork > /etc/hostname
guest> hostname stork

get some packages:
guest> apt-get update
guest> apt-get install ssh less 

Issues

HOSTFS

We don't want the UML virtual machine to be able to mount the host's filesystem, so that means we can't compile hostfs support into the UML Kernel. Unfortunately, someone could still compile and install hostfs support as a kernel module, so that means we must build our UML Kernel without module support.

Links

www.theshore.net/~caker/uml/