Tag Archives: guestmount

libguestfs on RHEL 5

I’ve spent the past couple of weeks [sic] getting a modern libguestfs into RHEL 5. RHEL 5 was first released in March 2007 and is thus over 5 years old.

It’s hard work.

Firstly RHEL 5 lacks virtio-serial, which is the mechanism used by the library to talk to the appliance. We used to use a TCP connection, but we gave that up since it’s slow, awkward and possibly insecure. To get RHEL 5 going again, I had to forward port the old TCP code into a modern branch of libguestfs.

Secondly RHEL 5 lacks a lot of features that libguestfs presents through the API. I got most of them working by carefully fixing and rewriting code, but some of them are impossible to do (eg. btrfs support).

Altogether I wrote about 30 patches, with about half going upstream, and the other half sitting in an “old Linux”-only side branch.

The release notes are attached below, and the packages should be available in EPEL 5 in a few days.

libguestfs for EPEL 5
by Richard W.M. Jones

This package contains modern libguestfs for EPEL 5. Although libguestfs is supplied in RHEL 5, the version supplied is very old and is only intended to be used with virt-v2v from RHEL 5. It is only available in the RHEL-5-V2V channel.

Therefore there exists a need for a modern libguestfs for RHEL 5 users. This package supplies this through the community-supported EPEL repository.

(1) Installation

After enabling the EPEL repository, install libguestfs in the normal way using yum. No post-installation configuration should be needed.

You must have a non-Xen kernel installed on the host. Note that the non-Xen kernel just needs to be installed, it does *not* need to be running (you can run libguestfs under Xen if you want). The non-Xen kernel is used to boot the libguestfs appliance.

You must use this package together with the version of qemu-kvm from RHEL 5 (usually called kvm-83-NNN.el5). Alternate versions of qemu, KVM, using $LIBGUESTFS_QEMU or QEMU wrappers, will probably not work.

Hardware virtualization will greatly improve the performance of libguestfs, but it is not required. libguestfs cannot use hardware virtualization when run in a Xen domain (not even dom0). For more performance tips, read guestfs-performance(1).

(2) Getting help

This package is supported voluntarily by the EPEL community and by the upstream libguestfs maintainers.

It is not supported by Red Hat.

It cannot be used with the virt-v2v package from RHEL 5. If you need to use virt-v2v on RHEL 5, use the libguestfs package from the same RHN channel. However we would advise you to use RHEL 6 or later because that version of virt-v2v is substantially more powerful.

To get help with this package, contact the libguestfs maintainers. See http://libguestfs.org for links to the mailing list, IRC, and how to file bugs.

(3) Features not available

The following features are not compatible with RHEL 5 and have been removed completely:

  • PHP bindings
  • GObject, GObject introspection, anything that uses GObject Introspection such as the Javascript bindings
  • Erlang bindings
  • The btrfs filesystem.
  • guestfs_fstrim
  • guestfs_wipefs
  • Various APIs that take UUIDs (eg. guestfs_mkswap_U)
  • virtio-scsi
  • Internationalization of any non-C programs.

(4) Features that may not work

The following features may not work in this version of libguestfs:

  • LUKS (encrypted filesystems within guests)
  • MD (RAID devices within guests)
  • FUSE, guestmount, the mount-local API. These appear to have some problems because of the older version of FUSE in RHEL 5.
  • virt-sysprep --script option (because it requires FUSE).
  • The ntfsclone_* APIs only partially work. In particular, the metadataonly flag is not working, and maybe other parts of this API won’t work.
  • guestfs_vfs_label cannot read labels from NTFS filesystems.
  • guestfs_blkid may return fewer fields than expected on a more modern Linux system.
  • guestfs_txz_in and guestfs_txz_out don’t work.
  • guestfs_utimens doesn’t let you set the time on a symbolic link (this is a limitation of the RHEL 5 kernel).
  • guestfs_mkswap_label followed by guestfs_swapon_label does not work. The reasons are not well understood.
  • Adding drives using non-virtio-blk interfaces.

