Pino Toscano
2016-May-12 15:14 UTC
[Libguestfs] [PATCH] New API: btrfs-filesystem-show (RHBZ#1164765)
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
Richard W.M. Jones
2016-May-12 15:20 UTC
Re: [Libguestfs] [PATCH] New API: btrfs-filesystem-show (RHBZ#1164765)
On Thu, May 12, 2016 at 05:14:50PM +0200, Pino Toscano wrote:> 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(-)Looks reasonable. I wonder if we should make more of a push to get btrfs upstream to implement a JSON mode. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/