# Short introduction to libguestfs

by Richard W.M. Jones <rjones@redhat.com>

## The Idea

Reuse qemu, Linux kernel and userspace tools to read and write disk images.

## The Stable API

      /* get the Linux VFS type corresponding to a mounted device */
    extern char *guestfs_vfs_type (guestfs_h *g, const char *device);

Example using this API: |
    #include <guestfs.h>

    char *fstype = guestfs_vfs_type (g, "/dev/vda1");
    printf ("%s\n", fstype);
    free (fstype);
    → ntfs
click to see a real example ...

      ("vfs_type",
       (RString "fstype",
            [Device "device"], []),
       198, [],
       [ (* tests *) ],
       "get the Linux VFS type corresponding to a mounted device",
       "\
    This command gets the filesystem type corresponding to
    the filesystem on C<device>.

    For most filesystems, the result is the name of the Linux
    VFS module which would be used to mount this filesystem
    if you mounted it without specifying the filesystem type.
    For example a string such as C<ext3> or C<ntfs>.");
full source ... |
    char *
    do_vfs_type (const char *device)
    {
      return get_blkid_tag (device, "TYPE");
    }

    GUESTFSD_EXT_CMD(str_blkid, blkid);
    static char *
    get_blkid_tag (const char *device, const char *tag)
    {
      char *out, *err;
      int r;

      r = commandr (&out, &err,
                    str_blkid,
                    "-c", "/dev/null",
                    "-o", "value", "-s", tag, device, NULL);
      if (r != 0 && r != 2) {
        if (r >= 0)
          reply_with_error ("%s: %s (blkid returned %d)",
                            device, err, r);
        else
          reply_with_error ("%s: %s", device, err);
        free (out);
        free (err);
        return NULL;
      }

      /* ... */

      return out;             /* caller frees */
    }
full source ...

Just these two fragments generate:

- bindings in C, Perl, Python, Ruby, Java, OCaml, PHP, Haskell, Erlang and C#
- guestfish (shell script)
- documentation in man pages and HTML
- internal RPC code

## Tools written around the API

    guestfish -N bootrootlv:/dev/VG/LV:ext4:ext4:10G:256M <<EOF
      mount /dev/VG/LV /
      mkdir /boot
      mount /dev/sda1 /boot
      txz-in filesystem.tar.xz /
      write /etc/HOSTNAME "test01.example.com\n"
      upload /etc/resolv.conf /etc/resolv.conf
    EOF
    guestmount -a test1.img -i mnt/
    ls mnt
    bin   dev  home        lib         mnt       proc  sbin  tmp  var
    boot  etc  initrd.img  lost+found  old-root  root  sys   usr  vmlinuz
    cat mnt/etc/HOSTNAME
    test01.example.com
    fusermount -u mnt
manual for guestfish ... manual for guestmount ...
    virt-df -a /dev/vg/F15x32 -h
    Filesystem                    Size  Used Available Use%
    F15x32:/dev/sda1              484M   31M      428M   7%
    F15x32:/dev/vg_f15x32/lv_root 5.5G  3.4G      1.8G  63%
manual ... |
    virt-cat -c qemu:///system -d WinXP 'c:\boot.ini'
    [boot loader]
    timeout=30
    default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
    [operating systems]
    multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=
    "Microsoft Windows XP Professional" /noexecute=optin
    /fastdetect
manual ...
    virt-edit -c qemu:///system -d F15x32 /etc/passwd
    (launches text editor to edit guest /etc/passwd)

    virt-edit -c qemu:///system -d F15x32 /etc/passwd \
      -e 's/^root:.*?:/root::/'
manual ... |
    virt-win-reg -c qemu:///system --unsafe-printable-strings \
      Win7x32 'HKLM\SYSTEM\ControlSet001\Services\Tcpip\Parameters' \
      | grep DhcpIPAddress
    "DhcpIPAddress"=str(1):"192.168.122.178"
manual ...

## Inspection

    $ virt-filesystems -c qemu:///system -d Win7x32 --all --long -h --uuid
    Name      Type       VFS  Label           MBR Size Parent   UUID
    /dev/sda1 filesystem ntfs System Reserved -   100M -        F81C92571C92112C
    /dev/sda2 filesystem ntfs -               -   20G  -        F2E8996AE8992E3B
    /dev/sda1 partition  -    -               07  100M /dev/sda -
    /dev/sda2 partition  -    -               07  20G  /dev/sda -
    /dev/sda  device     -    -               -   20G  -        -

manual ...

    $ virt-inspector -c qemu:///system -d Win7x32
    <?xml version="1.0"?>
    <operatingsystems>
      <operatingsystem>
        <root>/dev/sda2</root>
        <name>windows</name>
        <arch>i386</arch>
        <distro>windows</distro>
        <product_name>Windows 7 Enterprise</product_name>
        <product_variant>Client</product_variant>
        <major_version>6</major_version>
        <minor_version>1</minor_version>
        <windows_systemroot>/Windows</windows_systemroot>
        <windows_current_control_set>ControlSet001</windows_current_control_set>
        <hostname>win7x32</hostname>
    ... etc ...

full XML ...
manual ...

      char **roots;
      size_t i;
      char *type, *distro, *product_name;
      int major, minor;

      roots = guestfs_inspect_os (g);

      if (roots == NULL)
        exit (EXIT_FAILURE);

      if (roots[0] == NULL) {
        fprintf (stderr, "no operating systems found\n");
        exit (EXIT_FAILURE);
      }

      for (i = 0; roots[i] != NULL; ++i) {
        type = guestfs_inspect_get_type (g, roots[i]);
        distro = guestfs_inspect_get_distro (g, roots[i]);
        product_name = guestfs_inspect_get_product_name (g, roots[i]);
        major = guestfs_inspect_get_major_version (g, roots[i]);
        minor = guestfs_inspect_get_minor_version (g, roots[i]);

        printf ("Root: %s\n"
                "  Type: %s\n"
                "  Distro: %s\n"
                "  Version: %d.%d\n"
                "  Product name: %s\n\n");
                roots[i],
                type ? : "unknown", distro ? : "unknown", major, minor,
                product_name ? : "");

        free (type);
        free (distro);
        free (product_name);
        free (roots[i]);
      }

      free (roots);

full source ...

Click to enlarge the images

## Graphical browsers

source ...

source ...

## Find out more ...

libguestfs.org is the main website.

guestfs(3) is the manual page documenting the C API and the internals.

There are manual pages documenting guestfish, guestmount and each virt tool. See the main website or your local man command.

For information about virt-v2v and virt-p2v, see http://libguestfs.org/virt-v2v/

This page © 2011 Red Hat Inc. and distributed under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.