Migrating a VirtualBox Windows Virtual Machine to QEMU/KVM/virt-manager (Shallow Thoughts)

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Sat, 16 Apr 2022

Migrating a VirtualBox Windows Virtual Machine to QEMU/KVM/virt-manager

A month ago I wrote about Getting virt-manager Running on Debian. The ultimate goal of this was to migrate my Windows 10 install from VirtualBox to QEMU, because VirtualBox is becoming increasingly difficult to install on Linux, especially on Debian, which has removed VirtualBox from Bookworm (testing) and there are indications that it might be removed from Sid (unstable) as well. I gather there's something unsavory about the license now that Oracle owns it, but I haven't been following the details.

Anyway, after getting virt-manager running, I'd been putting off the rest of the migration out of a suspicion that there lay dragons. I was right: it took several days of struggling, but I now have Windows 10 working under virt-manager and qemu/kvm. Here's how.

Step 1, of course, was to get virt-manager running in the first place, the topic of the earlier article.

Step 2: Migrate the VM

This part was easy-peasy. VBoxManage list hdds tells you the name of the virtual machines you have installed. It'll probably turn out to be something like /path/to/VirtualBox Vms/your-vm-name/{LONG-UUID}.vdi. Pass that path to VBoxManage clonehd to make a raw disk image. I created a directory ~/QEMU to store my new VMs.

VBoxManage clonehd --format RAW '/path/to/VirtualBox Vms/your-vm-name/{LONG-UUID}.vdi' ~/QEMI/Win10.img

Then convert the raw file into a qemu-style QCOW file:

cd ~/QEMU
qemu-img convert -f raw Win10.img -O qcow2 Win10.qcow2

You should be able to delete the raw image now, but if you have space, I'd recommend keeping it around until you get everything working.

Step 3: Set Your System Info

When I set up my VirtualBox VM, I found several howtos explaining how I could copy my MSDM table, like this superuser.com answer. MSDM stands for MicroSoft Data Management, and it's an ACPI table that you can find in /sys/firmware/acpi/tables/MSDM. In VirtualBox, using it is trivial:

sudo cat /sys/firmware/acpi/tables/MSDM > ~/VirtualBox\ VMs/win10/msdm.bin
VBoxManage setextradata win10 \
    "VBoxInternal/Devices/acpi/0/Config/CustomTable" \
     ~/VirtualBox\ VMs/win10/msdm.bin

But in QEMU, it's not so easy.

First extract your various hardware and ACPI tables. I put these in the same place where I put my qcow file.

dmidecode -t 0 -u | grep $'^\t\t[^"]' | xargs -n1 | perl -lne 'printf "%c", hex($_)' > smbios_type_0.bin
dmidecode -t 1 -u | grep $'^\t\t[^"]' | xargs -n1 | perl -lne 'printf "%c", hex($_)' > smbios_type_1.bin
cat /sys/firmware/acpi/tables/SLIC > slic.bin
cat /sys/firmware/acpi/tables/MSDM > msdm.bin
(some of these required sudo). I skipped the slic.bin line because my CX1 apparently doesn't have a SLIC table (to check that, try dmesg | grep SLIC).

Now run virt-manager. Edit/Preferences and make sure Enable XML editing is checked.

Now make a new virtual machine, choosing Import existing disk image, that being the .qcow you made in step 2. Important: make sure Customize before install is checked, otherwise it will try to boot your Windows image as soon as you click Finish, before you've had a chance to import anything.

In the window that pops up after you click Finish, click the Info tab (the second icon in the toolbar, a lightbulb), click on the XML tab, and make sure you're looking at the XML for Overview in the left sidebar. Customize it as suggested in this gist, How to use Windows 10 OEM license in libvirt VM, using the path to the ACPI and hardware tables you stored earlier.

My new XML section looked like

  <qemu:commandline>
    <qemu:arg value='-acpitable'/>
    <qemu:arg value='file=/path/to/QEMU/acpitables/MSDM'/>
    <qemu:arg value='-smbios'/>
    <qemu:arg value='file=/path/to/QEMU/acpitables/smbios_type_0.bin'/>
    <qemu:arg value='-smbios'/>
    <qemu:arg value='file=/path/to/QEMU/acpitables/smbios_type_1.bin'/>
  </qemu:commandline>

Also change the first line of the XML file to read: <domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm"> so it will let you use the qemu:arg namespace.

Click Apply.

Conflicts Between virt-manager, virsh and Plain Old Editors

Any time you change virt-manager's XML, check that the changes you made are actually showing up in /etc/libvirt/qemu/win10.xml. I had some trouble with that.

The file has a prominent warning at the top that it's an auto-generated file and you shouldn't edit it. And indeed, if you edit it with a regular text editor, any changes you make won't be saved.

If you get tired of always editing with virt-manager's XML tab, you might be able to use virsh:

$ virsh list --all
 Id   Name    State
------------------------
 -    win10   shut off

$ virsh edit win10

That will open the XML file in your favorite editor. And when you write, the changes might persist. Or they might not. I found it inconsistent, so if you're making nontrivial changes, keep another copy in case you need to paste something into virt-manager later.

If virsh list --all doesn't see your VM at all, you may be running a root session in virt-manager (you can do that if you're in the right groups, like libvirt and libvirt-qemu). virsh only looks at user sessions by default, while virt-manager creates root sessions by default.

You can make virsh use root sessions with an environment variable:

export LIBVIRT_DEFAULT_URI="qemu:///system"
Or, of course, you could run virsh with sudo every time.

If you try to start your VM and see something like "error starting domain, network 'default' is not active", check its status with:

virsh net-list --all
If "default" isn't active, start it with: virsh net-start default and make it automatic with: virsh net-autostart default

How to Disable Networking

Speaking of networking, for my first boot, I wanted to disable the network, since I wasn't sure it was actually using my laptop's MSDM and I didn't want Windows to de-authorize me. So I tried clicking on the network in the Info (lightbulb) screen and un-checking active, but it made no difference, virt-manager activated its network anyway. (Fortunately I didn't get deactivated.)

I later found a more effective method: click on the Network device and click Remove. It's easy to add it back later once you're convinced your machine is set up okay.

Now I had my Windows 10 guest booting and running, and could remove virtualbox and try to clean up the mess I'd made of my system libraries to keep it installed. That's enough for now. I picked up a few other virt-manager/QEMU tips along the way, but I'll cover those in a separate article.

Tags: , , ,
[ 18:20 Apr 16, 2022    More linux | permalink to this entry | ]

Comments via Disqus:

blog comments powered by Disqus