Notes and information on installing KVM (Kernel-based Virtual Machine) and QEMU (Quick EMUlator) on a new Gentoo host.
Adding KVM Support to Kernel
Does Machine Support Virtualization
Check if machine support virtualization by running the command below which checks whether Intel Vt-x or AMD AMD-V virtualization technologies for supporting concurrent operating system use of CPUs are enabled/available. A result of > 0 would suggest the machine is capable of virtualization.
$ grep -E "^vmx|^svm" /proc/cpuinfo |wc -l
24
$
Kernel Settings
The machine I am installing this on is Intel based, so while there is no harm building the AMD processor support as a module, I opted not to waste time building something that won’t be used on this machine. There is also no need for Virtual Box Guest integration so I disabled that as well when I noticed it was on. I suspect there are other settings hidden about I might need to turn on, but I think the below should be sufficient to get things going. After rebuilding kernel, add to boot loader and reboot machine to load kernel before moving on to the next section.
[ * ] Virtualization --- >
--- Virtualization
<M> Kernel-based Virtual Machine ( KVM) support
<M> KVM for Intel ( and compatible) processors support
< > KVM for AMD processors support
[ * ] Audit KVM MMU
Device Drivers --- >
[ * ] Virtualization drivers --- >
--- Virtualization drivers
< > Virtual Box Guest integration support
< > Nitro Enclaves Support
[ * ] VHOST drivers --- >
--- VHOST drivers
<M> Host kernel accelerator for virtio net
<M> VHOST_SCSI TCM fabric driver
<M> vhost virtio-vsock driver
[ ] Cross-endian support for vhost
[ * ] Network device support --- >
--- Network device support
[ * ] Network core driver support
...
<M> Universal TUN/TAP device driver support
...
-* - Networking support --- >
--- Networking support
Networking options --- >
...
-* - The IPv6 protocol --- >
...
<M> 802.1d Ethernet Bridging
...
Test Kernel has KVM Support
I’ve rebooted the machine to load the new kernel and I make sure KVM support has been added by looking for the existence of /dev/kvm . If it wasn’t there, I would need to go back and check my work and troubleshoot until I got it to appear.
$ ls /dev/kvm
/dev/kvm
Install QEMU
Create Package Use Flags File and Install QEMU
QEMU has a lot of USE flags to control what features are built. As I am not entirely sure which features I will eventually use, I created a /etc/portage/package.use/app-emulation/qemu with some initial settings as below. As my needs change over time, I will be able to edit the file and rebuild QEMU to add or remove features as required.
$ sudo mkdir /etc/portage/package.use/app-emulation
$ sudo vim /etc/portage/package.use/app-emulation/qemu
app-emulation/qemu nfs plugins python ssh spice usb usbredir QEMU_SOFTMMU_TARGETS: arm aarch64 i386 x86_64 risc64 QEMU_USER_TARGETS: x86_64 aarch64 arm armeb i386 risc64
$ sudo emerge -avt qemu
These are the packages that would be merged, in reverse order:
Calculating dependencies... done !
[ ebuild N ] app-emulation/qemu-5.2.0-r2::gentoo USE = "aio bzip2 caps curl fdt filecaps jpeg ncurses nfs nls oss pin-upstream-blobs plugins png python seccomp slirp spice ssh udev usb usbredir vhost-net vnc xattr -accessibility -alsa -capstone -debug -doc -glusterfs -gnutls -gtk -infiniband -io-uring -iscsi -jack -jemalloc -lzo -multipath -numa -opengl -pulseaudio -rbd -sasl -sdl -sdl-image (-selinux) -smartcard -snappy -static -static-user -systemtap -test -vde -vhost-user-fs -virgl -virtfs -vte -xen -xfs -zstd" PYTHON_TARGETS = "python3_8 -python3_7 -python3_9" QEMU_SOFTMMU_TARGETS = "aarch64 arm i386 x86_64 -alpha -avr -cris -hppa -lm32 -m68k -microblaze -microblazeel -mips -mips64 -mips64el -mipsel -moxie -nios2 -or1k -ppc -ppc64 -riscv32 -riscv64 -rx -s390x -sh4 -sh4eb -sparc -sparc64 -tricore -unicore32 -xtensa -xtensaeb" QEMU_USER_TARGETS = "aarch64 arm armeb i386 x86_64 -aarch64_be -alpha -cris -hppa -m68k -microblaze -microblazeel -mips -mips64 -mips64el -mipsel -mipsn32 -mipsn32el -nios2 -or1k -ppc -ppc64 -ppc64abi32 -ppc64le -riscv32 -riscv64 -s390x -sh4 -sh4eb -sparc -sparc32plus -sparc64 -tilegx -xtensa -xtensaeb" 0 KiB
[ ebuild N ] app-emulation/spice-0.14.3::gentoo USE = "-gstreamer (-libressl) -lz4 -sasl -smartcard -static-libs" 0 KiB
[ ebuild N ] net-libs/libslirp-4.4.0::gentoo USE = "-static-libs" 0 KiB
[ nomerge ] app-emulation/qemu-5.2.0-r2::gentoo USE = "aio bzip2 caps curl fdt filecaps jpeg ncurses nfs nls oss pin-upstream-blobs plugins png python seccomp slirp spice ssh udev usb usbredir vhost-net vnc xattr -accessibility -alsa -capstone -debug -doc -glusterfs -gnutls -gtk -infiniband -io-uring -iscsi -jack -jemalloc -lzo -multipath -numa -opengl -pulseaudio -rbd -sasl -sdl -sdl-image (-selinux) -smartcard -snappy -static -static-user -systemtap -test -vde -vhost-user-fs -virgl -virtfs -vte -xen -xfs -zstd" PYTHON_TARGETS = "python3_8 -python3_7 -python3_9" QEMU_SOFTMMU_TARGETS = "aarch64 arm i386 x86_64 -alpha -avr -cris -hppa -lm32 -m68k -microblaze -microblazeel -mips -mips64 -mips64el -mipsel -moxie -nios2 -or1k -ppc -ppc64 -riscv32 -riscv64 -rx -s390x -sh4 -sh4eb -sparc -sparc64 -tricore -unicore32 -xtensa -xtensaeb" QEMU_USER_TARGETS = "aarch64 arm armeb i386 x86_64 -aarch64_be -alpha -cris -hppa -m68k -microblaze -microblazeel -mips -mips64 -mips64el -mipsel -mipsn32 -mipsn32el -nios2 -or1k -ppc -ppc64 -ppc64abi32 -ppc64le -riscv32 -riscv64 -s390x -sh4 -sh4eb -sparc -sparc32plus -sparc64 -tilegx -xtensa -xtensaeb"
[ nomerge ] dev-libs/glib-2.66.4:2::gentoo USE = "mime xattr -dbus -debug -fam -gtk-doc (-selinux) -static-libs -sysprof -systemtap -test -utils" ABI_X86 = "(64) -32 (-x32)"
[ ebuild N ] x11-misc/shared-mime-info-2.1::gentoo 0 KiB
[ ebuild N ] dev-libs/glib-2.66.4:2::gentoo USE = "mime xattr -dbus -debug -fam -gtk-doc (-selinux) -static-libs -sysprof -systemtap -test -utils" ABI_X86 = "(64) -32 (-x32)" 0 KiB
Total: 5 packages ( 5 new) , Size of downloads: 0 KiB
Would you like to merge these packages? [ Yes/No] yes
...
>>> Auto-cleaning packages...
>>> No outdated packages were found on your system.
* GNU info directory index is up-to-date.
$
Add User Account to KVM Group
$ sudo gpasswd -a chuck kvm
Adding user larry to group kvm
$
Reset Permissions on /dev/kvm
On new installs it is recommended to ask udev to rest the permissions on /dev/kvm , and so that is what the command below does.
$ sudo udevadm trigger -c add /dev/kvm
$
QEMU Networking Host & Guest VMs
As there is a bridge in my desired setup, best to start by installing bridge-utils to manage via brctl .
$sudo emerge -a bridge-utils
These are the packages that would be merged, in order:
Calculating dependencies... done !
[ ebuild N ] net-misc/bridge-utils-1.6 USE = "(-selinux)"
Would you like to merge these packages? [ Yes/No] yes
...
>>> Installing ( 1 of 1) net-misc/bridge-utils-1.6::gentoo
>>> Recording net-misc/bridge-utils in "world" favorites file...
>>> Auto-cleaning packages...
>>> No outdated packages were found on your system.
* GNU info directory index is up-to-date.
$
Install Libvirt
emerge -vat libvirt
These are the packages that would be merged, in reverse order:
Calculating dependencies... done !
[ ebuild N ] app-emulation/libvirt-7.0.0-r1:0/7.0.0::gentoo USE = "caps libvirtd nls qemu udev virt-network -apparmor -audit -dtrace -firewalld -fuse -glusterfs -iscsi -iscsi-direct -libssh -lvm -lxc -nfs -numa (-openvz) -parted -pcap -policykit -rbd -sasl (-selinux) -virtualbox -wireshark-plugins -xen -zfs" 0 KiB
[ ebuild N ] dev-perl/XML-XPath-1.420.0::gentoo USE = "-examples -test" 0 KiB
[ ebuild N ] x11-libs/libpciaccess-0.16::gentoo USE = "zlib" ABI_X86 = "(64) -32 (-x32)" 359 KiB
[ ebuild N ] media-fonts/font-util-1.3.2-r1::gentoo 155 KiB
[ ebuild N ] net-misc/radvd-2.19::gentoo USE = "(-selinux) -test" 218 KiB
[ ebuild N ] net-dns/dnsmasq-2.84-r101::gentoo USE = "dhcp dumpfile inotify ipv6 nls script -auth-dns -conntrack -dbus -dhcp-tools -dnssec -id -idn -libidn2 -lua -nettlehash (-selinux) -static -tftp" LUA_SINGLE_TARGET = "lua5-1 -lua5-2 -lua5-3 -lua5-4 -luajit" 503 KiB
[ ebuild N ] net-analyzer/openbsd-netcat-1.195::gentoo 58 KiB
[ ebuild N ] acct-user/qemu-0-r1::gentoo 0 KiB
[ ebuild N ] acct-group/qemu-0-r1::gentoo 0 KiB
[ ebuild N ] net-libs/libssh2-1.9.0_p20200614::gentoo USE = "zlib -gcrypt (-libressl) -mbedtls" ABI_X86 = "(64) -32 (-x32)" 472 KiB
[ nomerge ] net-dns/dnsmasq-2.84-r101::gentoo USE = "dhcp dumpfile inotify ipv6 nls script -auth-dns -conntrack -dbus -dhcp-tools -dnssec -id -idn -libidn2 -lua -nettlehash (-selinux) -static -tftp" LUA_SINGLE_TARGET = "lua5-1 -lua5-2 -lua5-3 -lua5-4 -luajit"
[ ebuild N ] acct-user/dnsmasq-0-r1::gentoo 0 KiB
[ nomerge ] app-emulation/libvirt-7.0.0-r1:0/7.0.0::gentoo USE = "caps libvirtd nls qemu udev virt-network -apparmor -audit -dtrace -firewalld -fuse -glusterfs -iscsi -iscsi-direct -libssh -lvm -lxc -nfs -numa (-openvz) -parted -pcap -policykit -rbd -sasl (-selinux) -virtualbox -wireshark-plugins -xen -zfs"
[ ebuild N ] net-firewall/ebtables-2.0.11-r3::gentoo USE = "perl -static" 419 KiB
[ ebuild N ] net-misc/ethertypes-0::gentoo 1 KiB
[ nomerge ] net-misc/radvd-2.19::gentoo USE = "(-selinux) -test"
[ ebuild N ] dev-libs/libdaemon-0.14-r3:0/5::gentoo USE = "-doc -examples -static-libs" ABI_X86 = "(64) -32 (-x32)" 333 KiB
[ nomerge ] x11-libs/libpciaccess-0.16::gentoo USE = "zlib" ABI_X86 = "(64) -32 (-x32)"
[ ebuild N ] x11-misc/util-macros-1.19.3::gentoo 83 KiB
[ nomerge ] app-emulation/libvirt-7.0.0-r1:0/7.0.0::gentoo USE = "caps libvirtd nls qemu udev virt-network -apparmor -audit -dtrace -firewalld -fuse -glusterfs -iscsi -iscsi-direct -libssh -lvm -lxc -nfs -numa (-openvz) -parted -pcap -policykit -rbd -sasl (-selinux) -virtualbox -wireshark-plugins -xen -zfs"
[ ebuild N ] app-text/xhtml1-20020801-r6::gentoo 227 KiB
[ ebuild N ] dev-python/docutils-0.16-r1::gentoo PYTHON_TARGETS = "python3_8 -pypy3 -python3_7 -python3_9" 1,917 KiB
[ ebuild N ] dev-python/pygments-2.7.4::gentoo USE = "-doc -test" PYTHON_TARGETS = "python3_8 -pypy3 -python3_7 -python3_9" 2,271 KiB
[ ebuild N ] dev-libs/yajl-2.1.0-r2:0/2::gentoo USE = "-static-libs" ABI_X86 = "(64) -32 (-x32)" 83 KiB
[ ebuild N ] sys-apps/dmidecode-3.3::gentoo USE = "(-selinux)" 56 KiB
[ ebuild N ] dev-libs/libnl-3.5.0:3::gentoo USE = "debug threads -python -static-libs -utils" ABI_X86 = "(64) -32 (-x32)" PYTHON_TARGETS = "python3_8 -python3_7 -python3_9" 946 KiB
[ ebuild N ] app-misc/scrub-2.6.1::gentoo 355 KiB
[ nomerge ] net-dns/dnsmasq-2.84-r101::gentoo USE = "dhcp dumpfile inotify ipv6 nls script -auth-dns -conntrack -dbus -dhcp-tools -dnssec -id -idn -libidn2 -lua -nettlehash (-selinux) -static -tftp" LUA_SINGLE_TARGET = "lua5-1 -lua5-2 -lua5-3 -lua5-4 -luajit"
[ ebuild N ] acct-group/dnsmasq-0-r1::gentoo 0 KiB
Total: 23 packages ( 23 new) , Size of downloads: 8,446 KiB
Would you like to merge these packages? [ Yes/No] yes
...
>>> Auto-cleaning packages...
>>> No outdated packages were found on your system.
* GNU info directory index is up-to-date.
Add User to libvirt
Add user account to libvirt group, then log oout and back in to pick up changes. This and the next step below should make virt-admin usable for users other than root .
$ sudo gpasswd -a larry libvirt
Adding user larry to group libvirt
$
Uncomment the following lines in /etc/libvirt/libvirtd.conf and save.
$ sudo vim etc/libvirt/libvirtd.conf
auth_unix_ro = "none"
auth_unix_rw = "none"
unix_sock_group = "libvirt"
unix_sock_ro_perms = "0777"
unix_sock_rw_perms = "0770"
Start libvirt Service
Enable, start and check the running status of __libvirtd__ using _systemd_.
$ sudo systemctl enable libvirtd
Created symlink /etc/systemd/system/multi-user.target.wants/libvirtd.service → /usr/lib/systemd/system/libvirtd.service.
Created symlink /etc/systemd/system/sockets.target.wants/virtlockd.socket → /usr/lib/systemd/system/virtlockd.socket.
Created symlink /etc/systemd/system/sockets.target.wants/virtlogd.socket → /usr/lib/systemd/system/virtlogd.socket.
Created symlink /etc/systemd/system/sockets.target.wants/libvirtd.socket → /usr/lib/systemd/system/libvirtd.socket.
Created symlink /etc/systemd/system/sockets.target.wants/libvirtd-ro.socket → /usr/lib/systemd/system/libvirtd-ro.socket.
$ sudo systemctl restart libvirtd
$ systemctl status libvirtd
● libvirtd.service - Virtualization daemon
Loaded: loaded ( /usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: disable>
Active: active ( running) since Mon 2021-02-15 04:45:55 CST; 45s ago
TriggeredBy: ● libvirtd-admin.socket
● libvirtd.socket
● libvirtd-ro.socket
Docs: man:libvirtd( 8)
https://libvirt.org
Main PID: 300698 ( libvirtd)
Tasks: 21 ( limit: 32768)
Memory: 10.2M
CPU: 450ms
CGroup: /system.slice/libvirtd.service
├─293488 /usr/sbin/dnsmasq --conf-file = /var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script = /usr/libexec/libvirt_leaseshelper
├─293489 /usr/sbin/dnsmasq --conf-file = /var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script = /usr/libexec/libvirt_leaseshelper
└─300698 /usr/sbin/libvirtd
Feb 15 04:45:55 sparky systemd[1]: Starting Virtualization daemon...
Feb 15 04:45:55 sparky systemd[1]: Started Virtualization daemon.
Feb 15 04:45:57 sparky dnsmasq[293488]: read /etc/hosts - 2 addresses
Feb 15 04:45:57 sparky dnsmasq[293488]: read /var/lib/libvirt/dnsmasq/default.addnhosts - 0 addresses
Feb 15 04:45:57 sparky dnsmasq-dhcp[293488]: read /var/lib/libvirt/dnsmasq/default.hostsfile
$
I think that is enough for now. The above was sufficient to get emulation KVM/QEMU set up on my new machine. If you have made it this far then good for you.
References