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

Wanlong Gao gaowanlong at cn.fujitsu.com
Fri Jul 13 07:24:18 UTC 2012


Add xfs_info to show the geometry of the xfs filesystem.

Signed-off-by: Wanlong Gao <gaowanlong at cn.fujitsu.com>
---

Hi Rich,
This version use the RStruct as you said,
but I also got some thing wrong, please
help reviewing and give some advises about
fixing or debugging.

Thanks,
Wanlong Gao

 daemon/Makefile.am                       |   1 +
 daemon/xfs.c                             | 306 +++++++++++++++++++++++++++++++
 generator/generator_actions.ml           |   6 +
 generator/generator_structs.ml           |  30 +++
 gobject/Makefile.inc                     |   2 +
 java/Makefile.inc                        |   1 +
 java/com/redhat/et/libguestfs/.gitignore |   1 +
 po/POTFILES                              |   2 +
 src/MAX_PROC_NR                          |   2 +-
 9 files changed, 350 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..47d027d
--- /dev/null
+++ b/daemon/xfs.c
@@ -0,0 +1,306 @@
+/* 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;
+  }
+#if 0
+  ret->inodesize = (uint32_t) -1;
+  ret->agcount = (uint32_t) -1;
+  ret->agsize = (uint32_t) -1;
+  ret->sectsize = (uint32_t) -1;
+  ret->attr = (uint32_t) -1;
+  ret->blocksize = (uint32_t) -1;
+  ret->datablocks = (uint64_t) -1;
+  ret->imaxpct = (uint32_t) -1;
+  ret->sunit = (uint32_t) -1;
+  ret->swidth = (uint32_t) -1;
+  ret->dirversion = (uint32_t) -1;
+  ret->dirblocksize = (uint32_t) -1;
+  ret->cimode = (uint32_t) -1;
+  ret->logblocksize = (uint32_t) -1;
+  ret->logblocks = (uint32_t) -1;
+  ret->logversion = (uint32_t) -1;
+  ret->logsectsize = (uint32_t) -1;
+  ret->logsunit = (uint32_t) -1;
+  ret->lazycount = (uint32_t) -1;
+  ret->rtextsize = (uint32_t) -1;
+  ret->rtblocks = (uint64_t) -1;
+  ret->rtextents = (uint64_t) -1;
+#endif
+
+  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;
+    }
+  }
+
+  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);
+}
+
+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;
+
+  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);
+  if (ret == NULL)
+    goto error;
+
+  free (err);
+  free (out);
+  free_strings (lines);
+  return ret;
+
+error:
+  free (out);
+  free (err);
+  if (lines)
+    free_strings (lines);
+  return NULL;
+}
diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
index beb2b3c..6d21351 100644
--- a/generator/generator_actions.ml
+++ b/generator/generator_actions.ml
@@ -8995,6 +8995,12 @@ 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>." };
 
+  ("xfs_info", (RStruct ("info", "xfsinfo"), [Pathname "path"], []), 337, [Optional "xfs"],
+   [],
+   "get geometry of XFS filesystem",
+   "\
+Thie function can print out the geometry of an 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..c8ec38d 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
@@ -173,6 +174,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