libvirt & virsh

Quick Reference

# List VMs
virsh list --all

# VM lifecycle
virsh start vm-name
virsh shutdown vm-name
virsh reboot vm-name
virsh destroy vm-name        # Force stop

# Console access
virsh console vm-name
virt-viewer vm-name

# VM info
virsh dominfo vm-name
virsh domblklist vm-name
virsh domiflist vm-name

# Create VM from ISO
virt-install --name myvm --ram 2048 --vcpus 2 --disk size=20 \
    --cdrom /path/to/installer.iso --os-variant detect=on

# Snapshots
virsh snapshot-create-as vm-name snap1 --description "Before upgrade"
virsh snapshot-revert vm-name snap1

Installation

Arch Linux

# Install libvirt and KVM
sudo pacman -S libvirt qemu-full virt-manager virt-viewer dnsmasq

# Optional: bridged networking
sudo pacman -S bridge-utils openbsd-netcat

# Enable libvirtd
sudo systemctl enable --now libvirtd.service

# Add user to libvirt group
sudo usermod -aG libvirt $USER
# Logout and login for group change

Debian/Ubuntu

# Install libvirt and KVM
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients \
    virtinst virt-manager virt-viewer bridge-utils

# Enable libvirtd
sudo systemctl enable --now libvirtd

# Add user to groups
sudo usermod -aG libvirt,kvm $USER

RHEL/Fedora

# Install virtualization group
sudo dnf install @virtualization

# Or individual packages
sudo dnf install qemu-kvm libvirt libvirt-client virt-install virt-manager

# Enable libvirtd
sudo systemctl enable --now libvirtd

# Add user to group
sudo usermod -aG libvirt $USER

Verify Installation

# Check KVM support
lsmod | grep kvm
# kvm_intel or kvm_amd should be loaded

# Check hardware virtualization
grep -E "(vmx|svm)" /proc/cpuinfo

# Verify libvirtd running
systemctl status libvirtd

# Test virsh connection
virsh -c qemu:///system list

# Check QEMU version
qemu-system-x86_64 --version

# List capabilities
virsh capabilities | head -50

libvirt Architecture

Components

libvirtd is the daemon that manages:

  • Hypervisors - QEMU/KVM, Xen, LXC, VirtualBox

  • Storage - Pools, volumes, images

  • Networking - Virtual networks, bridges

  • Node devices - PCI, USB passthrough

Connection URIs

# Local QEMU/KVM (system)
virsh -c qemu:///system

# Local QEMU/KVM (user session)
virsh -c qemu:///session

# Remote via SSH
virsh -c qemu+ssh://user@host/system

# Remote via TLS
virsh -c qemu+tls://host/system

# Set default connection
export LIBVIRT_DEFAULT_URI="qemu:///system"

# LXC containers
virsh -c lxc:///system

Storage Locations

# Default image location
/var/lib/libvirt/images/

# VM configurations
/etc/libvirt/qemu/

# Network configurations
/etc/libvirt/qemu/networks/

# User session storage
~/.local/share/libvirt/images/

Managing Virtual Machines

List VMs

# List running VMs
virsh list

# List all VMs (including stopped)
virsh list --all

# List with details
virsh list --all --title

# List specific state
virsh list --state-running
virsh list --state-shutoff

# Count VMs
virsh list --all | grep -c running

VM Lifecycle

# Start VM
virsh start vm-name

# Shutdown (graceful - ACPI)
virsh shutdown vm-name

# Reboot
virsh reboot vm-name

# Force stop (like pulling power)
virsh destroy vm-name

# Pause/Resume
virsh suspend vm-name
virsh resume vm-name

# Save state to file
virsh save vm-name /path/to/state.img

# Restore from saved state
virsh restore /path/to/state.img

# Reset (like pressing reset button)
virsh reset vm-name

VM Information

# General info
virsh dominfo vm-name

# CPU info
virsh vcpuinfo vm-name

# Memory stats
virsh dommemstat vm-name

# Block devices
virsh domblklist vm-name
virsh domblkinfo vm-name vda

