diff options
author | Richard Jones <rjones@redhat.com> | 2010-07-30 16:32:35 +0100 |
---|---|---|
committer | Richard Jones <rjones@redhat.com> | 2010-07-30 16:32:35 +0100 |
commit | 6280ac9b987c14f89749b4b4fdfec5a647567432 (patch) | |
tree | 343d127f4ac0abed347a6f937799994efd95be5e /daemon | |
parent | 737181bcd7b1de8c3a613d6282030c34efa78fb6 (diff) | |
download | libguestfs-6280ac9b987c14f89749b4b4fdfec5a647567432.tar.gz libguestfs-6280ac9b987c14f89749b4b4fdfec5a647567432.tar.xz libguestfs-6280ac9b987c14f89749b4b4fdfec5a647567432.zip |
New API: is-lv: check if a block device is a logical volume (RHBZ#619793)
This adds a new API, guestfs_is_lv (g, device), which returns true iff
the named device is an LVM2 logical volume.
A sample guestfish session:
><fs> lvs
/dev/vg_f13x64/lv_root
/dev/vg_f13x64/lv_swap
><fs> list-devices
/dev/vda
><fs> list-partitions
/dev/vda1
/dev/vda2
><fs> is-lv /dev/vg_f13x64/lv_root
true
><fs> is-lv /dev/vg_f13x64/lv_swap
true
><fs> is-lv /dev/vda
false
><fs> is-lv /dev/vda1
false
><fs> is-lv /dev/vda2
false
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/lvm.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/daemon/lvm.c b/daemon/lvm.c index 70c3c904..0df27e2f 100644 --- a/daemon/lvm.c +++ b/daemon/lvm.c @@ -23,6 +23,7 @@ #include <inttypes.h> #include <string.h> #include <unistd.h> +#include <sys/stat.h> #include "daemon.h" #include "c-ctype.h" @@ -662,3 +663,49 @@ do_vgscan (void) free (err); return 0; } + +/* Test if a device is a logical volume (RHBZ#619793). + * + * This is harder than it should be. A LV device like /dev/VG/LV is + * really a symlink to a device-mapper device like /dev/dm-0. However + * at the device-mapper (kernel) level, nothing is really known about + * LVM (a userspace concept). Therefore we use a convoluted method to + * determine this, by listing out known LVs and checking whether the + * rdev (major/minor) of the device we are passed matches any of them. + * + * Note use of 'stat' instead of 'lstat' so that symlinks are fully + * resolved. + */ +int +do_is_lv (const char *device) +{ + struct stat stat1, stat2; + + int r = stat (device, &stat1); + if (r == -1) { + reply_with_perror ("stat: %s", device); + return -1; + } + + char **lvs = do_lvs (); + if (lvs == NULL) + return -1; + + size_t i; + for (i = 0; lvs[i] != NULL; ++i) { + r = stat (lvs[i], &stat2); + if (r == -1) { + reply_with_perror ("stat: %s", lvs[i]); + free_strings (lvs); + return -1; + } + if (stat1.st_rdev == stat2.st_rdev) { /* found it */ + free_strings (lvs); + return 1; + } + } + + /* not found */ + free_strings (lvs); + return 0; +} |