On Mon, Feb 02, 2015 at 02:11:31PM +0800, Hu Tao wrote:
[..]
So in fact there are a few problems. I couldn't get btrfs balance to
actually do anything at all (perhaps it doesn't work on empty
filesystems), so this come only from code inspection.
+ lines = split_lines (out);
+ if (!lines)
+ return NULL;
+
+ ret = malloc(sizeof *ret);
+ if (ret == NULL) {
+ reply_with_perror ("malloc");
+ goto error;
+ }
+ memset (ret, 0, sizeof(*ret));
+
+ /* Output of `btrfs balance status' is like:
+ *
+ * running:
+ *
+ * Balance on '/' is running
+ * 3 out of about 8 chunks balanced (3 considered), 62% left
+ *
+ * paused:
+ *
+ * Balance on '/' is paused
+ * 3 out of about 8 chunks balanced (3 considered), 62% left
+ *
+ * no balance running:
+ *
+ * No Balance found on '/'
+ *
+ */
+ if (strstr (lines[0], "No balance found on")) {
In case the output of the btrfs command changes in future, you need to
check that the length of the lines[] array is >= 1 here, and >= 2
below. Otherwise this code will segfault.
+ ret->btrfsbalance_status = strdup("none");
Where you call strdup, you have to check that the return value is not
NULL, and if it is call reply_with_perror ("strdup").
+ return ret;
+ }
+
+ re = pcre_compile ("Balance on '.*' is (.*)", 0, &errptr,
&erroffset, NULL);
+ if (re == NULL) {
+ reply_with_error ("pcre_compile (%i): %s", erroffset, errptr);
+ goto error;
+ }
+ if (pcre_exec (re, NULL, lines[0], strlen (lines[0]), 0, 0,
+ ovector, N_MATCH * 3) < 0) {
+ reply_with_error ("unexpected output from 'btrfs balance status'
command: %s", lines[0]);
+ goto error;
+ }
+#undef N_MATCH
+
+ if (STREQ (lines[0] + ovector[2], "running"))
+ ret->btrfsbalance_status = strdup("running");
+ else if (STREQ (lines[0] + ovector[2], "paused"))
+ ret->btrfsbalance_status = strdup("paused");
+ else {
+ reply_with_error ("unexpected output from 'btrfs balance status'
command: %s", lines[0]);
+ goto error;
+ }
+
+ if (sscanf (lines[1], "%" SCNu64 " out of about %" SCNu64
+ " chunks balanced (%" SCNu64 " considered), %" SCNu64
"%% left",
+ &ret->btrfsbalance_balanced, &ret->btrfsbalance_total,
+ &ret->btrfsbalance_considered, &ret->btrfsbalance_left) !=
4) {
+ reply_with_perror ("sscanf");
+ goto error;
+ }
+
+ pcre_free (re);
+ return ret;
+
+error:
+ free (ret->btrfsbalance_status);
+ free (ret);
+ pcre_free (re);
+
+ return NULL;
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