Xen and KVM are the two major virtualization techologies that are freely available on linux. Although they are quite comparable performance wise, it still may be interesting to convert a Xen virtual machine to a KVM virtual machine.
Xen and KVM both use very similar images. However, there are some subtle differences in the setup:
- Xen block devices use the names “xvd?” where KVM uses “vd?”.
- The serial device in Xen is “xvc0” while on KVM it is “ttyS0”.
- Xen does not use the bootloader from the image but directly accesses the boot directory while KVM really uses the bootmanager.
- The modules that are needed for block devices are different.
- Although virsh supports both, Xen and KVM, the XML configuration is still somewhat different.
The easiest way would be to just install the necessary packages and do the needed modifications on a running Xen guest, however, if you don’t have your Xen host anymore, you would be busted. Therefore, lets do the migration of an image just on the KVM host.
First, make the image accessible with “kpartx”. To do this run the command
> kpartx -a disk0.raw -v add map loop0p1 (253:1): 0 319488 linear /dev/loop0 2048 add map loop0p2 (253:2): 0 16435200 linear /dev/loop0 321536
Now, determine which one is a real file system:
> lsblk -f /dev/mapper/loop0p? NAME FSTYPE LABEL MOUNTPOINT loop0p1 (dm-1) swap loop0p2 (dm-2) ext3
Obviously the device “/dev/mapper/loop0p2” is our root file system that we need to access. Lets mount it and add all the needed devices:
mount /dev/mapper/loop0p2 /mnt mount -o bind /dev /mnt/dev
Now, copy the needed kernel to the file system and do a “chroot” there:
cp kernel-default.rpm kernel-default-base.rpm /mnt/tmp chroot /mnt mount /sys mount /proc
Next, update several configuration files:
- /etc/inittab : comment the line starting with S0 and containing xvc0
- /etc/inittab : uncomment line starting with S0 and containing ttyS0. Change the speed to 115200 if needed.
- /etc/securetty : remove xvc0 and add ttyS0
- /etc/sysconfig/kernel : remove modules starting with xen from “INITRD_MODULES” and add “virtio_blk virtio” instead.
- /etc/fstab : remove the “x” from “/dev/xvda” (and possibly more needed block devices)
- /boot/grub/device.map : change from “/dev/xvda” to “/dev/vda”
- /boot/grub/menu.lst : comment line starting with gfxmenu
- /boot/grub/menu.lst : change the kernel and initrd lines to contain the kernel starting with “vmlinuz” and the default initrd as available in “/boot”.
- /boot/grub/menu.lst : fix the kernel parameters to contain the right root and console device, similar to: “root=/dev/vda2 console=ttyS0”.
Now, it is time to install the kernel:
rpm -Uhv /root/kernel-default.rpm /root/kernel-default-base.rpm
The only remaining task now is running “mkinitrd”. There will show up some error messages about not having the right root device available, which is correct. But the command commonly will work anyway.
To finish the work on the image, only some cleanup is needed:
- umount /sys
- umount /proc
- umount /mnt/dev
- umount /mnt
- kpartx -d disk0.raw
To start the image, the easiest way is to use “vm-install” and select activating an existing image “I have a disk or disk image …”. If it is just for testing, you can also use a command link this:
qemu-kvm \ -drive file=/kvm/images/disk0.raw,id=root,if=virtio \ -m 1024M -nographic
This should bring up your previous Xen image on a KVM machine.