(5) Other notes

An artificial pause of 1 second has been added after unmounting any filesystem.

*Without* the 1 second pause, the following test case will fail sometimes:

  guestfish <<EOF
  sparse test1.img 1G
  part-disk /dev/sda mbr
  mkfs msdos /dev/sda1
  mount /dev/sda1 /
  touch /foo
  umount /
  mkfs ntfs /dev/sda1
  # Next command would fail:
  mount /dev/sda1 /
  vfs-type /dev/sda1 -x

With the 1 second pause, this case passes. The reason is not understood.


Leave a comment

Filed under Uncategorized

Tip: Using mount-local API from C

Previously if you wanted to mount a disk image on the host from libguestfs, you had to use a separate program called guestmount.

A couple of months ago, we added FUSE support directly into the libguestfs API, and rewrote guestmount to use it. This also means you can use FUSE from your own libguestfs programs.

Yesterday I wrote a short example of using the mount-local API from C. This program creates a new disk image, formats it etc using libguestfs, then gives you a subshell so you can copy your own files, directories etc. in. When you quit the subshell, the disk image is synced and closed, and you end up with a virtual disk image containing all the files you just added. (Nothing that you couldn’t easily do before, but a nice little demonstration anyway).

Here it is in use:

$ gcc -Wall mount_local.c -o mount_local -lguestfs
$ ./mount_local /tmp/test.img

This is the 'mount-local' demonstration program.  Follow the
instructions on screen.

Creating and formatting the disk image, please wait a moment ...

The _current directory_ is a FUSE filesystem backed by the disk
image which is managed by libguestfs.  Any files or directories
you copy into here (up to 512 MB) will be saved into the disk
image.  You can also delete files, create certain special files
and so on.

When you have finished adding files, hit ^D or exit to exit the
shell and return to the mount-local program.

mount-local-shell> ls

From the subshell, I copy in some files:

mount-local-shell> cp -a /usr/share/doc/libguestfs-devel-1.17.40/ .
mount-local-shell> ls
libguestfs-devel-1.17.40  lost+found  PUT_FILES_AND_DIRECTORIES_HERE
mount-local-shell> ls libguestfs-devel-1.17.40/
AUTHORS			       example-ubuntu.xml
BUGS			       example-windows-2003-x64-cd.xml
ChangeLog		       example-windows-2003-x86-cd.xml
copy_over.c		       example-windows.xml
create_disk.c		       example-windows-xp-cd.xml
display_icon.c		       HACKING
example-debian-netinst-cd.xml  inspect_vm.c
example-debian.xml	       README
example-fedora-dvd.xml	       RELEASE-NOTES
example-fedora-netinst-cd.xml  ROADMAP
example-fedora.xml	       TODO
example-rhel-6-dvd.xml	       virt-dhcp-address.c
example-rhel-6-netinst-cd.xml  virt-inspector.rng

After copying in my files, I exit from the subshell:

mount-local-shell> exit

Any files or directories that you copied in have been saved into
the disk image called '/tmp/test.img'.

Try opening the disk image with guestfish to see those files:

  guestfish -a /tmp/test.img -m /dev/sda1

Here is the disk image that was created (note it is sparse, so it’s not really so large as it appears):

$ ll /tmp/test.img
-rw-r--r--. 1 rjones rjones 536870912 May 14 12:03 /tmp/test.img
$ du -sh /tmp/test.img
18M	/tmp/test.img

We can use guestfish to look inside it:

$ guestfish -a /tmp/test.img -m /dev/sda1

Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems.

Type: 'help' for help on commands
      'man' to read the manual
      'quit' to quit the shell

