[Libguestfs] [PATCH] Added btrfs support for vfs_min_size.
Richard W.M. Jones
rjones at redhat.com
Fri Oct 23 09:13:12 UTC 2015
On Thu, Oct 22, 2015 at 08:05:37PM +0300, Maxim Perevedentsev wrote:
> +/* 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;
> + if (result != -1)
> + return result;
> +
> + const char *cmd_pattern = "btrfs inspect-internal min-dev-size";
> +
> + int r = commandr (&out, &err, str_btrfs, "--help", NULL);
Let's move variable decls to the top of the function, and add
a newline between variable decls and the rest of the code.
> + 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 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");
> +
> + int r = command (&out, &err, str_btrfs, "inspect-internal",
> + "min-dev-size", path, NULL);
Same here.
> + 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..cb67b6f 100644
> --- a/daemon/fs-min-size.c
> +++ b/daemon/fs-min-size.c
> @@ -21,16 +21,57 @@
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> +#include <mntent.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
>
> #include "daemon.h"
> #include "actions.h"
>
> +static char*
> +get_mount_point (const char *device)
> +{
This function now exists in daemon/mount.c and here. It should
be shared. Just make the function in daemon/mount.c non-static,
and declare it in daemon/guestfsd.h, and you don't need the copy.
> + FILE *fp;
> + struct mntent *m;
> + struct stat stat1, stat2;
> + char *path;
> +
> + if (stat (device, &stat1) == -1) {
> + reply_with_perror ("stat: %s", device);
> + return NULL;
> + }
> +
> + /* NB: Eventually we should aim to parse /proc/self/mountinfo, but
> + * that requires custom parsing code.
> + */
> + fp = setmntent ("/proc/mounts", "r");
> + if (fp == NULL) {
> + fprintf (stderr, "setmntent: %s: %m\n", "/proc/mounts");
> + exit (EXIT_FAILURE);
> + }
> +
> + while ((m = getmntent (fp)) != NULL) {
> + if (stat (m->mnt_fsname, &stat2) == 0) {
> + if (stat1.st_rdev == stat2.st_rdev) {
> + /* found it */
> + path = strdup (m->mnt_dir);
> + endmntent (fp);
> + return path;
> + }
> + }
> + }
> +
> + endmntent (fp);
> + 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 +82,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)>." };
>
> ]
>
The rest looks fine to me.
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
More information about the Libguestfs
mailing list