summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard Jones <rjones@redhat.com>2010-09-15 17:22:29 +0100
committerRichard Jones <rjones@redhat.com>2010-09-15 19:42:23 +0100
commit000c4a82fbd78667849551114b6d08f391324796 (patch)
tree552a804d675573b0e975b44896cdf14bdab7cb14 /src
parentffd4820ffe953b0583e3a9357e37d74bed3a2320 (diff)
downloadlibguestfs-000c4a82fbd78667849551114b6d08f391324796.tar.gz
libguestfs-000c4a82fbd78667849551114b6d08f391324796.tar.xz
libguestfs-000c4a82fbd78667849551114b6d08f391324796.zip
New API: list-filesystems: list filesystems
This API is a simpler replacement for the guestfish commands list-devices / list-partitions / lvs, in the case where you are just examining a guest by hand to see what it contains. Typical usage and output in guestfish is like this: $ guestfish --ro -a /dev/vg_trick/F13x64 ><fs> run ><fs> list-filesystems /dev/vda1: ext4 /dev/vg_f13x64/lv_root: ext4 /dev/vg_f13x64/lv_swap: swap It can also be used to replace programs that try to mount devices to determine if they are mountable filesystems.
Diffstat (limited to 'src')
-rw-r--r--src/inspect.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/inspect.c b/src/inspect.c
index 74ae29fe..11a53740 100644
--- a/src/inspect.c
+++ b/src/inspect.c
@@ -1295,3 +1295,140 @@ guestfs__inspect_get_filesystems (guestfs_h *g, const char *root)
return ret;
}
+
+/* List filesystems.
+ *
+ * The current implementation just uses guestfs_vfs_type and doesn't
+ * try mounting anything, but we reserve the right in future to try
+ * mounting filesystems.
+ */
+
+static void remove_from_list (char **list, const char *item);
+static void check_with_vfs_type (guestfs_h *g, const char *dev, char ***ret, size_t *ret_size);
+
+char **
+guestfs__list_filesystems (guestfs_h *g)
+{
+ size_t i;
+ char **ret;
+ size_t ret_size;
+
+ ret = safe_malloc (g, sizeof (char *));
+ ret[0] = NULL;
+ ret_size = 0;
+
+ /* Look to see if any devices directly contain filesystems
+ * (RHBZ#590167). However vfs-type will fail to tell us anything
+ * useful about devices which just contain partitions, so we also
+ * get the list of partitions and exclude the corresponding devices
+ * by using part-to-dev.
+ */
+ char **devices;
+ devices = guestfs_list_devices (g);
+ if (devices == NULL) {
+ free_string_list (ret);
+ return NULL;
+ }
+ char **partitions;
+ partitions = guestfs_list_partitions (g);
+ if (partitions == NULL) {
+ free_string_list (devices);
+ free_string_list (ret);
+ return NULL;
+ }
+
+ for (i = 0; partitions[i] != NULL; ++i) {
+ char *dev = guestfs_part_to_dev (g, partitions[i]);
+ if (dev)
+ remove_from_list (devices, dev);
+ free (dev);
+ }
+
+ /* Use vfs-type to check for filesystems on devices. */
+ for (i = 0; devices[i] != NULL; ++i)
+ check_with_vfs_type (g, devices[i], &ret, &ret_size);
+ free_string_list (devices);
+
+ /* Use vfs-type to check for filesystems on partitions. */
+ for (i = 0; partitions[i] != NULL; ++i)
+ check_with_vfs_type (g, partitions[i], &ret, &ret_size);
+ free_string_list (partitions);
+
+ if (feature_available (g, "lvm2")) {
+ /* Use vfs-type to check for filesystems on LVs. */
+ char **lvs;
+ lvs = guestfs_lvs (g);
+ if (lvs == NULL) {
+ free_string_list (ret);
+ return NULL;
+ }
+
+ for (i = 0; lvs[i] != NULL; ++i)
+ check_with_vfs_type (g, lvs[i], &ret, &ret_size);
+ free_string_list (lvs);
+ }
+
+ return ret;
+}
+
+/* If 'item' occurs in 'list', remove and free it. */
+static void
+remove_from_list (char **list, const char *item)
+{
+ size_t i;
+
+ for (i = 0; list[i] != NULL; ++i)
+ if (STREQ (list[i], item)) {
+ free (list[i]);
+ for (; list[i+1] != NULL; ++i)
+ list[i] = list[i+1];
+ list[i] = NULL;
+ return;
+ }
+}
+
+/* Use vfs-type to look for a filesystem of some sort on 'dev'.
+ * Apart from some types which we ignore, add the result to the
+ * 'ret' string list.
+ */
+static void
+check_with_vfs_type (guestfs_h *g, const char *device,
+ char ***ret, size_t *ret_size)
+{
+ char *v;
+
+ guestfs_error_handler_cb old_error_cb = g->error_cb;
+ g->error_cb = NULL;
+ char *vfs_type = guestfs_vfs_type (g, device);
+ g->error_cb = old_error_cb;
+
+ if (!vfs_type)
+ v = safe_strdup (g, "unknown");
+ else {
+ /* Ignore all "*_member" strings. In libblkid these are returned
+ * for things which are members of some RAID or LVM set, most
+ * importantly "LVM2_member" which is a PV.
+ */
+ size_t n = strlen (vfs_type);
+ if (n >= 7 && STREQ (&vfs_type[n-7], "_member")) {
+ free (vfs_type);
+ return;
+ }
+
+ /* Ignore LUKS-encrypted partitions. These are also containers. */
+ if (STREQ (vfs_type, "crypto_LUKS")) {
+ free (vfs_type);
+ return;
+ }
+
+ v = vfs_type;
+ }
+
+ /* Extend the return array. */
+ size_t i = *ret_size;
+ *ret_size += 2;
+ *ret = safe_realloc (g, *ret, (*ret_size + 1) * sizeof (char *));
+ (*ret)[i] = safe_strdup (g, device);
+ (*ret)[i+1] = v;
+ (*ret)[i+2] = NULL;
+}