[Libguestfs] [PATCH V2] NEW API: add new api xfs_info
Wanlong Gao
gaowanlong at cn.fujitsu.com
Thu Jul 12 08:37:59 UTC 2012
On 07/12/2012 04:06 PM, Richard W.M. Jones wrote:
> On Thu, Jul 12, 2012 at 11:15:57AM +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,
>>
>> This is the v2 version, please help reviewing.
>> Formated the output, but seems that there's also
>> something wrong. And I'll add self test in next
>> version.
>
> Also you'll need to change it for the new way that functions
> are defined in the generator (see previous email).
>
> Sorry, I can only do a quick review now as I'm having all
> the electricity turned off this morning.
>
>> Thanks,
>> Wanlong Gao
>>
>>
>> daemon/Makefile.am | 1 +
>> daemon/xfs.c | 228 +++++++++++++++++++++++++++++++++++++++++
>> generator/generator_actions.ml | 6 ++
>> po/POTFILES | 1 +
>> src/MAX_PROC_NR | 2 +-
>> 5 files changed, 237 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..ea3782b
>> --- /dev/null
>> +++ b/daemon/xfs.c
>> @@ -0,0 +1,228 @@
>> +/* 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");
>> +}
>> +
>> +char **
>> +do_xfs_info (const char *path)
>> +{
>> + int r;
>> + int i, j;
>> + char *buf;
>> + char *out = NULL, *err = NULL;
>> + char **lines = NULL;
>> + char *line = NULL, *p = NULL, *s = NULL;
>> + char strbuf[BUFSIZ];
>> +
>> + DECLARE_STRINGSBUF (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;
>> +
>> + const char *md[] = {"meta-data", "isize", "agcount", "agsize",
>> + "sectsz", "attr", NULL};
>> + const char *data[] = {"data", "bsize", "blocks", "imaxpct",
>> + "sunit", "swidth", NULL};
>> + const char *name[] = {"naming", "bsize", "ascii-ci", NULL};
>> + const char *log[] = {"log", "bsize", "blocks", "version",
>> + "sectsz", "sunit", "lazy-count", NULL};
>> + const char *rt[] = {"realtime", "extsz", "blocks", "rtextents", NULL};
>> +
>> + for (j = 0; j < 2; j++) {
>> + line = lines[j];
>> + if (!line)
>> + goto error;
>> + s = line;
>> + for (i = 0; md[i] != NULL; i++) {
>> + p = strstr(s, md[i]);
>> + if (p) {
>> + while (*p != '=') p++;
>> + p++;
>> + s = p;
>> + while (*s != ' ' && *s != ',') s++;
>> + *s = '\0';
>> + s++;
>> + if (i == 0) {
>> + if (add_string (&ret, md[i]) == -1 ||
>> + add_string (&ret, p) == -1) goto error;
>> + } else {
>> + sprintf (strbuf, "%s.%s", md[0], md[i]);
>> + if (add_string (&ret, strbuf) == -1 ||
>> + add_string (&ret, p) == -1) goto error;
>> + }
>> + }
>> + }
>> + }
>> +
>> + for (j = 2; j < 4; j++) {
>> + line = lines[j];
>> + if (!line)
>> + goto error;
>> + s = line;
>> + for (i = 1; data[i] != NULL; i++) {
>> + p = strstr(s, data[i]);
>> + if (p) {
>> + while (*p != '=') p++;
>> + p++;
>> + s = p;
>> + while (*s != ' ' && *s != ',') s++;
>> + *s = '\0';
>> + s++;
>> + sprintf(strbuf, "%s.%s", data[0], data[i]);
>> + if (add_string (&ret, strbuf) == -1 ||
>> + add_string (&ret, p) == -1) goto error;
>> + }
>> + }
>> + }
>> +
>> + line = lines[4];
>> + if (!line)
>> + goto error;
>> + s = line;
>> + for (i = 0; name[i] != NULL; i++) {
>> + p = strstr(s, name[i]);
>> + if (p) {
>> + while (*p != '=') p++;
>> + p++;
>> + if (i == 0) {
>> + while (*p != ' ') p++; p++;
>> + }
>> + s = p;
>> + while (*s != ' ' && *s != ',') s++;
>> + *s = '\0';
>> + s++;
>> + if (i == 0) {
>> + sprintf(strbuf, "%s.%s", name[i], "version");
>> + if (add_string (&ret, strbuf) == -1 ||
>> + add_string (&ret, p) == -1) goto error;
>> + } else {
>> + sprintf(strbuf, "%s.%s", name[0], name[i]);
>> + if (add_string (&ret, strbuf) == -1 ||
>> + add_string (&ret, p) == -1) goto error;
>> + }
>> + }
>> + }
>> +
>> +
>> + for (j = 5; j < 7; j++) {
>> + line = lines[j];
>> + if (!line)
>> + goto error;
>> + s = line;
>> + for (i = 0; log[i] != NULL; i++) {
>> + p = strstr(s, log[i]);
>> + if (p) {
>> + while (*p != '=') p++;
>> + p++;
>> + s = p;
>> + while (*s != ' ' && *s != ',') s++;
>> + *s = '\0';
>> + s++;
>> + if (i == 0) {
>> + if (add_string (&ret, log[i]) == -1 ||
>> + add_string (&ret, p) == -1) goto error;
>> + } else {
>> + sprintf(strbuf, "%s.%s", log[0], log[i]);
>> + if (add_string (&ret, strbuf) == -1 ||
>> + add_string (&ret, p) == -1) goto error;
>> + }
>> + }
>> + }
>> + }
>> +
>> +
>> + line = lines[7];
>> + if (!line)
>> + goto error;
>> + s = line;
>> + for (i = 0; rt[i] != NULL; i++) {
>> + p = strstr(s, rt[i]);
>> + if (p) {
>> + while (*p != '=') p++;
>> + p++;
>> + s = p;
>> + while (*s != ' ' && *s != ',') s++;
>> + *s = '\0';
>> + s++;
>> + if (i == 0) {
>> + if (add_string (&ret, rt[i]) == -1 ||
>> + add_string (&ret, p) == -1) goto error;
>> + } else {
>> + sprintf(strbuf, "%s.%s", rt[0], rt[i]);
>> + if (add_string (&ret, strbuf) == -1 ||
>> + add_string (&ret, p) == -1) goto error;
>> + }
>> + }
>> + }
>> +
>> + free (out);
>> + free (err);
>> + free_strings (lines);
>> +
>> + if (end_stringsbuf (&ret) == -1)
>> + return NULL;
>> +
>> + return ret.argv;
>> +
>> +error:
>> + free (out);
>> + free (err);
>> + free_strings (lines);
>> + if (ret.argv != NULL)
>> + free_stringslen (ret.argv, ret.size);
>> + return NULL;
>> +}
>
> It seems like a reasonable approach given the complex and
> frankly obscure output of the xfs_info command.
>
> Did you have a look at the sources of XFS to see if the format
> is fixed or can change? It might also be worth considering using
> an 'RStruct' instead of 'RHashtable', although it mainly depends
> on whether the output can change in future or not.
>
Yes, it's defined like this.
printf(_(
"meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n"
" =%-22s sectsz=%-5u attr=%u\n"
"data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
" =%-22s sunit=%-6u swidth=%u blks\n"
"naming =version %-14u bsize=%-6u ascii-ci=%d\n"
"log =%-22s bsize=%-6u blocks=%u, version=%u\n"
" =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n"
"realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n"),
Thanks,
Wanlong Gao
>> diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
>> index 5baa9b2..e4cbee0 100644
>> --- a/generator/generator_actions.ml
>> +++ b/generator/generator_actions.ml
>> @@ -7374,6 +7374,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", (RHashtable "info", [String "path"], []), 337, [Optional "xfs"],
>> + [],
>> + "print out the geometry of the filesystem",
>> + "\
>> +Thie function can print out the geometry of an mounted XFS filesystem.");
>> +
>> ]
>>
>> let all_functions = non_daemon_functions @ daemon_functions
>> diff --git a/po/POTFILES b/po/POTFILES
>> index 747b341..8217314 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
>> 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
>
> Rich.
>
More information about the Libguestfs
mailing list