Table of Contents

Create a New Virtual Machine

The following command creates a new Virtual Machine with the name "live", 1024MB of RAM, boots from the live.iso in the current path, opens up an available VNC port listening on 192.168.1.1 and will use the pre-allocated image file /var/lib/libvirt/images/live.img as a harddrive.

To pre-allocate the image file run:

truncate --size=8192M /var/lib/libvirt/images/guest.img

which will create an image file at /var/lib/libvirt/images/guest.img of 8GB size.

Next, to start the install, run:

virt-install --name live \
    --network bridge:br0 --ram 1024 \
    --boot cdrom --cdrom live.iso \
    --graphics vnc,listen=192.168.1.1,port=5901 \
    --disk /var/lib/libvirt/images/live.img

Delete a Virtual Machine

destroy live #halts the machine forcibly
undefine live #removes live from the list of machines managed by virsh

Add ISO to Domain

First attach to the domain and edit it, by issuing:

virsh -c qemu:///system
list --all
edit domain # edit the domain name, obtained from the previous command

and then insert the following snippet:

    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/path/to/file.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='1' target='0' unit='0'/>
    </disk>

where /path/to/file.iso is the path to the ISO file to attach to the domain.

Speed-Up Virtualization using Virtio Drivers

virtio is a thin-layer networking and disk driver that will skip the overhead of a full emulation thereby making the guest faster. In order to enable it, edit a domain and change the disk section such that they use the virtio driver:

    <disk type='file' device='disk'>
...
      <target dev='hda' bus='virtio'/>
...
    </disk>

and be sure to remove any address tag because virsh will recreate it.

Also change the network driver to virtio:

    <interface type='bridge'>
...
      <model type='virtio'/>
      <driver>
        <host gso='off' tso4='off' tso6='off' ecn='off' ufo='off'/>
        <guest tso4='off' tso6='off' ecn='off'/>
      </driver>
    </interface>

The driver block ensures that various offload parameters are turned off for the host and guest which is deemed to be good practice for virtio interfaces on a bridge. Additionally, the bridge can be configured to turn off most of the offloading:

ethtool -K br0 tso off sg off ufo off gro off gso off

where:

Speed-Up Virtualization using Multi-Queue VirtIO Networking

Multi-queue virtio-net provides an approach to networking that scales up well as the number of virtual CPUs increases by allowing packets to be transmitted and received in parallel.

To configure multi-queue virtio-net, edit the guest domain configuration and add:

<driver name='vhost' queues='N'/>

to the network interface where N is the number of queues (from 1 to 8).

For instance, the following configuration:

    <interface type='bridge'>
      <mac address='5b:48:e3:4a:5b:32'/>
      <source bridge='br0'/>
      <model type='virtio'/>
      <driver name='vhost' queues='2'/>
    </interface>

will switch to the vhost driver and use 2 queues.

Speed-Up Virtualization using Native AIO

Native asynchronous IO gives better performance for virtual images, it can be enabled by editing the domain and adding the attribute io='native' to the disk tag:

<driver name='qemu' type='raw' io='native'/>

Disable Disk Cache to Speed-Up Disk Operations

Add the cache='none' attribute to the driver tag of the domain:

<driver name='qemu' type='raw' io='native' cache='none'/>

Expose CPU Capabilities to Guests

Execute:

virsh capabilties

in order to list all the available CPU features. The CPU type with all the features are listed under the <cpu> tag and can be copied directly to a domain configuration. In order to do that, first connect to the system using virsh:

virsh -c qemu:///system

and then edit the domain that the features should be added to:

edit guest1

and copy the desired features, including the tags (<cpu>…</cpu>) from the first step into the configuration and save the file.

CPU Passthrough

If you wish to expose the entire set of features, you can use the passthrough parameter passed to cpu by editing the guest configuration:

<cpu mode='host-passthrough'>
</cpu>

Selecting Correct Topology

Sometimes the default settings do not select the correct topology. This can be observed by running:

ps aux | grep kvm

and reading the following line:

-smp 2,sockets=1,cores=1,threads=1

Comparing to the correct topology, which can be obtained by running:

virsh capabilities | grep topology

which is:

<topology sockets='1' cores='2' threads='1'/>

we can observe that the number of cores is detected wrongly.

Thus, to enable the correct topology, we take the output of the previous command and place it in the cpu subsection of the domain xml:

  <cpu mode='host-passthrough'>
    <topology sockets='1' cores='2' threads='1'/>
  </cpu>

and then shutdown and restart the guest.

Increase Network Performance

