[Libguestfs] [PATCH] New API: btrfs-filesystem-show (RHBZ#1164765)

Pino Toscano ptoscano at redhat.com
Thu May 12 15:14:50 UTC 2016


Add a new API to list all the devices where a btrfs filesystem is
spanned.
---
 daemon/btrfs.c       | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 generator/actions.ml | 27 ++++++++++++++++++
 src/MAX_PROC_NR      |  2 +-
 3 files changed, 106 insertions(+), 1 deletion(-)

diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index 2a20cb0..62bdac7 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -2203,6 +2203,84 @@ do_btrfs_replace (const char *srcdev, const char *targetdev,
   return 0;
 }
 
+char **
+do_btrfs_filesystem_show (const char *device)
+{
+  CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (ret);
+  const size_t MAX_ARGS = 16;
+  const char *argv[MAX_ARGS];
+  size_t i = 0;
+  CLEANUP_FREE char *out = NULL;
+  CLEANUP_FREE char *err = NULL;
+  CLEANUP_FREE_STRING_LIST char **lines = NULL;
+  int r;
+
+  ADD_ARG (argv, i, str_btrfs);
+  ADD_ARG (argv, i, "filesystem");
+  ADD_ARG (argv, i, "show");
+  ADD_ARG (argv, i, device);
+  ADD_ARG (argv, i, NULL);
+
+  r = commandv (&out, &err, argv);
+  if (r == -1) {
+    reply_with_error ("%s: %s", device, err);
+    return NULL;
+  }
+
+  lines = split_lines (out);
+  if (!lines)
+    return NULL;
+
+  if (count_strings (lines) < 3) {
+    reply_with_error ("truncated output from 'btrfs filesystem show' command");
+    return NULL;
+  }
+
+  /* Output of `btrfs filesystem show' is like:
+   *
+   *   Label: none  uuid: 99a1b6ba-de46-4a93-8f91-7d7685970a6c
+   *           Total devices 3 FS bytes used 1.12MiB
+   *           devid    1 size 10.00GiB used 2.00GiB path /dev/sda
+   *           [...]
+   *
+   * or:
+   *
+   *   Label: none  uuid: 99a1b6ba-de46-4a93-8f91-7d7685970a6c
+   *           Total devices 3 FS bytes used 1.12MiB
+   *           devid    1 size 10.00GiB used 2.00GiB path /dev/sda
+   *           [...]
+   *           *** Some devices missing
+   */
+  for (i = 1; lines[i] != NULL; ++i) {
+    if (lines[i][0] == 0)
+      continue;
+    if (STRPREFIX (lines[i], "Label: "))
+      continue;
+    else if (STRPREFIX (lines[i], "\tTotal devices "))
+      continue;
+    else if (STRPREFIX (lines[i], "\tdevid ")) {
+      const char *p = strstr (lines[i], " path ");
+      const char *end;
+      if (!p)
+        continue;
+
+      p += strlen (" path ");
+      end = strchrnul (p, ' ');
+      add_sprintf (&ret, "%.*s", (int) (end - p), p);
+    } else if (STRPREFIX (lines[i], "\t*** Some devices missing")) {
+      reply_with_error_errno (ENODEV, "%s: missing devices", device);
+      return NULL;
+    } else {
+      reply_with_error ("unrecognized line in output from 'btrfs filesystem show': %s", lines[i]);
+      return NULL;
+    }
+  }
+
+  end_stringsbuf (&ret);
+
+  return take_stringsbuf (&ret);
+}
+
 /* btrfs command add a new command
  * inspect-internal min-dev-size <path>
  * since v4.2
diff --git a/generator/actions.ml b/generator/actions.ml
index e5cb939..3566371 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12958,6 +12958,33 @@ and save it as F<filename> on the local machine.
 
 This allows to download deleted or inaccessible files." };
 
+  { defaults with
+    name = "btrfs_filesystem_show"; added = (1, 33, 29);
+    style = RStringList "devices", [Device "device"], [];
+    proc_nr = Some 465;
+    optional = Some "btrfs"; camel_name = "BTRFSFilesystemsShow";
+    tests = [
+      InitScratchFS, Always, TestLastFail (
+        [["btrfs_filesystem_show"; "/dev/sdb"]]), [];
+      InitPartition, Always, TestResult (
+        [["mkfs_btrfs"; "/dev/sda1"; ""; ""; "NOARG"; ""; "NOARG"; "NOARG"; ""; ""];
+         ["btrfs_filesystem_show"; "/dev/sda1"]],
+         "is_string_list (ret, 1, \"/dev/sda1\")"), [];
+      InitEmpty, Always, TestResult (
+        [["part_init"; "/dev/sda"; "mbr"];
+         ["part_add"; "/dev/sda"; "p"; "64"; "2047999"];
+         ["part_add"; "/dev/sda"; "p"; "2048000"; "4095999"];
+         ["mkfs_btrfs"; "/dev/sda1 /dev/sda2"; ""; ""; "NOARG"; ""; "NOARG"; "NOARG"; ""; ""];
+         ["btrfs_filesystem_show"; "/dev/sda1"]],
+         "is_string_list (ret, 2, \"/dev/sda1\", \"/dev/sda2\")"), [];
+    ];
+    shortdesc = "list devices for btrfs filesystem";
+    longdesc = "\
+Show all the devices where the filesystems in C<device> is spanned over.
+
+If not all the devices for the filesystems are present, then this function
+fails and the C<errno> is set to C<ENODEV>." };
+
 ]
 
 (* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 3bb8a49..073c57b 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-464
+465
-- 
2.5.5




More information about the Libguestfs mailing list