# Network interfaces
virsh domiflist vm-name
virsh domifstat vm-name vnet0

# Full XML config
virsh dumpxml vm-name

# VM state
virsh domstate vm-name
virsh domstate vm-name --reason

Console and Display

# Serial console (needs console configured in VM)
virsh console vm-name
# Exit with Ctrl+]

# VNC viewer
virt-viewer vm-name

# Remote VNC viewer
virt-viewer -c qemu+ssh://user@host/system vm-name

# SPICE viewer (if configured)
virt-viewer --connect qemu:///system vm-name

# Get VNC port
virsh vncdisplay vm-name
# :0 means port 5900

# Screenshot
virsh screenshot vm-name /tmp/screenshot.ppm

Autostart

# Enable autostart
virsh autostart vm-name

# Disable autostart
virsh autostart --disable vm-name

# Check autostart status
virsh dominfo vm-name | grep Autostart

# List autostart VMs
ls /etc/libvirt/qemu/autostart/

Creating Virtual Machines

Using virt-install

# Basic VM from ISO
virt-install \
    --name myvm \
    --ram 2048 \
    --vcpus 2 \
    --disk size=20 \
    --cdrom /var/lib/libvirt/images/debian-12.iso \
    --os-variant debian12 \
    --network network=default \
    --graphics vnc

# With existing disk image
virt-install \
    --name myvm \
    --ram 4096 \
    --vcpus 4 \
    --disk path=/var/lib/libvirt/images/myvm.qcow2 \
    --import \
    --os-variant generic \
    --network bridge=br0

# Fully automated (preseed/kickstart)
virt-install \
    --name server \
    --ram 4096 \
    --vcpus 2 \
    --disk size=50 \
    --location http://deb.debian.org/debian/dists/bookworm/main/installer-amd64/ \
    --os-variant debian12 \
    --extra-args "auto=true url=http://example.com/preseed.cfg" \
    --network network=default

# PXE boot
virt-install \
    --name pxevm \
    --ram 2048 \
    --vcpus 2 \
    --disk size=20 \
    --pxe \
    --network network=default \
    --os-variant generic

virt-install Options

# CPU options
--vcpus 4                           # 4 vCPUs
--vcpus 4,maxvcpus=8               # Start with 4, max 8
--cpu host-passthrough             # Pass host CPU features

# Memory options
--ram 4096                         # 4GB RAM
--memory 4096,maxmemory=8192       # Start 4GB, max 8GB

# Disk options
--disk size=20                     # 20GB, default location
--disk path=/path/to/disk.qcow2    # Specific path
--disk path=/path/to/disk.qcow2,format=qcow2,bus=virtio
--disk none                        # No disk (live boot)

# Network options
--network network=default          # Default NAT network
--network bridge=br0               # Bridged network
--network type=direct,source=eth0  # macvtap
--network none                     # No network

# Graphics options
--graphics vnc                     # VNC display
--graphics vnc,listen=0.0.0.0     # VNC on all interfaces
--graphics spice                   # SPICE protocol
--graphics none                    # Headless

# Console
--console pty,target_type=serial   # Serial console

# Boot options
--boot hd                          # Boot from disk
--boot cdrom,hd                    # Boot order
--boot uefi                        # UEFI boot

# OS variant (helps with defaults)
--os-variant list                  # List known variants
--os-variant debian12
--os-variant ubuntu22.04
--os-variant win11

Clone VMs

# Clone existing VM
virt-clone \
    --original source-vm \
    --name clone-vm \
    --auto-clone

# Clone with specific disk
virt-clone \
    --original source-vm \
    --name clone-vm \
    --file /var/lib/libvirt/images/clone-vm.qcow2

# Clone must be shut down first
virsh shutdown source-vm

Import Existing Disk

# Import qcow2 image
virt-install \
    --name imported-vm \
    --ram 2048 \
    --vcpus 2 \
    --disk /var/lib/libvirt/images/existing.qcow2 \
    --import \
    --os-variant generic

# Convert and import VMware VMDK
qemu-img convert -f vmdk -O qcow2 disk.vmdk disk.qcow2
virt-install --name converted --disk disk.qcow2 --import ...