vnet devices created by virsh perform better with a txqueuelen set to a higher txqueuelen. In order to test, the txqueuelen can be set manually using:

ifconfig vnet0 txqueuelen 2500

To make the changes persistent, we add a file called 60-vnet.rules to /etc/udev/rules.d containing the line:

KERNEL=="vnet[0-9]*", RUN+="/sbin/ip link set %k txqueuelen 2500"

Fix Unstable TSC Warning

You may find an error message indicating that the current clock-source is unstable. If you issue:

dmesg | grep TSC

you may see:

kvm: SMP vm created on host with unstable TSC; guest TSC will not be reliable

In this case, it may be a good idea to supply an alternate clock-source to the kernel.

First, to check what clock-sources are available issue:

cat /sys/devices/system/clocksource/clocksource0/available_clocksource

which will return some of the following:

kvm-clock tsc hpet acpi_pm

To check the currently selected clock-source, issue:

cat /sys/devices/system/clocksource/clocksource0/current_clocksource

which will return the clock-source that Linux considers unstable.

In order to fix the unstable clock-source problem, edit /etc/default/grub or /etc/lilo.conf and add the following kernel parameter:

clocksource=acpi_pm

where acpi_pm is one of the available clock-sources. After which, a restart is required to pick-up the changes (remember to run lilo again if you are using lilo).

Clone Virtual Machine

In order to clone a virtual machine with virsh, first connect and list all the machines as root:

virsh -c qemu:///system

then on the virsh console, issue:

list --all 

and shutdown the virtual machine that you wish to clone:

shutdown example.domain

You can then issue list –all again to check when the virtual machine has been shut down:

 -     example.domain                  shut off

Now exit the virsh command prompt with Ctrl+D and issue as root:

virt-clone --connect=qemu:///system -o example.domain -n new.domain -f /var/lib/libvirt/images/new.domain.img

where:

Depending on how large the virtual machine is, after a while the new domain will be created. You should now go back to the virsh command line with:

virsh -c qemu:///system

and edit the new domain with:

edit new.domain

in order to make any last minute change to the VM.

After that, you can start the new domain / virtual machine using the virsh command line by issuing:

start new.domain

Alternatively, do not forget to set the autostart flag on the newly created virtual machine in case you want it to start automatically once the system boots:

autostart new.domain

Delete Resume State

Some resume states get corrupted which sometimes leads to the following error message when starting a domain:

error: failed to get domain 'testbed'
error: Unable to read from monitor: Connection reset by peer

In order to remove the saved state for the domain testbed issue the following command:

virsh managedsave-remove testbed

Set Startup Boot Order

The boot-order can be changed by editing the domain name and including the boot-order devices:

<os>
  <type>hvm</type>
  <loader>/usr/lib/xen/boot/hvmloader</loader>
  <boot dev='network'/>
  <boot dev='cdrom'/>
  <boot dev='hd'/>
  <bootmenu enable='yes'/>
</os>

Import Virtual Machine

Virtual Machines can be imported using the –import parameter with virt-install. For example, the following command could be used:

virt-install -n NAME \    # the name of the domain to be created
    -r 2048 \             # the amount of RAM to be assigned to the virtual machine 
    --disk  /var/lib/libvirt/images/NAME.IMG,device=disk,bus=virtio \    # the disk image NAME.IMG to be imported using the virtio driver
    -w bridge=br0,model=virtio \                                         # bridge the network to br0 using the virtio driver
    --vnc \               # enable VNC
    --noautoconsole \     # do not open a console after importing
    --import              # and import

Installing Windows

In case you have been accustomed to use the virtio bus, you will notice that booting off a Windows ISO and attempting to install will not find any disks connected. Switch the bus to ide and delete the address line (it will be recreated when you save the domain). You can then install Windows and install the virtio drivers and then switch back the bus to virtio.

Accessing Contents of an Image File

First determine an available loop device by issuing:

losetup -f 

which will display a device such as /dev/loop0. Then attach the image file to the loop device:

lopsetup /dev/loop0 /var/lib/libvirt/images/guest.img

You can check that the partitions are there by using fdisk.

Next we run kpartx to create a map to the partitions available in the image file:

kpartx -av /dev/loop0

this will create device files under /dev/mapper/, for example, for two partitions on loop0, it will create /dev/mapper/loop0p1 and /dev/mapper/loop0p2.

These can then be mounted using mount, for example, to mount the second partition, you would issue:

mount /dev/mapper/loop0p2 /mnt/transfer

Enable Shutdown of Windows Guests

