summaryrefslogtreecommitdiffstats
path: root/daemon
diff options
context:
space:
mode:
authorRichard Jones <rjones@redhat.com>2010-07-30 16:32:35 +0100
committerRichard Jones <rjones@redhat.com>2010-07-30 16:32:35 +0100
commit6280ac9b987c14f89749b4b4fdfec5a647567432 (patch)
tree343d127f4ac0abed347a6f937799994efd95be5e /daemon
parent737181bcd7b1de8c3a613d6282030c34efa78fb6 (diff)
downloadlibguestfs-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.c47
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;
+}