VM Configuration

Edit VM Configuration

# Edit XML directly (opens in $EDITOR)
virsh edit vm-name

# Dump XML, edit, define
virsh dumpxml vm-name > vm.xml
# Edit vm.xml
virsh define vm.xml

# Undefine VM (remove from libvirt, keeps disk)
virsh undefine vm-name

# Undefine and remove storage
virsh undefine vm-name --remove-all-storage

# Undefine and keep NVRAM (UEFI)
virsh undefine vm-name --nvram

Modify VM Resources

# Change memory (requires restart)
virsh setmaxmem vm-name 8G --config
virsh setmem vm-name 4G --config

# Hot-add memory (if supported)
virsh setmem vm-name 6G --live

# Change vCPUs (requires restart)
virsh setvcpus vm-name 4 --config --maximum
virsh setvcpus vm-name 4 --config

# Hot-add vCPU
virsh setvcpus vm-name 6 --live

# Rename VM (must be off)
virsh domrename old-name new-name

Attach/Detach Devices

# Attach disk
virsh attach-disk vm-name /path/to/disk.qcow2 vdb --driver qemu --subdriver qcow2

# Attach disk (persistent)
virsh attach-disk vm-name /path/to/disk.qcow2 vdb --persistent

# Detach disk
virsh detach-disk vm-name vdb

# Attach ISO as CDROM
virsh attach-disk vm-name /path/to/image.iso hdc --type cdrom --mode readonly

# Change CDROM
virsh change-media vm-name hdc /path/to/new.iso

# Eject CDROM
virsh change-media vm-name hdc --eject

# Attach network interface
virsh attach-interface vm-name network default --model virtio

# Detach interface
virsh detach-interface vm-name network --mac 52:54:00:xx:xx:xx

Snapshots

Create Snapshots

# Create snapshot
virsh snapshot-create-as vm-name snap1 --description "Clean install"

# Create disk-only snapshot (requires running VM)
virsh snapshot-create-as vm-name snap-disk --disk-only

# Create snapshot with memory (for running VM)
virsh snapshot-create-as vm-name snap-full --memspec file=/path/to/mem.img

# Atomic snapshot during operation
virsh snapshot-create-as vm-name snap1 --atomic

List and Manage Snapshots

# List snapshots
virsh snapshot-list vm-name

# List with tree structure
virsh snapshot-list vm-name --tree

# Snapshot info
virsh snapshot-info vm-name snap1

# Snapshot XML
virsh snapshot-dumpxml vm-name snap1

Revert Snapshots

# Revert to snapshot
virsh snapshot-revert vm-name snap1

# Revert to snapshot and start VM
virsh snapshot-revert vm-name snap1 --running

# Revert to snapshot (keep VM paused)
virsh snapshot-revert vm-name snap1 --paused

Delete Snapshots

# Delete snapshot
virsh snapshot-delete vm-name snap1

# Delete snapshot and children
virsh snapshot-delete vm-name snap1 --children

# Delete snapshot, merge to parent
virsh snapshot-delete vm-name snap1 --children-only

Storage Management

Storage Pools

# List pools
virsh pool-list --all

# Pool info
virsh pool-info default

# Create directory pool
virsh pool-define-as mypool dir - - - - /data/vms
virsh pool-build mypool
virsh pool-start mypool
virsh pool-autostart mypool

# Create LVM pool
virsh pool-define-as lvmpool logical - - - vg_vms /dev/vg_vms

# Refresh pool (scan for new volumes)
virsh pool-refresh default

# Delete pool
virsh pool-destroy mypool
virsh pool-undefine mypool

Storage Volumes

# List volumes in pool
virsh vol-list default

# Create volume
virsh vol-create-as default newdisk.qcow2 20G --format qcow2

# Volume info
virsh vol-info /var/lib/libvirt/images/disk.qcow2

# Clone volume
virsh vol-clone /var/lib/libvirt/images/source.qcow2 clone.qcow2 --pool default

# Resize volume
virsh vol-resize /var/lib/libvirt/images/disk.qcow2 50G

