Category Archives: Uncategorized

Use libguestfs to mount arbitrary disk images with FUSE

You can use guestmount to mount most virtual machine disk images on the host using FUSE.

However guestmount doesn’t work well for disk images that just consist of a pile of partitions.

But libguestfs at the API level has no problem, and we can write a script using the mount-local API to expose it, like this one:

#!/usr/bin/perl -w

use strict;
use Sys::Guestfs;

if (@ARGV != 2) {
    print "$0 disk-image mount-point\n";
    exit 1

die "$ARGV[1] must be a directory (mount point)" unless -d $ARGV[1];

print "Examining the disk $ARGV[0].\n";
print "Please wait a moment ...\n";
my $g = Sys::Guestfs->new ();
$g->add_drive ($ARGV[0]);
$g->launch ();

# List the filesystems.
my %fses = $g->list_filesystems ();

my $mounts = 0;

# Mount them on mountpoints in the libguestfs namespace.
foreach my $dev (sort keys %fses) {
    my $t = $fses{$dev};
    if ($t eq "unknown" || $t eq "swap") {
        print "ignored $t partition $dev\n";
    else {
        # Make a mountpoint.
        my $mp = $dev;
        $mp =~ s{^/}{};
        $mp =~ s{/}{_}g;
        $g->mkmountpoint ("/" . $mp);
        eval { $g->mount ($dev, "/" . $mp); };
        if ($@) {
            print "ignored unmountable partition $dev\n";
        } else {
            print "mounted $dev on $ARGV[1]/$mp\n";

if ($mounts == 0) {
    print "No mountable filesystems were found in this disk image.\n";
    print "Suggest using `guestfish' or `virt-filesystems' on the disk image.\n";
    exit 1;

# Now start the FUSE service.
$g->mount_local ($ARGV[1]);

print "\n";
print "Mounted on $ARGV[1] ...\n";
print "Run the following command to end the FUSE service:\n";
print "    guestunmount $ARGV[1]\n";

$g->mount_local_run ();

# Unmounted ...
$g->shutdown ();
$g->close ();

When you run this you will see each partition, logical volume or other mountable filesystem from the disk image exposed as a separate directory under the mountpoint, like this:

$ ls
dev_VG_LV1            # this is /dev/VG/LV1
$ cd dev_VG_LV1
$ ls -ltr
total 12
drwx------. 2 root root 12288 Aug  8 18:15 lost+found
-rw-r--r--. 1 root root     0 Aug  8 18:34 foo
-rw-r--r--. 1 root root     0 Aug  8 18:35 hello

Leave a comment

Filed under Uncategorized

libguestfs now works on 64 bit ARM


Pictured above is my 64 bit ARM server. It’s under NDA so I cannot tell you who supplied it or even show you a proper photo.

However it runs Fedora 21 & Rawhide:

Linux 3.16.0-0.rc6.git1.1.efirtcfix1.fc22.aarch64 #1 SMP Wed Jul 23 12:15:58 BST 2014 aarch64 aarch64 aarch64 GNU/Linux

libvirt and libguestfs run fine, with full KVM acceleration, although right now you have to use qemu from git as the Rawhide version of qemu is not new enough.

Also OCaml 4.02.0 beta works (after we found and fixed a few bugs in the arm64 native code generator last week).


Filed under Uncategorized

New(ish) in libguestfs 1.27.23 — add firstboot batch files to Windows guests

You’ve been able to do this for a while by hand but now virt-sysprep & virt-customize ≥ 1.27.23 let you easily install firstboot scripts into Windows guests:

$ cat /tmp/test.bat
echo Hello I am a batch file
$ virt-customize -a win7.qcow2 --firstboot /tmp/test.bat

Next time the guest boots, check the log file in C:\Program Files\Red Hat\Firstboot\log.txt

This works well for me in Windows 7 guests. It ought to work in other Windows guests too. So far the only other Windows flavour I tested was W2K3 where the service crashed for some unfathomable reason (I’m not very patient with debugging Windows problems).

So let us know how it goes and we’ll try to fix the bugs as we go along.

Leave a comment

Filed under Uncategorized

Tip: Use gdbserver to debug qemu running under libguestfs

If qemu crashes or fails when run under libguestfs, it can be a bit hard to debug things. However a small qemu wrapper and gdbserver can help.

Create a file called qemu-wrapper chmod +x and containing:

#!/bin/bash -

if ! echo "$@" | grep -sqE -- '-help|-version|-device \?' ; then
  gdbserver="gdbserver :1234"

exec $gdbserver /usr/bin/qemu-system-x86_64 "$@"

Set your environment variables so libguestfs will use the qemu wrapper instead of running qemu directly:

$ export LIBGUESTFS_BACKEND=direct
$ export LIBGUESTFS_HV=/path/to/qemu-wrapper

Now we run guestfish or another virt tool as normal:

$ guestfish -a /dev/null -v -x run

When qemu starts up, gdbserver will run and halt the process, printing:

Listening on port 1234

At this point you can connect gdb:

$ gdb
(gdb) file /usr/bin/qemu-system-x86_64
(gdb) target remote tcp::1234
set breakpoints etc here
(gdb) cont

Leave a comment

Filed under Uncategorized

Baremetal Raspberry Pi OS based on JONESFORTH

Go here:

Leave a comment

Filed under Uncategorized

Which services need restarting after an upgrade?

After you’ve run yum update to upgrade libraries, there may be services running which are still using the old copies of libraries. Such services might still be vulnerable to security bugs in the old libraries.

It’s relatively easy to discover which processes are affected using lsof to list processes using deleted files:

# lsof | awk '$5 == "DEL" { print }'
auditd     1001  1001 root DEL REG /usr/lib64/;53bd9626
libvirtd   1468  1509 root DEL REG /usr/lib64/;53bd9626
[lots more output]

If you actually run this command after updating (say) glibc, you’ll get pages and pages of output which is hard to sift through.

However with systemd we can map the process IDs to services and user sessions.

That’s what the following script does:

Typical output looks like this:

In order to complete the installation of glibc-2.18-11.fc20.x86_64,
you should restart the following services:

    - accounts-daemon.service - Accounts Service   
    - console-kit-daemon.service - Console Manager
    - udisks2.service - Disk Manager
    - auditd.service - Security Auditing Service
    - dbus.service - D-Bus System Message Bus
    - rtkit-daemon.service - RealtimeKit Scheduling Policy Service
    - upower.service - Daemon for power management
    - colord.service - Manage, Install and Generate Color Profiles
    - firewalld.service - firewalld - dynamic firewall daemon
    - polkit.service - Authorization Manager
    - rsyslog.service - System Logging Service 
    - NetworkManager.service - Network Manager   
    - libvirtd.service - Virtualization daemon
    - gdm.service - GNOME Display Manager

In order to complete the installation of glibc-2.18-11.fc20.x86_64,
you should tell the following users to log out and log in:

    - session-1.scope - Session 1 of user rjones


Filed under Uncategorized

CentOS 7

CentOS 7 is out.

Although there are no cloud images available right now, I have put up a virt-builder image, so you can install CentOS 7 right now just by doing:

$ virt-builder centos-7.0

Leave a comment

Filed under Uncategorized