virsh

On this page 7

virsh is the command-line management shell of libvirt, the standard toolkit for controlling virtual machines in Linux virtualization. It lets an administrator define, start, stop, migrate, snapshot and reconfigure guests on hypervisors such as KVM with QEMU, and it manages the storage pools and virtual networks those guests use.

Because virsh talks to the libvirt daemon rather than to the hypervisor directly, the same commands work on a local workstation and on a remote host reached over SSH. It is the scriptable counterpart of graphical tools such as virt-manager and GNOME Boxes, and it exposes nearly every option that libvirt supports.

How virsh communicates with libvirt

virsh is a client of the libvirt API. Each command opens a connection described by a connection URI, sends a request to a libvirt daemon (the monolithic libvirtd or the newer modular daemons such as virtqemud), and prints the result. The daemon in turn drives QEMU processes, configures cgroups, applies SELinux or AppArmor labels and sets up networking.

Every guest is described by an XML domain definition that lists CPUs, memory, disks, network interfaces and devices. virsh does not invent configuration; it reads, edits and submits this XML. Understanding the XML is therefore the key to using virsh beyond basic start and stop operations.

The connection URI decides which hypervisor and which privilege level virsh addresses, as the table shows.

URITargetTypical use
qemu:///systemSystem-wide KVM guestsServers and shared hosts
qemu:///sessionPer-user unprivileged guestsDesktops, user-mode networking
qemu+ssh://host/systemRemote host over SSHManaging several hypervisors
lxc:///systemlibvirt LXC containersContainer domains via libvirt
Common virsh connection URIs

A frequent source of confusion is that `system` and `session` are separate worlds: a guest defined in one connection does not appear in the other. If virsh list --all shows nothing, the first check is the URI, set with -c or the LIBVIRT_DEFAULT_URI variable.

Core command groups

virsh organizes its several hundred subcommands into groups by object type: domains, storage pools and volumes, networks, interfaces, node devices, snapshots and secrets. Most daily work uses a small subset, summarized below.

CommandActionNotes
list --allShows running and defined guestsWithout --all only running ones
define / undefineRegisters or removes a persistent guestUndefine keeps disk images by default
start / shutdownBoots or gracefully stops a guestShutdown sends an ACPI request
destroyForcibly stops a guestEquivalent to pulling the power cord
editOpens the domain XML in an editorValidates XML before saving
consoleAttaches to the serial consoleExit with Ctrl plus ]
snapshot-create-asCreates a named snapshotNeeds qcow2 for internal snapshots
migrateMoves a guest to another hostLive migration with --live
Frequently used virsh commands

The name `destroy` is misleading for newcomers: it does not delete anything, it only performs a hard power-off. Deleting a guest is undefine, optionally with --remove-all-storage.

Beyond guests, virsh manages the resources guests depend on. pool-list, pool-define-as and vol-create-as handle storage pools and volumes, which may be directories of qcow2 files, LVM volume groups, iSCSI targets or Ceph RBD images. net-list, net-start and net-edit control virtual networks, such as the default NAT network with its built-in DHCP and DNS service on the virbr0 bridge.

Monitoring commands complete the picture. domstats, domblkstat and domifstat report CPU time, disk I/O and network counters per guest, while nodeinfo and capabilities describe what the host and hypervisor can offer, which is useful before planning CPU models or device passthrough with VFIO.

Persistent and transient guests

libvirt distinguishes persistent domains, whose XML is stored on the host and survives reboots, from transient domains, which exist only while running. virsh exposes this distinction directly through define and create.

Changes to a running guest also come in two flavors: live changes apply immediately but vanish at shutdown, while config changes apply at the next boot. Commands such as setmem, setvcpus and attach-device accept --live, --config or both.

FlagApplies toSurvives guest restart
--liveRunning guest onlyNo
--configStored definition onlyYes, from next boot
--live --configBoth at onceYes
--currentWhichever state the guest is inDepends on that state
Scope of virsh configuration changes

Forgetting --config is the classic reason why a hot-added disk disappears after a reboot. Forgetting --live explains why a change seems to have no effect until the next restart.

virsh compared with other virtualization tools

virsh sits at a specific level in the Linux virtualization stack: above QEMU and KVM, beside graphical libvirt clients, below full platforms. Choosing between them depends on whether automation, convenience or cluster management matters most.

ToolInterfaceBest suited for
virshCommand line over libvirtScripting, servers, remote hosts
virt-managerGraphical libvirt clientInteractive desktop management
virt-installCommand line, creation onlyProvisioning new guests
QEMU directlyRaw command-line optionsTesting and unusual device setups
Proxmox VEWeb platform with own toolingClusters without libvirt
Where virsh sits among related tools

Running QEMU directly gives maximum control but bypasses libvirt’s security labeling, cgroup limits and lifecycle tracking. For production guests, virsh or another libvirt client is the safer route.

Pitfalls and good practice

Most virsh problems come from permissions, URIs and storage assumptions rather than from the tool itself. The following practices avoid the common traps.

  • Use `virsh edit` instead of editing XML files under /etc/libvirt by hand, because the daemon does not reread manually changed files.
  • Back up the domain XML with virsh dumpxml before major changes, so a guest can be redefined quickly.
  • Check guest agent availability before relying on shutdown --mode agent or filesystem freeze for consistent snapshots.
  • Prefer external snapshots for large production disks, and remember that they must be merged back with blockcommit.
  • Add administrators to the libvirt group rather than running every command as root on hosts that use polkit rules.

In simple terms

Imagine a building full of virtual computers and a building manager who holds every key. virsh is the way you give that manager instructions by typing short commands: start this computer, switch that one off, give this one more memory, move that one to another building.

Graphical tools do the same thing with buttons and windows. virsh is preferred when you want to repeat the same steps reliably, run them on a remote server, or put them in a script that works every night without anyone clicking.

A practical example

A university lab runs twelve KVM guests on two Linux hosts for student projects. Before each semester, the administrator uses a short shell script built on virsh: virsh snapshot-create-as takes a clean snapshot of every guest, and virsh setmem --config raises memory from 4 GiB to 8 GiB for the database course machines.

When one host needs a firmware update, the administrator runs virsh migrate --live for each guest to the second host over SSH, updates and reboots the first host, and migrates the guests back. Students notice only a brief pause of under a second, and at the end of the semester every guest is returned to its clean state with virsh snapshot-revert.