Jump to content
SUSE Linux Enterprise Server 11 SP4

Xen to KVM Migration Guide

SUSE Linux Enterprise Server 11 SP4

Abstract

As the KVM virtualization solution is becoming more and more popular among server administrators, many of them need a path to migrate their existing Xen based environments to KVM. As of now, there are no mature tools to automatically convert Xen VMs to KVM. There is, however, a technical solution that helps convert Xen virtual machines to KVM. Information and procedures introduced in this helps you smooth the migration.

Publication Date: 09/08/2025
Important
Important

The migration procedure described in this document is not fully supported by SUSE. We provide it as a guidance only.

1 Xen to KVM Manual Migration

1.1 General Outline

The preferred solution to manage virtual machines is based on libvirt (See http://libvirt.org/ for more details). It has several notable advantages over the manual way of defining/running virtual machines — libvirt is cross-platform, supports many hypervisors, secure remote management, virtual networking, and, most of all, provides a unified abstract layer to manage virtual machines. Therefore the main focus of this article is on the libvirt solution.

Generally, the Xen to KVM migration runs in the following basic steps:

  1. Make a backup copy of the original Xen VM Guest.

  2. OPTIONAL: Apply changes specific to paravirtualized guests.

  3. Obtain information about the original Xen VM Guest and update it to KVM equivalents.

  4. Shut down the guest on the Xen host, and run the new one under the KVM hypervisor.

Warning
Warning: No Live Migration

The Xen to KVM migration cannot be done live while the source VM Guest is running. Before running the new KVM-ready VM Guest, you are advised to shut down the original Xen VM Guest.

1.2 Back Up the Xen VM Guest

To back up your Xen VM Guest, follow these steps:

  1. Identify the relevant Xen guest you want to migrate, and remember its ID/name.

    # virsh list --all
    Id Name                 State
    ----------------------------------
     0 Domain-0             running
     1 SLES11SP3            running 
    [...]
  2. Shut down the guest. You can do this either by shutting down the guest OS, or with virsh:

    # virsh shutdown SLES11SP3
  3. Backup its configuration to an XML file.

    # virsh dumpxml SLES11SP3 > sles11sp3.xml
  4. Backup its disk image file. Use the cp or rsync commands to create the backup copy. Remember that it is always a good idea to check the copy with the md5sum command.

  5. After the image file is backed up, you can start the guest again with

    # virsh start SLES11SP3

1.3 Changes Specific to Paravirtualized Guests

Apply the following changes if you are migrating a paravirtualized Xen guest. You can do it either on the running guest, or on the stopped guest using guestfs-tools.

Important
Important

After applying the changes described in this section, the image file related to the migrated VM Guest will not be usable under Xen anymore.

1.3.1 Install the Default Kernel

Warning
Warning

After you install the default Kernel, do not try to boot the Xen guest with it, the system will not boot.

Before cloning the Xen guest disk image for use under the KVM hypervisor, make sure it is bootable without the Xen hypervisor. This is very important for paravirtualized Xen guests as they usually contain a special Xen Kernel, and often do not have a complete GRUB boot loader installed.

  1. Update the /etc/sysconfig/kernel file. Change the INITRD_MODULES parameter by removing all Xen drivers and replacing the with virtio drivers. Replace

    INITRD_MODULES="xenblk xennet"

    with

    INITRD_MODULES="virtio_blk virtio_pci virtio_net virtio_ballon"
  2. Paravirtualized Xen guests are running a specific Xen Kernel. To run the guest under KVM, you need to install the default Kernel.

    Note
    Note

    You do not need to install the default Kernel for a fully virtualized guests as it is already installed.

    Enter rpm -q kernel-default on the Xen guest to find out if the default Kernel is installed. If not, install it with zypper in kernel-default.

    The Kernel we are going to use to boot the guest under KVM must have virtio (paravirtualized) drivers available. Run the following command to find out. Do not forget to replace 3.8.9-4 with your Kernel version:

    # find /lib/modules/3.8.9-4-default/kernel/drivers/ -name virtio*
    /lib/modules/3.8.9-4-default/kernel/drivers/net/virtio_net.ko
    /lib/modules/3.8.9-4-default/kernel/drivers/scsi/virtio_scsi.ko
    /lib/modules/3.8.9-4-default/kernel/drivers/block/virtio_blk.ko
    /lib/modules/3.8.9-4-default/kernel/drivers/char/virtio_console.ko
    /lib/modules/3.8.9-4-default/kernel/drivers/char/hw_random/virtio-rng.ko
    /lib/modules/3.8.9-4-default/kernel/drivers/virtio
    /lib/modules/3.8.9-4-default/kernel/drivers/virtio/virtio.ko
    /lib/modules/3.8.9-4-default/kernel/drivers/virtio/virtio_pci.ko
    /lib/modules/3.8.9-4-default/kernel/drivers/virtio/virtio_balloon.ko
    /lib/modules/3.8.9-4-default/kernel/drivers/virtio/virtio_ring.ko
    /lib/modules/3.8.9-4-default/kernel/drivers/virtio/virtio_mmio.ko
  3. Update /etc/fstab. Change any storage devices from xvda to vda.

  4. Update the boot loader configuration. Enter rpm -q grub on the Xen guest to find out if GRUB is already installed. If not, install it with zypper in grub.

    Now make the newly installed default Kernel the default for booting the OS. Also remove/update the Kernel command line options that may refer to Xen-specific devices. You can do it either with YaST (System › Boot Loader), or manually:

    • In your favorite text editor, open /boot/grub/menu.lst.

    • Find the boot menu entry (entries start with title) containing the default non-Xen Kernel to boot, and set the global GRUB's default option to the number of the entry (counted from zero).

    • From the same menu entry's Kernel command line, remove/update any reference to Xen-specific devices. In the following example, you can replace

      root=/dev/xvda1 disk=/dev/xvda console=xvc

      with

      root=/dev/vda1 disk=/dev/vda

      Note that you need to remove all references to xvc-type consoles (such as xvc0).

  5. Update device.map in one of the /boot/grub, /boot/grub2, or /boot/grub2-efi directory. Change any storage device from xvda to vda.

1.3.2 Update the Guest for Boot under KVM

  1. Update the /etc/inittab file to use default serial console:

    • Comment the line containing xvc0.

    • OPTIONAL. Uncomment the line containing S0 if you are using a serial port.

  2. Update the /etc/securetty file. Replace xvc0 with ttyS0.

1.4 Update the Xen VM Guest Configuration

This section describes how to export the configuration of the original Xen VM Guest, and what particular changes to apply to it to be able to import it as a KVM guest into libvirt.

1.4.1 Export the Xen VM Guest Configuration

First export the configuration of the guest and save it to a file. A typical one may look like this:

# virsh dumpxml SLES11SP3
<domain type='xen'>
  <name>SLES11SP3</name>
  <uuid>fa9ea4d7-8f95-30c0-bce9-9e58ffcabeb2</uuid>
  <memory>524288</memory>
  <currentMemory>524288</currentMemory>
  <vcpu>1</vcpu>
  <bootloader>/usr/bin/pygrub</bootloader>
  <os>
    <type>linux</type>
  </os>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
    <disk type='file' device='disk'>
      <driver name='file'/>
      <source file='/var/lib/libvirt/images/SLES_11_SP2_JeOS.x86_64-0.0.2_para.raw'/>
      <target dev='xvda' bus='xen'/>
    </disk>
    <interface type='bridge'>
      <mac address='00:16:3e:2d:91:c3'/>
      <source bridge='br0'/>
      <script path='vif-bridge'/>
    </interface>
    <console type='pty'>
      <target type='xen' port='0'/>
    </console>
    <input type='mouse' bus='xen'/>
    <graphics type='vnc' port='-1' autoport='yes' keymap='en-us'/>
  </devices>
</domain>
Tip
Tip

You can find detailed information on the libvirt XML format for VM Guest description at http://libvirt.org/formatdomain.html.

1.4.2 General Changes to the Guest Configuration

You have to make a few general changes to the exported Xen guest XML configuration in order to run it under the KVM hypervisor. The following applies to both fully virtualized and paravirtualized guests. Note that not all of the following XML elements need to be present in your specific configuration.

Tip
Tip: Conventions Used

To refer to a node in the XML configuration file, an XPath syntax will be used throughout this document. For example, to refer to a <name> inside the <domain> tag

<domain>
  <name>sles11sp3</name>
</domain>

an XPath equivalent /domain/name will be used.

  1. Change the type attribute of the /domain element from xento kvm.

  2. Remove the /domain/bootloader element section.

  3. Remove the /domain/bootloader_args element section.

  4. Change the /domain/os/type element value from linux to hvm.

  5. Add <boot dev="hd"/> under the /domain/os element.

  6. Add the arch attribute to the /domain/os/type element. Acceptable values are arch=”x86_64” or arch=”i686”

  7. Change the /domain/devices/emulator element from /usr/lib/xen/bin/qemu-dm' to /usr/bin/qemu-kvm.

  8. For each disk associated with the paravirtualized (PV) guest, change the following:

    • Change the name attribute of the /domain/devices/disk/driver element from file to qemu, and add a type attribute for the disk type. For example, valid options include raw or qcow2.

    • Change the dev attribute of the /domain/devices/disk/target element from xvda to vda.

    • Change the bus attribute of the /domain/devices/disk/target element from xen to virtio.

  9. For each network interface card, do the following changes:

    • If there is model defined in /domain/devices/interface, change its type attribute value to virtio

      <model type=”virtio”>
    • Delete all /domain/devices/interface/script sections.

    • Delete all /domain/devices/interface/target elements if the dev attribute starts with vif or vnet or veth. If using a custom network then change the dev value to that target.

  10. Remove the /domain/devices/console element section if it exists.

  11. Remove the /domain/devices/serial element section if it exists.

  12. Change the bus attribute on the /domain/devices/input element from xen to ps2.

  13. Add the following element for memory ballooning features under the /domain/devices element.

    <memballoon model="virtio"/>
Tip
Tip

<target dev='hda' bus='ide'/> controls the device under which the disk is exposed to the guest OS. The dev attribute indicates the "logical" device name. The actual device name specified is not guaranteed to map to the device name in the guest OS. Therefore you may need to change the disk mapping on the boot loader command line. For example if the boot loader expects a root disk to be hda2 but KVM still sees it as sda2, change the boot loader command line from

[...] root=/dev/hda2 resume=/dev/hda1 [...]

to

[...] root=/dev/sda2 resume=/dev/sda1 [...]

or to

[...] root=/dev/vda2 resume=/dev/vda1 [...]

in the case of paravirtualized xvda devices.

Otherwise the VM Guest will refuse to boot in the KVM environment.

1.4.3 The Target KVM Guest Configuration

After having applied all the modifications mentioned above, you end up with the following configuration for your KVM guest:

<domain type='kvm'>
  <name>SLES11SP3</name>
  <uuid>fa9ea4d7-8f95-30c0-bce9-9e58ffcabeb2</uuid>
  <memory>524288</memory>
  <currentMemory>524288</currentMemory>
  <vcpu cpuset='0-3'>1</vcpu>
  <os>
    <type arch=”x86_64”>hvm</type>
    <boot dev="hd"/>
  </os>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/bin/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type="raw"/>
      <source file='/var/lib/libvirt/images/SLES_11_SP2_JeOS.x86_64-0.0.2_para.raw'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <interface type='bridge'>
      <mac address='00:16:3e:2d:91:c3'/>
      <source bridge='br0'/>
    </interface>
    <input type='mouse' bus='usb'/>
    <graphics type='vnc' port='5900' autoport='yes' keymap='en-us'/>
    <memballoon model="virtio"/>
  </devices>
</domain>

Save the configuration to a file in your home directory. After you later import it, it will be copied to the default /etc/libvirt/qemu. Suppose you save the file as SLES11SP3.xml.

1.5 Migrate the VM Guest

After you updated the VM Guest configuration, and applied necessary changes to the guest OS, it is time to shut down the original Xen guest, and run its clone under the KVM hypervisor.

  1. Shut down the guest on the Xen host by running shutdown -h now as root from the console.

  2. Copy the disk files associated with the VM Guest if needed. A default configuration will require the Xen disk files to be copied from /var/lib/xen/images to /var/lib/kvm/images. The /var/lib/kvm/images directory may need to be created (as root) if you have not previously created a VM Guest.

  3. Create the new domain, and register it with libvirt:

    # virsh define SLES11SP3.xml
     Domain SLES11SP3 defined from SLES11SP3.xml
  4. Verify that the new guest is seen in the KVM configuration:

    virsh list –all
  5. Once the domain is created, you can start it:

    # virsh start SLES11SP3
     Domain SLES11SP3 started

2 For more information

For more information on libvirt, see http://libvirt.org.

You can find more details on libvirt XML format at http://libvirt.org/formatdomain.html.

For more information on Xen administration, see https://www.suse.com/documentation/sles11/book_xen/data/book_xen.html.

For more information on virtualization with KVM, see https://www.suse.com/documentation/sles11/book_kvm/data/book_kvm.html.

3 Legal Notice

Copyright© 2006– 2025 SUSE LLC and contributors. All rights reserved.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or (at your option) version 1.3; with the Invariant Section being this copyright notice and license. A copy of the license version 1.2 is included in the section entitled GNU Free Documentation License.

For SUSE trademarks, see http://www.suse.com/company/legal/. All other third party trademarks are the property of their respective owners. A trademark symbol (®, ™ etc.) denotes a SUSE or Novell trademark; an asterisk (*) denotes a third party trademark.

All information found in this book has been compiled with utmost attention to detail. However, this does not guarantee complete accuracy. Neither SUSE LLC, its affiliates, the authors, nor the translators shall be held liable for possible errors or the consequences thereof.

Print this page