[Libguestfs] [PATCH 2/7] btrfs: Update btrfs_subvolume_list to take Mountable_or_Path

Richard W.M. Jones rjones at redhat.com
Tue Feb 12 12:08:44 UTC 2013


On Tue, Feb 12, 2013 at 11:04:21AM +0000, Matthew Booth wrote:
> btrfs_subvolume_list can now take either the path of a mounted btrfs
> filesystem, or a mountable describing the location of a btrfs
> filesystem, or one of its volumes. In the latter case, the filesystem
> will be automatically mounted outside of /sysroot before running the
> btrfs tool, and unmounted afterwards.
> ---
>  daemon/btrfs.c       | 71 ++++++++++++++++++++++++++++++++++++++++++++--------
>  generator/actions.ml |  2 +-
>  2 files changed, 61 insertions(+), 12 deletions(-)
> 
> diff --git a/daemon/btrfs.c b/daemon/btrfs.c
> index 81ce5f5..c3247ac 100644
> --- a/daemon/btrfs.c
> +++ b/daemon/btrfs.c
> @@ -34,6 +34,7 @@ GUESTFSD_EXT_CMD(str_btrfs, btrfs);
>  GUESTFSD_EXT_CMD(str_btrfstune, btrfstune);
>  GUESTFSD_EXT_CMD(str_btrfsck, btrfsck);
>  GUESTFSD_EXT_CMD(str_mkfs_btrfs, mkfs.btrfs);
> +GUESTFSD_EXT_CMD(str_umount, umount);
>  
>  int
>  optgroup_btrfs_available (void)
> @@ -307,16 +308,47 @@ do_btrfs_subvolume_create (const char *dest)
>  }
>  
>  guestfs_int_btrfssubvolume_list *
> -do_btrfs_subvolume_list (const char *fs)
> +do_btrfs_subvolume_list (const mountable_t *fs)
>  {
>    char **lines;
>  
>    /* Execute 'btrfs subvolume list <fs>', and split the output into lines */
>    {
> -    CLEANUP_FREE char *fs_buf = sysroot_path (fs);
> -    if (fs_buf == NULL) {
> -      reply_with_perror ("malloc");
> -      return NULL;
> +    CLEANUP_FREE char *fs_buf = NULL;
> +
> +    if (fs->type == MOUNTABLE_PATH) {
> +      fs_buf = sysroot_path (fs->device);
> +      if (fs_buf == NULL) {
> +        reply_with_perror ("malloc");
> +
> +      cmderror:
> +        if (fs->type != MOUNTABLE_PATH && fs_buf) {
> +          CLEANUP_FREE char *err = NULL;
> +          if (command (NULL, &err, str_umount, fs_buf, NULL) == -1)
> +            fprintf (stderr, "%s\n", err);
> +
> +          if (rmdir (fs_buf) == -1 && errno != ENOENT)
> +            fprintf (stderr, "rmdir: %m\n");
> +        }
> +        return NULL;
> +      }
> +    }
> +
> +    else {
> +      fs_buf = strdup ("/tmp/btrfs.XXXXXX");
> +      if (fs_buf == NULL) {
> +        reply_with_perror ("strdup");
> +        goto cmderror;
> +      }
> +
> +      if (mkdtemp (fs_buf) == NULL) {
> +        reply_with_perror ("mkdtemp");
> +        goto cmderror;
> +      }
> +
> +      if (mount_vfs_nochroot ("", NULL, fs, fs_buf, "<internal>") == -1) {
> +        goto cmderror;
> +      }
>      }
>  
>      size_t i = 0;
> @@ -328,16 +360,33 @@ do_btrfs_subvolume_list (const char *fs)
>      ADD_ARG (argv, i, fs_buf);
>      ADD_ARG (argv, i, NULL);
>  
> -    CLEANUP_FREE char *out = NULL, *err = NULL;
> -    int r = commandv (&out, &err, argv);
> +    CLEANUP_FREE char *out = NULL, *errout = NULL;
> +    int r = commandv (&out, &errout, argv);
> +
> +    if (fs->type != MOUNTABLE_PATH) {
> +      CLEANUP_FREE char *err = NULL;
> +      if (command (NULL, &err, str_umount, fs_buf, NULL) == -1) {
> +        reply_with_error ("%s", err ? err : "malloc");
> +        goto cmderror;
> +      }
> +
> +      if (rmdir (fs_buf) == -1 && errno != ENOENT) {
> +        reply_with_error ("rmdir: %m\n");
> +        goto cmderror;
> +      }
> +    }
> +
>      if (r == -1) {
> -      reply_with_error ("%s: %s", fs, err);
> -      return NULL;
> +      CLEANUP_FREE char *fs_desc = mountable_to_string (fs);
> +      if (fs_desc == NULL) {
> +        fprintf (stderr, "malloc: %m");
> +      }
> +      reply_with_error ("%s: %s", fs_desc ? fs_desc : "malloc", errout);
> +      goto cmderror;
>      }
>  
>      lines = split_lines (out);
> -    if (!lines)
> -      return NULL;
> +    if (!lines) return NULL;
>    }
>  
>    /* Output is:
> diff --git a/generator/actions.ml b/generator/actions.ml
> index 6a42bca..f17cb6a 100644
> --- a/generator/actions.ml
> +++ b/generator/actions.ml
> @@ -9519,7 +9519,7 @@ directory and the name of the snapshot, in the form C</path/to/dest/name>." };
>  
>    { defaults with
>      name = "btrfs_subvolume_list";
> -    style = RStructList ("subvolumes", "btrfssubvolume"), [Pathname "fs"], [];
> +    style = RStructList ("subvolumes", "btrfssubvolume"), [Mountable_or_Path "fs"], [];
>      proc_nr = Some 325;
>      optional = Some "btrfs"; camel_name = "BTRFSSubvolumeList";
>      tests = [] (* tested in tests/btrfs *);
> -- 
> 1.8.1.2

Looks good, ACK.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
libguestfs lets you edit virtual machines.  Supports shell scripting,
bindings from many languages.  http://libguestfs.org




More information about the Libguestfs mailing list