><fs> ll /
total 18
drwxr-xr-x  4 root root  1024 May 14 12:03 .
drwxr-xr-x 23 1000 1000  4096 May 14 12:18 ..
-rw-r--r--  1 root root     0 May 14 12:03 PUT_FILES_AND_DIRECTORIES_HERE
drwxr-xr-x  2 root root  1024 May 14 08:37 libguestfs-devel-1.17.40
drwx------  2 root root 12288 May 14 12:03 lost+found

Download the test program here: https://github.com/libguestfs/libguestfs/blob/master/examples/mount_local.c

Leave a comment

Filed under Uncategorized

libguestfs: mount local

New in libguestfs ≥ 1.17.22 is the ability to mount the guest filesystem on a local mountpoint. Well, you can already do that using guestmount, but the new thing is that you can do it from the API (from any language).

Here is an example using guestfish:

$ guestfish --ro -a /dev/vg_pin/F16x64 -i
Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems.

Type: 'help' for help on commands
      'man' to read the manual
      'quit' to quit the shell

Operating system: Fedora release 16 (Verne)
/dev/vg_f16x64/lv_root mounted on /
/dev/vda2 mounted on /boot

><fs> ! mkdir /tmp/mnt # creates a local directory
><fs> mount-local /tmp/mnt readonly:true
><fs> mount-local-run
# the errors come from a GNOME daemon that
# looks at all new mountpoints
libguestfs: error: lstat: /.Trash: No such file or directory
libguestfs: error: lstat: /.Trash-500: No such file or directory

Over in another terminal, we can see the filesystem mounted on the local directory /tmp/mnt:

$ ls /tmp/mnt
bin   dev  home  lib64       media  opt   root  sbin     srv  tmp  var
boot  etc  lib   lost+found  mnt    proc  run   selinux  sys  usr
$ cat /tmp/mnt/etc/redhat-release
Fedora release 16 (Verne)

Unmounting the filesystem causes the guestfish mount-local-run command to return (since that command was actually serving the FUSE requests from the kernel).

$ fusermount -u /tmp/mnt


Filed under Uncategorized

guestmount –live option

In libguestfs ≥ 1.13.26 you can finally use the guestmount --live option.

This option lets you mount the filesystem from a running virtual machine on your host (using FUSE). Reads and writes are handled by a daemon running inside the VM. Writes are permitted and you see guest changes in real time.

By the way, although this is fun, it’s still a bit of a baby-eater, so use with care. At the moment you need identical versions of libguestfs in the guest and host, but we will relax this restriction later.

# guestmount -d FedoraRawhidex64 --live /tmp/mnt
# ls /tmp/mnt/tmp # /tmp in the guest
foo                                  mallocing-threads
glibc-2.14.90-13.i686.rpm            mallocing-threads.c
glibc-2.14.90-13.src.rpm             nscd-2.14.90-13.i686.rpm
glibc-2.14.90-13.x86_64.rpm          nscd-2.14.90-13.x86_64.rpm
glibc-common-2.14.90-13.i686.rpm     ssh-ItDNrg1065
glibc-common-2.14.90-13.x86_64.rpm   ssh-RXAApq5656
glibc-devel-2.14.90-13.i686.rpm      ssh-SfeREo1125
glibc-devel-2.14.90-13.x86_64.rpm    ssh-xwLmEq1043
glibc-headers-2.14.90-13.i686.rpm    ssh-zZMbMr1430
glibc-headers-2.14.90-13.x86_64.rpm  valgrind.txt
glibc-static-2.14.90-13.i686.rpm     yum_save_tx-2011-10-24-16-250zmRGr.yumtx
glibc-static-2.14.90-13.x86_64.rpm   yum_save_tx-2011-10-24-16-31IMbTq9.yumtx
glibc-utils-2.14.90-13.i686.rpm      yum_save_tx-2011-10-24-16-31lPnb8j.yumtx
glibc-utils-2.14.90-13.x86_64.rpm    yum_save_tx-2011-10-24-16-33F1Fkj_.yumtx


