I’ve been running KVM for quite a while on my lab server. It’s been running without issue but with the release of vSphere/ESXi 6.0 I felt it was time to move back to VMware.

I wanted to preserve the virtual machines already running so I set out to move these to ESXi. I ran into some issues which I’m not sure is a generic problem or specific to ESXi 6.0 but I’ll describe what I have done.

In order to convert the existing disk images to VMware’s vmdk format you should you use the program qemu-img from the package qemu-utils (in Ubuntu).

The process is straight-forward

  • $ sudo qemu-img convert -p -i DiskImage.img -O vmdk DiskImage.vmdk
  • Transfer disk image to ESXi (using scp (enable ssh in ESXi)) or NFS (as I did)
  • Create new virtual machine with custom options and add the converted disk
  • Boot

Unfortunate this did not work as expected, when booting the converted images, the Linux instances inside all crashed during boot with this error message (or something similar)

lib6.so: unsupported version 0 of verneed record

It turns out, two steps were missing; after transfering the converted disk image to ESXi, do this from the ESXi cli (via SSH)

# vmkfstools -i /vmfs/volumes/nfs1/DiskImage.vmdk -d thin /vmfs/volumes/datastore1/MyServer/DiskImage.vmdk

-d is the output format which can be zeroedthick, eagerzeroedthick or thin.

Now open the newly created vmdk file in vi and change the line ddb.adapterType from ide to lsilogic.

After doing this, add the image(s) to a newly created VM and boot.

(This was done in Ubuntu and will work with any Linux variant with qemu-img. If you want to do this in Windows, StarWinds V2V converter is said to be able to do the job)

It’s been a while since I last had to run Windows on my laptop; back then I used Ext2 Installable File System For Windows to access data on my Linux-formated partitions.

In the meantime a few things have changed: Windows 7 and Ubuntu formating ext3 with a inode size of 256 – none of these are supported by ext3 ifs.

Ext2read supports Windows 7 (as well as ext4 and LVM2) but it’s more like a file browser and does not support assigning drive letters to Linux filesystems and since my /home is formatted with XFS it does not help me anyway.

Instead of going through reformatting the filesystems I wanted to access from Windows, I decided to build a virtual file server instead; that way I can access any filesystem type supported by Linux.

Software used: Windows 7, Virtualbox and Ubuntu (server edition)

This guide will work with other versions of Windows (and other OS’es as well), there are no ties to Virtualbox and the Linux version used can be anyone you like.

Continue reading

Please go to the updated article.

Since I wrote the post about running Windows applications on Linux with Sun xVM VirtualBox and SeamlessRDP I have been using the system almost daily to run some applications needed at work. It has been running well except for crashes in VirtualBox from time to time. Two new releases of VirtualBox has not fixed the problem.

Growing increasingly tired of this I decided to look at KVM (Kernel-based Virtual Machine).

Installing KVM

I run Ubuntu Jaunty (9.04) and at the time of writing the version of KVM in the repository is kvm-84. If you are running an older version of Ubuntu there is a PPA with updated KVM packages. Add it to your apt sources:

$ echo 'deb http://ppa.launchpad.net/intuitivenipple/ubuntu hardy main' | sudo tee /etc/apt/sources.list.d/intuitivenipple.list
$ sudo apt-get update

You are now ready to install KVM (and some other programs we are going to use later):

$ sudo apt-get install kvm dnsmasq qemu uml-utilities

I opted to install a new virtual machine but it should be possible to convert an existing virtual machine (VMware or VirtualBox) by converting the disk image and using it in a KVM machine – The method for converting a VMware image is described in the VirtalBox article.

If you want to convert a VirtualBox VDI image do the following:

$ VBoxManage internalcommands converttoraw OldDisk.vdi NewDisk.img

this requires VirtualBox.

If you are creating a new virtual machine then create a disk image:

$ qemu-img create -f qcow2 WindowsDisk.img 10G

Setting up the network

Because I need to contact the virtual machine from the host using the “user” networking facility (NAT) of KVM was not a possibility. Instead I chose to use a tap-based solution (with NAT’ing done a the host using iptables).

First, create the configuration in

/etc/network/interfaces

(just add this):

iface tap0 inet static
address 192.168.10.1
netmask 255.255.255.0
up /usr/sbin/dnsmasq --interface=${IFACE}  --except-interface=lo --bind-interfaces --user=nobody \
--dhcp-range=kvm,192.168.10.150,192.168.10.250,255.255.255.0,192.168.10.255,8h \
--domain=kvm.lan --pid-file=/var/run/${IFACE}_dnsmasq.pid --conf-file
down kill -s TERM `cat /var/run/${IFACE}_dnsmasq.pid` && rm -f /var/run/${IFACE}_dnsmasq.pid
tunctl_user 

