Hu Tao
2014-Dec-02 09:33 UTC
[Libguestfs] [PATCH 0/8] btrfs support part2: qgroup commands
Hi, This series adds support to btrfs qgroup related commands, inclduing quota commands, and two leftover of subvolume commands. Regards, Hu Hu Tao (8): New API: btrfs_subvolume_get_default New API: btrfs_subvolume_show New API: btrfs_quota_enable New API: btrfs_quota_disable New API: btrfs_quota_rescan New API: btrfs_qgroup_limit New API: btrfs_qgroup_create New API: btrfs_qgroup_destroy daemon/btrfs.c | 412 +++++++++++++++++++++++++++++++++++++++++++++++++++ generator/actions.ml | 73 +++++++++ src/MAX_PROC_NR | 2 +- 3 files changed, 486 insertions(+), 1 deletion(-) -- 1.9.3
Hu Tao
2014-Dec-02 09:33 UTC
[Libguestfs] [PATCH 1/8] New API: btrfs_subvolume_get_default
btrfs_subvolume_get_default is for getting the default subvolume of
a btrfs filesystem.
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
daemon/btrfs.c | 38 ++++++++++++++++++++++++++++++++++++++
generator/actions.ml | 9 +++++++++
src/MAX_PROC_NR | 2 +-
3 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index 754fdcd..471cfbd 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -545,6 +545,44 @@ do_btrfs_subvolume_set_default (int64_t id, const char *fs)
return 0;
}
+int64_t
+do_btrfs_subvolume_get_default (const char *mountpoint)
+{
+ const size_t MAX_ARGS = 64;
+ const char *argv[MAX_ARGS];
+ size_t i = 0;
+ CLEANUP_FREE char *fs_buf = NULL;
+ CLEANUP_FREE char *err = NULL;
+ CLEANUP_FREE char *out = NULL;
+ int r;
+ int64_t ret;
+
+ fs_buf = sysroot_path (mountpoint);
+ if (fs_buf == NULL) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+
+ ADD_ARG (argv, i, str_btrfs);
+ ADD_ARG (argv, i, "subvolume");
+ ADD_ARG (argv, i, "get-default");
+ ADD_ARG (argv, i, fs_buf);
+ ADD_ARG (argv, i, NULL);
+
+ r = commandv (&out, &err, argv);
+ if (r == -1) {
+ reply_with_error ("%s: %s", mountpoint, err);
+ return -1;
+ }
+ r = xstrtol (out + 2, NULL, 10, &ret, NULL);
+ if (r != LONGINT_OK) {
+ reply_with_error ("%s: could not parse subvolume id: %s.",
argv[0], out);
+ return -1;
+ }
+
+ return ret;
+}
+
int
do_btrfs_filesystem_sync (const char *fs)
{
diff --git a/generator/actions.ml b/generator/actions.ml
index 385b620..80c7ea7 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12027,6 +12027,15 @@ Set readahead (in 512-byte sectors) for the device.
This uses the L<blockdev(8)> command." };
+ { defaults with
+ name = "btrfs_subvolume_get_default";
+ style = RInt64 "id", [Pathname "mountpoint"], [];
+ proc_nr = Some 425;
+ optional = Some "btrfs"; camel_name =
"BTRFSSubvolumeGetDefault";
+ shortdesc = "get the default subvolume or snapshot of a
filesystem";
+ longdesc = "\
+Get the default subvolume or snapshot of a filesystem mounted at
C<mountpoint>." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 9524ef4..5e4a522 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-424
+425
--
1.9.3
btrfs_subvolume_show shows the detailed information of a subvolume or
snapshot.
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
daemon/btrfs.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++
generator/actions.ml | 9 +++
src/MAX_PROC_NR | 2 +-
3 files changed, 195 insertions(+), 1 deletion(-)
diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index 471cfbd..2cfb364 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -24,11 +24,13 @@
#include <pcre.h>
#include <string.h>
#include <unistd.h>
+#include <assert.h>
#include "daemon.h"
#include "actions.h"
#include "optgroups.h"
#include "xstrtol.h"
+#include "c-ctype.h"
GUESTFSD_EXT_CMD(str_btrfs, btrfs);
GUESTFSD_EXT_CMD(str_btrfstune, btrfstune);
@@ -810,3 +812,186 @@ do_btrfs_fsck (const char *device, int64_t superblock, int
repair)
return 0;
}
+
+/* analyze_line: analyze one line contains key:value pair.
+ * returns the next position following \n.
+ */
+static char *analyze_line (char *line, char **key, char **value)
+{
+ char *p = line;
+ char *next = NULL;
+ char delimiter = ':';
+ char *del_pos = NULL;
+
+ if (!line || *line == '\0') {
+ *key = NULL;
+ *value = NULL;
+ return NULL;
+ }
+
+ next = strchr (p, '\n');
+ if (next) {
+ *next = '\0';
+ ++next;
+ }
+
+ /* leading spaces and tabs */
+ while (*p && c_isspace (*p))
+ ++p;
+
+ assert (key);
+ if (*p == delimiter)
+ *key = NULL;
+ else
+ *key = p;
+
+ del_pos = strchr (p, delimiter);
+ if (del_pos) {
+ *del_pos = '\0';
+
+ /* leading spaces and tabs */
+ do {
+ ++del_pos;
+ } while (*del_pos && c_isspace (*del_pos));
+ assert (value);
+ *value = del_pos;
+ } else
+ *value = NULL;
+
+ return next;
+}
+
+char **do_btrfs_subvolume_show (const char *subvolume)
+{
+ const size_t MAX_ARGS = 64;
+ const char *argv[MAX_ARGS];
+ size_t i = 0;
+ CLEANUP_FREE char *subvolume_buf = NULL;
+ CLEANUP_FREE char *err = NULL;
+ CLEANUP_FREE char *out = NULL;
+ char *p, *key = NULL, *value = NULL;
+ DECLARE_STRINGSBUF (ret);
+ int r;
+
+ subvolume_buf = sysroot_path (subvolume);
+ if (subvolume_buf == NULL) {
+ reply_with_perror ("malloc");
+ return NULL;
+ }
+
+ ADD_ARG (argv, i, str_btrfs);
+ ADD_ARG (argv, i, "subvolume");
+ ADD_ARG (argv, i, "show");
+ ADD_ARG (argv, i, subvolume_buf);
+ ADD_ARG (argv, i, NULL);
+
+ r = commandv (&out, &err, argv);
+ if (r == -1) {
+ reply_with_error ("%s: %s", subvolume, err);
+ return NULL;
+ }
+
+ /* Output is:
+ *
+ * /
+ * Name: root
+ * uuid: c875169e-cf4e-a04d-9959-b667dec36234
+ * Parent uuid: -
+ * Creation time: 2014-11-13 10:13:08
+ * Object ID: 256
+ * Generation (Gen): 6579
+ * Gen at creation: 5
+ * Parent: 5
+ * Top Level: 5
+ * Flags: -
+ * Snapshot(s):
+ * snapshots/test1
+ * snapshots/test2
+ * snapshots/test3
+ *
+ */
+ p = analyze_line(out, &key, &value);
+ if (!p) {
+ reply_with_error ("truncated output: %s", out);
+ return NULL;
+ }
+
+ /* If the path is the btrfs root, `btrfs subvolume show' reports:
+ * <path> is btrfs root
+ */
+ if (strstr (key, "is btrfs root") != NULL) {
+ reply_with_error ("%s is btrfs root", subvolume);
+ return NULL;
+ }
+
+ /* The first line is the path of the subvolume. */
+ if (key && !value) {
+ if (add_string (&ret, "path") == -1)
+ return NULL;
+ if (add_string (&ret, key) == -1)
+ return NULL;
+ } else {
+ if (add_string (&ret, key) == -1)
+ return NULL;
+ if (add_string (&ret, value) == -1)
+ return NULL;
+ }
+
+ /* Read the lines and split into "key: value". */
+ p = analyze_line(p, &key, &value);
+ while (key) {
+ /* snapshot is special, see the output above */
+ if (STREQLEN (key, "Snapshot(s)", sizeof
("Snapshot(s)") - 1)) {
+ char *ss = NULL;
+ int ss_len = 0;
+
+ if (add_string (&ret, key) == -1)
+ return NULL;
+
+ p = analyze_line(p, &key, &value);
+
+ while (key && !value) {
+ ss = realloc (ss, ss_len + strlen (key) + 1);
+ if (!ss)
+ return NULL;
+
+ if (ss_len != 0)
+ ss[ss_len++] = ',';
+
+ memcpy (ss + ss_len, key, strlen (key));
+ ss_len += strlen (key);
+ ss[ss_len] = '\0';
+
+ p = analyze_line(p, &key, &value);
+ }
+
+ if (ss) {
+ if (add_string_nodup (&ret, ss) == -1) {
+ free (ss);
+ return NULL;
+ }
+ } else {
+ if (add_string (&ret, "") == -1)
+ return NULL;
+ }
+ } else {
+ if (add_string (&ret, key ? key : "") == -1)
+ return NULL;
+ if (value && !STREQ(value, "-")) {
+ if (add_string (&ret, value) == -1)
+ return NULL;
+ } else {
+ if (add_string (&ret, "") == -1)
+ return NULL;
+ }
+
+ p = analyze_line(p, &key, &value);
+ }
+ }
+
+ if (end_stringsbuf (&ret) == -1)
+ return NULL;
+
+ return ret.argv;
+
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index 80c7ea7..d5ec528 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12036,6 +12036,15 @@ This uses the L<blockdev(8)> command." };
longdesc = "\
Get the default subvolume or snapshot of a filesystem mounted at
C<mountpoint>." };
+ { defaults with
+ name = "btrfs_subvolume_show";
+ style = RHashtable "btrfssubvolumeinfo", [Pathname
"subvolume"], [];
+ proc_nr = Some 426;
+ optional = Some "btrfs"; camel_name =
"BTRFSSubvolumeShow";
+ shortdesc = "return detailed information of the subvolume";
+ longdesc = "\
+Return detailed information of the subvolume." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 5e4a522..9f51d08 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-425
+426
--
1.9.3
btrfs_quota_enable enables quota for subvolumes.
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
daemon/btrfs.c | 31 +++++++++++++++++++++++++++++++
generator/actions.ml | 9 +++++++++
src/MAX_PROC_NR | 2 +-
3 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index 2cfb364..31dd806 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -995,3 +995,34 @@ char **do_btrfs_subvolume_show (const char *subvolume)
return ret.argv;
}
+
+int do_btrfs_quota_enable (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;
+
+ path_buf = sysroot_path (path);
+ if (path_buf == NULL) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+
+ ADD_ARG (argv, i, str_btrfs);
+ ADD_ARG (argv, i, "quota");
+ ADD_ARG (argv, i, "enable");
+ 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 -1;
+ }
+
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index d5ec528..3af8380 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12045,6 +12045,15 @@ Get the default subvolume or snapshot of a filesystem
mounted at C<mountpoint>."
longdesc = "\
Return detailed information of the subvolume." };
+ { defaults with
+ name = "btrfs_quota_enable";
+ style = RErr, [Pathname "path"], [];
+ proc_nr = Some 427;
+ optional = Some "btrfs"; camel_name =
"BTRFSQuotaEnable";
+ shortdesc = "enable subvolume quota support";
+ longdesc = "\
+Enable subvolume quota support for filesystem which contains
C<path>." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 9f51d08..d2a1e59 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-426
+427
--
1.9.3
btrfs_quota_disable disables quota for subvolumes.
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
daemon/btrfs.c | 31 +++++++++++++++++++++++++++++++
generator/actions.ml | 9 +++++++++
src/MAX_PROC_NR | 2 +-
3 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index 31dd806..5fcb85b 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -1026,3 +1026,34 @@ int do_btrfs_quota_enable (const char *path)
return 0;
}
+
+int do_btrfs_quota_disable (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;
+
+ path_buf = sysroot_path (path);
+ if (path_buf == NULL) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+
+ ADD_ARG (argv, i, str_btrfs);
+ ADD_ARG (argv, i, "quota");
+ ADD_ARG (argv, i, "disable");
+ 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 -1;
+ }
+
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index 3af8380..ab1a07a 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12054,6 +12054,15 @@ Return detailed information of the subvolume." };
longdesc = "\
Enable subvolume quota support for filesystem which contains
C<path>." };
+ { defaults with
+ name = "btrfs_quota_disable";
+ style = RErr, [Pathname "path"], [];
+ proc_nr = Some 428;
+ optional = Some "btrfs"; camel_name =
"BTRFSQuotaDisable";
+ shortdesc = "disable subvolume quota support";
+ longdesc = "\
+Disable subvolume quota support for filesystem which contains
C<path>." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index d2a1e59..43d371a 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-427
+428
--
1.9.3
btrfs_quota_rescan trashs all qgroup numbers and scans the metadata
again with the current config.
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
daemon/btrfs.c | 31 +++++++++++++++++++++++++++++++
generator/actions.ml | 9 +++++++++
src/MAX_PROC_NR | 2 +-
3 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index 5fcb85b..6918d4f 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -1057,3 +1057,34 @@ int do_btrfs_quota_disable (const char *path)
return 0;
}
+
+int do_btrfs_quota_rescan (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;
+
+ path_buf = sysroot_path (path);
+ if (path_buf == NULL) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+
+ ADD_ARG (argv, i, str_btrfs);
+ ADD_ARG (argv, i, "quota");
+ ADD_ARG (argv, i, "rescan");
+ 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 -1;
+ }
+
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index ab1a07a..f24d5d7 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12063,6 +12063,15 @@ Enable subvolume quota support for filesystem which
contains C<path>." };
longdesc = "\
Disable subvolume quota support for filesystem which contains
C<path>." };
+ { defaults with
+ name = "btrfs_quota_rescan";
+ style = RErr, [Pathname "path"], [];
+ proc_nr = Some 429;
+ optional = Some "btrfs"; camel_name =
"BTRFSQuotaRescan";
+ shortdesc = "trash all qgroup numbers and scan the metadata again with
the current config";
+ longdesc = "\
+Trash all qgroup numbers and scan the metadata again with the current
config." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 43d371a..3560666 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-428
+429
--
1.9.3
btrfs_qgroup_limit limits the size of a qgroup.
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
daemon/btrfs.c | 32 ++++++++++++++++++++++++++++++++
generator/actions.ml | 10 ++++++++++
src/MAX_PROC_NR | 2 +-
3 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index 6918d4f..033d460 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -1088,3 +1088,35 @@ int do_btrfs_quota_rescan (const char *path)
return 0;
}
+
+int do_btrfs_qgroup_limit (const char *subvolume, const char *size)
+{
+ const size_t MAX_ARGS = 64;
+ const char *argv[MAX_ARGS];
+ size_t i = 0;
+ CLEANUP_FREE char *subvolume_buf = NULL;
+ CLEANUP_FREE char *err = NULL;
+ CLEANUP_FREE char *out = NULL;
+ int r;
+
+ subvolume_buf = sysroot_path (subvolume);
+ if (subvolume_buf == NULL) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+
+ ADD_ARG (argv, i, str_btrfs);
+ ADD_ARG (argv, i, "qgroup");
+ ADD_ARG (argv, i, "limit");
+ ADD_ARG (argv, i, size);
+ ADD_ARG (argv, i, subvolume_buf);
+ ADD_ARG (argv, i, NULL);
+
+ r = commandv (&out, &err, argv);
+ if (r == -1) {
+ reply_with_error ("%s: %s", subvolume, err);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index f24d5d7..5d64350 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12072,6 +12072,16 @@ Disable subvolume quota support for filesystem which
contains C<path>." };
longdesc = "\
Trash all qgroup numbers and scan the metadata again with the current
config." };
+ { defaults with
+ name = "btrfs_qgroup_limit";
+ style = RErr, [Pathname "subvolume"; String "size"],
[];
+ proc_nr = Some 430;
+ optional = Some "btrfs"; camel_name =
"BTRFSQgroupLimit";
+ shortdesc = "limit the size of a subvolume";
+ longdesc = "\
+Limit the size of a subvolume which's path is C<subvolume>.
C<size>
+can have suffix of G, M, or K. " };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 3560666..c15fb93 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-429
+430
--
1.9.3
btrfs_qgroup_create creates a new qgroup.
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
daemon/btrfs.c | 32 ++++++++++++++++++++++++++++++++
generator/actions.ml | 9 +++++++++
src/MAX_PROC_NR | 2 +-
3 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index 033d460..dccaf5a 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -1120,3 +1120,35 @@ int do_btrfs_qgroup_limit (const char *subvolume, const
char *size)
return 0;
}
+
+int do_btrfs_qgroup_create (const char *qgroupid, const char *subvolume)
+{
+ const size_t MAX_ARGS = 64;
+ const char *argv[MAX_ARGS];
+ size_t i = 0;
+ CLEANUP_FREE char *subvolume_buf = NULL;
+ CLEANUP_FREE char *err = NULL;
+ CLEANUP_FREE char *out = NULL;
+ int r;
+
+ subvolume_buf = sysroot_path (subvolume);
+ if (subvolume_buf == NULL) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+
+ ADD_ARG (argv, i, str_btrfs);
+ ADD_ARG (argv, i, "qgroup");
+ ADD_ARG (argv, i, "create");
+ ADD_ARG (argv, i, qgroupid);
+ ADD_ARG (argv, i, subvolume_buf);
+ ADD_ARG (argv, i, NULL);
+
+ r = commandv (&out, &err, argv);
+ if (r == -1) {
+ reply_with_error ("%s: %s", subvolume, err);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index 5d64350..608ddf6 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12082,6 +12082,15 @@ Trash all qgroup numbers and scan the metadata again
with the current config." }
Limit the size of a subvolume which's path is C<subvolume>.
C<size>
can have suffix of G, M, or K. " };
+ { defaults with
+ name = "btrfs_qgroup_create";
+ style = RErr, [String "qgroupid"; Pathname
"subvolume"], [];
+ proc_nr = Some 431;
+ optional = Some "btrfs"; camel_name =
"BTRFSQgroupCreate";
+ shortdesc = "create a subvolume quota group";
+ longdesc = "\
+Create a quota group (qgroup) for subvolume at C<subvolume>." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index c15fb93..ed4f162 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-430
+431
--
1.9.3
btrfs_qgroup_destroy destroys a qgroup.
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
daemon/btrfs.c | 32 ++++++++++++++++++++++++++++++++
generator/actions.ml | 9 +++++++++
src/MAX_PROC_NR | 2 +-
3 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index dccaf5a..15e481a 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -1152,3 +1152,35 @@ int do_btrfs_qgroup_create (const char *qgroupid, const
char *subvolume)
return 0;
}
+
+int do_btrfs_qgroup_destroy (const char *qgroupid, const char *subvolume)
+{
+ const size_t MAX_ARGS = 64;
+ const char *argv[MAX_ARGS];
+ size_t i = 0;
+ CLEANUP_FREE char *subvolume_buf = NULL;
+ CLEANUP_FREE char *err = NULL;
+ CLEANUP_FREE char *out = NULL;
+ int r;
+
+ subvolume_buf = sysroot_path (subvolume);
+ if (subvolume_buf == NULL) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+
+ ADD_ARG (argv, i, str_btrfs);
+ ADD_ARG (argv, i, "qgroup");
+ ADD_ARG (argv, i, "destroy");
+ ADD_ARG (argv, i, qgroupid);
+ ADD_ARG (argv, i, subvolume_buf);
+ ADD_ARG (argv, i, NULL);
+
+ r = commandv (&out, &err, argv);
+ if (r == -1) {
+ reply_with_error ("%s: %s", subvolume, err);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index 608ddf6..78aafb7 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12091,6 +12091,15 @@ can have suffix of G, M, or K. " };
longdesc = "\
Create a quota group (qgroup) for subvolume at C<subvolume>." };
+ { defaults with
+ name = "btrfs_qgroup_destroy";
+ style = RErr, [String "qgroupid"; Pathname
"subvolume"], [];
+ proc_nr = Some 432;
+ optional = Some "btrfs"; camel_name =
"BTRFSQgroupDestroy";
+ shortdesc = "destroy a subvolume quota group";
+ longdesc = "\
+Destroy a quota group." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index ed4f162..84796bf 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-431
+432
--
1.9.3
btrfs_qgroup_show shows all qgroups on a btrfs filesystem.
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
daemon/btrfs.c | 88 ++++++++++++++++++++++++++++++++
generator/actions.ml | 10 ++++
generator/structs.ml | 10 ++++
gobject/Makefile.inc | 2 +
java/Makefile.inc | 1 +
java/com/redhat/et/libguestfs/.gitignore | 1 +
po/POTFILES | 1 +
src/MAX_PROC_NR | 2 +-
8 files changed, 114 insertions(+), 1 deletion(-)
diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index 15e481a..3d7e79c 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -1184,3 +1184,91 @@ int 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 78aafb7..c7df0dd 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12100,6 +12100,16 @@ Create a quota group (qgroup) for subvolume at
C<subvolume>." };
longdesc = "\
Destroy a quota group." };
+ { defaults with
+ name = "btrfs_qgroup_show";
+ style = RStructList ("qgroups", "btrfsqgroup"),
[Pathname "path"], [];
+ proc_nr = Some 433;
+ 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 578ebb7..df3ff47 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 56a2fc3..2b15a10 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 \
@@ -105,6 +106,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 614caaa..34938fb 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 4882c96..1d4accc 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 36f61b2..ed40658 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -228,6 +228,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 84796bf..21fbd2e 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-432
+433
--
1.9.3
btrfs_qgroup_assign adds a qgroup to a parent qgroup.
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
daemon/btrfs.c | 33 +++++++++++++++++++++++++++++++++
generator/actions.ml | 10 ++++++++++
src/MAX_PROC_NR | 2 +-
3 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index 3d7e79c..0a04dd3 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -1272,3 +1272,36 @@ error:
return NULL;
}
+
+int do_btrfs_qgroup_assign (const char *src, const char *dst, 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;
+
+ path_buf = sysroot_path (path);
+ if (path_buf == NULL) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+
+ ADD_ARG (argv, i, str_btrfs);
+ ADD_ARG (argv, i, "qgroup");
+ ADD_ARG (argv, i, "assign");
+ ADD_ARG (argv, i, src);
+ ADD_ARG (argv, i, dst);
+ 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 -1;
+ }
+
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index c7df0dd..deb2d58 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12110,6 +12110,16 @@ Destroy a quota group." };
Show all subvolume quota groups in a btrfs filesystem, inclding their
usages." };
+ { defaults with
+ name = "btrfs_qgroup_assign";
+ style = RErr, [String "src"; String "dst"; Pathname
"path"], [];
+ proc_nr = Some 434;
+ optional = Some "btrfs"; camel_name =
"BTRFSQgroupAssign";
+ shortdesc = "add a qgroup to a parent qgroup";
+ longdesc = "\
+Add qgroup C<src> to parent qgroup C<dst>. This command can group
+several qgroups into a parent qgroup to share common limit." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 21fbd2e..e828e5d 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-433
+434
--
1.9.3
btrfs_qgroup_remove removes a qgroup from its parent qgroup.
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
daemon/btrfs.c | 33 +++++++++++++++++++++++++++++++++
generator/actions.ml | 9 +++++++++
src/MAX_PROC_NR | 2 +-
3 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/daemon/btrfs.c b/daemon/btrfs.c
index 0a04dd3..d40c432 100644
--- a/daemon/btrfs.c
+++ b/daemon/btrfs.c
@@ -1305,3 +1305,36 @@ int do_btrfs_qgroup_assign (const char *src, const char
*dst, const char *path)
return 0;
}
+
+int do_btrfs_qgroup_remove (const char *src, const char *dst, 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;
+
+ path_buf = sysroot_path (path);
+ if (path_buf == NULL) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+
+ ADD_ARG (argv, i, str_btrfs);
+ ADD_ARG (argv, i, "qgroup");
+ ADD_ARG (argv, i, "remove");
+ ADD_ARG (argv, i, src);
+ ADD_ARG (argv, i, dst);
+ 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 -1;
+ }
+
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index deb2d58..c1169cc 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12120,6 +12120,15 @@ usages." };
Add qgroup C<src> to parent qgroup C<dst>. This command can group
several qgroups into a parent qgroup to share common limit." };
+ { defaults with
+ name = "btrfs_qgroup_remove";
+ style = RErr, [String "src"; String "dst"; Pathname
"path"], [];
+ proc_nr = Some 435;
+ optional = Some "btrfs"; camel_name =
"BTRFSQgroupRemove";
+ shortdesc = "remove a qgroup from its parent qgroup";
+ longdesc = "\
+Remove qgroup C<src> from the parent qgroup C<dst>." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index e828e5d..5910394 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-434
+435
--
1.9.3
Richard W.M. Jones
2014-Dec-05 12:27 UTC
Re: [Libguestfs] [PATCH 1/8] New API: btrfs_subvolume_get_default
On Tue, Dec 02, 2014 at 05:33:31PM +0800, Hu Tao wrote:> + ADD_ARG (argv, i, str_btrfs); > + ADD_ARG (argv, i, "subvolume"); > + ADD_ARG (argv, i, "get-default"); > + ADD_ARG (argv, i, fs_buf); > + ADD_ARG (argv, i, NULL); > + > + r = commandv (&out, &err, argv); > + if (r == -1) { > + reply_with_error ("%s: %s", mountpoint, err); > + return -1; > + } > + r = xstrtol (out + 2, NULL, 10, &ret, NULL);Unfortunately even gnulib's "xstrtol" function is a minefield, and the code above won't work [specifically -- it's insecure] on 32 bit machines. Anyway, I think it's better to use sscanf here, so: if (sscanf (out, "ID %" SCNi64, &ret) != 2) { // error ... }> + if (r != LONGINT_OK) { > + reply_with_error ("%s: could not parse subvolume id: %s.", argv[0], out); > + return -1; > + } > + > + return ret; > +} > + > int > do_btrfs_filesystem_sync (const char *fs) > { > diff --git a/generator/actions.ml b/generator/actions.ml > index 385b620..80c7ea7 100644 > --- a/generator/actions.ml > +++ b/generator/actions.ml > @@ -12027,6 +12027,15 @@ Set readahead (in 512-byte sectors) for the device. > > This uses the L<blockdev(8)> command." }; > > + { defaults with > + name = "btrfs_subvolume_get_default"; > + style = RInt64 "id", [Pathname "mountpoint"], []; > + proc_nr = Some 425; > + optional = Some "btrfs"; camel_name = "BTRFSSubvolumeGetDefault"; > + shortdesc = "get the default subvolume or snapshot of a filesystem"; > + longdesc = "\ > +Get the default subvolume or snapshot of a filesystem mounted at C<mountpoint>." }; > +All of these APIs need tests. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-builder quickly builds VMs from scratch http://libguestfs.org/virt-builder.1.html
Richard W.M. Jones
2014-Dec-05 12:30 UTC
Re: [Libguestfs] [PATCH 2/8] New API: btrfs_subvolume_show
On Tue, Dec 02, 2014 at 05:33:32PM +0800, Hu Tao wrote:> btrfs_subvolume_show shows the detailed information of a subvolume or > snapshot. > > Signed-off-by: Hu Tao <hutao@cn.fujitsu.com> > --- > daemon/btrfs.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++ > generator/actions.ml | 9 +++ > src/MAX_PROC_NR | 2 +- > 3 files changed, 195 insertions(+), 1 deletion(-) > > diff --git a/daemon/btrfs.c b/daemon/btrfs.c > index 471cfbd..2cfb364 100644 > --- a/daemon/btrfs.c > +++ b/daemon/btrfs.c > @@ -24,11 +24,13 @@ > #include <pcre.h> > #include <string.h> > #include <unistd.h> > +#include <assert.h> > > #include "daemon.h" > #include "actions.h" > #include "optgroups.h" > #include "xstrtol.h" > +#include "c-ctype.h" > > GUESTFSD_EXT_CMD(str_btrfs, btrfs); > GUESTFSD_EXT_CMD(str_btrfstune, btrfstune); > @@ -810,3 +812,186 @@ do_btrfs_fsck (const char *device, int64_t superblock, int repair) > > return 0; > }Ugh. 'btrfs' should have more easily parsable output.> +/* analyze_line: analyze one line contains key:value pair. > + * returns the next position following \n. > + */ > +static char *analyze_line (char *line, char **key, char **value)Can you put the function name on a new line, so: static char * analyze_line (char *line, char **key, char **value) The reason for this is to allow you to easily grep function declarations in the source: git grep ^analyze_line> +{ > + char *p = line; > + char *next = NULL; > + char delimiter = ':'; > + char *del_pos = NULL; > + > + if (!line || *line == '\0') { > + *key = NULL; > + *value = NULL; > + return NULL; > + } > + > + next = strchr (p, '\n'); > + if (next) { > + *next = '\0'; > + ++next; > + } > + > + /* leading spaces and tabs */ > + while (*p && c_isspace (*p)) > + ++p; > + > + assert (key); > + if (*p == delimiter) > + *key = NULL; > + else > + *key = p; > + > + del_pos = strchr (p, delimiter); > + if (del_pos) { > + *del_pos = '\0'; > + > + /* leading spaces and tabs */ > + do { > + ++del_pos; > + } while (*del_pos && c_isspace (*del_pos)); > + assert (value); > + *value = del_pos; > + } else > + *value = NULL; > + > + return next; > +}> +char **do_btrfs_subvolume_show (const char *subvolume) > +{ > + const size_t MAX_ARGS = 64; > + const char *argv[MAX_ARGS]; > + size_t i = 0; > + CLEANUP_FREE char *subvolume_buf = NULL; > + CLEANUP_FREE char *err = NULL; > + CLEANUP_FREE char *out = NULL; > + char *p, *key = NULL, *value = NULL; > + DECLARE_STRINGSBUF (ret); > + int r; > + > + subvolume_buf = sysroot_path (subvolume); > + if (subvolume_buf == NULL) { > + reply_with_perror ("malloc"); > + return NULL; > + } > + > + ADD_ARG (argv, i, str_btrfs); > + ADD_ARG (argv, i, "subvolume"); > + ADD_ARG (argv, i, "show"); > + ADD_ARG (argv, i, subvolume_buf); > + ADD_ARG (argv, i, NULL); > + > + r = commandv (&out, &err, argv); > + if (r == -1) { > + reply_with_error ("%s: %s", subvolume, err); > + return NULL; > + } > + > + /* Output is: > + * > + * / > + * Name: root > + * uuid: c875169e-cf4e-a04d-9959-b667dec36234 > + * Parent uuid: - > + * Creation time: 2014-11-13 10:13:08 > + * Object ID: 256 > + * Generation (Gen): 6579 > + * Gen at creation: 5 > + * Parent: 5 > + * Top Level: 5 > + * Flags: - > + * Snapshot(s): > + * snapshots/test1 > + * snapshots/test2 > + * snapshots/test3 > + * > + */ > + p = analyze_line(out, &key, &value); > + if (!p) { > + reply_with_error ("truncated output: %s", out); > + return NULL; > + } > + > + /* If the path is the btrfs root, `btrfs subvolume show' reports: > + * <path> is btrfs root > + */ > + if (strstr (key, "is btrfs root") != NULL) { > + reply_with_error ("%s is btrfs root", subvolume); > + return NULL; > + } > + > + /* The first line is the path of the subvolume. */ > + if (key && !value) { > + if (add_string (&ret, "path") == -1) > + return NULL; > + if (add_string (&ret, key) == -1) > + return NULL; > + } else { > + if (add_string (&ret, key) == -1) > + return NULL; > + if (add_string (&ret, value) == -1) > + return NULL; > + } > + > + /* Read the lines and split into "key: value". */ > + p = analyze_line(p, &key, &value); > + while (key) { > + /* snapshot is special, see the output above */ > + if (STREQLEN (key, "Snapshot(s)", sizeof ("Snapshot(s)") - 1)) { > + char *ss = NULL; > + int ss_len = 0; > + > + if (add_string (&ret, key) == -1) > + return NULL; > + > + p = analyze_line(p, &key, &value); > + > + while (key && !value) { > + ss = realloc (ss, ss_len + strlen (key) + 1); > + if (!ss) > + return NULL; > + > + if (ss_len != 0) > + ss[ss_len++] = ','; > + > + memcpy (ss + ss_len, key, strlen (key)); > + ss_len += strlen (key); > + ss[ss_len] = '\0'; > + > + p = analyze_line(p, &key, &value); > + } > + > + if (ss) { > + if (add_string_nodup (&ret, ss) == -1) { > + free (ss); > + return NULL; > + } > + } else { > + if (add_string (&ret, "") == -1) > + return NULL; > + } > + } else { > + if (add_string (&ret, key ? key : "") == -1) > + return NULL; > + if (value && !STREQ(value, "-")) { > + if (add_string (&ret, value) == -1) > + return NULL; > + } else { > + if (add_string (&ret, "") == -1) > + return NULL; > + } > + > + p = analyze_line(p, &key, &value); > + } > + } > + > + if (end_stringsbuf (&ret) == -1) > + return NULL; > + > + return ret.argv; > + > +} > diff --git a/generator/actions.ml b/generator/actions.ml > index 80c7ea7..d5ec528 100644 > --- a/generator/actions.ml > +++ b/generator/actions.ml > @@ -12036,6 +12036,15 @@ This uses the L<blockdev(8)> command." }; > longdesc = "\ > Get the default subvolume or snapshot of a filesystem mounted at C<mountpoint>." }; > > + { defaults with > + name = "btrfs_subvolume_show"; > + style = RHashtable "btrfssubvolumeinfo", [Pathname "subvolume"], []; > + proc_nr = Some 426; > + optional = Some "btrfs"; camel_name = "BTRFSSubvolumeShow"; > + shortdesc = "return detailed information of the subvolume"; > + longdesc = "\ > +Return detailed information of the subvolume." }; > + > ] > > (* Non-API meta-commands available only in guestfish. > diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR > index 5e4a522..9f51d08 100644 > --- a/src/MAX_PROC_NR > +++ b/src/MAX_PROC_NR > @@ -1 +1 @@ > -425 > +426This desperately needs tests. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-builder quickly builds VMs from scratch http://libguestfs.org/virt-builder.1.html
Richard W.M. Jones
2014-Dec-05 12:32 UTC
Re: [Libguestfs] [PATCH 3/8] New API: btrfs_quota_enable
On Tue, Dec 02, 2014 at 05:33:33PM +0800, Hu Tao wrote:> btrfs_quota_enable enables quota for subvolumes. > > Signed-off-by: Hu Tao <hutao@cn.fujitsu.com> > --- > daemon/btrfs.c | 31 +++++++++++++++++++++++++++++++ > generator/actions.ml | 9 +++++++++ > src/MAX_PROC_NR | 2 +- > 3 files changed, 41 insertions(+), 1 deletion(-) > > diff --git a/daemon/btrfs.c b/daemon/btrfs.c > index 2cfb364..31dd806 100644 > --- a/daemon/btrfs.c > +++ b/daemon/btrfs.c > @@ -995,3 +995,34 @@ char **do_btrfs_subvolume_show (const char *subvolume) > return ret.argv; > > } > + > +int do_btrfs_quota_enable (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; > + > + path_buf = sysroot_path (path); > + if (path_buf == NULL) { > + reply_with_perror ("malloc"); > + return -1; > + } > + > + ADD_ARG (argv, i, str_btrfs); > + ADD_ARG (argv, i, "quota"); > + ADD_ARG (argv, i, "enable"); > + 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 -1; > + } > + > + return 0; > +} > diff --git a/generator/actions.ml b/generator/actions.ml > index d5ec528..3af8380 100644 > --- a/generator/actions.ml > +++ b/generator/actions.ml > @@ -12045,6 +12045,15 @@ Get the default subvolume or snapshot of a filesystem mounted at C<mountpoint>." > longdesc = "\ > Return detailed information of the subvolume." }; > > + { defaults with > + name = "btrfs_quota_enable"; > + style = RErr, [Pathname "path"], []; > + proc_nr = Some 427; > + optional = Some "btrfs"; camel_name = "BTRFSQuotaEnable"; > + shortdesc = "enable subvolume quota support"; > + longdesc = "\ > +Enable subvolume quota support for filesystem which contains C<path>." }; > + > ] > > (* Non-API meta-commands available only in guestfish. > diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR > index 9f51d08..d2a1e59 100644 > --- a/src/MAX_PROC_NR > +++ b/src/MAX_PROC_NR > @@ -1 +1 @@ > -426 > +427ACK, but could benefit from a test too. 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/
Richard W.M. Jones
2014-Dec-05 12:33 UTC
Re: [Libguestfs] [PATCH 4/8] New API: btrfs_quota_disable
On Tue, Dec 02, 2014 at 05:33:34PM +0800, Hu Tao wrote:> btrfs_quota_disable disables quota for subvolumes. > > Signed-off-by: Hu Tao <hutao@cn.fujitsu.com> > --- > daemon/btrfs.c | 31 +++++++++++++++++++++++++++++++ > generator/actions.ml | 9 +++++++++ > src/MAX_PROC_NR | 2 +- > 3 files changed, 41 insertions(+), 1 deletion(-) > > diff --git a/daemon/btrfs.c b/daemon/btrfs.c > index 31dd806..5fcb85b 100644 > --- a/daemon/btrfs.c > +++ b/daemon/btrfs.c > @@ -1026,3 +1026,34 @@ int do_btrfs_quota_enable (const char *path) > > return 0; > } > + > +int do_btrfs_quota_disable (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; > + > + path_buf = sysroot_path (path); > + if (path_buf == NULL) { > + reply_with_perror ("malloc"); > + return -1; > + } > + > + ADD_ARG (argv, i, str_btrfs); > + ADD_ARG (argv, i, "quota"); > + ADD_ARG (argv, i, "disable"); > + 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 -1; > + } > + > + return 0; > +} > diff --git a/generator/actions.ml b/generator/actions.ml > index 3af8380..ab1a07a 100644 > --- a/generator/actions.ml > +++ b/generator/actions.ml > @@ -12054,6 +12054,15 @@ Return detailed information of the subvolume." }; > longdesc = "\ > Enable subvolume quota support for filesystem which contains C<path>." }; > > + { defaults with > + name = "btrfs_quota_disable"; > + style = RErr, [Pathname "path"], []; > + proc_nr = Some 428; > + optional = Some "btrfs"; camel_name = "BTRFSQuotaDisable"; > + shortdesc = "disable subvolume quota support"; > + longdesc = "\ > +Disable subvolume quota support for filesystem which contains C<path>." }; > + > ] > > (* Non-API meta-commands available only in guestfish. > diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR > index d2a1e59..43d371a 100644 > --- a/src/MAX_PROC_NR > +++ b/src/MAX_PROC_NR > @@ -1 +1 @@ > -427 > +428ACK. Could do with a test. How about combining this with the previous API, so you'd have: guestfs_btrfs_quota (guestfs_h *g, int enable); ? Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org
Richard W.M. Jones
2014-Dec-05 12:33 UTC
Re: [Libguestfs] [PATCH 5/8] New API: btrfs_quota_rescan
On Tue, Dec 02, 2014 at 05:33:35PM +0800, Hu Tao wrote:> btrfs_quota_rescan trashs all qgroup numbers and scans the metadata > again with the current config. > > Signed-off-by: Hu Tao <hutao@cn.fujitsu.com> > --- > daemon/btrfs.c | 31 +++++++++++++++++++++++++++++++ > generator/actions.ml | 9 +++++++++ > src/MAX_PROC_NR | 2 +- > 3 files changed, 41 insertions(+), 1 deletion(-) > > diff --git a/daemon/btrfs.c b/daemon/btrfs.c > index 5fcb85b..6918d4f 100644 > --- a/daemon/btrfs.c > +++ b/daemon/btrfs.c > @@ -1057,3 +1057,34 @@ int do_btrfs_quota_disable (const char *path) > > return 0; > } > + > +int do_btrfs_quota_rescan (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; > + > + path_buf = sysroot_path (path); > + if (path_buf == NULL) { > + reply_with_perror ("malloc"); > + return -1; > + } > + > + ADD_ARG (argv, i, str_btrfs); > + ADD_ARG (argv, i, "quota"); > + ADD_ARG (argv, i, "rescan"); > + 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 -1; > + } > + > + return 0; > +} > diff --git a/generator/actions.ml b/generator/actions.ml > index ab1a07a..f24d5d7 100644 > --- a/generator/actions.ml > +++ b/generator/actions.ml > @@ -12063,6 +12063,15 @@ Enable subvolume quota support for filesystem which contains C<path>." }; > longdesc = "\ > Disable subvolume quota support for filesystem which contains C<path>." }; > > + { defaults with > + name = "btrfs_quota_rescan"; > + style = RErr, [Pathname "path"], []; > + proc_nr = Some 429; > + optional = Some "btrfs"; camel_name = "BTRFSQuotaRescan"; > + shortdesc = "trash all qgroup numbers and scan the metadata again with the current config"; > + longdesc = "\ > +Trash all qgroup numbers and scan the metadata again with the current config." }; > + > ] > > (* Non-API meta-commands available only in guestfish. > diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR > index 43d371a..3560666 100644 > --- a/src/MAX_PROC_NR > +++ b/src/MAX_PROC_NR > @@ -1 +1 @@ > -428 > +429ACK. Could use a simple test. 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/
Richard W.M. Jones
2014-Dec-05 12:34 UTC
Re: [Libguestfs] [PATCH 6/8] New API: btrfs_qgroup_limit
On Tue, Dec 02, 2014 at 05:33:36PM +0800, Hu Tao wrote:> btrfs_qgroup_limit limits the size of a qgroup. > + style = RErr, [Pathname "subvolume"; String "size"], []; > + proc_nr = Some 430; > + optional = Some "btrfs"; camel_name = "BTRFSQgroupLimit"; > + shortdesc = "limit the size of a subvolume"; > + longdesc = "\ > +Limit the size of a subvolume which's path is C<subvolume>. C<size> > +can have suffix of G, M, or K. " };Oh dear no. Pass size as an 'Int64'. 'guestfish' will magically allow people to use size qualifiers. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW
Richard W.M. Jones
2014-Dec-05 12:35 UTC
Re: [Libguestfs] [PATCH 7/8] New API: btrfs_qgroup_create
On Tue, Dec 02, 2014 at 05:33:37PM +0800, Hu Tao wrote:> btrfs_qgroup_create creates a new qgroup. > > Signed-off-by: Hu Tao <hutao@cn.fujitsu.com> > --- > daemon/btrfs.c | 32 ++++++++++++++++++++++++++++++++ > generator/actions.ml | 9 +++++++++ > src/MAX_PROC_NR | 2 +- > 3 files changed, 42 insertions(+), 1 deletion(-) > > diff --git a/daemon/btrfs.c b/daemon/btrfs.c > index 033d460..dccaf5a 100644 > --- a/daemon/btrfs.c > +++ b/daemon/btrfs.c > @@ -1120,3 +1120,35 @@ int do_btrfs_qgroup_limit (const char *subvolume, const char *size) > > return 0; > } > + > +int do_btrfs_qgroup_create (const char *qgroupid, const char *subvolume) > +{ > + const size_t MAX_ARGS = 64; > + const char *argv[MAX_ARGS]; > + size_t i = 0; > + CLEANUP_FREE char *subvolume_buf = NULL; > + CLEANUP_FREE char *err = NULL; > + CLEANUP_FREE char *out = NULL; > + int r; > + > + subvolume_buf = sysroot_path (subvolume); > + if (subvolume_buf == NULL) { > + reply_with_perror ("malloc"); > + return -1; > + } > + > + ADD_ARG (argv, i, str_btrfs); > + ADD_ARG (argv, i, "qgroup"); > + ADD_ARG (argv, i, "create"); > + ADD_ARG (argv, i, qgroupid); > + ADD_ARG (argv, i, subvolume_buf); > + ADD_ARG (argv, i, NULL); > + > + r = commandv (&out, &err, argv); > + if (r == -1) { > + reply_with_error ("%s: %s", subvolume, err); > + return -1; > + } > + > + return 0; > +} > diff --git a/generator/actions.ml b/generator/actions.ml > index 5d64350..608ddf6 100644 > --- a/generator/actions.ml > +++ b/generator/actions.ml > @@ -12082,6 +12082,15 @@ Trash all qgroup numbers and scan the metadata again with the current config." } > Limit the size of a subvolume which's path is C<subvolume>. C<size> > can have suffix of G, M, or K. " }; > > + { defaults with > + name = "btrfs_qgroup_create"; > + style = RErr, [String "qgroupid"; Pathname "subvolume"], []; > + proc_nr = Some 431; > + optional = Some "btrfs"; camel_name = "BTRFSQgroupCreate"; > + shortdesc = "create a subvolume quota group"; > + longdesc = "\ > +Create a quota group (qgroup) for subvolume at C<subvolume>." }; > + > ] > > (* Non-API meta-commands available only in guestfish. > diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR > index c15fb93..ed4f162 100644 > --- a/src/MAX_PROC_NR > +++ b/src/MAX_PROC_NR > @@ -1 +1 @@ > -430 > +431Seems OK, but there needs to be a test of qgroups. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v
Richard W.M. Jones
2014-Dec-05 12:36 UTC
Re: [Libguestfs] [PATCH 09/11] New API: btrfs_qgroup_show
On Fri, Dec 05, 2014 at 04:20:40PM +0800, Hu Tao wrote:> btrfs_qgroup_show shows all qgroups on a btrfs filesystem. > > Signed-off-by: Hu Tao <hutao@cn.fujitsu.com> > --- > daemon/btrfs.c | 88 ++++++++++++++++++++++++++++++++ > generator/actions.ml | 10 ++++ > generator/structs.ml | 10 ++++ > gobject/Makefile.inc | 2 + > java/Makefile.inc | 1 + > java/com/redhat/et/libguestfs/.gitignore | 1 + > po/POTFILES | 1 + > src/MAX_PROC_NR | 2 +- > 8 files changed, 114 insertions(+), 1 deletion(-) > > diff --git a/daemon/btrfs.c b/daemon/btrfs.c > index 15e481a..3d7e79c 100644 > --- a/daemon/btrfs.c > +++ b/daemon/btrfs.c > @@ -1184,3 +1184,91 @@ int 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 78aafb7..c7df0dd 100644 > --- a/generator/actions.ml > +++ b/generator/actions.ml > @@ -12100,6 +12100,16 @@ Create a quota group (qgroup) for subvolume at C<subvolume>." }; > longdesc = "\ > Destroy a quota group." }; > > + { defaults with > + name = "btrfs_qgroup_show"; > + style = RStructList ("qgroups", "btrfsqgroup"), [Pathname "path"], []; > + proc_nr = Some 433; > + 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 578ebb7..df3ff47 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 56a2fc3..2b15a10 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 \ > @@ -105,6 +106,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 614caaa..34938fb 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 4882c96..1d4accc 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 36f61b2..ed40658 100644 > --- a/po/POTFILES > +++ b/po/POTFILES > @@ -228,6 +228,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 84796bf..21fbd2e 100644 > --- a/src/MAX_PROC_NR > +++ b/src/MAX_PROC_NR > @@ -1 +1 @@ > -432 > +433Looks OK, needs to be included in some kind of qgroup test. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://people.redhat.com/~rjones/virt-top
Richard W.M. Jones
2014-Dec-05 12:37 UTC
Re: [Libguestfs] [PATCH 10/11] New API: btrfs_qgroup_assign
On Fri, Dec 05, 2014 at 04:20:41PM +0800, Hu Tao wrote:> btrfs_qgroup_assign adds a qgroup to a parent qgroup. > > Signed-off-by: Hu Tao <hutao@cn.fujitsu.com> > --- > daemon/btrfs.c | 33 +++++++++++++++++++++++++++++++++ > generator/actions.ml | 10 ++++++++++ > src/MAX_PROC_NR | 2 +- > 3 files changed, 44 insertions(+), 1 deletion(-) > > diff --git a/daemon/btrfs.c b/daemon/btrfs.c > index 3d7e79c..0a04dd3 100644 > --- a/daemon/btrfs.c > +++ b/daemon/btrfs.c > @@ -1272,3 +1272,36 @@ error: > > return NULL; > } > + > +int do_btrfs_qgroup_assign (const char *src, const char *dst, 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; > + > + path_buf = sysroot_path (path); > + if (path_buf == NULL) { > + reply_with_perror ("malloc"); > + return -1; > + } > + > + ADD_ARG (argv, i, str_btrfs); > + ADD_ARG (argv, i, "qgroup"); > + ADD_ARG (argv, i, "assign"); > + ADD_ARG (argv, i, src); > + ADD_ARG (argv, i, dst); > + 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 -1; > + } > + > + return 0; > +} > diff --git a/generator/actions.ml b/generator/actions.ml > index c7df0dd..deb2d58 100644 > --- a/generator/actions.ml > +++ b/generator/actions.ml > @@ -12110,6 +12110,16 @@ Destroy a quota group." }; > Show all subvolume quota groups in a btrfs filesystem, inclding their > usages." }; > > + { defaults with > + name = "btrfs_qgroup_assign"; > + style = RErr, [String "src"; String "dst"; Pathname "path"], []; > + proc_nr = Some 434; > + optional = Some "btrfs"; camel_name = "BTRFSQgroupAssign"; > + shortdesc = "add a qgroup to a parent qgroup"; > + longdesc = "\ > +Add qgroup C<src> to parent qgroup C<dst>. This command can group > +several qgroups into a parent qgroup to share common limit." }; > + > ] > > (* Non-API meta-commands available only in guestfish. > diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR > index 21fbd2e..e828e5d 100644 > --- a/src/MAX_PROC_NR > +++ b/src/MAX_PROC_NR > @@ -1 +1 @@ > -433 > +434Looks OK, needs a test. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://people.redhat.com/~rjones/virt-top
Richard W.M. Jones
2014-Dec-05 12:37 UTC
Re: [Libguestfs] [PATCH 11/11] New API: btrfs_qgroup_remove
On Fri, Dec 05, 2014 at 04:20:42PM +0800, Hu Tao wrote:> btrfs_qgroup_remove removes a qgroup from its parent qgroup. > > Signed-off-by: Hu Tao <hutao@cn.fujitsu.com> > --- > daemon/btrfs.c | 33 +++++++++++++++++++++++++++++++++ > generator/actions.ml | 9 +++++++++ > src/MAX_PROC_NR | 2 +- > 3 files changed, 43 insertions(+), 1 deletion(-) > > diff --git a/daemon/btrfs.c b/daemon/btrfs.c > index 0a04dd3..d40c432 100644 > --- a/daemon/btrfs.c > +++ b/daemon/btrfs.c > @@ -1305,3 +1305,36 @@ int do_btrfs_qgroup_assign (const char *src, const char *dst, const char *path) > > return 0; > } > + > +int do_btrfs_qgroup_remove (const char *src, const char *dst, 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; > + > + path_buf = sysroot_path (path); > + if (path_buf == NULL) { > + reply_with_perror ("malloc"); > + return -1; > + } > + > + ADD_ARG (argv, i, str_btrfs); > + ADD_ARG (argv, i, "qgroup"); > + ADD_ARG (argv, i, "remove"); > + ADD_ARG (argv, i, src); > + ADD_ARG (argv, i, dst); > + 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 -1; > + } > + > + return 0; > +} > diff --git a/generator/actions.ml b/generator/actions.ml > index deb2d58..c1169cc 100644 > --- a/generator/actions.ml > +++ b/generator/actions.ml > @@ -12120,6 +12120,15 @@ usages." }; > Add qgroup C<src> to parent qgroup C<dst>. This command can group > several qgroups into a parent qgroup to share common limit." }; > > + { defaults with > + name = "btrfs_qgroup_remove"; > + style = RErr, [String "src"; String "dst"; Pathname "path"], []; > + proc_nr = Some 435; > + optional = Some "btrfs"; camel_name = "BTRFSQgroupRemove"; > + shortdesc = "remove a qgroup from its parent qgroup"; > + longdesc = "\ > +Remove qgroup C<src> from the parent qgroup C<dst>." }; > + > ]Ditto. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW
Apparently Analagous Threads
- [PATCH v3 00/11] btrfs support part2: qgroup/quota commands
- [PATCH v2 00/11] btrfs support part2: qgroup/quota commands
- [PATCH v2 0/5] btrfs support part1: subvolume commands
- [PATCH 00/16] btrfs: add support to btrfs scrub, balance, rescue and inspect
- [PATCH 0/6] btrfs support part1: subvolume commands