On 07/16/2012 05:15 PM, Richard W.M. Jones wrote:
On Mon, Jul 16, 2012 at 05:05:39PM +0800, Wanlong Gao wrote:
> Add xfs_info to show the geometry of the xfs filesystem.
>
> Signed-off-by: Wanlong Gao <gaowanlong(a)cn.fujitsu.com>
>
> Hi Rich,
> I got an odd error, can you help me with this error
> or give me a debug method?
I think in general the patch is looking good. Is does however
really need a test, and it should be possible to add one using
something like this (untested):
tests = [
InitEmpty, IfAvailable "xfs", TestOutputStruct (
[["part_disk"; "/dev/sda"; "mbr"];
["mkfs"; "xfs"; "/dev/sda1"; "";
"NOARG"; ""; ""];
["mount_options"; ""; "/dev/sda1";
"/"];
["xfs_info"; "/"]],
[CompareWithInt ("blocksize", 4096);
(* other comparisons here if you want *)
]);
]
Yes, thank you.
(NB This requires the mkfs-opts -> mkfs patch that I posted on
the mailing list on Saturday, but which is not upstream)
Yeah, I saw this patch series that day. ;)
What is the odd error that you are seeing? For debugging, just
print
stuff out, as you are doing, and then run the program using
LIBGUESTFS_DEBUG=1.
OK, I will, I just got some odd output, so I asked for your help.
I'll do further debugging.
Thanks,
Wanlong Gao
Rich.
> Thanks,
> Wanlong Gao
>
>
> daemon/Makefile.am | 1 +
> daemon/xfs.c | 278 +++++++++++++++++++++++++++++++
> generator/generator_actions.ml | 8 +
> generator/generator_structs.ml | 30 ++++
> gobject/Makefile.inc | 2 +
> java/Makefile.inc | 1 +
> java/com/redhat/et/libguestfs/.gitignore | 1 +
> po/POTFILES | 3 +
> src/MAX_PROC_NR | 2 +-
> 9 files changed, 325 insertions(+), 1 deletion(-)
> create mode 100644 daemon/xfs.c
>
> diff --git a/daemon/Makefile.am b/daemon/Makefile.am
> index 9e2a633..afe8874 100644
> --- a/daemon/Makefile.am
> +++ b/daemon/Makefile.am
> @@ -165,6 +165,7 @@ guestfsd_SOURCES = \
> utimens.c \
> wc.c \
> xattr.c \
> + xfs.c \
> zero.c \
> zerofree.c
> guestfsd_LDADD = \
> diff --git a/daemon/xfs.c b/daemon/xfs.c
> new file mode 100644
> index 0000000..b328d09
> --- /dev/null
> +++ b/daemon/xfs.c
> @@ -0,0 +1,278 @@
> +/* libguestfs - the guestfsd daemon
> + * Copyright (C) 2012 Fujitsu Limited.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <config.h>
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <inttypes.h>
> +#include <string.h>
> +#include <unistd.h>
> +
> +#include "guestfs_protocol.h"
> +#include "daemon.h"
> +#include "c-ctype.h"
> +#include "actions.h"
> +
> +int
> +optgroup_xfs_available (void)
> +{
> + return prog_exists ("mkfs.xfs");
> +}
> +
> +static char *
> +split_strdup (char *string)
> +{
> + char *end = string;
> + while (*end != ' ' && *end != ',') end++;
> + size_t len = end - string;
> + char *ret = malloc (len + 1);
> + if (!ret) {
> + reply_with_perror ("malloc");
> + return NULL;
> + }
> + strncpy (ret, string, len);
> + ret[len] = '\0';
> + fprintf(stderr, "%s\n", ret);
> + return ret;
> +}
> +
> +static int
> +parse_uint32 (uint32_t *ret, const char *str)
> +{
> + uint32_t r;
> +
> + if (sscanf (str, "%" SCNu32, &r) != 1) {
> + reply_with_error ("cannot parse numeric field from isoinfo: %s",
str);
> + return -1;
> + }
> +
> + *ret = r;
> + return 0;
> +}
> +
> +static int
> +parse_uint64 (uint64_t *ret, const char *str)
> +{
> + uint64_t r;
> +
> + if (sscanf (str, "%" SCNu64, &r) != 1) {
> + reply_with_error ("cannot parse numeric field from isoinfo: %s",
str);
> + return -1;
> + }
> +
> + *ret = r;
> + return 0;
> +}
> +
> +static guestfs_int_xfsinfo *
> +parse_xfs_info (char **lines)
> +{
> + guestfs_int_xfsinfo *ret;
> + char *buf, *p;
> + size_t i;
> +
> + ret = calloc (1, sizeof *ret);
> + if (ret == NULL) {
> + reply_with_error ("calloc");
> + return NULL;
> + }
> +
> + for (i = 0; lines[i] != NULL; ++i) {
> + if (p = strstr (lines[i], "meta-data=")) {
> + ret->mntpoint = split_strdup (p + 10);
> + if (ret->mntpoint == NULL) goto error;
> + } else if (p = strstr (lines[i], "isize=")) {
> + buf = split_strdup (p + 6);
> + if (buf == NULL) goto error;
> + if (parse_uint32 (&ret->inodesize, buf) == -1)
> + goto error;
> + } else if (p = strstr (lines[i], "agcount=")) {
> + buf = split_strdup (p + 8);
> + if (buf == NULL) goto error;
> + if (parse_uint32 (&ret->agcount, buf) == -1)
> + goto error;
> + } else if (p = strstr (lines[i], "agsize=")) {
> + buf = split_strdup (p + 7);
> + if (buf == NULL) goto error;
> + if (parse_uint32 (&ret->agsize, buf) == -1)
> + goto error;
> + } else if (p = strstr (lines[i], "sectsz=")) {
> + buf = split_strdup (p + 7);
> + if (buf == NULL) goto error;
> + if (i == 1)
> + if (parse_uint32 (&ret->sectsize, buf) == -1)
> + goto error;
> + else if (i == 6)
> + if (parse_uint32 (&ret->logsectsize, buf) == -1)
> + goto error;
> + else goto error;
> + } else if (p = strstr (lines[i], "attr=")) {
> + buf = split_strdup (p + 5);
> + if (buf == NULL) goto error;
> + if (parse_uint32 (&ret->attr, buf) == -1)
> + goto error;
> + } else if (p = strstr (lines[i], "bsize=")) {
> + buf = split_strdup (p + 6);
> + if (buf == NULL) goto error;
> + if (i == 2)
> + if (parse_uint32 (&ret->blocksize, buf) == -1)
> + goto error;
> + else if (i == 4)
> + if (parse_uint32 (&ret->dirblocksize, buf) == -1)
> + goto error;
> + else if (i == 5)
> + if (parse_uint32 (&ret->logblocksize, buf) == -1)
> + goto error;
> + else goto error;
> + } else if (p = strstr (lines[i], "blocks=")) {
> + buf = split_strdup (p + 7);
> + if (buf == NULL) goto error;
> + if (i == 2)
> + if (parse_uint64 (&ret->datablocks, buf) == -1)
> + goto error;
> + else if (i == 5)
> + if (parse_uint32 (&ret->logblocks, buf) == -1)
> + goto error;
> + else if (i == 7)
> + if (parse_uint64 (&ret->rtblocks, buf) == -1)
> + goto error;
> + else goto error;
> + } else if (p = strstr (lines[i], "imaxpct=")) {
> + buf = split_strdup (p + 8);
> + if (buf == NULL) goto error;
> + if (parse_uint32 (&ret->imaxpct, buf) == -1)
> + goto error;
> + } else if (p = strstr (lines[i], "sunit=")) {
> + buf = split_strdup (p + 6);
> + if (buf == NULL) goto error;
> + if (i == 3)
> + if (parse_uint32 (&ret->sunit, buf) == -1)
> + goto error;
> + else if (i == 6)
> + if (parse_uint32 (&ret->logsunit, buf) == -1)
> + goto error;
> + else goto error;
> + } else if (p = strstr (lines[i], "swidth=")) {
> + buf = split_strdup (p + 7);
> + if (buf == NULL) goto error;
> + if (parse_uint32 (&ret->swidth, buf) == -1)
> + goto error;
> + } else if (p = strstr (lines[i], "naming =version ")) {
> + buf = split_strdup (p + 18);
> + if (buf == NULL) goto error;
> + if (parse_uint32 (&ret->dirversion, buf) == -1)
> + goto error;
> + } else if (p = strstr (lines[i], "ascii-ci=")) {
> + buf = split_strdup (p + 9);
> + if (buf == NULL) goto error;
> + if (parse_uint32 (&ret->cimode, buf) == -1)
> + goto error;
> + } else if (p = strstr (lines[i], "log =")) {
> + ret->logname = split_strdup (p + 10);
> + if (ret->logname == NULL) goto error;
> + } else if (p = strstr (lines[i], "version=")) {
> + buf = split_strdup (p + 8);
> + if (buf == NULL) goto error;
> + if (parse_uint32 (&ret->logversion, buf) == -1)
> + goto error;
> + } else if (p = strstr (lines[i], "lazy-count=")) {
> + buf = split_strdup (p + 11);
> + if (buf == NULL) goto error;
> + if (parse_uint32 (&ret->lazycount, buf) == -1)
> + goto error;
> + } else if (p = strstr (lines[i], "realtime =")) {
> + ret->rtname = split_strdup (p + 10);
> + if (ret->rtname == NULL) goto error;
> + } else if (p = strstr (lines[i], "rtextents=")) {
> + buf = split_strdup (p + 10);
> + if (buf == NULL) goto error;
> + if (parse_uint64 (&ret->rtextents, buf) == -1)
> + goto error;
> + }
> +
> + free (buf);
> + }
> +
> + if (ret->mntpoint == NULL) {
> + ret->mntpoint = strdup ("");
> + if (ret->mntpoint == NULL) goto error;
> + }
> + if (ret->logname == NULL) {
> + ret->logname = strdup ("");
> + if (ret->logname == NULL) goto error;
> + }
> + if (ret->rtname == NULL) {
> + ret->rtname = strdup ("");
> + if (ret->rtname == NULL) goto error;
> + }
> +
> + return ret;
> +
> +error:
> + free (buf);
> + free (ret->mntpoint);
> + free (ret->logname);
> + free (ret->rtname);
> + free (ret);
> + return NULL;
> +}
> +
> +guestfs_int_xfsinfo *
> +do_xfs_info (const char *path)
> +{
> + int r;
> + char *buf;
> + char *out = NULL, *err = NULL;
> + char **lines = NULL;
> + guestfs_int_xfsinfo *ret = NULL;
> +
> + if (do_is_dir (path)) {
> + buf = sysroot_path (path);
> + if (!buf) {
> + reply_with_perror ("malloc");
> + return NULL;
> + }
> + } else {
> + buf = strdup(path);
> + if (!buf) {
> + reply_with_perror ("strdup");
> + return NULL;
> + }
> + }
> +
> + r = command (&out, &err, "xfs_info", buf, NULL);
> + free (buf);
> + if (r == -1) {
> + reply_with_error ("%s", err);
> + goto error;
> + }
> +
> + lines = split_lines (out);
> + if (lines == NULL)
> + goto error;
> +
> + ret = parse_xfs_info (lines);
> +
> +error:
> + free (err);
> + free (out);
> + if (lines)
> + free_strings (lines);
> + return ret;
> +}
> diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
> index c83bf70..dd9ea03 100644
> --- a/generator/generator_actions.ml
> +++ b/generator/generator_actions.ml
> @@ -8995,6 +8995,14 @@ be returned if you called C<guestfs_list_devices>.
> To find out the maximum number of devices that could be added,
> call C<guestfs_max_disks>." };
>
> + { defaults with
> + name = "xfs_info";
> + style = RStruct ("info", "xfsinfo"), [Pathname
"path"], [];
> + proc_nr = Some 337;
> + shortdesc = "get geometry of XFS filesystem";
> + longdesc = "\
> +This functions can print out the geometry of a mounted XFS filesystem." };
> +
> ]
>
> (* Non-API meta-commands available only in guestfish.
> diff --git a/generator/generator_structs.ml b/generator/generator_structs.ml
> index 024bb3c..3dded35 100644
> --- a/generator/generator_structs.ml
> +++ b/generator/generator_structs.ml
> @@ -213,6 +213,35 @@ let structs = [
> "iso_volume_effective_t", FInt64;
> ];
>
> + (* XFS info descriptor. *)
> + "xfsinfo", [
> + "mntpoint", FString;
> + "inodesize", FUInt32;
> + "agcount", FUInt32;
> + "agsize", FUInt32;
> + "sectsize", FUInt32;
> + "attr", FUInt32;
> + "blocksize", FUInt32;
> + "datablocks", FUInt64;
> + "imaxpct", FUInt32;
> + "sunit", FUInt32;
> + "swidth", FUInt32;
> + "dirversion", FUInt32;
> + "dirblocksize", FUInt32;
> + "cimode", FInt32;
> + "logname", FString;
> + "logblocksize", FUInt32;
> + "logblocks", FUInt32;
> + "logversion", FUInt32;
> + "logsectsize", FUInt32;
> + "logsunit", FUInt32;
> + "lazycount", FUInt32;
> + "rtname", FString;
> + "rtextsize", FUInt32;
> + "rtblocks", FUInt64;
> + "rtextents", FUInt64;
> + ];
> +
> (* /proc/mdstat information. See linux.git/drivers/md/md.c *)
> "mdstat", [
> "mdstat_device", FString;
> @@ -243,6 +272,7 @@ let camel_structs = [
> "partition", "Partition";
> "application", "Application";
> "isoinfo", "ISOInfo";
> + "xfsinfo", "XFSInfo";
> "mdstat", "MDStat";
> "btrfssubvolume", "BTRFSSubvolume";
> ]
> diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
> index e84236d..d70e106 100644
> --- a/gobject/Makefile.inc
> +++ b/gobject/Makefile.inc
> @@ -36,6 +36,7 @@ guestfs_gobject_headers= \
> include/guestfs-gobject/struct-partition.h \
> include/guestfs-gobject/struct-application.h \
> include/guestfs-gobject/struct-isoinfo.h \
> + include/guestfs-gobject/struct-xfsinfo.h \
> include/guestfs-gobject/struct-mdstat.h \
> include/guestfs-gobject/struct-btrfssubvolume.h \
> include/guestfs-gobject/optargs-internal_test.h \
> @@ -80,6 +81,7 @@ guestfs_gobject_sources= \
> src/struct-partition.c \
> src/struct-application.c \
> src/struct-isoinfo.c \
> + src/struct-xfsinfo.c \
> src/struct-mdstat.c \
> src/struct-btrfssubvolume.c \
> src/optargs-internal_test.c \
> diff --git a/java/Makefile.inc b/java/Makefile.inc
> index efad2a0..da8de49 100644
> --- a/java/Makefile.inc
> +++ b/java/Makefile.inc
> @@ -35,4 +35,5 @@ java_built_sources = \
> com/redhat/et/libguestfs/VG.java \
> com/redhat/et/libguestfs/Version.java \
> com/redhat/et/libguestfs/XAttr.java \
> + com/redhat/et/libguestfs/XFSInfo.java \
> com/redhat/et/libguestfs/GuestFS.java
> diff --git a/java/com/redhat/et/libguestfs/.gitignore
b/java/com/redhat/et/libguestfs/.gitignore
> index 9556d81..1034665 100644
> --- a/java/com/redhat/et/libguestfs/.gitignore
> +++ b/java/com/redhat/et/libguestfs/.gitignore
> @@ -13,3 +13,4 @@ StatVFS.java
> VG.java
> Version.java
> XAttr.java
> +XFSInfo.java
> diff --git a/po/POTFILES b/po/POTFILES
> index 6c819d3..017f5bd 100644
> --- a/po/POTFILES
> +++ b/po/POTFILES
> @@ -84,6 +84,7 @@ daemon/upload.c
> daemon/utimens.c
> daemon/wc.c
> daemon/xattr.c
> +daemon/xfs.c
> daemon/zero.c
> daemon/zerofree.c
> df/df.c
> @@ -155,6 +156,7 @@ gobject/src/optargs-ntfsclone_out.c
> gobject/src/optargs-ntfsfix.c
> gobject/src/optargs-ntfsresize_opts.c
> gobject/src/optargs-set_e2attrs.c
> +gobject/src/optargs-test0.c
> gobject/src/optargs-tune2fs.c
> gobject/src/optargs-umount_local.c
> gobject/src/session.c
> @@ -173,6 +175,7 @@ gobject/src/struct-stat.c
> gobject/src/struct-statvfs.c
> gobject/src/struct-version.c
> gobject/src/struct-xattr.c
> +gobject/src/struct-xfsinfo.c
> gobject/src/tristate.c
> inspector/virt-inspector.c
> java/com_redhat_et_libguestfs_GuestFS.c
> diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
> index e64f24d..f59a90f 100644
> --- a/src/MAX_PROC_NR
> +++ b/src/MAX_PROC_NR
> @@ -1 +1 @@
> -336
> +337
> --
> 1.7.11.1.165.g299666c