The libguestfs is a C library and a collection of tools on this library to create, view, access and modify virtual machine disk images in Linux. You can look inside the disk images, modify the files they contain, create them from scratch, resize them, and a lot more. It doesn’t require libvirt or KVM and doesn’t require root privileges either. Red Hat sponsors the development of libguestfs. It supports many Linux distributions and Unix variants like Mac OS.
Libguestfs works with almost all Linux file systems (ext2/3/4, XFS, btrfs, etc.), windows file systems (vfat and ntfs), Mac OS and BSD file systems, LVM2 volumes, MBR and GPT disk partitions, RAW disks, QCOW2, VirtualBox VDI, VMWare VMDK, and Hyper-V VHD/VHDX. It can even access local files and local devices like CD and DVD ISOs, SD cards, or remotely over FTP, HTTP, SSH, iSCSI, NBD, GlusterFS, Ceph, Sheepdog, and much more.
Using libguest tools, we can do a whole lot of tasks as listed below:
- Create guest virtual machines,
- Clone virtual machines,
- Build VMs,
- Customize VMs,
- Scripting changes to VMs,
- Inspect VM images,
- View and edit files inside guest machines,
- Copy files and directories to and from virtual machines,
- Display information about filesystems, devices, LVM,
- Archive, upload and download files,
- Monitor disk used/free statistics,
- Format virtual disks,
- Resize virtual disks,
- Performing backups,
- Mount and unmount guest filesystem in host system,
- P2V (convert a physical machine to run virtualized on KVM, OpenStack, oVirt, Red Hat Virtualization),
- V2V (convert a guest machine from a foreign hypervisor to run on KVM),
- Display log files,
- Merge changes in the windows registry in windows guests,
- and much more.
You can do all of these tasks either via a scriptable shell called guestfish, or an interactive rescue shell virt-rescue.
Install libguestfs on Linux
Run the following command to install libguestfs on Debian, Ubuntu:
$ sudo apt install libguestfs-tools
On CentOS, RHEL:
$ sudo dnf install libguestfs-tools
Once installed, check the version of guestfish using command:
$ guestfish --version guestfish 1.40.2
Access And Modify Virtual Machine Disk Images With Libguestfs
Make sure the guest machines are powered off. You must not modify the live images for any reason. It may lead to permanent disk corruption and data loss. Always backup the disk images before making any changes in them.
1. Guestfish shell
Guestfish, short for guest filesystem shell, is an interactive shell for editing virtual machine filesystems and disk images.
1.1. Access existing disk images and mount guest filesystems manually
First, let us load an existing disk image to inspect.
Run the following command from to enter into guestfish interactive shell:
Welcome to guestfish, the guest filesystem shell for editing virtual machine filesystems and disk images. Type: ‘help’ for help on commands ‘man’ to read the manual ‘quit’ to quit the shell ><fs>
Here, ><fs> indicates the guestfish prompt.
..and then add the disk images using command:
><fs> add ~/CentOS_8_Server.img
Next, run the following command to initiate the library and attach (launch) the disk image:
It will take a few seconds in the first time. The subsequent starts will finish much faster.
Now you need to list and mount guest filesystems manually.
To view the list of filesystems in the disk, run this command from guestfish prompt:
/dev/sda1: ext4 /dev/cl/root: xfs /dev/cl/swap: swap
Mount a filesystem:
><fs> mount /dev/cl/root /
Display mount points:
><fs> mountpoints /dev/cl/root: /
Similarly, mount the other filesystems.
1.2. Access existing disk images and mount guest filesystems automatically
Instead of manually listing and mounting the guest filesystems, you can let the guestfish to automatically inspect the images and mount filesystems using -i flag like below.
$ guestfish -a CentOS_8_Server.img -i
- -a (–add) parameter will automatically detect the disk image format. To override this and specify a particular format use the –format option.
- -i (–inspector) – Inspect the disks and mount the filesystems.
- CentOS_8_Server.img – name of the disk image. I have this image in my current directory.
This command will load the given image, mount guest file systems and land you inside the guestfish shell.
Welcome to guestfish, the guest filesystem shell for editing virtual machine filesystems and disk images. Type: ‘help’ for help on commands ‘man’ to read the manual ‘quit’ to quit the shell Operating system: CentOS Linux release 8.2.2004 (Core) /dev/cl/root mounted on / /dev/sda1 mounted on /boot ><fs>
If you used the “-i” parameter, you don’t have to list and mount guest filesystems manually. The filesystems will be automatically mounted. Also, you don’t need to initiate the library and attach the disk image by yourself. Guestfish itself will take care of it.
1.3. Access virtual machines instead of just disk images
Guestfish has an option to access the virtual machines (domains) instead of the disk images.
First, get the name of the virtual machines using command:
$ virsh list --all Id Name State -------------------------------- - centos8-uefi shut off - nginx_centos8 shut off
To access the VM named “centos8-uefi”, use -d or –domain option like below.
$ guestfish -d centos8-uefi -i
1.4. Viewing And Modifying Contents Of Disk Images
Guestfish supports hundreds of commands to view and modify disk images as you please. You will be overwhelmed if you look into the whole man page. So it is better to know how to get help first.
List all commands
If you don’t know where to start, simply bring up the help section using command:
To list all available commands along with a brief description, run:
><fs> help -l
Get help of a specific command
To get help of any command, for example mkdir, run:
<fs> help mkdir
Now let us see a few examples.
List block devices
To list all the block devices in the image, run:
><fs> list-devices /dev/sda
To list all the partitions detected on all block devices, run:
><fs> list-partitions /dev/sda1 /dev/sda2
List directory contents
To list the files in a given directory, run:
><fs> ls /root .bash_history .bash_logout .bash_profile .bashrc .cshrc .tcshrc
View file contents
To display the contents of a file, run:
><fs> cat /etc/fstab # # /etc/fstab # Created by anaconda on Thu Feb 6 06:43:28 2020 # # Accessible filesystems, by reference, are maintained under '/dev/disk/'. # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info. # # After editing this file, run 'systemctl daemon-reload' to update systemd # units generated from this file. # /dev/mapper/cl-root / xfs defaults 0 0 UUID=5e675dd6-7f64-46cd-8535-3617f3cf870b /boot ext4 defaults 1 2 /dev/mapper/cl-swap swap swap defaults 0 0
The following command will create a directory named “ostechnix” under /root directory in the guest system.
><fs> mkdir /root/ostechnix
Create empty files
To create an empty file inside the guest machine, do:
><fs> touch /root/ostechnix/file.txt
Verify if the file has been created:
><fs> ls /root/ostechnix/ file.txt
Create files with contents
To create a file with some contents in it, use write command:
><fs> write /root/ostechnix/file2.txt https://ostechnix.com
The above command will create file2.txt in /root/ostechnix/ directory and write “https://ostechnix.com” in it.
You can verify it using “cat” command:
><fs> cat /root/ostechnix/file2.txt https://ostechnix.com
Append contents to existing files
To append new content at the end of an already created file, use “write-append” command:
<fs> write-append /root/ostechnix/file2.txt /about
The above command will add the word “/about” at the end of the file1.txt contents.
Verify if the line is added, use cat command:
><fs> cat /root/ostechnix/file2.txt https:/ostechnix.com/about
To edit a file on the guest machine, use “edit” command:
><fs> edit /root/ostechnix/file.txt
The given file will open in the default editor.
Remove files and directories
To remove a file from the guest machine:
><fs> rm /root/ostechnix/file2.txt ><fs> rm /root/ostechnix/file.txt
To remove a directory, use “rmdir” command:
><fs> rmdir /root/ostechnix/
Copy local files or directories into disk image
The “copy-in” command copies the local files or directories recursively into the disk image.
The following command will copy the file ostechnix.txt from the local system to /root/ostechnix/ in disk image.
<fs> copy-in ostechnix.txt /root/ostechnix/
Verify it using ls command:
<fs> ls /root/ostechnix/ file.txt ostechnix.txt
Copy files or directories from disk image to host system
Similarly, we can copy the files or directories from a disk image to the local host system using “copy-out” command like below.
<fs> copy-out /root/ostechnix/ /home/sk/Downloads/
In the above example, I am copying the /root/ostechnix/ directory to Downloads directory in the host system.
Download files to the host system
This is same as copy-out command.
Guestfish allows you to download and upload contents from guest machine to host machine and vice versa.
The general syntax to download files:
download <guest_file_location> <host_file_location>
The following command will download the “/etc/fstab” file from the guest machine to the /home/sk/Downloads/ directory in the KVM host system.
<fs> download /etc/fstab /home/sk/Downloads/fstab
Upload files from host system to guest system
This is same as copy-in command.
To upload a file from your host system to the guest machine, run:
><fs> upload /home/sk/Downloads/fstab /etc/fstab
Here, I am uploading /home/sk/Downloads/fstab file from my local system to /etc/fstab in the guest machine.
Display guestfish manual page
To display the man pages of guestfish:
To exit from guestfish shell, run:
What we have seen so far is we accessed, mounted, inspected and modified existing disk images. Guestfish can also help you to create new disk images instantly.
1.5. Creating new disk images
The following commands should be run outside of the guestfish shell. In other words, they should be run in your host terminal.
Remember we added the existing images using -a parameter? Yes. To create a new disk image, we are going to -N (–new) parameter.
To create a new disk image and automatically launch it, run the following command from the host terminal (not in the guestfish) prompt:
$ guestfish -N fs
This command will create a new disk named “test1.img” in the current directory and land you inside the guestfish prompt. This disk will contain a single partition, with an empty filesystem. By default, the disk size will be 1GB. If you run the same command next time, it will create a new disk named “test2.img” with size 1G and so on.
Instead of creating a fixed size 1G disk, It is possible to create a custom-sized disk image as well.
To create a blank 500MB disk, run:
$ guestfish -N disk:500M
You can also create a disk image formatted with specific file system. For instance, the following command will create a 1G disk with an ext4-formatted partition, called test1.img in the current directory:
$ guestfish -N fs:ext4
Create a 500MB disk with a VFAT-formatted partition, and mount it:
$ guestfish -N fs:vfat:500M -m /dev/sda1
Create a blank 500MB disk called blankdisk.img (instead of default name test1.img):
$ guestfish -N blankdisk.img=disk:500M
1.6. Adding remote disk images
Not just local disk images, we can also add disks located on a remote SSH, FTP, HTTP or TFTP server.
Add a disk located on a remote SSH server:
$ guestfish -a ssh://[email protected]/disk.img
Replace the username and IP address in the above command with your own.
Add a disk located on a remote FTP server:
$ guestfish -a ftp://[email protected]:port/disk.img
$ guestfish -a ftps://[email protected]:port/disk.img
Add a disk located on a remote HTTP server:
$ guestfish -a http://[email protected]:port/disk.img
$ guestfish -a https://[email protected]:port/disk.img
Add a disk located on a remote TFTP server:
$ guestfish -a tftp://[email protected]:port/disk.img
2. Access, View and modify disk images without entering into guestfish shell
Libguestfs provides many other equivalent commands to access, view and modify disk images, without actually entering into guestfish shell.
Guestmount command is used to mount a guest filesystem on the host using FUSE and libguestfs.
The following command will mount the centos8-uefi guest machine’s fulesystem in ~/guestvm/ in the host system.
$ mkdir ~/guestvm/
$ sudo guestmount -d centos8-uefi -i ~/guestvm/
Verify the contents of the mount directory:
$ sudo ls -l ~/guestvm
total 16 lrwxrwxrwx. 1 root root 7 May 11 2019 bin -> usr/bin dr-xr-xr-x. 6 root root 4096 Jul 18 15:46 boot drwxr-xr-x. 2 root root 6 Jul 18 15:23 dev drwxr-xr-x. 78 root root 8192 Jul 25 17:54 etc drwxr-xr-x. 2 root root 6 May 11 2019 home lrwxrwxrwx. 1 root root 7 May 11 2019 lib -> usr/lib lrwxrwxrwx. 1 root root 9 May 11 2019 lib64 -> usr/lib64 drwxr-xr-x. 2 root root 6 May 11 2019 media drwxr-xr-x. 2 root root 6 May 11 2019 mnt drwxr-xr-x. 2 root root 6 May 11 2019 opt drwxr-xr-x. 2 root root 6 Jul 18 15:23 proc dr-xr-x---. 2 root root 135 Jul 18 15:46 root drwxr-xr-x. 2 root root 6 Jul 18 15:23 run lrwxrwxrwx. 1 root root 8 May 11 2019 sbin -> usr/sbin drwxr-xr-x. 2 root root 6 May 11 2019 srv drwxr-xr-x. 2 root root 6 Jul 18 15:23 sys drwxrwxrwt. 7 root root 119 Jul 25 18:44 tmp drwxr-xr-x. 12 root root 144 Jul 18 15:24 usr drwxr-xr-x. 20 root root 278 Jul 18 15:45 var
To unmount it, run:
$ sudo umount ~/guestvm
For more details, refer man pages.
$ man guestmount
Virt-cat command isued to view the contents of a file stored in a disk image or virtual machine.
$ sudo virt-cat -a CentOS_8_Server.img /etc/fstab
$ sudo virt-cat -d centos8-uefi /etc/fstab
# # /etc/fstab # Created by anaconda on Sat Jul 18 05:53:25 2020 # # Accessible filesystems, by reference, are maintained under '/dev/disk/'. # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info. # # After editing this file, run 'systemctl daemon-reload' to update systemd # units generated from this file. # /dev/mapper/cl-root / xfs defaults 0 0 UUID=6a7f6481-5eb3-4589-ad19-b2291ddfcda1 /boot ext4 defaults 1 2 UUID=6906-5D0A /boot/efi vfat umask=0077,shortname=winnt 0 2 /dev/mapper/cl-swap swap swap defaults 0 0
Virt-copy-in command is used to copy files and directories from host to a disk image or virtual machine.
$ sudo virt-copy-in -a CentOS_8_Server.img ostechnix.txt /root/
$ sudo virt-copy-in -d centos8-uefi ostechnix.txt /root/
Virt-copy-out command is used to copy files and directories out of a disk image or virtual machine.
$ sudo virt-copy-out -a CentOS_8_Server.img /root/ostechnix.txt ~/Downloads
$ sudo virt-copy-in -d centos8-uefi /root/ostechnix.txt ~/Downloads
The above commands will copy the /root/ostechnix.txt file from the virtual machine disk to ~/Downloads directory in the local host system.
Virt-df command displays the free space on a guest machine filesystem.
View free space on a disk image:
$ sudo virt-df -a CentOS_8_Server.img
Filesystem Size Used Available Use% CentOS_8_Server.img:/dev/sda1 976M 260M 649M 27% CentOS_8_Server.img:/dev/cl/root 17G 1.4G 16G 9%
View disk space on a VM:
$ sudo virt-copy-in -d centos8-uefi /root/ostechnix.txt ~/Downloads
Filesystem Size Used Available Use% centos8-uefi:/dev/sda1 599M 6.6M 592M 2% centos8-uefi:/dev/sda2 976M 121M 788M 13% centos8-uefi:/dev/cl/root 16G 1.2G 15G 8%
Edit a file in a disk image or virtual machine.
$ sudo virt-edit -a CentOS_8_Server.img /root/ostechnix.txt
$ sudo virt-edit -d centos8-uefi /root/ostechnix.txt
This command will open the remote file in the default editor. Just make the changes and save and close the file.
List filesystems, partitions, block devices, LVM in a virtual machine or disk image.
$ sudo virt-filesystems -a CentOS_8_Server.img -l
$ sudo virt-filesystems -d centos8-uefi -l
Name Type VFS Label Size Parent /dev/sda1 filesystem vfat - 629145600 - /dev/sda2 filesystem ext4 - 1073741824 - /dev/cl/root filesystem xfs - 17620271104 -
To display partition details, add –partitions in the above command:
$ sudo virt-filesystems -d centos8-uefi --partitions /dev/sda1 /dev/sda2 /dev/sda3
Similarly, you can use –logical-volumes, –volume-groups, –physical-volumes, –block-devices to list those items.
Virt-inspector is used to display operating system version and other information about a disk image or virtual machine.
$ sudo virt-inspector -a CentOS_8_Server.img
$ sudo virt-inspector -d centos8-uefi
Virt-ls is used to display the files and directories and their sizes, attributes, checksums in a disk image or virtual machine.
$ sudo virt-ls -R -a CentOS_8_Server.img / | less
$ sudo virt-ls -R -d centos8-uefi /root
You can use most of the normal “ls” command options/flags with virt-ls command.
Virt-log is used to display the log files from a disk image or virtual machine.
$ sudo virt-log -a CentOS_8_Server.img
$ sudo virt-log -d centos8-uefi
Virt-tail command is used to follow log files in a disk image or a virtual machine.
$ sudo virt-tail -a CentOS_8_Server.img /var/log/messages
$ sudo virt-tail -d centos8-uefi /var/log/messages
There are many more commands available. I suggest you to refer the libguestfs website linked at the end of this guide.
Here are the solutions for a few common issues.
1. libguestfs doesn’t work without root permissions on Ubuntu
You might be encountered with this error when trying to access the disk images on Ubuntu:
libguestfs: error: /usr/bin/supermin exited with error status 1. To see full error messages you may need to enable debugging. Do: export LIBGUESTFS_DEBUG=1 LIBGUESTFS_TRACE=1 and run the command again. For further information, read: http://libguestfs.org/guestfs-faq.1.html#debugging-libguestfs
To fix this issue, run:
$ sudo chmod 0644 /boot/vmlinuz*
You may need to add yourself to the kvm group:
$ sudo usermod -a -G kvm sk
Replace “sk” in the above command with your own user name.
- If you already have installed libvirt or KVM on your system and try to use libguesfs tools as root user, you should see this permission error:
libguestfs: error: could not create appliance through libvirt. Try running qemu directly without libvirt using this environment variable: export LIBGUESTFS_BACKEND=direct Original error from libvirt: Cannot access backing file '/root/CentOS_8_Server.qcow2' of storage file '/tmp/libguestfsiPjmga/overlay1.qcow2' (as uid:107, gid:107): Permission denied [code=38 int1=13]
This is caused by libvirt, and so only happens when using the libvirt backend. To fix this, switch to the direct backend by setting this environment variable:
To make it permanently, add this line to your ~/.bashrc file.