Migrate from VirtualBox to libvirt
In my day job sometimes I need to edit documents using tools that are only available on Windows. As such, I have a virtual machine with Windows 10 running on VirtualBox.
Recently I upgraded to Debian 13 and I took the opportunity to migrate to a libvirt-based solution. I explain here the steps that I did.
VirtualBox
Being able to emulate a computer (the virtual computer, or the guest computer) within another computer (the host computer) is always a very amazing thing to see. Virtualisation technology has gone a long way since its inception, decades ago in the context of big, expensive mainframes. It is now commonly used by cloud providers to efficiently offer computational resources and it is also available in personal computers.
“Virtual machine” is a key concept of virtualisation. This is a very broad and
generic term and in this context I mean something that emulates a computer (the
virtual computer). A virtual computer will have virtual hardware and such
hardware is typically handled by a virtual machine manager or hypervisor.
Hypervisors range from relatively low level ones (such as Xen) which act like
if they were an operating system devoted only to manage virtual machines, to
higher-level ones (such as qemu
), which, in its default operation mode, can
emulate a computer, including its virtual hardware, purely in software.
VirtualBox is one of those hypervisors and it is paired with a rich offering of command-line tools and a graphical user interface. This makes it very intuitive to manage virtual machines. VirtualBox also uses hardware extensions provided by most modern CPUs, such as Intel-VT or AMD-V, and paravirtualisation (virtual hardware that is efficiently implemented by the hypervisor) for a more efficient virtualisation.
Why migrate?
VirtualBox is all good and fine but, for me, has two downsides:
- it needs an out-of-tree Linux module. These days, Linux distributions, including Debian, provide mechanisms to automatically build the Linux module against the installed Linux kernels. This makes this less a problem but it may get in the way when updating the operating system.
- some (arguably) basic functionality is only available through the VirtualBox Extension Pack. This extension has a different licencing to the rest of VirtualBox and in practice, except for personal use, requires purchasing a licence.
I suggest to stay with VirtualBox if none of the above are problematic.
There are other, less technical and more philosophical and/or moral, reasons to not use VirtualBox but I will not discuss them here.
KVM
KVM (Kernel-based Virtual Machine), is a Linux module that makes the Linux kernel to function as a hypervisor and allows it to use hardware virtualisation extensions along with paravirtualisation.
KVM itself is a low-level mechanism that emulators, such as qemu
, can use for
a more efficient virtualisation. Because qemu
is a generic system emulator
which can emulate CPUs of different architectures as the host architecture,
qemu/kvm
(qemu
using KVM) only makes sense when emulating a computer of the
same architecture as the host. The dominant architecture these days is x86-64,
so KVM is useful if you are on Linux and you want to run another OS on x86-64
such as, say, Linux itself (for instance another distribution), FreeBSD,
Windows, etc.
libvirt and virt-manager
I earlier mentioned that VirtualBox provides command-line tools and a graphical user interface. None of these are provided by KVM itself, so while it is possible to run qemu/kvm manually, it quickly gets old and one ends reinventing the wheel, especially of there is a need to manage different virtual machines or virtual hardware (such as virtual storage), etc.
The libvirt
project aims at filling the gap of common needs among all the
virtualisation technologies. It provides a set of tools and libraries to manage
virtual machines from different virtualisation providers (including qemu/kvm)
and it serves as a building block for further tooling.
One of those tools built on top of libvirt
is virt-manager
. virt-manager
is a graphical interface to handle virtual machines and virtual hardware
conveniently.
virt-manager
, along with libvirt
and qemu/kvm
, seems a good candidate
to replace VirtualBox.
Migrating a Windows 10 VM on Debian 13
In my case I want to migrate a Windows 10 VM. At the time of writing this blog post, there is no VirtualBox yet for Debian 13, so some of the operations were carried out in a Debian 12, and resumed after Debian 13 was fully upgraded.
Preparation
I suggest to clone the VM, fully, so you have a backup in case things go wrong. You can do that in the VirtualBox interface (look for the sheep icon, which is a late-90s reference to cloning things).
Though not needed, for hygiene, we will uninstall the VirtualBox Guest
Additions in our Windows 10 guest. This is not mandatory but will make things
less noisy when booting Windows 10 under virt-manager
for the first time.
Also make sure you remove any disk snapshots. Later on we will convert the disk image from VirtualBox to qemu’s native qcow2 format and I think it may get confused by the presence snapshots.
Installation of virt-manager
As root
, install virt-manager
which should install all the rest.
apt install virt-manager
Add your user <user-id>
to the groups kvm
and libvirt
so you can access
kvm
and libvirt
components that require elevated privileges.
usermod -a -G kvm,libvirt <user-id>
The group information is only read during login. The easiest way is to reboot
your system (logging out and logging in again does not seem to be enough). You
can also attempt a systemctl soft-reboot
. Use id
in a terminal to confirm
your user is part of these two groups.
Convert the virtual disk
Convert your .vdi
disk into .qcow2
format using qemu-img
. Assuming your
.vdi
disk is called Windows 10.vdi
this is a way to convert it to qcow2 into
a file named Windows 10.qcow2
.
qemu-img convert -f vdi -O qcow2 'Windows 10.vdi' 'Windows 10.qcow2'
I suggest you move the qcow2 disk in its own directory and add that directory
to a storage pool in virt-manager
.
Import the image in virt-manager
Now create a new virtual machine in virt-manager
choosing Import existing disk image. Set up
the virtual memory and virtual CPUs.
Note: if your Windows 10 VM boots with UEFI, make sure you choose
Customise configuration before install so you can change that in Overview
section. Change the Firmware, which will default to BIOS
to UEFI
. Failing
to do this will render an unbootable machine and this cannot be changed once
the machine has been created. You will have to delete the VM and start anew.
Now your Windows should boot for the first time. It will reconfigure some devices and your machine will be annoying to use: no mouse integration, no screen automatic resize, no clipboard with the host. This is expected.
Install the paravirtualised drivers for VirtIO
Download, in the Windows 10 VM, this installer and install all of the drivers. Mouse and screen integration should start shortly. You may need to reboot Windows at this point.
Extras
This may be enough for you, but there are number of goodies that can be worth considering.
Change the ethernet to VirtIO
Paravirtualised devices should have less overhead than actual emulated hardware
so, in virt-manager
change your NIC to have virtio
as its Device model. The
drivers we installed earlier will allow Windows to recognise the device without
problems.
Add a shared folder
This one is a bit involved.
- On the Debian 13 host install
virtiofsd
.apt install virtiofsd
- Now go to
virt-manager
and in the Memory section of your VM enable the checkbox Enable shared memory. - Now press Add Hardware and choose Filesystem. Set the Driver to
virtiofs
. Source path is a path of your host (for instance,/home/<user-id>
) and Target path is a name that will be displayed on Windows (for instancehost_<user-id>
). - Start the VM.
- Now in the Windows 10 VM, install WinFSP (the default options are fine).
- Type
Services
in the start menu of Windows and open the Services applet. Search for VirtIO-FS Service, double click it and change its Startup Type to Automatic. Also press the Start button to start the service now. Now go to the File Explorer, a new disk inZ:
should have appeared with your files from the host.
Change the boot disk to VirtIO
Your disk is probably still a SATA device. It is possible to move it to VirtIO as well, but the process is a bit complex as we need to make sure the boot phase of Windows loads the VirtIO driver for disks and so it encounters the system disk.
- Boot Windows normally.
- Run as administrator
cmd.exe
and typebcdedit /set "{current}" safeboot minimal
- Shutdown the VM machine
- Add a dummy disk (a small one will do) on the VirtIO bus. This is
VirtIO Disk 1
- Boot Windows, it should be in safe boot mode.
- Shutdown Windows.
- Remove the SATA disk but be careful not to remove the backing file!.
- Add a new disk on the VirtIO bus using the backing file of the previous step. This disk will now be
VirtIO Disk 2
- Fix the boot mode so it boots on
VirtIO Disk 2
instead ofVirtIO Disk 1
. - Boot Windows, it should boot normally.
- Run as administrator
cmd.exe
and typebcdedit /deletevalue "{current}" safeboot
- Shutdown the VM
- Remove the dummy disk
VirtIO Disk 1
(nowVirtIO Disk 2
becomesVirtIO Disk 1
). You probably want to the remove the backing file now. - Boot Windows again, it should boot normally.