[Libguestfs] [PATCHv3] Added btrfs support to vfs_minimum_size.

Richard W.M. Jones rjones at redhat.com
Tue Oct 27 14:59:53 UTC 2015


On Tue, Oct 27, 2015 at 05:55:40PM +0300, Maxim Perevedentsev wrote:
> ---
>  daemon/btrfs.c       | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  daemon/daemon.h      |  1 +
>  daemon/fs-min-size.c | 34 ++++++++++++++++++++++++-
>  generator/actions.ml |  6 ++++-
>  4 files changed, 110 insertions(+), 2 deletions(-)
> 
> diff --git a/daemon/btrfs.c b/daemon/btrfs.c
> index ddb029d..652a17e 100644
> --- a/daemon/btrfs.c
> +++ b/daemon/btrfs.c
> @@ -2190,3 +2190,74 @@ do_btrfs_replace (const char *srcdev, const char *targetdev,
> 
>    return 0;
>  }
> +
> +/* btrfs command add a new command
> + * inspect-internal min-dev-size <path>
> + * since v4.2
> + * We could check whether 'btrfs' supports
> + * 'min-dev-size' command by checking the output of
> + * 'btrfs --help' command.
> + */
> +static int
> +test_btrfs_min_dev_size (void)
> +{
> +  CLEANUP_FREE char *err = NULL, *out = NULL;
> +  static int result = -1;
> +  const char *cmd_pattern = "btrfs inspect-internal min-dev-size";
> +  int r;
> +
> +  if (result != -1)
> +    return result;
> +
> +  r = commandr (&out, &err, str_btrfs, "--help", NULL);
> +
> +  if (r == -1) {
> +    reply_with_error ("btrfs: %s", err);
> +    return -1;
> +  }
> +
> +  if (strstr (out, cmd_pattern) == NULL)
> +    result = 0;
> +  else
> +    result = 1;
> +
> +  return result;
> +}
> +
> +int64_t
> +btrfs_minimum_size (const char *path)
> +{
> +  CLEANUP_FREE char *err = NULL, *out = NULL;
> +  int64_t ret = 0;
> +  int r;
> +  int min_size_supported = test_btrfs_min_dev_size ();
> +
> +  if (min_size_supported == -1)
> +    return -1;
> +  else if (min_size_supported == 0)
> +    NOT_SUPPORTED (-1, "'btrfs inspect-internal min-dev-size' \
> +                        needs btrfs-progs >= 4.2");
> +
> +  r = command (&out, &err, str_btrfs, "inspect-internal",
> +               "min-dev-size", sysroot_path (path), NULL);
> +
> +  if (r == -1) {
> +    reply_with_error ("%s", err);
> +    return -1;
> +  }
> +
> +#if __WORDSIZE == 64
> +#define XSTRTOD64 xstrtol
> +#else
> +#define XSTRTOD64 xstrtoll
> +#endif
> +
> +  if (XSTRTOD64 (out, NULL, 10, &ret, NULL) != LONGINT_OK) {
> +    reply_with_error ("cannot parse minimum size");
> +    return -1;
> +  }
> +
> +#undef XSTRTOD64
> +
> +  return ret;
> +}
> diff --git a/daemon/daemon.h b/daemon/daemon.h
> index 8bcc9bd..4a969dd 100644
> --- a/daemon/daemon.h
> +++ b/daemon/daemon.h
> @@ -280,6 +280,7 @@ extern char *btrfs_get_label (const char *device);
>  extern int btrfs_set_label (const char *device, const char *label);
>  extern int btrfs_set_uuid (const char *device, const char *uuid);
>  extern int btrfs_set_uuid_random (const char *device);
> +extern int64_t btrfs_minimum_size (const char *path);
> 
>  /*-- in ntfs.c --*/
>  extern char *ntfs_get_label (const char *device);
> diff --git a/daemon/fs-min-size.c b/daemon/fs-min-size.c
> index 4f93f8c..ca71c4d 100644
> --- a/daemon/fs-min-size.c
> +++ b/daemon/fs-min-size.c
> @@ -25,12 +25,37 @@
>  #include "daemon.h"
>  #include "actions.h"
> 
> +static char*
> +get_mount_point (const char *device)
> +{
> +  CLEANUP_FREE_STRING_LIST char **mountpoints = do_mountpoints();
> +  size_t i;
> +  char *path;
> +
> +  if (mountpoints == NULL) {
> +    reply_with_error ("cannot get mountpoints");
> +    return NULL;
> +  }
> +
> +  for (i = 0; mountpoints[i] != NULL; i += 2) {
> +    if (STREQ (mountpoints[i], device)) {
> +      path = strdup (mountpoints[i + 1]);
> +      if (path == NULL)
> +        reply_with_perror ("strdup");
> +      return path;
> +    }
> +  }
> +
> +  reply_with_error ("device not mounted: %s", device);
> +  return NULL;
> +}
> +
>  int64_t
>  do_vfs_minimum_size (const mountable_t *mountable)
>  {
>    int64_t r;
> 
> -  /* How we set the label depends on the filesystem type. */
> +  /* How we get minimum size depends on the filesystem type. */
>    CLEANUP_FREE char *vfs_type = do_vfs_type (mountable);
>    if (vfs_type == NULL)
>      return -1;
> @@ -41,6 +66,13 @@ do_vfs_minimum_size (const mountable_t *mountable)
>    else if (STREQ (vfs_type, "ntfs"))
>      r = ntfs_minimum_size (mountable->device);
> 
> +  else if (STREQ (vfs_type, "btrfs")) {
> +    CLEANUP_FREE char *path = get_mount_point (mountable->device);
> +    if (path == NULL)
> +      return -1;
> +    r = btrfs_minimum_size (path);
> +  }
> +
>    else
>      NOT_SUPPORTED (-1, "don't know how to get minimum size of '%s' filesystems",
>                     vfs_type);
> diff --git a/generator/actions.ml b/generator/actions.ml
> index 62176ab..8832410 100644
> --- a/generator/actions.ml
> +++ b/generator/actions.ml
> @@ -12761,6 +12761,10 @@ To read the UUID on a filesystem, call C<guestfs_vfs_uuid>." };
>        InitPartition, IfAvailable "ntfsprogs", TestRun(
>          [["mkfs"; "ntfs"; "/dev/sda1"; ""; "NOARG"; ""; ""; "NOARG"];
>           ["vfs_minimum_size"; "/dev/sda1"]]), [];
> +      InitPartition, Always, TestRun (
> +        [["mkfs"; "btrfs"; "/dev/sda1"; ""; "NOARG"; ""; ""; "NOARG"];
> +         ["mount"; "/dev/sda1"; "/"];
> +         ["vfs_minimum_size"; "/dev/sda1"]]), [];
>      ];
>      shortdesc = "get minimum filesystem size";
>      longdesc = "\
> @@ -12770,7 +12774,7 @@ This is the minimum possible size for filesystem shrinking.
>  If getting minimum size of specified filesystem is not supported,
>  this will fail and set errno as ENOTSUP.
> 
> -See also L<ntfsresize(8)>, L<resize2fs(8)>." };
> +See also L<ntfsresize(8)>, L<resize2fs(8)>, L<btrfs(8)>." };

This looks good.  Just running the tests, and should be able to push
it shortly.

Thanks,

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