Managing Virtual Machines

The primary tool for managing KVM virtual machines from the command line is virsh, which talks to the libvirt daemon. Everything you can do in virt-manager's GUI you can do with virsh, making it suitable for automation and headless server management. This article covers the daily operations: starting/stopping VMs, checking status, modifying resources, and connecting to VM consoles.

virsh basics

# List VMs:
virsh list          # Running VMs only
virsh list --all    # All VMs including stopped

# Get VM info:
virsh dominfo ubuntu-test
virsh domstats ubuntu-test    # Resource usage statistics

virsh list --all output

 Id   Name          State
-------------------------------
 1    ubuntu-prod   running
 -    ubuntu-test   shut off
 -    ubuntu-dev    paused

VM lifecycle commands

# Start / stop / restart:
virsh start ubuntu-test         # Start a stopped VM
virsh shutdown ubuntu-test      # Graceful shutdown (sends ACPI signal)
virsh destroy ubuntu-test       # Force stop (like pulling the power cord)
virsh reboot ubuntu-test        # Reboot
virsh suspend ubuntu-test       # Pause (freeze in memory)
virsh resume ubuntu-test        # Resume from suspended state

# Connect to VM console (serial console):
virsh console ubuntu-test    # Exit with Ctrl+]

# Get VM's IP address:
virsh domifaddr ubuntu-test

⚠️ WARNING: virsh destroy is a hard power-off — it stops the VM immediately without flushing disk buffers, which can corrupt the filesystem. Always use virsh shutdown first and only use destroy if the VM is unresponsive.

Modifying VM resources

# Add CPU/RAM (requires VM to be stopped):
virsh setmaxmem ubuntu-test 4G --config    # Set max allowed RAM
virsh setmem ubuntu-test 4G --config       # Set current RAM
virsh setvcpus ubuntu-test 4 --config --maximum
virsh setvcpus ubuntu-test 4 --config

# Edit VM XML configuration directly:
virsh edit ubuntu-test    # Opens in $EDITOR

# Add a disk to a running VM:
virsh attach-disk ubuntu-test /var/lib/libvirt/images/extra.qcow2 vdb   --cache none --persistent

# Resize an existing disk image (VM must be stopped):
sudo qemu-img resize /var/lib/libvirt/images/ubuntu-test.qcow2 +20G
# Then expand the partition inside the VM (growpart + resize2fs)

Autostart and scheduling

# Start VM automatically when host boots:
virsh autostart ubuntu-prod

# Disable autostart:
virsh autostart ubuntu-prod --disable

# List VMs with autostart status:
virsh list --all --autostart

# Suspend all VMs before a maintenance window:
for vm in $(virsh list --name); do virsh suspend $vm; done
# Resume all:
for vm in $(virsh list --name); do virsh resume $vm; done

Conclusion

Daily VM management with virsh: virsh list --all for status overview, virsh start/shutdown for power operations, and virsh console when you need to access a VM that has lost network connectivity. Enable virsh autostart for production VMs that should survive host reboots. Keep virsh destroy as a last resort, not a first response to a stuck VM.

Need help with Ubuntu administration?

Work directly with Muhammad Irfan Aslam for Ubuntu Server, Linux, cloud, Docker, DevOps, CI/CD, or infrastructure troubleshooting support.

Work with Muhammad Irfan Aslam