Configure Virtual Machine Resources with libvirt

LinuxBeginner
Practice Now

Introduction

Virtual machine administration involves more than creating and starting a domain. Operators frequently inherit an existing VM and must change its persistent resource definition: increase memory, expose additional virtual CPUs, attach storage, enable automatic startup, and prove that the running state matches the requested configuration.

In libvirt terminology, a virtual machine is a domain. A persistent domain has a saved definition—conceptually, its hardware blueprint—even when no QEMU process is running. Starting the domain creates a running instance from that definition; stopping it removes the running instance but keeps the blueprint. Keeping persistent configuration separate from runtime state is the central idea of this lab.

In this lab, a shut-off libvirt domain named lfcs-config is already defined with a small boot disk, 64 MiB of memory, and one vCPU. You will inspect that baseline and use virsh resource-management commands to reconfigure it. The environment does not expose /dev/kvm, so QEMU uses software emulation, and the disks do not contain a guest operating system. The management workflow and persistent libvirt configuration are nevertheless real.

Inspect the Existing Domain Configuration

In this step, you will establish the persistent configuration and runtime state of the existing lfcs-config domain before making changes.

Move to the project directory.

cd /home/labex/project

List all domains. The --all option includes stopped domains, so lfcs-config should appear in the shut off state.

sudo virsh list --all

Without --all, virsh list normally shows only active domains. Seeing a stopped name in the expanded list confirms that libvirt still knows about its persistent definition even though the VM is not consuming CPU time as a running guest.

Inspect the domain summary.

sudo virsh dominfo lfcs-config

dominfo combines identity, lifecycle, CPU, memory, persistence, and autostart information. At this stage, read it as a baseline rather than a target: later output should change only in the fields you deliberately reconfigure.

Focus on the stable configuration fields:

Name:           lfcs-config
State:          shut off
CPU(s):         1
Max memory:     65536 KiB
Used memory:    65536 KiB
Persistent:     yes
Autostart:      disable

Libvirt reports memory in KiB here. Because 1 MiB equals 1024 KiB, 65536 KiB is 64 MiB. Persistent: yes means the definition survives shutdown, while Autostart: disable means libvirt will not automatically start this domain when its virtualization service starts.

List the attached block devices. vda is the prepared root disk, and its source is the existing qcow2 image.

sudo virsh domblklist lfcs-config --details

In this table, Target is the device name presented to the guest, while Source is the host path that stores its data. The virtio disk named vda is analogous to a virtual drive connected to the VM; the qcow2 source file is the drive's backing image on the host.

This baseline separates what already exists from the resource changes you will make in later steps.

Configure Persistent Memory and vCPUs

In this step, you will increase the domain's persistent maximum memory, current memory allocation, and vCPU count while it is shut off.

Libvirt distinguishes the maximum memory ceiling from the memory assigned at the next boot. Set the persistent maximum to 128 MiB first. The --config flag changes the saved domain definition rather than a temporary runtime value.

sudo virsh setmaxmem lfcs-config 128M --config

The ceiling must be large enough to contain the assigned amount. Think of max memory as the size of the virtual machine's memory capacity and current memory as the amount requested for normal use. Because the domain is shut off, changing --config is predictable and will take effect the next time it starts.

Set the memory assigned at the next start to 96 MiB.

sudo virsh setmem lfcs-config 96M --config

The M suffix asks virsh to interpret the value in mebibytes. The later dominfo output converts 128 MiB to 131072 KiB and 96 MiB to 98304 KiB; these are the same quantities expressed in different units.

The maximum number of vCPUs must be raised before the current persistent allocation can use two CPUs.

sudo virsh setvcpus lfcs-config 2 --config --maximum

This first CPU command changes the upper limit in the saved definition. It does not by itself assign two usable vCPUs. Separating the maximum from the active allocation allows a VM definition to reserve future scaling capacity.

Set two vCPUs for the next boot.

sudo virsh setvcpus lfcs-config 2 --config

The second command sets the persistent allocation within that new limit. The order matters: requesting two assigned vCPUs while the maximum is still one would fail.

Inspect the updated persistent definition.

sudo virsh dominfo lfcs-config

The relevant fields should now show:

CPU(s):         2
Max memory:     131072 KiB
Used memory:    98304 KiB

Create and Attach a Persistent Data Disk

In this step, you will create a second qcow2 image and attach it as a persistent virtio disk named vdb.

Create a sparse 64 MiB qcow2 image in libvirt's image directory.

sudo qemu-img create -f qcow2 /var/lib/libvirt/images/lfcs-config-data.qcow2 64M

The command creates a virtual disk container, not a filesystem and not a mounted directory. -f qcow2 selects QEMU's copy-on-write image format, and 64M sets its virtual capacity. A newly created sparse image initially consumes much less host storage than its virtual size and grows as guest data is written.

