The below steps were tested while pulling my hair out trying to migrate a Windows 2k3 guest from VMWare ESX to KVM managed by libvirt, hopefully this will save you from much windows related pain and suffering.
Prep the VM while it’s still running in VMware
Download MergeIDE.zip and run MergeIDE.bat. This is a really important step that will prepare the system to boot using an IDE driver when we bring it up in KVM. Skipping this step will likely result in blue screen errors and much frustration.
MergeIDE can be downloaded at
http://www.virtualbox.org/attachment/wiki/Migrate_Windows/MergeIDE.zip
Also, ensure that you know the local administrator password. This seems rather obvious but networking may not come up, so best to be prepared.
Now you’re ready to shut down and copy the vm.
Shutdown the VM and copy it’s vmdk
Gracefully shut down the VM. Once it’s down, ssh into your ESX server and navigate to the appropriate VMFS volume containing your VM.
[root@esx1 example-vm]# pwd
/vmfs/volumes/VMFS1/example-vm
[root@esx1 example-vm]# ls
example-vm-flat.vmdk example-vm.vmdk example-vm.vmx
example-vm.nvram example-vm.vmsd example-vm.vmxf
vmware-0.log vmware-2.log vmware-7.log vmware.log
vmware-1.log vmware-6.log vmware-8.log |
[root@esx1 example-vm]# pwd
/vmfs/volumes/VMFS1/example-vm
[root@esx1 example-vm]# ls
example-vm-flat.vmdk example-vm.vmdk example-vm.vmx
example-vm.nvram example-vm.vmsd example-vm.vmxf
vmware-0.log vmware-2.log vmware-7.log vmware.log
vmware-1.log vmware-6.log vmware-8.log
SCP the “flat” .vmdk file (or files if your machine has multiple virtual disks) from your ESX host to your KVM host.
[root@esx1 example-vm]# scp -pr example-vm-flat.vmdk kvm1:/etc/libvirt/images/
root@kvm1 password:
example-vm-flat.vmdk 100% 20GB 14.6MB/s 23:20 |
[root@esx1 example-vm]# scp -pr example-vm-flat.vmdk kvm1:/etc/libvirt/images/
root@kvm1 password:
example-vm-flat.vmdk 100% 20GB 14.6MB/s 23:20
Prepare the libvirt/KVM instance
Create an XML file to define the attributes of the virtual machine. You’ll likely want to copy things like the memory size, number of CPUs and MAC address from the vmware vmx file, in our case this is /vmfs/volumes/VMFS1/example-vm/example-vm.vmx
.
In order to set up virtio we first set our primry disk as bus type ide and create a secondary disk with a bus type of virtio. This will allow us to boot from the existing OS without special drivers. From there windows will detect the secondary virtio SCSI adapter and prompt for driver installation. We’ll also attach a virtio guest drivers floppy while we’re at it.
Virtio guest driver iso and floppy images can be downloaded at
http://alt.fedoraproject.org/pub/alt/virtio-win/latest/images/bin/
<domain type='kvm'>
<name>example-vm</name>
<uuid>5de881b6-7738-4c30-8f14-da203c1b09f5</uuid>
<memory>2097152</memory>
<currentMemory>2097152</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='x86_64' machine='rhel5.4.0'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' cache='none'/>
<source file='/etc/libvirt/images/example-vm/example-vm-flat.vmdk'/>
<target dev='hda' bus='ide'/>
<driver name='qemu' cache='none'/>
<source file='/etc/libvirt/images/example-vm/virtio-temp.raw'/>
<target dev='vdb' bus='virtio'/>
</disk>
<disk type='file' device='floppy'>
<source file='/root/virtio-win-1.1.16.vfd'/>
<target dev='fda' bus='fdc'/>
</disk>
<readonly/>
</disk>
<interface type='bridge'>
<mac address='00:50:56:b9:4e:50'/>
<source bridge='virbr0'/>
<model type='virtio'/>
</interface>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes' keymap='en-us'/>
</devices>
</domain> |
<domain type='kvm'>
<name>example-vm</name>
<uuid>5de881b6-7738-4c30-8f14-da203c1b09f5</uuid>
<memory>2097152</memory>
<currentMemory>2097152</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='x86_64' machine='rhel5.4.0'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' cache='none'/>
<source file='/etc/libvirt/images/example-vm/example-vm-flat.vmdk'/>
<target dev='hda' bus='ide'/>
<driver name='qemu' cache='none'/>
<source file='/etc/libvirt/images/example-vm/virtio-temp.raw'/>
<target dev='vdb' bus='virtio'/>
</disk>
<disk type='file' device='floppy'>
<source file='/root/virtio-win-1.1.16.vfd'/>
<target dev='fda' bus='fdc'/>
</disk>
<readonly/>
</disk>
<interface type='bridge'>
<mac address='00:50:56:b9:4e:50'/>
<source bridge='virbr0'/>
<model type='virtio'/>
</interface>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes' keymap='en-us'/>
</devices>
</domain>
Note: if you need to generate a new uuid simply run uuidgen
Now you’re ready to “Define” the new virtual machine in libvirt.
[root@kvm1 ~]# virsh define /etc/libvirt/qemu/example-vm.xml
Domain example-vm defined from /etc/libvirt/qemu/example-vm.xml |
[root@kvm1 ~]# virsh define /etc/libvirt/qemu/example-vm.xml
Domain example-vm defined from /etc/libvirt/qemu/example-vm.xml
Boot the KVM guest
Using virt-manager, start the virtual machine. It should boot up and allow you to log in as a local administrator or with cached credentials. If you are seeing a bsod (blue screen) with error 0x000007b boot errors, verify that the MergeIDE step was successful. This resolved my 0x7b errors.
Install the windows virtio guest drivers
Upon logging in, windows should detect the new virtio SCSI and network hardware and prompt you for drivers. You’ll want to point it at the floppy drive we attached to the guest.
A very detailed description of what to do is available at
http://www.linux-kvm.org/page/WindowsGuestDrivers/viostor/installation#Non-System_disk_installation_procedure.
Change the primary disk from ide to virtio
Finally, once the virtio drivers have been successfully installed you’re ready to change your boot disk to a bus type of virtio and can remove the temporary second drive. This can be done by executing virsh edit example-vm
while the host is running and changing the disk dev= and bus= as follows:
<disk type='file' device='disk'>
<driver name='qemu' cache='none'/>
<source file='/etc/libvirt/images/example-vm/example-vm-flat.vmdk'/>
<target dev='vda' bus='virtio'/>
</disk> |
<disk type='file' device='disk'>
<driver name='qemu' cache='none'/>
<source file='/etc/libvirt/images/example-vm/example-vm-flat.vmdk'/>
<target dev='vda' bus='virtio'/>
</disk>
You can also remove the driver floppy at this time.
Perform a full reboot of the guest
To make the above change take effect simply shut the machine down completely and then re-start it with virt-manager. Don’t simply issue a reboot from within the VM, we need to apply the changes to the libvirt domain definition.
You’re done!
Your VM should now be up and running, free from vmware and benefiting from the performance gains of virtio.