We also start dnsmasq (which will only listen in the tap0 interface) to act as DNS and DHCP server for virtual machines (the idea came from this HOWTO.

Test that everything works:

$ sudo ifup tap0

For some reason (security I guess) a normal user is, per default, not allowed to use the tap/tun interfaces. To fix this:

$ echo "KERNEL==\"tun[0-9]*\",GROUP=\"uml-net\" MODE=\"0660\"" | sudo tee -a /etc/udev/rules.d/40-permissions.rules

and then reread the udev rules:

$ sudo udevadm control --reload-rules

You also need to be member of the uml-net group:

$ sudo adduser $(id -un)

You need to log out and log on again for the changes to take effect.

If you want your virtual machine to be able to access the the outside world you need to setup NAT. One way of doing this is to Ubuntu’s Uncomplicated Firewall.

Configurating and running KVM

Installing Windows in KVM

There is the possibility of using one of the graphical interfaces for Qemu/KVM but I just created a script for my Windows machine, it looks like this:

#!/bin/sh
HD="-hda Windows.img"
NIC1MAC="00:16:3e:66:42:73"
KVM="kvm"
#VNC="-vnc :1"
NET="-net nic,model=rtl8139,macaddr=$NIC1MAC,vlan=0 -net tap,vlan=0,ifname=tap0,script=no"
SOUND="-soundhw es1370"
TIME="-localtime"
MEM="-m 512"
NAME="-name Windows"
CPU="-cpu core2duo"
KB="-k da"
OTHERARG="-daemonize"
$KVM $HD $NET $VNC $SOUND $MEM $TIME $NAME $CPU $KB "[email protected]"

Adjust MEM, NIC1MAC, CPU and KB to suit your setup, use this small script to generate a random MAC address:

#!/usr/bin/python
# macgen.py script to generate a MAC address for Red Hat Virtualization guests
#
import random
#
def randomMAC():
mac = [ 0x00, 0x16, 0x3e,
random.randint(0x00, 0x7f),
random.randint(0x00, 0xff),
random.randint(0x00, 0xff) ]
return ':'.join(map(lambda x: "%02x" % x, mac))
#
print randomMAC()

When installing the Windows guest run the script like this:

$ kvm-windows -cdrom /path/to/windows.iso -boot -d

Once the virtual machine is installed shut down Windows. We are going to switch the network card from an emulated Realtek rtl8139 to the much fast virtio, this reqiures paravirtual network drivers for Windows. Download it from here.

Change the NET= line in the kvm-windows script:

NET="-net nic,model=virtio,macaddr=$NIC1MAC,vlan=0 -net tap,vlan=0,ifname=tap0,script=no"

Boot the machine again:

$ kvm-windows -cdrom /path/to/NETKVM-20081229.iso

Once the virtual Windows machine comes up, install the driver from the CD-drive when Windows asks for drivers.

Let us wrap it all up by allowing the virtual machine to start without the SDL-based console by removing the # from VNC and OTHERARGS. This will run kvm daemonized (detaching it from the tty) and with the console output redirected to a VNC server on display :1.

Enabling Terminal Services

Terminal Services is called Remote Access in Windows XP – enable it in Start -> Control Panel -> System -> Remote Access.

One downside is that someone needs to log on before XP punches a hole in the firewall. To circumvent this either manually add an exception for the RDP service or simply turn of the firewall (that’s what I did since the host will be protected by the host’s firewall as well as the NAT feature of VirtualBox).

Tuning Terminal Services

One of the more annoying limitations in Windows XP is that the color depth by default is limited to 16 bits.

To change this open the Group Policy Editor (Start -> Run -> gpedit.msc) and navigate to Administrative Template -> Windows Components -> Terminal Services and change the limit:

Setting connection limit in Terminal Services

Setting connection limit in Terminal Services

There are a few other parameters one can change, feel free to poke around.

SeamlessRDP

The main component in this setup is SeamlessRDP which allows one to launch a single application using RDP (remote desktop) and open only the window of that application. The drawback (with Windows XP) is that you are only allowed to open one session which means you can only launch one application at the same time.

Luckily someone grew tired of this and has made a patch to both rdesktop and SeamlessRDP that makes it possible to launch more than one application over the same SeamlessRDP session.

Installing rdesktop from CVS

First make sure that you have all the required packages for building

$ sudo apt-get build-dep rdesktop

Download rdesktop from CVS

$ cvs -d:pserver:[email protected]:/cvsroot/rdesktop login
$ cvs -z3 -d:pserver:[email protected]:/cvsroot/rdesktop co -P rdesktop

Download the patch to the checked out source

$ cd rdesktop
$ wget http://www.fontis.com.au/system/files/rdesktop.patch

Patch the source

$ patch -p2 < rdesktop.patch

Compile the source and install (install it as rdesktop-cvs to not interfere with the Ubuntu package)

$ ./bootstrap
$ ./configure
$ make
$ sudo make install
$ sudo mv /usr/local/bin/rdesktop /usr/local/bin/rdesktop-cvs

Now download the updated SeamlessRDP program and unpack it to c:\seamlessrdp on the virtual machine.

Making it all come together

winrun

Used to run any application on you Windows machine.

Create a script in $HOME/bin called winrun (requires that you have added $HOME/bin to your $PATH).

RDESKTOP="/usr/local/bin/rdesktop-cvs"
SRDP="c:\seamlessrdp\seamlessrdpshell.exe"
SOCKET="$HOME/.rdesktop/socket"
RDESKTOP_ARGS="-k da -u  -p   -z -x l -M $SOCKET -A"
RHOST=""
RUNNING=$(pgrep -c -U $USER -x rdesktop-cvs)
if [ -e $SOCKET -a $RUNNING -ge 1 ]
then
$RDESKTOP $RDESKTOP_ARGS -l "$*"
else
$RDESKTOP $RDESKTOP_ARGS -s "$SRDP $*" $RHOST
fi

Run as winrun c:pathtoprogram.exe

Sharing data between host and VM

There are (at least) three ways of sharing data between the host and the virtual machine

Remote Desktop resource redirection

This is the easiest way of sharing data but it has some drawbacks.

Enable it by adding this to RDESKTOP_ARGS in winrun:

-r disk:Home=$HOME

This will make your entire home directory available to your virtual machine but only when you are connected and not with an assigned drive letter.

Redirected local resource in RDP

Redirected local resource in RDP

Samba

Last but not least one could use a Samba server on the host

$ sudo apt-get install samba

By default the section in /etc/samba/smb.conf concerning home directories is commented out

[homes]
comment = Home Directories
browseable = no
read only = no
create mask = 0700
directory mask = 0700
valid users = %S