Installing and configuring QEMU with KVM in Arch Linux

Written by Martín E. Zahnd

Published: 2021-09-24 19:42

Edited: 2022-02-21 10:50

Tags: qemu, kvm, vm, linux, virtualization, arch


This is a brief tutorial for running VMs using QEMU/KVM in the same machine they’re created (localhost), using ArchLinux as host OS. It is heavily influenced by the ArchWiki posts on the subject (see Sources and useful links).

Hardware support

In the first place we have to verify that our hardware has virtualization support.

To this, either run

1
]$ LC_ALL=C lscpu | grep Virtualization

or

1
]$ grep -E --color=auto 'vmx|svm|0xc0f' /proc/cpuinfo

If the previous command echoes nothing in the terminal, there’s no virtualization support included in your current hardware.

Kernel modules

After that, one has to verify that the needed modules are compiled with the current kernel and loaded at runtime.

Running

1
]$ zgrep CONFIG_KVM /proc/config.gz

should print a list with all options set as y or m.

The modules that have to be loaded are kvm and, for Intel CPUs, kvm_intel or kvm_amd for AMD ones.

Run

1
]$ lsmod | grep kvm

to verify that both modules are loaded.

Packages to install

We’ll need a bunch of packages in our system, some of which are actually optional but recommended to make our work a little easier.

  • qemu (or qemu-headless for the version without GUI).
  • libvirt
  • samba: SMB/CIFS server support.
  • virt-manager: Graphically manage KVM, Xen, or LXC via libvirt.
  • virt-viewer: Simple remote display client. (part of virt-manager)
  • bridge-utils: For bridged networking.
  • iptables-nft, dnsmasq: For the default NAT/DHCP networking.
  • openbsd-netcat: For remote management over SSH.
  • edk2-ovmf: UEFI support for guests. Must be installed with package qemu-arch-extra.
  • qemu-arch-extra: Extra architectures support and enables UEFI firmware while creating the Virtual Machine.

Note: If you are using firewalld, as of libvirt 5.1.0 and firewalld 0.7.0 you no longer need to change the firewall backend to iptables. libvirt now installs a zone called ‘libvirt’ in firewalld and manages its required network rules there. Firewall and network filtering in libvirt.

1
]# pacman -S qemu libvirt samba virt-manager virt-viewer bridge-utils iptables-nft dnsmasq openbsd-netcat edk2-ovmf

libvirt configuration

Setting up authentication

Add your user to libvirt group.

1
]# usermod -a -G libvirt <username>

Then modify the /etc/libvirt/libvirtd.conf file and look for unix_sock_groupand unix_sock_ro_perms options:

# Set the UNIX domain socket group ownership. This can be used to
# allow a 'trusted' set of users access to management capabilities
# without becoming root.
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# This is restricted to 'root' by default.
unix_sock_group = "libvirt"

# Set the UNIX socket permissions for the R/O socket. This is used
# for monitoring VM status only
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# Default allows any user. If setting group ownership, you may want to
# restrict this too.
unix_sock_ro_perms = "0777"

Note: In the previous block of text, comments were copied from the distributed configuration file.

Services

Start libvirtd.service and virtlogd.service.

1
2
]# systemctl start libvirtd.service
]# systemctl start virtlogd.service

If you want to enable them, only do so with libvirtd.service, which also enables virtlogd.socket and virtlockd.socket, so there’s no need to enable virtlogd.service.

1
]# systemctl enable libvirtd.service

Test

To test if libvirt is working properly on a system level, we should run:

1
]$ virsh -c qemu:///system

To do the same for a user-session level:

1
]$ virsh -c qemu:///session

In both cases, if everything’s working a virsh session should open.

Creating and managing virtual machines

Disk image creation using the command line

Creating a disk for our virtual machine can be achieved both using qemu-img (command-line style) or the Virtual Machine Manager (GUI style) while creating a new VM, as described a few sections later in this post.

Altough various image formats are supported by QEMU, I’ll be using qcow2 (QEMU Copy-On-Write 2) because it seems to be QEMU’s favourite image format and it has a few usefull features, like compression and snapshots. 1 Another interesting image format is raw, the default file format, which takes advantage of holes support in the filesystem. 2

There’re two basic alternatives for image allocation: using preallocated disk space, which means that the image file will reserve for itself all the disk space we tell it to, or using a dinamically allocated disk space, that is, the image file size grows on-demand (like the default VirtualBox option for VDI).

To keep things organized, I find useful creating a folder exclusively for disk images and another one for ISO files as this will simplify the machines creation and maintenance later.

Fixed size disk image

Using qcow2 file format, we should run the following command:

1
]$ qemu-img create -f qcow2 <image-name> <image-size>
  • -f: Sets the file type. In this case is qcow2.
  • <image-name>: Filename for the image file.
  • <image-size>: Disk image size in bytes. Optional suffixes k or K (kilobyte, 1024), M (megabyte, 1024k), G (gigabyte, 1024M) and T (terabyte, 1024G) are supported. b is ignored. 3