To enable the shutdown of Windows guests running under qemu/kvm, the following settings should be made:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows]
"ShutdownWarningDialogTimeout"=dword:00000001

You can now issue: shutdown windows.guest to shutdown a Windows domain named windows.guest.

Rename Virtual Machine Domain

Virtual machines (domains) are tied into the virsh system tightly such that there is no simple solution to renaming them except following the same steps:

You may want to actually save the new XML at /etc/libvirt/qemu/ where all the other domain XML files are located before importing the domain.

Windows, VIRTIO and DHCP

If you are running a Windows guest under libvirt using a virtio adapter type, you may notice that the Windows guest will not be able to acquire an IP address using DHCP.

To fix that TSO has to be disabled on the virtio interface. In order to do that, launch a registry editor and navigate to HKEY_LOCAL_MACHINE→SYSTEM→CurrentControlSet→Services→Tcpip→Parameters and add a new DWORD (32 bit). Give it the name DisableTaskOffload and set the value to 1. After that, restart the Windows guest and DHCP should work fine.

The VirtIO Pseudo-Random Generator

Guest machines can be configured to use the host random hardware for pseudo-random number generation. First, edit the virtual machine domain configuration and add the following configuration lines:

    <rng model='virtio'>
      <backend model='random'>/dev/random</backend>
    </rng> 

Next, install the rng-tools package:

apt-get install rng-tools

and start rngd:

systemctl restart rng-tools

EGD

To use egd, you would have to install:

aptitude install egd

and then run egd in the background:

egd.pl --debug-client --nofork localhost:8888

where 8888 is the port to listen on.

After that, you would add the following configuration lines to the guest:

 <rng model='virtio'>
   <backend model='egd' type='tcp'>
     <source mode='connect' host='127.0.0.1' service='8888'/>
   </backend>
 </rng>

Testing

In order to test, you would log-in to a machine and verify with:

lsmod | grep virt

that the virtio_rng module is loaded.

Mount Images

Using losetup and partx images can be mounted from files. Let's say the image file is domain.img and we would like to detect and create a device for all partitions inside the image. We would first mount the image over loopback using losetup:

losetup -v -f /path/to/domain.img

This should create a loop device such as /dev/loop0 and display it. Next, we can list the partitions with partx:

partx --show /dev/loop0

To make partix add loop devices for all partitions on the image, we issue:

partx -v --add /dev/loop0

which should create devices such as /dev/loop0p1 (first partition), /dev/loop0p2 (second partition), etc…

Share a Folder Between Guest and Host

To mount a shared folder inside the guest shared with the host, connect with virsh and edit the domain to add the following lines:

<filesystem type='mount' accessmode='mapped'>
    <source dir='/mnt/guest_shared'/>
    <target dir='host_share'/>
</filesystem>

This will expose the folder /mnt/guest_shared to the guest. The guest will then be able to mount the folder from the host /mnt/guest_shared by using the name host_share. Inside the guest, you would run:

mount -t 9p -o trans=virtio,version=9p2000.L host_share /mnt/shared/

which will mount the folder /mnt/guest_shared from the server to the folder /mnt/shared on the guest.

Hotswap Disk

First, the guest needs to have a device defined for a CDROM. After that, the command:

virsh attach-disk domain /dev/sr0 hdc --type cdrom

or, for Windows:

virsh attach-disk domain /mnt/isos/cd.iso hdc --type cdrom

executed on the host operating system will mount the ISO inside the domain. The converse virsh command is detach-disk.

Hotswap CD-ROM or Floppy

First, in order to make sure that libvirt will boot off the CD-ROM or Floppy and then proceed to the next bootable device, edit the domain and make sure that the lines:

    <boot dev='cdrom'/>
    <boot dev='hd'/>

are added inside the os tag.

Then, to eject a CD-ROM or Floppy, issue:

virsh change-media domain drive --eject --config

where:

Conversely, to insert a CD-ROM or floppy, issue:

virsh change-media domain drive /var/lib/libvirt/iso/virtio-win.iso --insert --config

Turn Domain Autostart On and Off

To make a virtual machine autostart on virsh start, issue on the virsh command line:

autostart domain

where domain is the name of the virtual machine.

In order to remove the autostart flag such that a virtual machine will not be start on virsh boot, issue:

autostart domain --disable

Enable Jumbo Frames for Bridged Networking

To enable Jumbo frames on a bridge, you will need to ensure that all member interfaces of the bridge are also set to use Jumbo frames.

Create an udev persistent network file (or edit it if it is available) on the machine hosting the virtual machines guests at /etc/udev/rules.d/70-persistent-net.rules with the following contents:

