User Mode Linux Howto
Table of contents
- 1 Introduction
- 2 Let's prepare a directory and get the Linux kernel sources
- 3 Now, we will build the kernel
- 4 Compile the kernel
- 5 Download a Filesystem Image
- 6 Booting the GNU/Linux based Gentoo operating system
- 7 Prepare host system for networking
- 8 Become root
- 9 Set permissions on the tun device
- 10 Create tun device
- 11 Enable tun device
- 12 Kernel settings
- 13 Masquerading
- 14 The host's routing table
- 15 Become a normal user again
- 16 Now boot the Gentoo based system with networking enabled.
- 17 Configure networking on the UML system
- 18 The UML system's routing table
- 19 Test the connection
- 20 Set your nameserver for connecting the outside world from your UML system
- 21 Links
Introduction
This howto describes in a very short way how to use "User Mode Linux" with networking.
I know there are more detailed howtos around the web but sometimes it is much more helpful to have a short overview on how to get things running. Here it is:
Let's prepare a directory and get the Linux kernel sources
hanez@phantom ~ % mkdir linux hanez@phantom ~ % cd linux hanez@phantom linux % wget http://kernel.org/pub/linux/kernel/v2.6/linux-2.6.23.13.tar.bz2 --00:33:09-- http://kernel.org/pub/linux/kernel/v2.6/linux-2.6.23.13.tar.bz2 => `linux-2.6.23.13.tar.bz2' Resolving kernel.org... 204.152.191.5, 204.152.191.37 Connecting to kernel.org|204.152.191.5|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 45,473,072 (43M) [application/x-bzip2] 100%[====================================>] 45,473,072 574.14K/s ETA 00:00 00:34:30 (556.48 KB/s) - `linux-2.6.23.13.tar.bz2' saved [45473072/45473072] hanez@phantom linux % tar -xjf linux-2.6.23.13.tar.bz2 hanez@phantom linux % cd linux-2.6.23.13 hanez@phantom linux-2.6.23.13 %
Now, we will build the kernel
First of all we need to configure the kernel. In this example I am using the default kernel configuration to make things fast... ;) If you don't want the default kernel configuration you could do the configuration as normal. But take care that you enable all functions needed for UML. The following command will configure the kernel automatically and adds support for User Mode Linux.
hanez@phantom linux-2.6.23.13 % make ARCH=um defconfig
Compile the kernel
hanez@phantom linux-2.6.23.13 % make ARCH=um
Since we are running this kernel in "user mode" we don't need to install it to some place. Just run the newly created kernel with the following command:
hanez@phantom linux-2.6.23.13 % ./linux
The output should look something like this:
Core dump limits : soft - 0 hard - NONE Checking that ptrace can change system call numbers...OK Checking syscall emulation patch for ptrace...OK Checking advanced syscall emulation patch for ptrace...OK Checking for tmpfs mount on /dev/shm...OK Checking PROT_EXEC mmap in /dev/shm/...OK Checking for the skas3 patch in the host: - /proc/mm...not found: No such file or directory - PTRACE_FAULTINFO...not found - PTRACE_LDT...not found UML running in SKAS0 mode Adding 29028352 bytes to physical memory to account for exec-shield gap Linux version 2.6.23.13 (hanez@phantom.home.hanez.org) (gcc version 4.1.2 20070925 (Red Hat 4.1.2-27)) #1 Mon Jan 14 00:51:25 CET 2008 Built 1 zonelists in Zone order. Total pages: 15160 Kernel command line: root=98:0 PID hash table entries: 256 (order: 8, 1024 bytes) Dentry cache hash table entries: 8192 (order: 3, 32768 bytes) Inode-cache hash table entries: 4096 (order: 2, 16384 bytes) Memory: 29840k available Mount-cache hash table entries: 512 Checking for host processor cmov support...Yes Checking for host processor xmm support...No Checking that host ptys support output SIGIO...Yes Checking that host ptys support SIGIO on close...No, enabling workaround Using 2.6 host AIO NET: Registered protocol family 16 NET: Registered protocol family 2 IP route cache hash table entries: 1024 (order: 0, 4096 bytes) TCP established hash table entries: 2048 (order: 2, 16384 bytes) TCP bind hash table entries: 2048 (order: 1, 8192 bytes) TCP: Hash tables configured (established 2048 bind 2048) TCP reno registered Checking host MADV_REMOVE support...OK mconsole (version 2) initialized on /home/hanez/.uml/LRi3R2/mconsole Host TLS support detected Detected host type: i386 VFS: Disk quotas dquot_6.5.1 Dquot-cache hash table entries: 1024 (order 0, 4096 bytes) io scheduler noop registered io scheduler anticipatory registered (default) io scheduler deadline registered io scheduler cfq registered TCP cubic registered NET: Registered protocol family 1 NET: Registered protocol family 17 Initialized stdio console driver Console initialized on /dev/tty0 console [tty0] enabled Initializing software serial port version 1 console [mc-1] enabled Couldn't stat "root_fs" : err = 2 Failed to initialize ubd device 0 :Couldn't determine size of device's file VFS: Cannot open root device "98:0" or unknown-block(98,0) Please append a correct "root=" boot option; here are the available partitions: Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(98,0) EIP: 0073:[<00110402>] CPU: 0 Not tainted ESP: 007b:00268fc0 EFLAGS: 00200246 Not tainted EAX: 00000000 EBX: 000037e4 ECX: 00000013 EDX: 000037e4 ESI: 000037e0 EDI: 00000011 EBP: 00268fd8 DS: 007b ES: 007b 09dc2e6c: [<0806a0f8>] show_regs+0xb4/0xb9 09dc2e98: [<0805887c>] panic_exit+0x25/0x3f 09dc2eac: [<0807b62c>] notifier_call_chain+0x21/0x46 09dc2ecc: [<0807b6c7>] __atomic_notifier_call_chain+0x17/0x19 09dc2ee8: [<0807b6de>] atomic_notifier_call_chain+0x15/0x17 09dc2f04: [<080703f2>] panic+0x52/0xdd 09dc2f24: [<08049a83>] mount_block_root+0xf8/0x10e 09dc2f78: [<08049ae5>] mount_root+0x4c/0x54 09dc2f9c: [<08049bf9>] prepare_namespace+0x10c/0x133 09dc2fa4: [<080497ae>] kernel_init+0x79/0x85 09dc2fb4: [<08064463>] run_kernel_thread+0x37/0x40 09dc2fe0: [<08058c89>] new_thread_handler+0x57/0x7e 09dc2ffc: [<00000000>] _sinittext+0xf7fb7000/0x88 zsh: segmentation fault ./linux hanez@phantom linux-2.6.23.13 %
Since we have no filesystem image for the new kernel it segfaults. We need to prepare the filesystem next...
Download a Filesystem Image
To get a filesystem image go to http://fs.devloop.org.uk/. I have choosen to use a Gentoo image for my tests but you decide, it should work with every distribution. I have tested Fedora 7 and Gentoo.
To get the Gentoo image I am using for this howto run the following commands:
hanez@phantom linux-2.6.23.13 % wget http://uml.nagafix.co.uk/Gentoo-2006.1/Gentoo-2006.1-x86-root_fs.bz2 hanez@phantom linux-2.6.23.13 % bunzip2 Gentoo-2006.1-x86-root_fs.bz2
Now you have the following file in the current directory:
hanez@phantom linux-2.6.23.13 % ls -l Gentoo-2006.1-x86-root_fs -rw-r--r-- 1 hanez hanez 2684354560 2008-01-13 04:10 Gentoo-2006.1-x86-root_fs hanez@phantom linux-2.6.23.13 %
For me it looks like this:
Booting the GNU/Linux based Gentoo operating system
Run this command to start the whole new system:
hanez@phantom linux-2.6.23.13 % ./vmlinux ubda=./Gentoo-2006.1-x86-root_fs mem=128M umid=gentoo
The parameter "umid" is used later for connecting from the host system to the guest with the use of the uml_console. "mem" is the RAM provided by the host.
There we are, a running Linux system:
Core dump limits : soft - 0 hard - NONE Checking that ptrace can change system call numbers...OK Checking syscall emulation patch for ptrace...OK Checking advanced syscall emulation patch for ptrace...OK Checking for tmpfs mount on /dev/shm...OK Checking PROT_EXEC mmap in /dev/shm/...OK Checking for the skas3 patch in the host: - /proc/mm...not found: No such file or directory - PTRACE_FAULTINFO...not found - PTRACE_LDT...not found UML running in SKAS0 mode Adding 14073856 bytes to physical memory to account for exec-shield gap Linux version 2.6.23.13 (hanez@phantom.home.hanez.org) (gcc version 4.1.2 20070925 (Red Hat 4.1.2-27)) #1 Mon Jan 14 00:51:25 CET 2008 Built 1 zonelists in Zone order. Total pages: 35922 Kernel command line: ubda=./Gentoo-2006.1-x86-root_fs mem=128M root=98:0 PID hash table entries: 1024 (order: 10, 4096 bytes) Dentry cache hash table entries: 32768 (order: 5, 131072 bytes) Inode-cache hash table entries: 16384 (order: 4, 65536 bytes) Memory: 126576k available Mount-cache hash table entries: 512 Checking for host processor cmov support...Yes Checking for host processor xmm support...No Checking that host ptys support output SIGIO...Yes Checking that host ptys support SIGIO on close...No, enabling workaround Using 2.6 host AIO NET: Registered protocol family 16 NET: Registered protocol family 2 IP route cache hash table entries: 2048 (order: 1, 8192 bytes) TCP established hash table entries: 8192 (order: 4, 65536 bytes) TCP bind hash table entries: 8192 (order: 3, 32768 bytes) TCP: Hash tables configured (established 8192 bind 8192) TCP reno registered Checking host MADV_REMOVE support...OK mconsole (version 2) initialized on /home/hanez/.uml/gentoo/mconsole Host TLS support detected Detected host type: i386 VFS: Disk quotas dquot_6.5.1 Dquot-cache hash table entries: 1024 (order 0, 4096 bytes) io scheduler noop registered io scheduler anticipatory registered (default) io scheduler deadline registered io scheduler cfq registered TCP cubic registered NET: Registered protocol family 1 NET: Registered protocol family 17 Initialized stdio console driver Console initialized on /dev/tty0 console [tty0] enabled Initializing software serial port version 1 console [mc-1] enabled ubda: unknown partition table EXT3-fs: INFO: recovery required on readonly filesystem. EXT3-fs: write access will be enabled during recovery. kjournald starting. Commit interval 5 seconds EXT3-fs: recovery complete. EXT3-fs: mounted filesystem with ordered data mode. VFS: Mounted root (ext3 filesystem) readonly. line_ioctl: tty0: ioctl KDSIGACCEPT called INIT: version 2.86 booting line_ioctl: tty0: ioctl TIOCLINUX called Gentoo Linux; http://www.gentoo.org/ Copyright 1999-2007 Gentoo Foundation; Distributed under the GPLv2 Press I to enter interactive boot mode * Mounting proc at /proc ... [ ok ] * Mounting sysfs at /sys ... [ ok ] * Mounting /dev for udev ... [ ok ] * Seeding /dev with needed nodes ... [ ok ] * Starting udevd ... [ ok ] * Populating /dev with existing devices through uevents ... [ ok ] * Letting udev process events ... [ ok ] * Finalizing udev configuration ... [ ok ] * Mounting devpts at /dev/pts ... [ ok ] * Checking root filesystem .../dev/ubda: clean, 197388/327680 files, 412750/655360 blocks [ ok ] * Remounting root filesystem read/write ... [ ok ] * Warning: the current /etc/modules.conf has not been automatically generated * Use "update-modules force" to force (re)generation FATAL: Could not load /lib/modules/2.6.23.13/modules.dep: No such file or directory * Checking all filesystems ... [ ok ] * Mounting local filesystems ... [ ok ] * Activating (possible) swap ... [ ok ] * Setting system clock using the hardware clock [UML] ... [ ok ] * Configuring kernel parameters ... [ ok ] * Updating environment ... [ ok ] * Cleaning /var/lock, /var/run ... [ ok ] * Cleaning /tmp directory ... [ ok ] * Device initiated services: udev-postmount * Setting hostname to localhost ... [ ok ] * Loading key mappings ... [ ok ] * Setting user font ... [ ok ] * Starting lo * Bringing up lo * 127.0.0.1/8 [ ok ] * Adding routes * 127.0.0.0/8 ... [ ok ] * Initializing random number generator ... [ ok ] INIT: Entering runlevel: 3 * Starting syslog-ng ... [ ok ] * Starting eth0 * You are using a deprecated configuration syntax for eth0 * You are advised to read /etc/conf.d/net.example and upgrade it accordingly * Bringing up eth0 * 192.168.0.1 * network interface eth0 does not exist * Please verify hardware or kernel module (driver) [ !! ] [ !! ] * ERROR: cannot start netmount as net.eth0 could not start * Starting vixie-cron ... [ ok ] * Starting local ... [ ok ] This is localhost.(none) (Linux i686 2.6.23.13) 00:07:50 localhost login:
Just login as user "root" without a password. Your new Linux system is running! Jehaaaa!
Please ignore the network configuration errors because my gentoo filesystem image is configured already but the host system does not support networking at this point. Networking will be the next step.
Shut the system down with the normal commands:
localhost ~ # init 0 INIT: Switching to runlevel: 0 INIT: Sending processes the TERM signal ... System halted. hanez@phantom linux-2.6.23.13 %
Prepare host system for networking
Let's check if our system supports tun devices and if we have permissions for reading and writing to tun devices:
hanez@phantom linux-2.6.23.13 % ls -l /dev/net total 0 crw------- 1 root root 10, 200 2008-01-13 16:31 tun
As you can see, we have tun device support but the tun device is not read-/writeable for users. So let's change this temporary. For security reasons this not a good idea but for getting a network running fast, it is the easiest way... ;)
Become root
hanez@phantom linux-2.6.23.13 % su - Password: root@phantom ~ #
Set permissions on the tun device
root@phantom ~ # chmod 0666 /dev/net/tun root@phantom ~ # ls -l /dev/net total 0 crw-rw-rw- 1 root root 10, 200 2008-01-13 16:31 tun root@phantom ~ #
Now we can read and write to tun devices as normal user.
Create tun device
On the host system we need to create a new tun device. In this case I created a tun device for user hanez.
root@phantom ~ # tunctl -u hanez Set 'tap0' persistent and owned by uid 1000 root@phantom ~ #
Enable tun device
This newly created tun device is the gateway for the UML system for connecting your network.
root@phantom ~ # ifconfig tap0 192.168.0.254 up root@phantom ~ # ifconfig tap0 tap1 Link encap:Ethernet HWaddr 00:FF:92:80:C7:9F inet addr:192.168.0.254 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::2ff:92ff:fe80:c79f/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:35 overruns:0 carrier:0 collisions:0 txqueuelen:500 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b) root@phantom ~ #
Kernel settings
Enable IP forwarding on the host system.
root@phantom ~ # echo 1 > /proc/sys/net/ipv4/ip_forward
Masquerading
We need to activate network address translation (NAT), in Linux called masquerading, on the host system to allow the UML system connecting the network. Make also shure that no firewall rules are blocking the newly created network 192.168.0.0/24.
My current output of iptables-save looks like this:
root@phantom ~ # iptables-save root@phantom ~ #
Now, enable masquerading and look at the output again:
root@phantom ~ # iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE root@phantom ~ # iptables-save # Generated by iptables-save v1.3.8 on Sat Jan 19 23:45:21 2008 *nat :PREROUTING ACCEPT [44:4467] :POSTROUTING ACCEPT [13:1416] :OUTPUT ACCEPT [64:4618] -A POSTROUTING -o eth0 -j MASQUERADE COMMIT # Completed on Sat Jan 19 23:45:21 2008 root@phantom ~ #
The host's routing table
root@phantom ~ # route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.0.1 * 255.255.255.255 UH 0 0 0 tap1 192.168.1.0 * 255.255.255.0 U 0 0 0 eth0 192.168.0.0 * 255.255.255.0 U 0 0 0 tap0 default 192.168.1.2 0.0.0.0 UG 0 0 0 eth0 root@phantom ~ #
Become a normal user again
root@phantom ~ # exit hanez@phantom linux-2.6.23.13 %
Now boot the Gentoo based system with networking enabled.
hanez@phantom linux-2.6.23.13 % ./vmlinux ubda=./Gentoo-2006.1-x86-root_fs mem=128M eth0=tuntap,,,192.168.0.254 umid=gentoo
This command creates the network interface eth0 in the UML system with 192.168.0.254 as the TUN/TAP IP backend.
Configure networking on the UML system
Enable the network interface:
localhost ~ # ifconfig eth0 192.168.0.1 up localhost ~ # ifconfig eth0 eth0 Link encap:Ethernet HWaddr 9A:05:02:D6:A0:BF inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:97 errors:0 dropped:0 overruns:0 frame:0 TX packets:38 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:22856 (22.3 Kb) TX bytes:2496 (2.4 Kb) Interrupt:5 localhost ~ #
Set the default gateway in the UML system:
localhost# route add default gw 192.168.0.254
The UML system's routing table
localhost ~ # route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 0.0.0.0 192.168.0.254 0.0.0.0 UG 0 0 0 eth0 localhost ~ #
Test the connection
Now let's ping to the host system to check if the network is working like expected:
localhost ~ # ping -c 4 192.168.0.254 PING 192.168.0.254 (192.168.0.254) 56(84) bytes of data. 64 bytes from 192.168.0.254: icmp_seq=1 ttl=64 time=0.242 ms 64 bytes from 192.168.0.254: icmp_seq=2 ttl=64 time=0.182 ms 64 bytes from 192.168.0.254: icmp_seq=3 ttl=64 time=0.178 ms 64 bytes from 192.168.0.254: icmp_seq=4 ttl=64 time=0.179 ms --- 192.168.0.254 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3003ms rtt min/avg/max/mdev = 0.178/0.195/0.242/0.028 ms localhost ~ #
Set your nameserver for connecting the outside world from your UML system
localhost ~ # echo "nameserver 192.168.1.2" > /etc/resolv.conf localhost ~ # cat /etc/resolv.conf nameserver 192.168.1.2 localhost ~ #
Check if it works:
localhost ~ # ping -c 4 kernel.org PING kernel.org (204.152.191.37) 56(84) bytes of data. 64 bytes from pub2.kernel.org (204.152.191.37): icmp_seq=1 ttl=51 time=205 ms 64 bytes from pub2.kernel.org (204.152.191.37): icmp_seq=2 ttl=51 time=204 ms 64 bytes from pub2.kernel.org (204.152.191.37): icmp_seq=3 ttl=51 time=203 ms 64 bytes from pub2.kernel.org (204.152.191.37): icmp_seq=4 ttl=51 time=204 ms --- kernel.org ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3008ms rtt min/avg/max/mdev = 203.822/204.465/205.203/0.709 ms localhost ~ #
Links
- http://user-mode-linux.sourceforge.net/ - The User Mode Linux homepage
- http://kernel.org/ - The Linux kernel source
- http://fs.devloop.org.uk/ - The source for UML filesystem images
- http://uml.nagafix.co.uk/ - The source for UML Kernel images
- http://user-mode-linux.sourceforge.net/old/UserModeLinux-HOWTO.html - The "main" User Mode Linux Howto
- http://valerieaurora.org/uml_tips.html - Valerie Aurora's User-Mode Linux tips