Access and modify virtual machines disk images with libguestfs tools

In a previous article, we saw how to create kvm virtual machines from the command line; in this tutorial, instead, we learn how to access and modify virtual machines disk images, using some utilities which are part of the libguestfs package on the most commonly used Linux distributions. Those tools let us perform a variety of tasks.

We will focus on some of them, like virt-filesystems and guestmount, which can be used to list filesystems existing on guest disk images, and mount them on the host system, respectively.

In this tutorial you will learn:

  • How to install libguestfs-tools on some of the most used Linux distributions
  • How to list partitions and filesystems existing on guest disk images
  • How to mount and unmount guest filesystems on the host system
  • How to edit guest files from the host system
  • How to copy files in and out of a guest system
00-introduction-to-libguestfs-tools
Introduction to libguestfs-tools
Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Distribution-independent
Software Guestfs utilities
Other Root privileges to perform administrative tasks
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

Installation

We can install the tools we will talk about in this tutorial directly from the official repositories of the most used Linux distribution by using their native package managers. On Fedora, for example, we usednf. On this distribution, the utilities are included in the libguest package:

$ sudo dnf install libguestfs



On the Debian family of distributions, and Debian itself, instead, to perform the installation, we can use the apt wrapper. The name of the package is libguestfs-tools:

$ sudo apt install libguestfs-tools

On Archlinux, like on Fedora, the package is called libguestfs. We can perform the installation by using pacman:

$ sudo pacman -Sy libguestfs

The package provides a lot of utilities which let us interact with virtual machines disk images, and perform very useful tasks. A note before we start seeing some examples: if we use libvirt and try to invoke one of the aforementioned utilities, we will receive the following error message:

libguestfs: error: could not create appliance through libvirt.

A solution to this problem, is to to run qemu directly, by setting and exporting the LIBGUESTFS_BACKEND variable to “direct” in the shell we are using to invoke the commands, or make it part of our environment:

export LIBGUESTFS_BACKEND=direct

Listing guest partitions and filesystems

The virt-filesystems utility let us list filesystem, partitions and block devices existing on virtual machine disks images. Let’s see some example of its usage. The tool, as practically all those who are part of the suite, can be used basically in two ways: the first is by passing the domain of the virtual machine with the -d option. When this strategy is adopted, all the disks used by the guest are analyzed:

virt-filesystems [options] -d <domain>

The other strategy we can use is to provide the utility with the path of a disk image directly, as the argument of the -a option:

virt-filesystems [options] -a /path/to/disk

Let’s test what the command returns on a virtualized Fedora 35 system which uses the fedora35.qcow2 disk image. To list all filesystem existing on the disk, we run:

$ virt-filesystems -a fedora35.qcow2
/dev/sda1
/dev/sda2

The command discovered two filesystems. To obtain extra information about them, we can add the -l option to it (short for --long):

$ virt-filesystems -la fedora35.qcow2
Name       Type        VFS   Label  Size         Parent
/dev/sda1  filesystem  ext4  -      1020702720   -
/dev/sda2  filesystem  ext4  -      20038230016  -

As you can see, details like the filesystem type and its size were included. To make the filesystems size human-readable (fourth column), we can add the -h option to the command. The output becomes the following:

$ virt-filesystems -lha fedora35.qcow2
Name       Type        VFS   Label  Size  Parent
/dev/sda1  filesystem  ext4  -      973M  -
/dev/sda2  filesystem  ext4  -      19G   -

By default only filesystems which can be mounted are reported in the list; to make also non-mountable filesystems (swap, for example) appear in the list, we can use the --extra option.

Specifying device types

As we saw above, the default action of the utility is to show filesystems existing on a disk image. We can, however, specify the type of “entity” which should be listed explicitly. For example, to obtain a list of the partitions existing on a disk image, we can use the --partitions option:

$ virt-filesystems --partitions -la fedora35.qcow2
Name       Type       MBR  Size         Parent
/dev/sda1  partition  83   1073741824   /dev/sda
/dev/sda2  partition  83   20400046080  /dev/sda



In the same fashion, we can visualize logical volumes (--logical-volumes), volume groups (--volume-groups) or physical volumes (--physical-volumes). To make the utility include all of them, we can simply use the --all option:

$ virt-filesystems --all -la fedora35.qcow2

When we do so, some entries will appear in the output list more than once: /dev/sda1, for example, is a partition, but contains an ext4 filesystem:

Name       Type        VFS   Label  MBR  Size         Parent
/dev/sda1  filesystem  ext4  -      -    1020702720   -
/dev/sda2  filesystem  ext4  -      -    20038230016  -
/dev/sda1  partition   -     -      83   1073741824   /dev/sda
/dev/sda2  partition   -     -      83   20400046080  /dev/sda
/dev/sda   device      -     -      -    21474836480  -

Formatting the output as CSV

As we saw in the previous examples, the output produced byvirt-filesystems is formatted as a list by default; by using the --csv option, however, we can make so that the CSV (Comma Separated Values) format is used:

$ virt-filesystems --all --csv -la fedora35.qcow2
Name,Type,VFS,Label,MBR,Size,Parent
/dev/sda1,filesystem,ext4,,,1020702720,
/dev/sda2,filesystem,ext4,,,20038230016,
/dev/sda1,partition,,,83,1073741824,/dev/sda
/dev/sda2,partition,,,83,20400046080,/dev/sda
/dev/sda,device,,,,21474836480,

