[Libguestfs] [PATCH] New API: btrfs_filesystem_show_all

Chen Hanxiao chenhanxiao at cn.fujitsu.com
Thu Jun 11 04:24:18 UTC 2015


Signed-off-by: Chen Hanxiao <chenhanxiao at cn.fujitsu.com>
---
 daemon/btrfs.c       | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++
 generator/actions.ml |  19 ++++++
 generator/structs.ml |  13 ++++
 src/MAX_PROC_NR      |   2 +-
 4 files changed, 209 insertions(+), 1 deletion(-)

diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index 39392f7..09f7615 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -2083,3 +2083,179 @@ do_btrfs_image (char *const *sources, const char *image,
 
   return 0;
 }
+
+guestfs_int_btrfsfsshow_list *
+do_btrfs_filesystem_show_all (void)
+{
+  const size_t MAX_ARGS = 64;
+  const char *argv[MAX_ARGS];
+  size_t i = 0;
+  size_t nr_filesystem_show = 0;
+  CLEANUP_FREE char *err = NULL;
+  char *out = NULL;
+  char **lines;
+  int r;
+  /* Info from Label line will be reused for the following devid line
+   * make two temp space to hold them */
+  char *label_tmp = NULL, *uuid_tmp = NULL;
+
+  ADD_ARG (argv, i, str_btrfs);
+  ADD_ARG (argv, i, "filesystem");
+  ADD_ARG (argv, i, "show");
+  ADD_ARG (argv, i, NULL);
+
+  r = commandv (&out, &err, argv);
+  if (r == -1) {
+    reply_with_error ("%s", err);
+    free(out);
+    return NULL;
+  }
+
+  lines = split_lines (out);
+  if (!lines)
+    return NULL;
+
+  size_t nlines = count_strings (lines);
+  for (i = 0; i < nlines; i++)
+    if (strstr(lines[i], "\tdevid"))
+        nr_filesystem_show++;
+
+  guestfs_int_btrfsfsshow_list *ret = NULL;
+  ret = malloc(sizeof *ret);
+  if (ret == NULL) {
+    reply_with_perror ("malloc");
+    return NULL;
+  }
+
+  /* No btrfs fs found, return directly */
+  if (nr_filesystem_show == 0) {
+    memset (ret, 0, sizeof(*ret));
+    return ret;
+  }
+
+  ret->guestfs_int_btrfsfsshow_list_len = nr_filesystem_show;
+  ret->guestfs_int_btrfsfsshow_list_val =
+    calloc (nr_filesystem_show, sizeof (struct guestfs_int_btrfsfsshow));
+  if (ret->guestfs_int_btrfsfsshow_list_val == NULL) {
+    reply_with_perror ("calloc");
+    goto error;
+  }
+
+  /* Output of `btrfs filesystem show' is like:
+   *
+   * Label: none uuid: e34452fa-5444-4e7b-9faa-c26fa1b83686
+   * Total devices 1 FS bytes used 176.00KiB
+   * devid 1 size 1.00GiB used 236.00MiB path /dev/sda6
+   *
+   * Label: none uuid: 9cdb73b9-d5b9-46c4-9395-25a952e7922a
+   * Total devices 5 FS bytes used 112.00KiB
+   * devid 1 size 10.00GiB used 1.02GiB path /dev/sdb
+   * devid 2 size 10.00GiB used 2.00GiB path /dev/sdd
+   * devid 3 size 10.00GiB used 2.00GiB path /dev/sde
+   *
+   * Btrfs v3.18.2
+   *
+   *
+   * If no btrfs device found, output is like:
+   *
+   * Btrfs v3.18.2
+   *
+   */
+  if (nlines < 1) {
+      reply_with_perror ("No filesystem show output");
+      return NULL;
+  }
+
+  char *p, *p1;
+  size_t k;
+
+  for (i = 0, k = 0; i < nlines - 2; i++) {
+    char *line = lines[i];
+
+    struct guestfs_int_btrfsfsshow *this =
+      &ret->guestfs_int_btrfsfsshow_list_val[k];
+    if (STRPREFIX(line, "Label")) {
+      if ((p = strstr (line, "uuid")) == NULL) {
+        reply_with_error ("No uuid field found");
+        return NULL;
+      }
+      p1 = lines[i] + strlen("Label: ");
+      if ((p - p1) < 1) {
+        reply_with_error ("No Label field found");
+        return NULL;
+      }
+
+      if (label_tmp) {
+        free (label_tmp);
+        label_tmp = NULL;
+      }
+      if (uuid_tmp) {
+        free (uuid_tmp);
+        uuid_tmp = NULL;
+      }
+
+      p += strlen ("uuid: ");
+      uuid_tmp = strdup(p);
+      p -= strlen ("uuid: ");
+      *p = '\0';
+      label_tmp = strdup(p1);
+      continue;
+    }
+
+    if (STRPREFIX (line, "\tdevid")) {
+      if ((this->btrfsfsshow_uuid = strdup (uuid_tmp)) == NULL)
+        goto error;
+      if ((this->btrfsfsshow_label = strdup (label_tmp)) == NULL)
+        goto error;
+
+      if ((p = strstr (lines[i], "path ")) == NULL) {
+        reply_with_error ("No path field found");
+        goto error;
+      }
+      p += strlen ("path ");
+      if ((this->btrfsfsshow_device = strdup (p)) == NULL)
+        goto error;
+      if (sscanf (line, "\tdevid %4d size %9s used %9s path",
+               &this->btrfsfsshow_devid,
+               this->btrfsfsshow_total_bytes,
+               this->btrfsfsshow_bytes_used) != 3) {
+        reply_with_error ("cannot parse output of filesystem show command: %s", line);
+        goto error;
+      }
+      k++;
+    }
+  }
+
+  if (label_tmp)
+    free (label_tmp);
+  if (uuid_tmp)
+    free (uuid_tmp);
+  free (lines);
+
+  return ret;
+
+error:
+  free_stringslen (lines, nlines);
+  if (label_tmp)
+    free (label_tmp);
+  if (uuid_tmp)
+    free (uuid_tmp);
+
+  for (i = 0; i < nr_filesystem_show; i++) {
+    struct guestfs_int_btrfsfsshow *this_new =
+      &ret->guestfs_int_btrfsfsshow_list_val[i];
+
+    if (this_new->btrfsfsshow_label)
+      free (this_new->btrfsfsshow_label);
+    if (this_new->btrfsfsshow_uuid)
+      free (this_new->btrfsfsshow_uuid);
+    if (this_new->btrfsfsshow_device)
+      free (this_new->btrfsfsshow_device);
+  }
+
+  if (ret)
+    free (ret->guestfs_int_btrfsfsshow_list_val);
+  free (ret);
+
+  return NULL;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index 7252295..26f9083 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12593,6 +12593,25 @@ numbered C<partnum> on device C<device>.
 
 It returns C<primary>, C<logical>, or C<extended>." };
 
+  { defaults with
+    name = "btrfs_filesystem_show_all"; added = (1, 29, 46);
+    style = RStructList ("fsshow", "btrfsfsshow"), [], [];
+    (*style = RString "output", [], [OString "device"];*)
+    proc_nr = Some 455;
+    tests = [
+      InitPartition, Always, TestRun (
+        [["part_init"; "/dev/sda"; "mbr"];
+         ["part_add"; "/dev/sda"; "p"; "64"; "204799"];
+         ["part_add"; "/dev/sda"; "p"; "204800"; "-64"];
+         ["mkfs_btrfs"; "/dev/sda1 /dev/sda2"; ""; ""; "NOARG"; ""; "NOARG"; "NOARG"; ""; ""];
+         ["mkfs_btrfs"; "/dev/sdb"; ""; ""; "NOARG"; ""; "NOARG"; "NOARG"; ""; ""];
+         ["btrfs_filesystem_show_all"]]), [];
+    ];
+    optional = Some "btrfs"; camel_name = "BTRFSFilesystemShowAll";
+    shortdesc = "show all devices run btrfs filesystem with some additional info";
+    longdesc = "\
+This show all devices run btrfs filesystem with some additional info." };
+
 ]
 
 (* Non-API meta-commands available only in guestfish.
diff --git a/generator/structs.ml b/generator/structs.ml
index ea110a1..80f03ae 100644
--- a/generator/structs.ml
+++ b/generator/structs.ml
@@ -374,6 +374,19 @@ let structs = [
     ];
     s_camel_name = "BTRFSScrub" };
 
+  (* btrfs filesystem show output *)
+  { defaults with
+    s_name = "btrfsfsshow";
+    s_cols = [
+      "btrfsfsshow_label", FString;
+      "btrfsfsshow_uuid", FString;
+      "btrfsfsshow_devid", FUInt32;
+      "btrfsfsshow_total_bytes", FUUID;
+      "btrfsfsshow_bytes_used", FUUID;
+      "btrfsfsshow_device", FString;
+    ];
+    s_camel_name = "BTRFSFilesystemShowAll" };
+
   (* XFS info descriptor. *)
   { defaults with
     s_name = "xfsinfo";
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 515f19a..4930863 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-454
+455
-- 
2.1.0




More information about the Libguestfs mailing list