Federico Fuga

Engineering, Tech, Informatics & science

From VmWare to KVM, in OpenSuSE

05 Oct 2024 18:35 CEST

I recently bought a Tuxedo Linux AMD Laptop, but my experience with TuxedoOS convinced me to migrate my OS from Debian based (Ubuntu, Tuxedo, Mint) to OpenSuSE.

Why OpenSuSE? Because I was very happy with it when Ubuntu was still an experiment (I’m talking of about 2006 or so), and recently I wasn’t at all satisfied by some changes that happened on Ubuntu.

Back in 2018 I bought a thinkpad but there were a lot of unsupported things that prevented my experience with linux on a laptop to be 100% good. And recently Tuxedo broke the support for their laptop hardware by jumping from kernel 6.5 to 6.11, and the frequency scaling, the graphics on USB3, and other things becomes extremely unstable or broken.

So a few weeks ago I switched to OpenSuSE, and when I decided to install vmware to allow me to work on Windows for one extremely important project I am involved with, it was a disaster.

VmWare’s quality has fallen. There are a huge amount of small issues on linux that Broadcom simply ignores. One is the fact that the vm drivers fails to compile on the new mainline kernel and people must rely on private developed patched. That is silly and stupid.

For this reason, after years of paying licenses to VmWare (I had fusion for almost 10 years and then VmWare Workstation), I left it.

The best option in linux seems to be KVM/QEMU with libvirt-manager.

Migrating the storage

I will not explain how to install KVM on OpenSuSE, YAST2 has a pattern for it.

First thing I had to do, was to migrate the storage. libvirt provides a tool for migrating from physical to virtual and from virtual to virtual storage. Unfortunately I forgot to shut down the VM before cloning my SSD, so it refused to work.

Fortunately, qemu is able to copy from different VM storage formats, and doesn’t bother if the VM has been suspended or shut down. So all I had to do was to use qemu-img convert:

$ qemu-img convert -f vmdk ../vmware/Win11/Win11-s001.vmdk -O qcow2 Win11.qcow2

After a while, very few dozen of seconds indeed, the 120Gb storage was converted into the new qcow2 format.

With that I could use virt-manager to create a new VM and run it.

All ok? Not really. But nothing dramatic, except one thing, but first things first.

CPU slow?

First thing to notice is that Win11 will be VERY slow if you accept the CPU configuration proposed by virt-manager as is.

You, like me, probably run it on a new single CPU multi core system, but the default proposed by virt will have as many single core CPU as is the number of cores allocated. If you have a 16 cores CPU, a 16 CPUs machine will be created, but Win11 will only use 2 CPUs, because it is licensed this way.

So you’ll need to manually change the topology of your CPU, to 1 CPU and 16 cores, or 8 cores 16 threads.

This will use the full power of your system!

Fixed Graphics?

Next thing to fix is the fact that the graphics will be fixed at, say, 800x600 pixel configuration or similar. Why? Because you need drivers installed to change it.

There are two options here: change the Graphics type from QXL to virtio, and just use it, it seems Windows already has a driver that is compatible with virtio. Unfortunately on my system this didn’t work too well and the performances were not very good.

The other option is to install the spice drivers. Spice is a protocol that allows the graphcis to pass through from VM to the Host without loosing performances.

Spice drivers can be downloaded and installed from the spice-space website. Install all under the “Guest” section in the “Windows binaries” subsection, in particular the NSIS package and the webdav daemon.

After that, you can use QXL and change the resolution of the screen to some predefined configurations.

Network

By default, virt-manager uses NAT configuration for network, but this doesn’t seem to be very reliable. Users suggest to change it to a bridge configuration, but though I was able to make it work for a while, it seems to be a bit unreliable so it might be even better to use the macvtap configuration, that is simpler and works well.

The two solutions are different and have pros and cons.

  • bridge solution is complex but allows the guest OS to use all the functionalities of a normal network adapter
  • macvtap is easier to implement but prevents guest OS to use some funcitonality.
  • bridge solution can use only ethernet adapter
  • macvtap, on the other hand, allows the use of wifi adapters too.

Let’s see both solution, starting from the easier.

Configuring macvtap solution

Configuring the bridge solution

There are a pletora of instructions on how to do this, but modern OpenSuSE use NetworkManager to manage the network devices and YAST2 can’t configure the bridge when NM is in use.

For this reason, configuration must be done from the command line.

The best instructions I found are here, but it misses an important point, that I found in another page.

Important note: Bridged connection cannot work on Wifi, but only on Ethernet.

From a terminal, first create a bridge connection named br0 using nmcli. We need a bridge and a bridge-slave that are connected together. The bridge-slave will have your ethernet device as iface, in my case is enp3s0, in your system it may have a different name.

$ sudo nmcli con add type bridge ifname br0 con-name br0
$ sudo nmcli con add type bridge-slave ifname enp3s0 master br0

The first command creates the bridge, the second the slave.

$ nmcli connection show

Will show the list of connections.

You also want to disable the Spanning Tree Protocol:

$ sudo nmcli con modify br0 bridge.stp no

Then you need to turn off your ethernet, and turn on the bridge:

$ sudo nmcli con down "Wired connection 1"
$ sudo nmcli con up br0
$ nmcli con show

Next, create the bridge interface in the virt-manager or using virsh. Create a file named /tmp/br0.xml with the following content

<network>
  <name>br0</name>
  <forward mode="bridge"/>
  <bridge name="br0" />
</network>

Then use virsh to add it:

$ sudo virsh net-define /tmp/br0.xml
$ sudo virsh net-start br0
$ sudo virsh net-autostart br0
$ sudo virsh net-list --all

Name                 State      Autostart     Persistent
----------------------------------------------------------
 br0                  active     yes           yes
 default              inactive   no            yes

VERY IMPORTANT!

Here is what most recipes fail to note. You need to disable netfilter on the bridge level, otherwise Windows will see the interface but will not be able to receive an IP:

Create a file named /etc/sysctl.d/99-netfilter-bridge.conf with the following content:

net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0

Then load it

$ sudo sysctl -p /etc/sysctl.d/99-netfilter-bridge.conf

At this point the network should work fine.