Mounting and unmounting guest filesystems on host

By using the guestmount and guestunmount utilities is possible to respectively mount and unmount guest filesystems on the host. If the guest system is running, the filesystems should always be mounted in read-only mode, otherwise they
may be corrupted: so, if we need to perform write operations, we should shutdown the virtual machine, first.

Guest filesystems can be mounted on the host as a non-root user by using FUSE (filesystem in userspace). In such case, the user who must be the owner of the directory to be used as mountpoint.

Let’s see a practical example using the fedora35.qcow2 disk image we saw before. From the output of virt-filesystems we know that an ext4 filesystem exists on /dev/sda1; here we create a directory called mountpoint
and mount the guest filesystem in read-only mode:

$ mkdir mountpoint 
$ guestmount -a fedora35.qcow2 -m /dev/sda1 --ro mountpoint

Let’s examine the command above. As we did in the previous examples, we provided the path of the disk image via the -a option. With the -moption, instead, we specified the guest filesystem which should be mounted, and with --ro that it should be mounted in read-only mode. Finally, we specified where, in the host filesystem, it should be mounted.

$ ls -l mountpoint 
total 110224 
-rw-r--r--. 1 root root 240738 Feb 23 18:25 config-5.16.11-200.fc35.x86_64 
drwxr-xr-x. 3 root root 17 Feb 27 15:51 efi 
drwx------. 5 root root 97 Feb 27 15:56 grub2 
-rw-------. 1 root root 62396530 Feb 27 15:55 initramfs-0-rescue-c4f17c4c03ad474cb43ee9e586b29d0c.img
-rw-------. 1 root root 21517654 Feb 27 15:57 initramfs-5.16.11-200.fc35.x86_64.img 
drwxr-xr-x. 3 root root 21 Feb 27 15:52 loader 
lrwxrwxrwx. 1 root root 47 Feb 27 15:52 symvers-5.16.11-200.fc35.x86_64.gz -> /lib/modules/5.16.11-200.fc35.x86_64/symvers.gz 
-rw-------. 1 root root 5958331 Feb 23 18:25 System.map-5.16.11-200.fc35.x86_64 
-rwxr-xr-x. 1 root root 11371408 Feb 27 15:54 vmlinuz-0-rescue-c4f17c4c03ad474cb43ee9e586b29d0c 
-rwxr-xr-x. 1 root root 11371408 Feb 23 18:25 vmlinuz-5.16.11-200.fc35.x86_64

What if we want to mount guest filesystem recursively? For example, suppose that inside the guest /dev/sda1represents the boot partition, mounted on /boot;  the root partition, instead, is /dev/sda2, therefore it should be mounted before it, if we want to reproduce this mount scheme on the host. We can do it easily, with the following command:

$ guestmount -a fedora35.qcow2 -m /dev/sda2 -m /dev/sda1:/boot --ro mountpoint

Above, we used the -m option two times, one for each filesystem we want to mount. With the /dev/sda1:/boot notation, we declared that the /dev/sda1 filesystem should be mounted on /boot, where “/boot” is the mountpoint in the guest.

Unmounting the guest filesystems

To unmount the guest filesystems we can useguestunmount. Its usage is very simple: we just invoke the utility and pass the mountpoint as argument. In this case we would run:

$ guestunmount mountpoint

Editing files inside a guest system

The virt-edit utility let us modify files which exist in a virtual machine disk directly from the host system. As we already said, modifying files when a virtual machine is running can be dangerous, therefore the guest system should be stopped before performing such operations.



Editing files with virt-edit is quite simple. As in the previous examples, we provide the path of the disk image or the guest system domain and the path of the file itself. Just as an example, to edit the /etc/fstab file in the guest identified by the “fedora” domain, we would run:

$ virt-edit -d fedora /etc/fstab

The file is copied in the host filesystem /tmp directory and opened with the default editor. Multiple files can be specified with one command, one after another. In such case they will be opened sequentially (the second will be opened after the first one is closed, etc…):

$ virt-edit -d fedora /etc/fstab /etc/crypttab

Copying files in and out of a guest system

To copy files to and from a virtual machine disk image, we can use the virt-copy-in and virt-copy-out utilities, respectively. Once again we can reference the domain with the -d option, then the file or files to be copied, and finally the destination directory.

Nothing better than an example to demonstrate how the commands work. Suppose we want to copy the /etc/fstab file from the guest system associated with the “fedora” domain, to our current working directory in the host filesystem. Here is how we would invoke virt-copy-out:

$ virt-copy-out -d fedora /etc/fstab .

To copy one or more files from our host to a guest virtual machine filesystem, instead, we use virt-copy-in. Here is what we would do to copy back the “fstab” file in our current directory, back to the /etc/ directory in the guest filesystem:

$ virt-copy-in -d fedora fstab /etc/

Closing thoughts

In this tutorial we learned how to install the libguestfs tools on some of the most used Linux distributions, and how to use some of them. We saw how to list filesystems and partitions existing on a disk image, how to mount and unmount guest filesystems on a host system, how to edit guest files directly from the host, and finally how to copy files from and to a guest filesystem.



Comments and Discussions
Linux Forum