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 *)
]);
]
(NB This requires the mkfs-opts -> mkfs patch that I posted on
the mailing list on Saturday, but which is not upstream)
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.
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
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://et.redhat.com/~rjones/virt-top