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
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
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
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)
Remote Management
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
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