Filed under Uncategorized

Tip: Open VirtualBox VDI file using libguestfs

Not much of a tip, but I was playing with VirtualBox today and I noticed that qemu supports VirtualBox’s native disk format, VDI. This means you can just open, mount etc these *.vdi files directly using guestfish, guestmount and the other libguestfs tools.

$ guestfish --ro -i -a fedora-test.vdi

Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems.

Type: 'help' for a list of commands
      'man' to read the manual
      'quit' to quit the shell

Operating system: Fedora release 13 (Goddard)
/dev/mapper/vg_fedoravbox-lv_root mounted on /
/dev/vda1 mounted on /boot

><fs> cat /etc/issue
Fedora release 13 (Goddard)
Kernel \r on an \m (\l)
><fs> exit
$ virt-df -h fedora-test.vdi
Filesystem                                Size       Used  Available  Use%
fedora-test.vdi:/dev/sda1               484.2M      27.0M     432.2M    6%
                                          2.6G       2.0G     616.3M   76%
$ virt-tar -xz fedora-test.vdi /home /tmp/home.tar.gz
$ zcat /tmp/home.tar.gz | tar tf -
$ cd /tmp
$ mkdir mnt
$ guestmount --ro -a fedora-test.vdi -m /dev/vg_fedoravbox/lv_root mnt/
$ ls mnt/
bin   dev  home  lost+found  mnt  proc  sbin     srv  tmp  var
boot  etc  lib   media       opt  root  selinux  sys  usr
$ fusermount -u /tmp/mnt

I like it when stuff just works for free!

1 Comment

Filed under Uncategorized

libguestfs binaries for all Linux distros

I uploaded some distro-independent Linux/x86-64 binaries of libguestfs, guestfish, guestmount and the virt-* tools. Be sure to read the README file first.

These are a little experimental and I’d welcome feedback. I got them to work fine on Debian 5.0 after upgrading glibc and Perl, but YMMV.

Update: OpenSUSE 11.3 working.

The version of KVM supplied is too old (doesn’t support virtio-serial) so I had to compile qemu from git and drop the following qemu wrapper in place:

#!/bin/sh -
exec $qemudir/x86_64-softmmu/qemu-system-x86_64 -L $qemudir/pc-bios "$@"

The next problem which had me confused for a very long time was that qemu kept aborting while allocating memory. After trying things like adding swap, playing with overcommit settings and so on, it turned out that SUSE uses some really silly, and very small default ulimits for virtual memory. You have to do:

ulimit -Hv unlimited
ulimit -Sv unlimited
ulimit -Hm unlimited
ulimit -Sm unlimited

Update: Ubuntu 10.04 working.

As with SUSE, the version of KVM shipped by Ubuntu is too old to support virtio-serial. All I had to do was replace it with qemu from git and the same qemu wrapper above.

After that guestfish works fine.

If you need the Perl tools, then you have to upgrade Perl to 5.12.1, install hivex, and link libpcre.so.0 -> libpcre.so.3.

Leave a comment

Filed under Uncategorized

KDE Filelight with guestmount

Prompted by Adam Williamson’s comment, I decided to see if we can use filelight on a guestmount (FUSE-mounted) virtual machine.

Obviously the answer is yes, but it’s pretty slow. It took a few minutes for filelight to scan /usr/share/doc from the virtual machine (about 5300 files). I gave up on scanning the whole VM disk.

The reason is that filelight makes ordinary system calls to scan the disk. These are redirected through the magic of FUSE through to discrete libguestfs calls into the appliance (see the libguestfs architecture diagram here). Compare that to the “du” example which is far more efficient — a single “du” message is sent to the appliance which then processes everything internally before sending a single response message back. The du command is far faster, even though it must be doing roughly the same amount of work.

If filelight (or baobab) was able to make native libguestfs calls, then we could make it a lot more efficient.

1 Comment

Filed under Uncategorized