# Delete volume
virsh vol-delete /var/lib/libvirt/images/disk.qcow2

Disk Image Operations

# Create disk image (qemu-img)
qemu-img create -f qcow2 disk.qcow2 20G

# Create with backing file (thin provisioning)
qemu-img create -f qcow2 -b base.qcow2 -F qcow2 overlay.qcow2

# Get image info
qemu-img info disk.qcow2

# Convert image format
qemu-img convert -f raw -O qcow2 disk.raw disk.qcow2

# Resize image
qemu-img resize disk.qcow2 +10G

# Compact qcow2 image
qemu-img convert -O qcow2 disk.qcow2 disk-compact.qcow2

# Check image for errors
qemu-img check disk.qcow2

virt-manager (GUI)

Overview

virt-manager provides a graphical interface for:

  • Creating and managing VMs

  • Viewing console

  • Configuring hardware

  • Managing storage and networks

# Launch virt-manager
virt-manager

# Connect to remote host
virt-manager -c qemu+ssh://user@host/system

Key Features

  • New VM Wizard - Step-by-step VM creation

  • Console Viewer - Integrated VNC/SPICE

  • Hardware Details - View/modify VM config

  • Performance Graphs - CPU, memory, disk, network

  • Clone Wizard - Clone existing VMs

  • Snapshot Manager - Create/revert snapshots

Remote Management

SSH Access

# Connect via SSH
virsh -c qemu+ssh://user@host/system list --all

# Configure SSH key auth for password-less access
ssh-copy-id user@host

# virt-manager remote
virt-manager -c qemu+ssh://user@host/system

TLS Access

# Generate certificates (see libvirt documentation)
# /etc/pki/libvirt/

# Configure libvirtd for TLS
# /etc/libvirt/libvirtd.conf
listen_tls = 1
tls_port = "16514"

# Connect via TLS
virsh -c qemu+tls://host/system

Troubleshooting

Common Issues

# Permission denied
# Check group membership
groups | grep libvirt

# Check socket permissions
ls -la /var/run/libvirt/libvirt-sock

# VM won't start - check logs
journalctl -u libvirtd -f
cat /var/log/libvirt/qemu/vm-name.log

# Network not working
virsh net-list --all
virsh net-start default

# Storage pool inactive
virsh pool-list --all
virsh pool-start default

Debug Mode

# Enable debug logging
# /etc/libvirt/libvirtd.conf
log_level = 1
log_outputs = "1:file:/var/log/libvirt/libvirtd.log"

# Restart libvirtd
sudo systemctl restart libvirtd

# Test connection with debug
virsh -d 4 -c qemu:///system list

VM Recovery

# VM stuck in paused state
virsh resume vm-name

# VM marked as crashed
virsh destroy vm-name
virsh start vm-name

# Corrupt VM config
virsh dumpxml vm-name > backup.xml  # If possible
virsh undefine vm-name
virsh define backup.xml

Quick Command Reference

# VM lifecycle
virsh list --all                          # List all VMs
virsh start VM                            # Start
virsh shutdown VM                         # Graceful stop
virsh destroy VM                          # Force stop
virsh reboot VM                           # Reboot

# VM info
virsh dominfo VM                          # General info
virsh dumpxml VM                          # Full config
virsh domblklist VM                       # Disks
virsh domiflist VM                        # Network interfaces

# Console
virsh console VM                          # Serial console
virt-viewer VM                            # Graphical console

# Snapshots
virsh snapshot-create-as VM NAME          # Create
virsh snapshot-list VM                    # List
virsh snapshot-revert VM NAME             # Revert
virsh snapshot-delete VM NAME             # Delete

# Storage
virsh pool-list --all                     # List pools
virsh vol-list POOL                       # List volumes
qemu-img info FILE                        # Image info

# Configuration
virsh edit VM                             # Edit XML
virsh define VM.xml                       # Define from XML
virsh undefine VM                         # Remove VM

# Creation
virt-install --name VM ...                # New VM
virt-clone --original VM --name NEW       # Clone VM