Allow the QEMU process in this training environment to open the disposable image.

sudo chmod 666 /var/lib/libvirt/images/lfcs-config-data.qcow2

Mode 666 grants read and write permission to every user class. That broad permission keeps this disposable lab independent of host-specific QEMU user and group settings, but it is not a production recommendation. On a real host, prefer the ownership, group, SELinux label, or AppArmor policy required by the local libvirt service.

Attach the file to lfcs-config. The --target vdb option names the guest block device, --subdriver qcow2 records the image format, and --config modifies the persistent definition for the next start.

sudo virsh attach-disk lfcs-config \
  /var/lib/libvirt/images/lfcs-config-data.qcow2 \
  vdb --targetbus virtio --subdriver qcow2 --config

The source path belongs to the host; vdb is the name the guest would see. --targetbus virtio selects a paravirtualized disk interface commonly used for efficient Linux guests. Since the domain is shut off and the command uses --config, libvirt records the device in the saved blueprint instead of attempting a live hot-plug.

List the persistent block device configuration.

sudo virsh domblklist lfcs-config --details

The output should now contain both vda and vdb, with vdb pointing to lfcs-config-data.qcow2.

At this point the image file and the domain attachment are two separate facts. Creating a qcow2 file alone does not connect it to a VM, and detaching a disk later would not automatically delete its source file.

Enable Autostart and Validate Runtime State

In this step, you will enable automatic domain startup, start the VM now, and compare its runtime resources with the persistent settings.

Enable autostart so libvirt marks this domain to start when the virtualization service starts.

sudo virsh autostart lfcs-config

Autostart is a saved policy flag, not a request to start the domain immediately. It is useful for infrastructure services that should return automatically after the host or libvirt service restarts.

Start the domain with its updated persistent definition.

sudo virsh start lfcs-config

Starting creates a QEMU process from the saved definition you edited: two vCPUs, the new memory limits, and both disks. The command reports that the domain started; dominfo and domblklist provide the evidence that its state matches the intended configuration.

Give QEMU a few seconds to enter the running state.

sleep 3

Inspect the domain. It should be running with two vCPUs, 128 MiB maximum memory, and autostart enabled.

sudo virsh dominfo lfcs-config

On this software-emulated domain, the running Used memory field is normally 128 MiB even though the persistent currentMemory request is 96 MiB. There is no guest operating system or balloon driver cooperating with libvirt to reduce the runtime allocation. Inspect the inactive XML to confirm that the next-start configuration still records 96 MiB:

sudo virsh dumpxml lfcs-config --inactive | grep -E '<memory|<currentMemory|<vcpu'

dumpxml --inactive asks for the saved definition rather than the live QEMU view. The pipe passes that XML to grep, which displays only the memory and CPU elements. This focused comparison prevents an expected runtime reporting difference from being mistaken for a failed configuration change.

The stable values include <memory unit='KiB'>131072</memory>, <currentMemory unit='KiB'>98304</currentMemory>, and a vCPU value of 2. This comparison illustrates why persistent configuration and runtime resource reporting should be checked separately.

List the disks in the active domain.

sudo virsh domblklist lfcs-config --details

Both vda and vdb should appear. This demonstrates that the saved configuration was applied when QEMU started.

Stop the VM and Confirm Persistent State

In this step, you will stop the guest process while preserving the configured domain, storage, and autostart setting.

Because the training disks do not contain an operating system, a graceful guest shutdown cannot complete. Use destroy to stop the QEMU process immediately. This changes runtime state but does not delete the persistent domain definition.

sudo virsh destroy lfcs-config

Despite its name, virsh destroy is closer to cutting power than deleting a VM. It is appropriate here only because the exercise has no guest operating system or valuable data. For a real running guest, prefer virsh shutdown and allow the operating system to flush data and stop cleanly.

Confirm that the domain is stopped.

sudo virsh domstate lfcs-config

The output should be:

shut off

Inspect the persistent configuration one final time.

sudo virsh dominfo lfcs-config

The expected shut off state describes runtime only. CPU, memory, disk attachments, and autostart remain in the persistent definition. Removing that definition would require a different operation, such as virsh undefine; even undefining a domain does not necessarily delete its disk image files.

List all domains and their autostart state. The stopped lfcs-config domain should remain defined and marked for autostart.

sudo virsh list --all --autostart

The VM is now stopped but ready to start later with the resource configuration you created.

Summary

You took over an existing libvirt domain and changed its persistent resource configuration without rewriting its XML. You increased maximum and assigned memory, configured two vCPUs, created and attached a second qcow2 disk, enabled autostart, validated the configuration in a running QEMU domain, and stopped the process while preserving the managed VM. This is the practical difference between merely exploring a VM lifecycle and configuring a VM to a requested target state.