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

Wanlong Gao gaowanlong at cn.fujitsu.com
Wed Jul 18 01:58:43 UTC 2012


Add xfs_info to show the geometry of the xfs filesystem.

Signed-off-by: Wanlong Gao <gaowanlong at cn.fujitsu.com>
---
 daemon/Makefile.am                       |   1 +
 daemon/xfs.c                             | 312 +++++++++++++++++++++++++++++++
 generator/generator_actions.ml           |  18 ++
 generator/generator_structs.ml           |  30 +++
 gobject/Makefile.inc                     |   2 +
 java/Makefile.inc                        |   1 +
 java/com/redhat/et/libguestfs/.gitignore |   1 +
 po/POTFILES                              |   6 +
 src/MAX_PROC_NR                          |   2 +-
 9 files changed, 372 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..ba9fb16
--- /dev/null
+++ b/daemon/xfs.c
@@ -0,0 +1,312 @@
+/* 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 "daemon.h"
+#include "actions.h"
+#include "optgroups.h"
+
+int
+optgroup_xfs_available (void)
+{
+  return prog_exists ("mkfs.xfs");
+}
+
+static char *
+split_strdup (char *string)
+{
+  char *end = string;
+  while (*end != ' ' && *end != ',' && *end != '\0') 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';
+  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 = NULL, *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;
+    }
+    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;
+      free (buf);
+    }
+    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;
+      free (buf);
+    }
+    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;
+      free (buf);
+    }
+    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;
+        free (buf);
+      } else if (i == 6) {
+        if (parse_uint32 (&ret->logsectsize, buf) == -1)
+          goto error;
+        free (buf);
+      } else goto error;
+    }
+    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;
+      free (buf);
+    }
+    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;
+        free (buf);
+      } else if (i == 4) {
+        if (parse_uint32 (&ret->dirblocksize, buf) == -1)
+          goto error;
+        free (buf);
+      } else if (i == 5) {
+        if (parse_uint32 (&ret->logblocksize, buf) == -1)
+          goto error;
+        free (buf);
+      } else goto error;
+    }
+    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;
+        free (buf);
+      } else if (i == 5) {
+        if (parse_uint32 (&ret->logblocks, buf) == -1)
+          goto error;
+        free (buf);
+      } else if (i == 7) {
+        if (parse_uint64 (&ret->rtblocks, buf) == -1)
+          goto error;
+        free (buf);
+      } else goto error;
+    }
+    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;
+      free (buf);
+    }
+    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;
+        free (buf);
+      } else if (i == 6) {
+        if (parse_uint32 (&ret->logsunit, buf) == -1)
+          goto error;
+        free (buf);
+      } else goto error;
+    }
+    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;
+      free (buf);
+    }
+    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;
+      free (buf);
+    }
+    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;
+      free (buf);
+    }
+    if ((p = strstr (lines[i], "log      ="))) {
+      ret->logname = split_strdup (p + 10);
+      if (ret->logname == NULL) goto error;
+    }
+    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;
+      free (buf);
+    }
+    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;
+      free (buf);
+    }
+    if ((p = strstr (lines[i], "realtime ="))) {
+      ret->rtname = split_strdup (p + 10);
+      if (ret->rtname == NULL) goto error;
+    }
+    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 90cc661..e456fa4 100644
--- a/generator/generator_actions.ml
+++ b/generator/generator_actions.ml
@@ -8948,6 +8948,24 @@ 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;
+    optional = Some "xfs";
+    tests = [
+      InitEmpty, IfAvailable "xfs", TestOutputStruct (
+        [["part_disk"; "/dev/sda"; "mbr"];
+         ["mkfs"; "xfs"; "/dev/sda1"; ""; "NOARG"; ""; ""];
+         ["mount_options"; ""; "/dev/sda1"; "/"];
+         ["xfs_info"; "/"]],
+        [CompareWithInt ("blocksize", 4096);
+        ])
+    ];
+    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..22302ba 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", FUInt32;
+    "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 4de56a9..2ca9e19 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 7f67911..92189ef 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
@@ -134,6 +135,7 @@ format/format.c
 fuse/guestmount.c
 gobject/src/optargs-add_domain.c
 gobject/src/optargs-add_drive.c
+gobject/src/optargs-add_drive_opts.c
 gobject/src/optargs-btrfs_filesystem_resize.c
 gobject/src/optargs-btrfs_fsck.c
 gobject/src/optargs-compress_device_out.c
@@ -149,12 +151,15 @@ gobject/src/optargs-internal_test.c
 gobject/src/optargs-md_create.c
 gobject/src/optargs-mkfs.c
 gobject/src/optargs-mkfs_btrfs.c
+gobject/src/optargs-mkfs_opts.c
 gobject/src/optargs-mount_9p.c
 gobject/src/optargs-mount_local.c
 gobject/src/optargs-ntfsclone_out.c
 gobject/src/optargs-ntfsfix.c
 gobject/src/optargs-ntfsresize.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 +178,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.2.249.g31c7954




More information about the Libguestfs mailing list