13.2 Managing Disk Images with qemu-img

In the previous section (see Section 13.1, Basic Installation with qemu-kvm, we used the qemu-img command to create an image of a hard disk. You can, however, use qemu-img for general disk image manipulation. This section introduces useful qemu-img subcommands to help manage the disk images flexibly.

13.2.1 General Information on qemu-img Invocation

qemu-img uses subcommands (like zypper does) to do specific tasks. Each subcommand understands a different set of options. Some of these options are general and used by more of these subcommands, while some of them are unique to the related subcommand. See the qemu-img manual page (man 1 qemu-img) for a complete list of all supported options. qemu-img uses the following general syntax:

qemu-img subcommand [options]

and supports the following subcommands:

create

Creates a new disk image on the file system.

check

Checks an existing disk image for errors.

convert

Converts an existing disk image to a new one in a different format.

info

Displays information about the relevant disk image.

snapshot

Manages snapshots of existing disk images.

commit

Applies changes made to an existing disk image.

rebase

Creates a new base image based on an existing image.

resize

Increases or decreases the size of an existing image.

13.2.2 Creating, Converting and Checking Disk Images

This section describes how to create disk images, check their condition, convert a disk image from one format to another, and get detailed information about a particular disk image.

qemu-img create

Use qemu-img create to create a new disk image for your VM Guest operating system. The command uses the following syntax:

qemu-img create -f fmt -o options fname size

The format of the target image. To get a complete list of image formats supported by QEMU, run qemu-img -h and look at the last line of the output.

Some of the image formats support additional options to be passed on the command line. You can specify them here with the -o option. The raw image format supports only the size option, so it is possible to insert -o size=8G instead of adding the size option at the end of the command.

Path to the target disk image to be created.

Size of the target disk image (if not already specified with the -o size=<image_size> option. Optional suffixes for the image size are K (kilobyte), M (megabyte), G (gigabyte), or T (terabyte).

To create a new disk image sles11sp1.raw in the directory /images growing up to a maximum size of 4 GB, run the following command:

tux@venus:~> qemu-img create -f raw -o size=4G /images/sles11sp1.raw
Formatting '/images/sles11sp1.raw', fmt=raw size=4294967296

tux@venus:~> ls -l /images/sles11sp1.raw
-rw-r--r-- 1 tux users 4294967296 Nov 15 15:56 /images/sles11sp1.raw

tux@venus:~> qemu-img info /images/sles11sp1.raw
image: /images/sles11sp1.raw
file format: raw
virtual size: 4.0G (4294967296 bytes)
disk size: 0

As you can see, the virtual size of the newly created image is 4 GB, but the actual reported disk size is 0 as no data has been written to the image yet.

qemu-img convert

Use qemu-img convert to convert disk images to another format. To get a complete list of image formats supported by QEMU, run qemu-img -h and look at the last line of the output. The command uses the following syntax:

qemu-img convert -c -f fmt -O out_fmt -o options fname out_fname

Applies compression on the target disk image. Only qcow and qcow2 formats support compression.

The format of the source disk image. It is autodetected in most cases and can therefore be omitted.

The format of the target disk image.

Specify additional options relevant for the target image format. Use -o ? to view the list of options supported by the target image format:

Path to the source disk image to be converted.

Path to the converted target disk image.

tux@venus:~> qemu-img convert -O vmdk /images/sles11sp1.raw \
/images/sles11sp1.vmdk

tux@venus:~> ls -l /images/
-rw-r--r-- 1 tux users 4294967296 16. lis 10.50 sles11sp1.raw
-rw-r--r-- 1 tux users 2574450688 16. lis 14.18 sles11sp1.vmdk

To see a list of options relevant for the selected target image format, run the following command (replace vmdk with your image format):

tux@venus:~> qemu-img convert -O vmdk /images/sles11sp1.raw \
/images/sles11sp1.vmdk -o ?
Supported options:
size             Virtual disk size
backing_file     File name of a base image
compat6          VMDK version 6 image
subformat        VMDK flat extent format, can be one of {monolithicSparse \
    (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat}
scsi             SCSI image

qemu-img check

Use qemu-img check to check the existing disk image for errors. Not all disk image formats support this feature. The command uses the following syntax:

qemu-img check -f fmt fname

The format of the source disk image. It is autodetected in most cases and can therefore be omitted.

Path to the source disk image to be checked.

If no error is found, the command returns no output. Otherwise, the type and number of errors found is shown.

tux@venus:~> qemu-img check -f qcow2 /images/sles11sp1.qcow2
ERROR: invalid cluster offset=0x2af0000
[...]
ERROR: invalid cluster offset=0x34ab0000
378 errors were found on the image.

Increasing the Size of an Existing Disk Image

When creating a new image, you must specify its maximum size before the image is created (see qemu-img create). After you install and run VM Guest for some time, the initial size of the image may no longer be sufficient and you need to add more space to it.

To increase the size of an existing disk image by 2 Gigabytes, use

qemu-img resize /images/sles11sp1.raw +2GB

NOTE: You can resize the raw disk images only. To resize other image formats, convert it to raw with qemu-img convert first.

The image now contains an empty space of 2 GB after the final partition. You can resize the existing partitions or add new ones.

Figure 13-1 New 2GB Partition in Guest YaST Partitioner

13.2.3 Managing Snapshots of Virtual Machines with qemu-img

Virtual machine snapshots are snapshots of the complete environment in which a VM Guest is running. The snapshot includes the state of the processor (CPU), memory (RAM), devices, and all writable disks.

Snapshots are helpful when you need to save your virtual machine in a particular state. For example, after you configured network services on a virtualized server and want to quickly start the virtual machine in the same state you last saved it. Or you can create a snapshot after the virtual machine has been powered off to create a backup state before you try something experimental and possibly make VM Guest unstable. This section introduces the latter case, while the former is described in Section 16.0, Administrating Virtual Machines with QEMU Monitor.

To use snapshots, your VM Guest must contain at least one writable hard disk image in qcow2 format. This device is usually the first virtual hard disk.

Virtual machine snapshots are created with the savevm command in the interactive QEMU monitor. You can assign a 'tag' to each snapshot which makes its identification easier. For more information on QEMU monitor, see Section 16.0, Administrating Virtual Machines with QEMU Monitor.

Once your qcow2 disk image contains saved snapshots, you can inspect them with the qemu-img snapshot command.

WARNING: Do not create or delete virtual machine snapshots with the qemu-img snapshot command while the virtual machine is running. Otherwise, you can damage the disk image with the state of the virtual machine saved.

Listing Existing Snapshots

Use qemu-img snapshot -l disk_image to view a list of all existing snapshots saved in the disk_image image. You can get the list even while the VM Guest is running.

tux@venus:~> qemu-img snapshot -l /images/sles11sp1.qcow2 
Snapshot list:
ID       TAG               VM SIZE        DATE          VM CLOCK
1         booting                4.4M 2010-11-22 10:51:10   00:00:20.476
2         booted                 184M 2010-11-22 10:53:03   00:02:05.394
3         logged_in              273M 2010-11-22 11:00:25   00:04:34.843
4         ff_and_term_running    372M 2010-11-22 11:12:27   00:08:44.965

Unique identification number of the snapshot. Usually auto-incremented.

Unique description string of the snapshot. It is meant as a human readable version of the ID.

The disk space occupied by the snapshot. Note that the more memory is consumed by running applications, the bigger the snapshot is.

Time and date the snapshot was created.

The current state of the virtual machine's clock.

Creating Snapshots of a Powered-Off Virtual Machine

Use qemu-img snapshot -c snapshot_title disk_image to create a snapshot of the current state of a virtual machine which was previously powered off.

tux@venus:~> qemu-img snapshot -c backup_snapshot /images/sles11sp1.qcow2
tux@venus:~> qemu-img snapshot -l /images/sles11sp1.qcow2 
Snapshot list:
ID        TAG                 VM SIZE                DATE       VM CLOCK
1         booting                4.4M 2010-11-22 10:51:10   00:00:20.476
2         booted                 184M 2010-11-22 10:53:03   00:02:05.394
3         logged_in              273M 2010-11-22 11:00:25   00:04:34.843
4         ff_and_term_running    372M 2010-11-22 11:12:27   00:08:44.965
5         backup_snapshot           0 2010-11-22 14:14:00   00:00:00.000

Once something breaks in your VM Guest and you need to restore the state of the saved snapshot (id 5 in our example), power off your VM Guest and do the following:

tux@venus:~> qemu-img snapshot -a 5 /images/sles11sp1.qcow2

Next time you run the virtual machine with qemu-kvm, it will be in the state of snapshot number 5.

NOTE: The qemu-img snapshot -c command is not related to the savevm command of QEMU monitor (see Section 16.0, Administrating Virtual Machines with QEMU Monitor. For example, you cannot apply a snapshot with qemu-img snapshot -a on a snapshot created with savevm in QEMU's monitor.

Deleting Snapshots

Use qemu-img snapshot -d snapshot_id disk_image to delete old or unneeded snapshots of a virtual machine. This saves some disk space inside the qcow2 disk image as the space occupied by the snapshot data is restored:

tux@venus:~> qemu-img snapshot -d 2 /images/sles11sp1.qcow2

13.2.4 Manipulate Disk Images Effectively

Imagine the following real-life situation: you are a server administrator who runs and manages a number of virtualized operating systems. One group of these systems are based on one specific distribution, while another group (or groups) is based on different versions of the distribution or even on a different (and maybe non-Unix) platform. And to make the case even more complex, individual virtual guest systems based on the same distribution usually differ according to the department and deployment: a file server typically uses different setup and services than a Web server does, while both may still be based on SUSE® Linux Enterprise Server 11 SP1.

With QEMU it is possible to create base disk images. You can use them as template virtual machines. These base images will save you plenty of time because you will never need to install the same operating system more than once.

Base and Derived Images

First, build a disk image as usual and install the target system on it. For more information, see Section 13.1, Basic Installation with qemu-kvm and Section 13.2.2, Creating, Converting and Checking Disk Images. Then build a new image while using the first one as a base image. The base image is also called a 'backing' file. After your new 'derived' image is built, never boot the base image again, but boot the derived image instead. Several derived images may depend on one base image at the same time. Therefore, changing the base image can damage the dependencies. While using your derived image, QEMU writes changes to it and uses the base image only for reading.

It is a good practice to create a base image from a freshly installed (and, if needed, registered) operating system with no patches applied and no additional applications installed or removed. Later on, you can create another base image with the latest patches applied and based on the original base image.

Creating Derived Images

NOTE: While you can use the raw format for base images, you cannot use it for derived images because the raw format does not support the backing_file option. Use for example the qcow2 format for the derived images.

For example, /images/sles11sp1_base.raw is the base image holding a freshly installed system.

tux@venus:~> qemu-img info /images/sles11sp1_base.raw 
image: /images/sles11sp1_base.raw
file format: raw
virtual size: 4.0G (4294967296 bytes)
disk size: 2.4G

The image's reserved size is 4 GB, the actual size is 2.4 GB, and its format is raw. Create an image derived from the /images/sles11sp1_base.raw base image with:

tux@venus:~> qemu-img create -f qcow2 /images/sles11sp1_derived.qcow2 \
-o backing_file=/images/sles11sp1_base.raw 
Formatting '/images/sles11sp1_derived.qcow2', fmt=qcow2 size=4294967296 \
backing_file='/images/sles11sp1_base.raw' encryption=off cluster_size=0

Look at the derived image details:

tux@venus:~> qemu-img info /images/sles11sp1_derived.qcow2 
image: /images/sles11sp1_derived.qcow2
file format: qcow2
virtual size: 4.0G (4294967296 bytes)
disk size: 140K
cluster_size: 65536
backing file: /images/sles11sp1_base.raw \
(actual path: /images/sles11sp1_base.raw)

Although the reserved size of the derived image is the same as the size of the base image (4 GB), the actual size is 140 KB only. The reason is that only changes made to the system inside the derived image are saved. Run the derived virtual machine, register it, if needed, and apply the latest patches. Do any other changes in the system such as removing unneeded or installing new software packages. Then shut the VM Guest down and examine its details once more:

tux@venus:~> qemu-img info /images/sles11sp1_derived.qcow2
image: /images/sles11sp1_derived.qcow2
file format: qcow2
virtual size: 4.0G (4294967296 bytes)
disk size: 1.1G
cluster_size: 65536
backing file: /images/sles11sp1_base.raw \
(actual path: /images/sles11sp1_base.raw)

The disk size value has grown to 1.1 GB, which is the disk space occupied by the changes on the file system compared to the base image.

Rebasing Derived Images

Once you modify the derived image (apply patches, install specific applications, or change the environment settings etc.) into a satisfactory shape, at some point you probably want to create a new base image 'merged' from the base image and the derived one. Your first base image (/images/sles11sp1_base.raw) holds a freshly installed system and can be a template for new modified base images, while the new one can contain the same system as the first one plus all security and update patches applied, for example. After you created this new base image, you can use it as a template for more specialized derived images as well. The new base image becomes independent of the original one. The process of creating base images from derived ones is called 'rebasing':

tux@venus:~> qemu-img convert /images/sles11sp1_derived.qcow2 \
-O raw /images/sles11sp1_base2.raw

This command created the new base image /images/sles11sp1_base2.raw using the raw format.

tux@venus:~> qemu-img info /images/sles11sp1_base2.raw
image: /images/sles11sp1_base2.raw
file format: raw
virtual size: 4.0G (4294967296 bytes)
disk size: 2.8G

The new image is 0.4 gigabytes bigger than the original base image. It uses no backing file, and you can easily create new derived images based upon it. This lets you create a sophisticated hierarchy of virtual disk images for your organization, saving a lot of time and work.

Mounting an Image on a VM Host Server

Sometimes it is useful to mount a virtual disk image under the host system. For example, if VM Host Server does not have a network support, this can be the only way to transfer files in and out of a VM Guest.

Linux systems can mount an internal partition of a raw disk image using a 'loopback' device. The first example procedure is more complex but more illustrative, while the second one is straightforward:

Mounting Disk Image by Calculating Partition Offset

  1. Set a loop device on the disk image whose partition you want to mount.

    tux@venus:~> losetup /dev/loop0 /images/sles11sp1_base.raw
  2. Find the sector size and the starting sector number of the partition you want to mount.

    tux@venus:~> fdisk -lu /dev/loop0
    
    Disk /dev/loop0: 4294 MB, 4294967296 bytes
    255 heads, 63 sectors/track, 522 cylinders, total 8388608 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Disk identifier: 0x000ceca8
    
           Device Boot      Start         End      Blocks   Id  System
    /dev/loop0p1              63     1542239      771088+  82  Linux swap
    /dev/loop0p2   *     1542240    8385929     3421845   83  Linux

    The disk sector size.

    The starting sector of the partition.

  3. Calculate the partition start offset:

    sector_size * sector_start = 512 * 1542240 = 789626880

  4. Delete the loop and mount the partition inside the disk image with the calculated offset on a prepared directory.

    tux@venus:~> losetup -d /dev/loop0
    tux@venus:~> mount -o loop,offset=789626880 \
    /images/sles11sp1_base.raw /mnt/sles11sp1/
    tux@venus:~> ls -l /mnt/sles11sp1/
    total 112
    drwxr-xr-x   2 root root  4096 Nov 16 10:02 bin
    drwxr-xr-x   3 root root  4096 Nov 16 10:27 boot
    drwxr-xr-x   5 root root  4096 Nov 16 09:11 dev
    [...]
    drwxrwxrwt  14 root root  4096 Nov 24 09:50 tmp
    drwxr-xr-x  12 root root  4096 Nov 16 09:16 usr
    drwxr-xr-x  15 root root  4096 Nov 16 09:22 var
    
  5. Copy one or more files onto the mounted partition and unmount it when finished.

    tux@venus:~> cp /etc/X11/xorg.conf /mnt/sles11sp1/root/tmp
    tux@venus:~> ls -l /mnt/sles11sp1/root/tmp
    tux@venus:~> umount /mnt/sles11sp1/

Mounting Disk Image while Utilizing kpartx

  1. Set a loop device on the disk image whose partition you want to mount.

    tux@venus:~> losetup /dev/loop0 /images/sles11sp1_base.raw
  2. Create a device map from the disk image's partitions.

    tux@venus:~> kpartx -a /dev/loop0
  3. Mount any partition of the disk image on a prepared mount point.

    tux@venus:~> mount /dev/mapper/loop0p1 /mnt/p1

    You can replace loop0p1 with the number of the partition you want to mount, for example loop0p3 to mount the third partition on the disk image.

  4. Copy or move files or directories to and from the mounted partition as you like. Once you finish, unmount the partition and delete the loop.

    tux@venus:~> umount /mnt/p1
    tux@venus:~> losetup -d /dev/loop0

WARNING: Never mount a partition of an image of a running virtual machine in a read-write mode. This could corrupt the partition and break the whole VM Guest.