[Libguestfs] [PATCH V4] NEW API: add new api xfs_info

Wanlong Gao gaowanlong at cn.fujitsu.com
Mon Jul 16 09:27:32 UTC 2012


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 at 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
> 





More information about the Libguestfs mailing list