libvirt

On this page 7

libvirt is an open-source virtualization management library, daemon set and toolkit that provides one stable API for defining, starting, stopping, migrating and monitoring virtual machines, virtual networks and storage. In Linux virtualization, libvirt is the standard control layer above KVM and QEMU, and it also supports other drivers such as LXC containers, Xen and bhyve.

libvirt does not run guests itself. It translates management requests into hypervisor-specific actions, for example by building a QEMU command line, configuring cgroups and setting up bridges. Tools such as virsh, virt-manager, virt-install, Cockpit, OpenStack Nova and KubeVirt all build on it, which makes libvirt the common language of Linux virtualization management.

Architecture of the libvirt stack

The stack has three layers: a client library linked into management tools, one or more daemons that hold state and talk to the hypervisor, and hypervisor drivers that perform the actual work. Clients connect through a connection URI that names the driver, the scope and optionally a remote host.

Historically a single libvirtd daemon handled everything. Current distributions such as Fedora and RHEL 9 use modular daemons instead, one per responsibility, which reduces the privileges and attack surface of each component and allows them to be restarted independently.

DaemonResponsibility
virtqemudQEMU and KVM virtual machines
virtnetworkdVirtual networks, NAT and DHCP
virtstoragedStorage pools and volumes
virtnodedevdHost devices for passthrough
virtsecretdSecrets such as disk encryption keys
virtnwfilterdNetwork traffic filters for guests
virtproxydCompatibility endpoint for remote clients
Modular libvirt daemons and their responsibilities

Domains, connection URIs and XML definitions

In libvirt terminology a virtual machine is a domain, and every object is described by an XML definition. A domain XML lists CPUs, memory, disks, network interfaces, firmware and devices. A domain can be persistent, defined permanently with virsh define, or transient, existing only while it runs.

The connection URI selects where and with what privilege a client operates. The table shows the most common forms.

URIMeaningTypical use
qemu:///systemSystem-wide instance running as rootServers, bridged networking, shared storage
qemu:///sessionPer-user instance without rootDesktop VMs, development
qemu+ssh://host/systemRemote system instance over SSHManaging other hosts securely
qemu+tls://host/systemRemote access with TLS certificatesLarge fleets and automation
lxc:///systemLXC container driverSystem containers managed like VMs
Common libvirt connection URIs

The session instance cannot create bridges or access host devices without help, so guests started under it typically use user-mode networking. This distinction explains many cases where a VM created as an ordinary user cannot be reached from the network.

Networks, storage pools and everyday virsh commands

Besides domains, libvirt manages virtual networks and storage pools. The default network virbr0 provides NAT on 192.168.122.0/24 with DHCP and DNS served by dnsmasq, while bridged and macvtap modes connect guests directly to the physical network. Storage pools abstract directories, LVM volume groups, iSCSI targets, NFS shares and Ceph RBD images.

The command-line client virsh exposes almost the entire API. The following table lists the commands administrators use daily.

CommandAction
virsh list –allShow running and stopped domains
virsh start / shutdownBoot a domain or request a clean guest shutdown
virsh destroyForce off a domain immediately, like pulling the plug
virsh editEdit the domain XML with validation
virsh dumpxmlPrint the current domain definition
virsh snapshot-create-asCreate a named snapshot
virsh migrate –liveMove a running domain to another host
Frequently used virsh commands

Note that `virsh destroy` does not delete anything; it only stops the guest abruptly. Removing the definition requires virsh undefine, and disk images are deleted only with the explicit --remove-all-storage option.

Comparison with neighboring virtualization components

libvirt is often confused with the components it manages. It is a management layer, while KVM is a kernel module and QEMU is the machine emulator that runs each guest as a process.

ComponentLayerRole
KVMKernelHardware-assisted CPU and memory virtualization
QEMUUser space processDevice emulation and guest execution
VirtioParavirtual devicesFast disk and network interfaces for guests
libvirtManagementAPI, lifecycle, networking and storage control
virt-manager and CockpitUser interfaceGraphical front ends using the libvirt API
LXCContainersOS-level virtualization, also reachable through libvirt
libvirt and related virtualization components

Running QEMU directly offers maximum flexibility for experiments, but loses persistent definitions, security labeling with SELinux or AppArmor through sVirt, cgroup placement and migration support. For anything beyond a quick test, libvirt is the recommended entry point.

Pitfalls in libvirt administration

Most operational problems stem from scope confusion, manual changes outside libvirt and storage handling. The following points summarize them.

  • System versus session: a domain defined under one URI is invisible from the other, which looks like a missing VM.
  • Editing XML files on disk: files under /etc/libvirt are overwritten; changes belong in virsh edit or the API.
  • Image permissions: sVirt labels disk images, so images in unusual directories may be denied access until labeled correctly.
  • Snapshot types: internal qcow2 snapshots and external snapshots behave differently for backup and live migration.
  • Default network conflicts: the 192.168.122.0/24 range may collide with an existing network and break routing.

A plain-language summary

A virtual machine is a computer that exists only in software. libvirt is the control desk for those software computers. It keeps a record of every machine, knows how much memory and disk each one has, and starts, stops or moves them on request.

Without it, every program that wanted to manage virtual machines would need to learn the details of each underlying engine. With it, all tools speak one common language, and the engine underneath can do the heavy lifting.

An example from practice

A mid-sized company runs about sixty internal virtual machines on four KVM hosts with shared Ceph storage. The administrators want to patch hosts during working hours without interrupting the accounting system, the wiki and the build servers.

Each host runs the modular libvirt daemons, and all guests use Virtio disks backed by an RBD storage pool, so every host can see every disk. Before patching a host, an automation script lists its domains with virsh and runs virsh migrate --live --persistent --undefinesource to move each one to the least loaded neighbor over qemu+ssh connections.

Users notice nothing beyond a sub-second pause during each migration. The host is updated, rebooted and returned to service, and maintenance no longer requires a weekend window.