XEN to KVM Migration

I will describe a way to move a XEN domU virtual machine into a KVM virtual machine. Xen stores the machine as one partition in one file. KVM stores the machine as a whole disk.

There are many ways to do this. This might work for you.

NOTE! The packages parted and kpartx must be installed for this.

  1. First, install grub and a kernel in the virtual machine (xen domU), since a KVM-machine is a self contained machine and needs its own kernel.
# aptitude install grub linux-image-686
  1. Shutdown the virtual machine, and make a copy of its root file system. My copy is named xen.img.

  2. Make a new image for the KVM-machine, at least the same size as the old machine. My old xen-machine lives in a 500MB file, so we make the new machine 1GB.

# dd if=/dev/zero of=kvm.img bs=1M count=1024
  1. We need two partitions in that big file. One 750MB for the root file system and one 250MB for swap. The first partition is set to be bootable. We use parted, since fdisk and cfdisk can only manage block devices. And, yes, the first partition is set to ext2, since parted doesn’t understand ext3. The partition is later overwritten with our ext3-image, so it really doesn’t matter.
# parted kvm.img mklabel msdos
# parted kvm.img mkpart primary ext2 0 750
# parted kvm.img mkpart primary linux-swap 750 1000
# parted kvm.img set 1 boot on
  1. Now it gets interesting! We will copy the contents of the old 500MB xen.img into the 750MB partition of kvm.img and resize it to 750MB. Skip the fsck/resize2fs part if the xen.img is a reiserfs/xfs/jfs-file system.
# modprobe dm-mod
# losetup /dev/loop0 kvm.img
# kpartx -a /dev/loop0

# dd if=xen.img of=/dev/mapper/loop0p1 bs=1M
# fsck.ext3 -f /dev/mapper/loop0p1
# resize2fs /dev/mapper/loop0p1
# fsck.ext3 -f /dev/mapper/loop0p1
  1. The last step is installing grub on the kvm.img. We copy the stage*-files from the host system. We also create a menu.lst from scratch. You need to check and adjust the kernel names.
# mount /dev/mapper/loop0p1 /mnt
# mkdir -p /mnt/boot/grub
# cp /boot/grub/stage1 /mnt/boot/grub/
# cp /boot/grub/stage2 /mnt/boot/grub/
# cp /boot/grub/e2fs_stage1_5 /mnt/boot/grub/

# echo "default 0
timeout 0
title Linux
root (hd0,0)
kernel /boot/vmlinuz-2.6.18-6-686 root=/dev/hda1 ro
initrd /boot/initrd.img-2.6.18-6-686" >/mnt/boot/grub/menu.lst

# echo "device (hd0) kvm.img
root (hd0,0)
setup (hd0)
quit" > /tmp/grub.input
# grub --device-map=/dev/null < /tmp/grub.input 
# umount /mnt 
# kpartx -d /dev/loop0 
# losetup -d /dev/loop0
  1. Now we have a bootable kvm.img. You also can test it with qemu.
# qemu kvm.img

Remember to remove all lines in /etc/udev/rules.d/70-persistent-net.rules (debian lenny) or /etc/udev/rules.d/z25-persistent-net.rules (debian etch) to avoid having your NIC renamed.

This is also probably the way to migrate a xen domU to a real physical machine, since the kvm.img can easily be copied onto a physical hard disk. I will test this real soon…

Update 2008-10-29 ! Oh yes, deployment of kvm.img to physical disk and physical hardware, worked out great. No problem at all, just as planned. :)

Thanks to Alex Hudson and David M. Barrett for hints and inspiration.


Written by SirPing
Later article
Black Day