Tag Archives: guestfs

Tip: libguestfs API: Get the mounted device from a path

This useful libguestfs API tip shows you how to get the device name that contains a mounted path. You can use this if you want to find out the filesystem type of a path (eg. is this directory mounted on ext4?).

What you do is call guestfs_mountpoints which returns a hash of device name to mount point, eg:

/dev/sda1 -> /boot
/dev/sda2 -> /
/dev/sda3 -> /usr

Then compare the pathname (“/boot/grub”) to each entry in the hash. If the mountpoint is a string prefix of the path, give this entry a score which is the length of the mountpoint string. If it is not a prefix, give the entry a score 0. So:

/dev/sda1 -> /boot (score: 5)
/dev/sda2 -> / (score: 1)
/dev/sda3 -> /usr (score: 0)

Then sort the entries to pick the highest score. If the hash is empty or the highest score is 0, then return an error, otherwise return the device with the highest score.

Here is the code to implement this in OCaml:

open Printf
open ExtString
open ExtList

let get_mounted_device g path =
  let mps = g#mountpoints () in
  let mps = List.map (
    fun (dev, mp) ->
      if String.starts_with path mp then
        dev, String.length mp
      else
        dev, 0
  ) mps in
  let cmp (_,n1) (_,n2) = compare n2 n1 in
  let mps = List.sort ~cmp mps in
  match mps with
  | [] ->
      invalid_arg (sprintf "%s: not mounted" path)
  | (_,0) :: _ ->
      invalid_arg (sprintf "%s: not found on any filesystem" path)
  | (dev,_) :: _ -> dev

To answer the question “is this directory mounted on ext4?” you would then call guestfs_vfs_type on the result of this, eg:

if g#vfs_type (get_mounted_device g "/boot/grub") = "ext4" then
  (* do something based on ext4 *)

Leave a comment

Filed under Uncategorized

libguestfs 0.8, now with fewer bugs :-)

I released libguestfs 0.8 yesterday, the library for accessing virtual machines. This version fixes a large number of bugs, because I wrote a test suite which sends several hundred commands through the library and verifies the results. Took a couple of days to fix all the bugs this found …

Here are some interesting things you can do with guestfish.

1: Just find out what’s in a virtual machine:

$ guestfish -a RHEL52PV32.img run : list-devices
/dev/sda
$ guestfish -a RHEL52PV32.img run : list-partitions
/dev/sda1
/dev/sda2
$ guestfish -a RHEL52PV32.img run : lvs
/dev/VolGroup00/LogVol00
/dev/VolGroup00/LogVol01

2: Make virtual machine filesystems containing partitions, LVM, filesystems and whatever else you want:

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

Type: 'help' for help with commands
      'quit' to quit the shell

><fs> alloc /tmp/test 500M
><fs> run
><fs> pvcreate /dev/sda
><fs> vgcreate VG /dev/sda
><fs> vgs
VG
><fs> lvcreate LV VG 250
><fs> lvs
/dev/VG/LV
><fs> mkfs ext3 /dev/VG/LV
><fs> mount /dev/VG/LV /
><fs> touch /myfile
><fs> ll /
total 13
drwxr-xr-x  3 root root  1024 Apr 12 17:19 .
drwxr-xr-x 18 root root     0 Apr 12 17:15 ..
drwx------  2 root root 12288 Apr 12 17:19 lost+found
-rw-r--r--  1 root root     0 Apr 12 17:19 myfile
><fs> sync
><fs> quit
$ ll /tmp/test
-rw-rw-r--. 1 rjones rjones 524288000 2009-04-12 22:19 /tmp/test
$ file /tmp/test
/tmp/test: LVM2 (Linux Logical Volume Manager) , UUID: bhL0DP0rySspzviDKHN7TZABBcfTWuo

3: Use Augeas to edit configuration files:

$ guestfish -a RHEL52PV32.img -m /dev/VolGroup00/LogVol00
  
  Welcome to guestfish, the libguestfs filesystem interactive shell for
  editing virtual machine filesystems.
  
  Type: 'help' for help with commands
        'quit' to quit the shell
  
><fs> aug-init / 0
><fs> aug-match /augeas/*
/augeas/root
/augeas/save
/augeas/files
><fs> aug-match /files//error
><fs> aug-match /augeas//error
><fs> aug-match /augeas/root/*
><fs> aug-match /files/etc/*
/files/etc/ldap.conf
/files/etc/aliases
/files/etc/yum.repos.d
/files/etc/yum.conf
/files/etc/sysconfig
[etc]
><fs> aug-match /files/etc/hosts/*
/files/etc/hosts/comment[1]
/files/etc/hosts/comment[2]
/files/etc/hosts/1
/files/etc/hosts/2
><fs> cat /etc/hosts               
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1      	       localhost.localdomain localhost
::1		               localhost6.localdomain6 localhost6
><fs> aug-get /files/etc/hosts/comment[1]
Do not remove the following line, or various programs
><fs> help aug-insert
aug-insert - insert a sibling Augeas node
       aug-insert   
  
      Create a new sibling "label" for "path", inserting it into the tree
      before or after "path" (depending on the boolean flag "before").
  
      "path" must match exactly one existing node in the tree, and "label"
      must be a label, ie. not contain "/", "*" or end with a bracketed index
      "[N]".
  
><fs> aug-insert /files/etc/hosts/comment[2] comment false
><fs> aug-match /files/etc/hosts/*
/files/etc/hosts/comment[1]
/files/etc/hosts/comment[2]
/files/etc/hosts/comment[3]
/files/etc/hosts/1
/files/etc/hosts/2
><fs> aug-set /files/etc/hosts/comment[3] HELLO
><fs> aug-save
><fs> cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
# HELLO
127.0.0.1		localhost.localdomain localhost
::1			localhost6.localdomain6 localhost6

There are C, C++, shell, Perl and OCaml bindings for all of these calls, and you don’t need to be root to do any of it.

Leave a comment

Filed under Uncategorized

libguestfs: LVM support

libguestfs is the library I’m writing that lets you examine and modify any virtual machine disk image, offline or online.

I spent about 18 hours finding a bug in the LVM parsing code, but that bug has now been squashed and as of version 0.4 on the website you can examine PVs, VGs and LVs, as well as listing devices and partitions.

Next up: language bindings for Perl, OCaml and Python.
(C and C++ and shell scripting access already exist).

$ guestfish 

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

Type: 'help' for help with commands
      'quit' to quit the shell

><fs> add /mnt/share/tmp/RHEL52PV32.img
><fs> run
><fs> pvs
/dev/sda2
><fs> lvs
/dev/VolGroup00/LogVol00
/dev/VolGroup00/LogVol01
><fs> mount /dev/VolGroup00/LogVol00 /
><fs> ls /
bin
boot
dev
etc
home
[...]

Leave a comment

Filed under Uncategorized