[Libguestfs] [PATCH 1/2] New API: btrfs_balance_status

Richard W.M. Jones rjones at redhat.com
Mon Feb 2 13:29:35 UTC 2015


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




More information about the Libguestfs mailing list