diff --git a/daemon/btrfs.c b/daemon/btrfs.c index b49979e19..88c324846 100644 --- a/daemon/btrfs.c +++ b/daemon/btrfs.c @@ -1186,3 +1186,92 @@ do_btrfs_qgroup_destroy (const char *qgroupid, const char *subvolume) return 0; } + +guestfs_int_btrfsqgroup_list * +do_btrfs_qgroup_show (const char *path) +{ + const size_t MAX_ARGS = 64; + const char *argv[MAX_ARGS]; + size_t i = 0; + CLEANUP_FREE char *path_buf = NULL; + CLEANUP_FREE char *err = NULL; + CLEANUP_FREE char *out = NULL; + int r; + char **lines; + + path_buf = sysroot_path (path); + if (path_buf == NULL) { + reply_with_perror ("malloc"); + return NULL; + } + + ADD_ARG (argv, i, str_btrfs); + ADD_ARG (argv, i, "qgroup"); + ADD_ARG (argv, i, "show"); + ADD_ARG (argv, i, path_buf); + ADD_ARG (argv, i, NULL); + + r = commandv (&out, &err, argv); + if (r == -1) { + reply_with_error ("%s: %s", path, err); + return NULL; + } + + lines = split_lines (out); + if (!lines) + return NULL; + + /* line 0 and 1 are: + * + * qgroupid rfer excl + * -------- ---- ---- + */ + size_t nr_qgroups = count_strings (lines) - 2; + guestfs_int_btrfsqgroup_list *ret = NULL; + ret = malloc (sizeof *ret); + if (!ret) { + reply_with_perror ("malloc"); + goto error; + } + + ret->guestfs_int_btrfsqgroup_list_len = nr_qgroups; + ret->guestfs_int_btrfsqgroup_list_val = + calloc (nr_qgroups, sizeof (struct guestfs_int_btrfsqgroup)); + if (ret->guestfs_int_btrfsqgroup_list_val == NULL) { + reply_with_perror ("malloc"); + goto error; + } + + for (i = 0; i < nr_qgroups; ++i) { + char *line = lines[i + 2]; + struct guestfs_int_btrfsqgroup *this = + &ret->guestfs_int_btrfsqgroup_list_val[i]; + uint64_t dummy1, dummy2; + char *p; + + if (sscanf (line, "%" SCNu64 "/%" SCNu64 " %" SCNu64 " %" SCNu64, + &dummy1, &dummy2, &this->btrfsqgroup_rfer, + &this->btrfsqgroup_excl) != 4) { + reply_with_perror ("sscanf"); + goto error; + } + p = strchr(line, ' '); + if (!p) { + reply_with_error ("truncated line: %s", line); + goto error; + } + *p = '\0'; + this->btrfsqgroup_id = line; + } + + free (lines); + return ret; + +error: + free_stringslen (lines, nr_qgroups + 2); + if (ret) + free (ret->guestfs_int_btrfsqgroup_list_val); + free (ret); + + return NULL; +} diff --git a/generator/actions.ml b/generator/actions.ml index 9bbfdb57e..53ddbc034 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -12188,6 +12188,25 @@ Create a quota group (qgroup) for subvolume at C." }; longdesc = "\ Destroy a quota group." }; + { defaults with + name = "btrfs_qgroup_show"; + style = RStructList ("qgroups", "btrfsqgroup"), [Pathname "path"], []; + proc_nr = Some 432; + tests = [ + InitPartition, Always, TestRun ( + [["mkfs_btrfs"; "/dev/sda1"; ""; ""; "NOARG"; ""; "NOARG"; "NOARG"; ""; ""]; + ["mount"; "/dev/sda1"; "/"]; + ["btrfs_quota_enable"; "/"; "true"]; + ["btrfs_subvolume_create"; "/sub1"; "NOARG"]; + ["btrfs_qgroup_create"; "0/1000"; "/sub1"]; + ["btrfs_qgroup_show"; "/"]]), []; + ]; + optional = Some "btrfs"; camel_name = "BTRFSQgroupShow"; + shortdesc = "show subvolume quota groups"; + longdesc = "\ +Show all subvolume quota groups in a btrfs filesystem, inclding their +usages." }; + ] (* Non-API meta-commands available only in guestfish. diff --git a/generator/structs.ml b/generator/structs.ml index 578ebb79f..df3ff47f3 100644 --- a/generator/structs.ml +++ b/generator/structs.ml @@ -330,6 +330,16 @@ let structs = [ ]; s_camel_name = "BTRFSSubvolume" }; + (* btrfs qgroup show output *) + { defaults with + s_name = "btrfsqgroup"; + s_cols = [ + "btrfsqgroup_id", FString; + "btrfsqgroup_rfer", FUInt64; + "btrfsqgroup_excl", FUInt64; + ]; + s_camel_name = "BTRFSQgroup" }; + (* XFS info descriptor. *) { defaults with s_name = "xfsinfo"; diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc index 218eef752..91c4ea6da 100644 --- a/gobject/Makefile.inc +++ b/gobject/Makefile.inc @@ -25,6 +25,7 @@ guestfs_gobject_headers= \ include/guestfs-gobject/tristate.h \ include/guestfs-gobject/struct-application.h \ include/guestfs-gobject/struct-application2.h \ + include/guestfs-gobject/struct-btrfsqgroup.h \ include/guestfs-gobject/struct-btrfssubvolume.h \ include/guestfs-gobject/struct-dirent.h \ include/guestfs-gobject/struct-hivex_node.h \ @@ -106,6 +107,7 @@ guestfs_gobject_sources= \ src/tristate.c \ src/struct-application.c \ src/struct-application2.c \ + src/struct-btrfsqgroup.c \ src/struct-btrfssubvolume.c \ src/struct-dirent.c \ src/struct-hivex_node.c \ diff --git a/java/Makefile.inc b/java/Makefile.inc index 614caaa5f..34938fb87 100644 --- a/java/Makefile.inc +++ b/java/Makefile.inc @@ -22,6 +22,7 @@ java_built_sources = \ com/redhat/et/libguestfs/Application.java \ com/redhat/et/libguestfs/Application2.java \ + com/redhat/et/libguestfs/BTRFSQgroup.java \ com/redhat/et/libguestfs/BTRFSSubvolume.java \ com/redhat/et/libguestfs/Dirent.java \ com/redhat/et/libguestfs/HivexNode.java \ diff --git a/java/com/redhat/et/libguestfs/.gitignore b/java/com/redhat/et/libguestfs/.gitignore index 4882c9672..1d4accca0 100644 --- a/java/com/redhat/et/libguestfs/.gitignore +++ b/java/com/redhat/et/libguestfs/.gitignore @@ -1,5 +1,6 @@ Application.java Application2.java +BTRFSQgroup.java BTRFSSubvolume.java Dirent.java HivexNode.java diff --git a/po/POTFILES b/po/POTFILES index 9ba5b40e9..b18895b2b 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -229,6 +229,7 @@ gobject/src/optargs-xfs_repair.c gobject/src/session.c gobject/src/struct-application.c gobject/src/struct-application2.c +gobject/src/struct-btrfsqgroup.c gobject/src/struct-btrfssubvolume.c gobject/src/struct-dirent.c gobject/src/struct-hivex_node.c diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index ed4f16201..84796bf1c 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -431 +432