# LibVirt Jumbo Frames
SUBSYSTEM=="net", ACTION=="add", KERNEL=="vnet*", ATTR{mtu}="9000"
# Tap Interfaces Jumbo Frames
SUBSYSTEM=="net", ACTION=="add", KERNEL=="tap*", ATTR{mtu}="9000"

Debian Derivates

Edit /etc/network/interfaces and amend all configured interfaces to set the interface MTU to 9000. For instance, for an interface eth0 that will be a bridge member, you would have something like:

# Part of Bridge
allow-hotplug eth0
iface eth0 inet static
        # other options...
        mtu 9000

In case you are not on Sid or Etch, then you may need to add the line:

pre-up /sbin/ifconfig $IFACE mtu 1492

after the mtu 9000 line to make sure that dynamic interfaces also have the MTU set.

Additionally, in /etc/network/interfaces, make sure that the bridge also has the MTU set appropriately:

auto br0
iface br0 inet static
        # other options...
        mtu 9000
        pre-up /sbin/ifconfig $IFACE mtu 9000

RedHat Derivates

Next, for all interfaces configured in /etc/sysconfig/network-scripts/ add the parameter:

MTU=9000

in order to enable Jumbo frames.

Install Guest Agent

Similar to other virtualization software, qemu comes bundled with an agent that runs on the guest and facilitates various features. To install the qemu guest agent, first the agent itself has to be installed inside the guest, for instance, on Debian by issuing:

aptitude install qemu-guest-agent

and then the domain definition has to be changed to include:

    <channel type='unix'>
      <source mode='bind'/>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
    </channel>

inside the devices tags.

Delete LVM backed Domain and Pool

Shut down the domain, or destroy it if it cannot be shutdown:

virsh destroy mydomain.db

where:

Undefine the domain from libvirt:

virsh undefine mydomain.db

Finally, remove the volume from the pool:

virsh vol-delete --pool vms mydomain.db

where:

Passing Plan 9 Permissions

Access Mode Mapped

The following configuration changes for the domain have to be made:

    <filesystem type='mount' accessmode='mapped'>
      <source dir='/mnt/cdrom'/>
      <target dir='cd'/>
    </filesystem>

Access Mode Passthrough

For passthrough access mode, the following configuration change has to be made for the domain:

    <filesystem type='mount' accessmode='passthrough'>
      <source dir='/mnt/cdrom'/>
      <target dir='cd'/>
    </filesystem>

Virtual machines running under qemu / kvm have to be started as root. To accomplish that, edit /etc/default/libvirt/qemu.conf and set:

user = "root"
group = "root"

Additionally, the following setting:

clear_emulator_capabilities = 0

has to be added to /etc/default/libvirt/qemu.conf.

Mounting the Share

Once the virtual machine boots, the share can then be automatically mounted by adding the following line:

cd  /mnt/share     9p      defaults,trans=virtio,version=9p2000.L,posixacl 0       0

to /etc/fstab, where

Setting Custom Interface Name for Bridge Networking Mode

libvirt allows using:

<target dev='...'/>

to set the custom name for bridge interfaces such as vnet0, vnet1, etc…

However, if the name of the interface contains the substring vnet, libvirt will ignore the entry and will not save it, for instance, setting the interface name with:

<target dev='vnet888'/>

will just be ignored by libvirt.

To resolve this issue, use a more custom-tailored interface name, for instance:

<target dev='mynet0'/>

without containing the vnet substring.

Strange Windows Install Errors

One easy workaround for a BSoD on a fresh Windows install complaining about IRQL_NOT_LESS_OR_EQUAL or reaching a fatal error is to increase the RAM available above $3GiB$.

Passing an USB Device to the Guest

The USB device has to be identified first by vendor and product number which can be obtained by issuing the command:

lsusb -v

and checking the idVendor and idProduct field, for example:

  idVendor           0x2040 Hauppauge
  idProduct          0x8268

Based on the vendor and product numbers, a domain XML file can be generated, such as:

    <hostdev mode='subsystem' type='usb' managed='yes'>
      <source>
        <vendor id='0x2040'/>
        <product id='0x8268'/>
      </source>
    </hostdev>

that can then be inserted as part of the domain definition.

In order to plug and unplug a device from the guest to the host and vice-versa, the following twin converse commands can be used:

virsh attach-device DOMAIN --file device.xml --config
virsh detach-device DOMAIN --file device.xml

where:

The additional –config parameter passed to attach-device makes it such that the device will be included as part of the domain definition after the command executes.