Dynamically allocated disk image

The creation of a dynamically allocated disk images is accomplished by running

1
]$ qemu-img create -f qcow2 -o preallocation=off <image-name> <image-size>

Which is almost the same command used for fixed size disk images, with the addition of the preallocation option.

Note: Options are set using the -o flag.

In the qemu-img(1) man page there’re two definitions of what the preallocation options actually does.

For qcow2 it is defined as:

preallocation

Preallocation mode (allowed values: off, metadata, falloc, full). An image with preallocated metadata is initially larger but can improve performance when the image needs to grow. falloc and full preallocations are like the same options of raw format, but sets up metadata also.

And for raw:

preallocation

Preallocation mode (allowed values: off, falloc, full). falloc mode preallocates space for image by calling posix_fallocate(). full mode preallocates space for image by writing data to underlying storage. This data may or may not be zero, depending on the storage location.

Setting up the virtual machine using Virtual Machine Manager

The most common way to setup virtual machines is through pure libvirt, using the command line and manually editing configuration files.

Altough I feel really comfortable doing it that way, this time I’ll comment on how to do it using a GUI interface, Virtual Machine Manager.

Establishing a connection

First, one should add a Connection (File -> Add Connection) between libvirt and the QEMU/KVM hypervisor (with URI qemu:///system).

Configuring the disk image

We’ll now see a section called QEMU/KVM in the VMM. Right click it, select Details and go to the Storage tab.

Once there, you probably want to disable the default storage path, which is /var/lib/libvirt/images, as /var is usually a separated partition with limited disk space. 4 To do this, stop the pool using the Stop pool button on the bottom left corner and then remove it (or rename it to something different. It’ll be perfectly fine as long as it’s different than ‘default’).

Let’s now add two new storage pools, using the Add pool button on the bottom left corner of the window. The first one will be called ‘iso’, and point to a folder with all our ISO files for the virtual machines; the second will point to our disks folder and will be called ‘default’.

Apply all changes, and close the window.

Creating a virtual machine

Once in VMM, there’s a big plus ( + ) button on the top left corner which reads Create a new virtual machine (another way is File -> New Virtual Machine).

There’re a few options in the New VM window, which has just appeared, we’ll pick Local Install Media (ISO image or CDROM). One step forward, and we can browse our storage pools and pick the desired ISO image. The operating system should be autodetected by virt-manager.

In case the ISO image file doesn’t appear in our ‘iso’ pool, there’s a refresh button just above the list of files.

Disk image

When we have reached the step that asks us about the disk image for the virtual machine, I prefer doing it by picking the custom storage option and manually selecting an image that its already created, altough creating a new one through VMM in a storage pool (different than the one with ISO images) is a perfectly good option. When using the GUI option, checking Allocate entire volume now when adding a new storage volume will have the same effect as setting the preallocation option when using the command line.

One thing that should be noted is that image files created by virt-manager are owned by root and have rw permissions only for the owner. When this is not the desired behaviour, creating the image using the command line and ‘chowning’ it to the desired user/group can end up being more simple.

Final step in the wizard

Finally, we should give a name our virtual machine. Its name must be unique for migration purposes, cannot consists only of numbers, and it can contain letters, numbers, periods (.), underscores (_), and hyphens (-).

Before clicking on Finish, check the Customize configuration before install option and verify that ‘Network selection’ is set to Virtual network: 'default': NAT (if it shows as ‘inactive’ check Starting Virtual network ‘default’ section).

Finishing touches before running for the first time

A new window should be opened now showing us the VM details.

In the Overview section, look for Hypervisor Details and pick UEFI x86_64 as the firmware (the one that doesn’t say secboot.fd at the end of its name). Apply the changes.

Click Begin installation on the top left corner and the installation media will be booted.

Network connection

As far as I know, the default NIC, Virtual network 'default': Nat using virtio as device model works out of the box for internet connection and SSH access from the host machine.

Starting virtual network: ‘default’

To manually start the default network, the following command should be run:

1
]# virsh net-start default

If the desired behaviour is to autostart it on boot time, run

1
]# virsh net-autostart default

Sources and useful links

Changelog

  • 2022-02-21 10:50 -0300: Added qemu-arch-extra to packages list for proper UEFI guest support.
  1. From qemu-img(1) manual:

    qcow2

    QEMU image format, the most versatile format. Use it to have smaller images (useful if your filesystem does not supports holes, for example on Windows), optional AES encryption, zlib based compression and support of multiple VM snapshots.

  2. From qemu-img(1) manual:

    raw

    Raw disk image format (default). This format has the advantage of being simple and easily exportable to all other emulators. If your file system supports holes (for example in ext2 or ext3 on Linux or NTFS on Windows), then only the written sectors will reserve space. Use qemu-img info to know the real size used by the image or ls -ls on Unix/Linux.

  3. From qemu-img(1) manual

  4. Most distributions GUI installers give the option (and incentivize their users) to put home in a separated partition from root. That limits var disk space by itself.

    It’s also an option to have var in a completely separated partition as it has the system logs by default.