|
|
022f11 |
From 57e674ae7bff996a263ca4f70ebea7606e250eb0 Mon Sep 17 00:00:00 2001
|
|
|
022f11 |
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
|
022f11 |
Date: Thu, 3 Oct 2013 18:17:39 +0100
|
|
|
022f11 |
Subject: [PATCH] daemon: Fix xfs_info parser because of new format.
|
|
|
022f11 |
|
|
|
022f11 |
The old parser had several problems: firstly it called the error path
|
|
|
022f11 |
sometimes without calling reply_with_error causing a protocol hang.
|
|
|
022f11 |
More seriously it had hard-coded line numbers, and since Fedora 21 the
|
|
|
022f11 |
output of xfs_info has changed, moving lines around.
|
|
|
022f11 |
|
|
|
022f11 |
Change the parser to be more robust against added fields by using the
|
|
|
022f11 |
first name on the line as the section name, thus 'bsize=' is
|
|
|
022f11 |
interpreted differently depending on whether it appears in the "data"
|
|
|
022f11 |
section or the "naming" section.
|
|
|
022f11 |
|
|
|
022f11 |
Ensure also that we don't call the error path without calling
|
|
|
022f11 |
reply_with_error, which is a side-effect of the above change.
|
|
|
022f11 |
|
|
|
022f11 |
(cherry picked from commit 8abd0a83b3a94e4adbd0926df818686be982cdb8)
|
|
|
022f11 |
---
|
|
|
022f11 |
daemon/xfs.c | 114 ++++++++++++++++++++++++++++++++++++-----------------------
|
|
|
022f11 |
1 file changed, 70 insertions(+), 44 deletions(-)
|
|
|
022f11 |
|
|
|
022f11 |
diff --git a/daemon/xfs.c b/daemon/xfs.c
|
|
|
022f11 |
index e31da8f..725f7b3 100644
|
|
|
022f11 |
--- a/daemon/xfs.c
|
|
|
022f11 |
+++ b/daemon/xfs.c
|
|
|
022f11 |
@@ -28,6 +28,8 @@
|
|
|
022f11 |
#include "actions.h"
|
|
|
022f11 |
#include "optgroups.h"
|
|
|
022f11 |
|
|
|
022f11 |
+#include "c-ctype.h"
|
|
|
022f11 |
+
|
|
|
022f11 |
#define MAX_ARGS 64
|
|
|
022f11 |
|
|
|
022f11 |
GUESTFSD_EXT_CMD(str_mkfs_xfs, mkfs.xfs);
|
|
|
022f11 |
@@ -42,7 +44,7 @@ optgroup_xfs_available (void)
|
|
|
022f11 |
return prog_exists (str_mkfs_xfs);
|
|
|
022f11 |
}
|
|
|
022f11 |
|
|
|
022f11 |
-/* Return everything up to the first comma or space in the input
|
|
|
022f11 |
+/* Return everything up to the first comma, equals or space in the input
|
|
|
022f11 |
* string, strdup'ing the return value.
|
|
|
022f11 |
*/
|
|
|
022f11 |
static char *
|
|
|
022f11 |
@@ -51,7 +53,7 @@ split_strdup (char *string)
|
|
|
022f11 |
size_t len;
|
|
|
022f11 |
char *ret;
|
|
|
022f11 |
|
|
|
022f11 |
- len = strcspn (string, " ,");
|
|
|
022f11 |
+ len = strcspn (string, " ,=");
|
|
|
022f11 |
ret = strndup (string, len);
|
|
|
022f11 |
if (!ret) {
|
|
|
022f11 |
reply_with_perror ("malloc");
|
|
|
022f11 |
@@ -92,6 +94,7 @@ parse_uint64 (uint64_t *ret, const char *str)
|
|
|
022f11 |
*
|
|
|
022f11 |
* meta-data=/dev/sda1 isize=256 agcount=4, agsize=6392 blks
|
|
|
022f11 |
* = sectsz=512 attr=2
|
|
|
022f11 |
+ *[ = crc=0 ]
|
|
|
022f11 |
* data = bsize=4096 blocks=25568, imaxpct=25
|
|
|
022f11 |
* = sunit=0 swidth=0 blks
|
|
|
022f11 |
* naming =version 2 bsize=4096 ascii-ci=0
|
|
|
022f11 |
@@ -99,6 +102,8 @@ parse_uint64 (uint64_t *ret, const char *str)
|
|
|
022f11 |
* = sectsz=512 sunit=0 blks, lazy-count=1
|
|
|
022f11 |
* realtime =none extsz=4096 blocks=0, rtextents=0
|
|
|
022f11 |
*
|
|
|
022f11 |
+ * [...] line only appears in Fedora >= 21
|
|
|
022f11 |
+ *
|
|
|
022f11 |
* We may need to revisit this parsing code if the output changes
|
|
|
022f11 |
* in future.
|
|
|
022f11 |
*/
|
|
|
022f11 |
@@ -106,6 +111,7 @@ static guestfs_int_xfsinfo *
|
|
|
022f11 |
parse_xfs_info (char **lines)
|
|
|
022f11 |
{
|
|
|
022f11 |
guestfs_int_xfsinfo *ret;
|
|
|
022f11 |
+ CLEANUP_FREE char *section = NULL; /* first column, eg "meta-data", "data" */
|
|
|
022f11 |
char *p;
|
|
|
022f11 |
size_t i;
|
|
|
022f11 |
|
|
|
022f11 |
@@ -145,6 +151,18 @@ parse_xfs_info (char **lines)
|
|
|
022f11 |
ret->xfs_rtextents = -1;
|
|
|
022f11 |
|
|
|
022f11 |
for (i = 0; lines[i] != NULL; ++i) {
|
|
|
022f11 |
+ if (verbose)
|
|
|
022f11 |
+ fprintf (stderr, "xfs_info: lines[%zu] = \'%s\'\n", i, lines[i]);
|
|
|
022f11 |
+
|
|
|
022f11 |
+ if (c_isalpha (lines[i][0])) {
|
|
|
022f11 |
+ free (section);
|
|
|
022f11 |
+ section = split_strdup (lines[i]);
|
|
|
022f11 |
+ if (!section) goto error;
|
|
|
022f11 |
+
|
|
|
022f11 |
+ if (verbose)
|
|
|
022f11 |
+ fprintf (stderr, "xfs_info: new section %s\n", section);
|
|
|
022f11 |
+ }
|
|
|
022f11 |
+
|
|
|
022f11 |
if ((p = strstr (lines[i], "meta-data="))) {
|
|
|
022f11 |
ret->xfs_mntpoint = split_strdup (p + 10);
|
|
|
022f11 |
if (ret->xfs_mntpoint == NULL) goto error;
|
|
|
022f11 |
@@ -168,15 +186,17 @@ parse_xfs_info (char **lines)
|
|
|
022f11 |
goto error;
|
|
|
022f11 |
}
|
|
|
022f11 |
if ((p = strstr (lines[i], "sectsz="))) {
|
|
|
022f11 |
- CLEANUP_FREE char *buf = split_strdup (p + 7);
|
|
|
022f11 |
- if (buf == NULL) goto error;
|
|
|
022f11 |
- if (i == 1) {
|
|
|
022f11 |
- if (parse_uint32 (&ret->xfs_sectsize, buf) == -1)
|
|
|
022f11 |
- goto error;
|
|
|
022f11 |
- } else if (i == 6) {
|
|
|
022f11 |
- if (parse_uint32 (&ret->xfs_logsectsize, buf) == -1)
|
|
|
022f11 |
- goto error;
|
|
|
022f11 |
- } else goto error;
|
|
|
022f11 |
+ if (section) {
|
|
|
022f11 |
+ CLEANUP_FREE char *buf = split_strdup (p + 7);
|
|
|
022f11 |
+ if (buf == NULL) goto error;
|
|
|
022f11 |
+ if (STREQ (section, "meta-data")) {
|
|
|
022f11 |
+ if (parse_uint32 (&ret->xfs_sectsize, buf) == -1)
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
+ } else if (STREQ (section, "log")) {
|
|
|
022f11 |
+ if (parse_uint32 (&ret->xfs_logsectsize, buf) == -1)
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
+ }
|
|
|
022f11 |
+ }
|
|
|
022f11 |
}
|
|
|
022f11 |
if ((p = strstr (lines[i], "attr="))) {
|
|
|
022f11 |
CLEANUP_FREE char *buf = split_strdup (p + 5);
|
|
|
022f11 |
@@ -185,32 +205,36 @@ parse_xfs_info (char **lines)
|
|
|
022f11 |
goto error;
|
|
|
022f11 |
}
|
|
|
022f11 |
if ((p = strstr (lines[i], "bsize="))) {
|
|
|
022f11 |
- CLEANUP_FREE char *buf = split_strdup (p + 6);
|
|
|
022f11 |
- if (buf == NULL) goto error;
|
|
|
022f11 |
- if (i == 2) {
|
|
|
022f11 |
- if (parse_uint32 (&ret->xfs_blocksize, buf) == -1)
|
|
|
022f11 |
- goto error;
|
|
|
022f11 |
- } else if (i == 4) {
|
|
|
022f11 |
- if (parse_uint32 (&ret->xfs_dirblocksize, buf) == -1)
|
|
|
022f11 |
- goto error;
|
|
|
022f11 |
- } else if (i == 5) {
|
|
|
022f11 |
- if (parse_uint32 (&ret->xfs_logblocksize, buf) == -1)
|
|
|
022f11 |
- goto error;
|
|
|
022f11 |
- } else goto error;
|
|
|
022f11 |
+ if (section) {
|
|
|
022f11 |
+ CLEANUP_FREE char *buf = split_strdup (p + 6);
|
|
|
022f11 |
+ if (buf == NULL) goto error;
|
|
|
022f11 |
+ if (STREQ (section, "data")) {
|
|
|
022f11 |
+ if (parse_uint32 (&ret->xfs_blocksize, buf) == -1)
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
+ } else if (STREQ (section, "naming")) {
|
|
|
022f11 |
+ if (parse_uint32 (&ret->xfs_dirblocksize, buf) == -1)
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
+ } else if (STREQ (section, "log")) {
|
|
|
022f11 |
+ if (parse_uint32 (&ret->xfs_logblocksize, buf) == -1)
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
+ }
|
|
|
022f11 |
+ }
|
|
|
022f11 |
}
|
|
|
022f11 |
if ((p = strstr (lines[i], "blocks="))) {
|
|
|
022f11 |
- CLEANUP_FREE char *buf = split_strdup (p + 7);
|
|
|
022f11 |
- if (buf == NULL) goto error;
|
|
|
022f11 |
- if (i == 2) {
|
|
|
022f11 |
- if (parse_uint64 (&ret->xfs_datablocks, buf) == -1)
|
|
|
022f11 |
- goto error;
|
|
|
022f11 |
- } else if (i == 5) {
|
|
|
022f11 |
- if (parse_uint32 (&ret->xfs_logblocks, buf) == -1)
|
|
|
022f11 |
- goto error;
|
|
|
022f11 |
- } else if (i == 7) {
|
|
|
022f11 |
- if (parse_uint64 (&ret->xfs_rtblocks, buf) == -1)
|
|
|
022f11 |
- goto error;
|
|
|
022f11 |
- } else goto error;
|
|
|
022f11 |
+ if (section) {
|
|
|
022f11 |
+ CLEANUP_FREE char *buf = split_strdup (p + 7);
|
|
|
022f11 |
+ if (buf == NULL) goto error;
|
|
|
022f11 |
+ if (STREQ (section, "data")) {
|
|
|
022f11 |
+ if (parse_uint64 (&ret->xfs_datablocks, buf) == -1)
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
+ } else if (STREQ (section, "log")) {
|
|
|
022f11 |
+ if (parse_uint32 (&ret->xfs_logblocks, buf) == -1)
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
+ } else if (STREQ (section, "realtime")) {
|
|
|
022f11 |
+ if (parse_uint64 (&ret->xfs_rtblocks, buf) == -1)
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
+ }
|
|
|
022f11 |
+ }
|
|
|
022f11 |
}
|
|
|
022f11 |
if ((p = strstr (lines[i], "imaxpct="))) {
|
|
|
022f11 |
CLEANUP_FREE char *buf = split_strdup (p + 8);
|
|
|
022f11 |
@@ -219,15 +243,17 @@ parse_xfs_info (char **lines)
|
|
|
022f11 |
goto error;
|
|
|
022f11 |
}
|
|
|
022f11 |
if ((p = strstr (lines[i], "sunit="))) {
|
|
|
022f11 |
- CLEANUP_FREE char *buf = split_strdup (p + 6);
|
|
|
022f11 |
- if (buf == NULL) goto error;
|
|
|
022f11 |
- if (i == 3) {
|
|
|
022f11 |
- if (parse_uint32 (&ret->xfs_sunit, buf) == -1)
|
|
|
022f11 |
- goto error;
|
|
|
022f11 |
- } else if (i == 6) {
|
|
|
022f11 |
- if (parse_uint32 (&ret->xfs_logsunit, buf) == -1)
|
|
|
022f11 |
- goto error;
|
|
|
022f11 |
- } else goto error;
|
|
|
022f11 |
+ if (section) {
|
|
|
022f11 |
+ CLEANUP_FREE char *buf = split_strdup (p + 6);
|
|
|
022f11 |
+ if (buf == NULL) goto error;
|
|
|
022f11 |
+ if (STREQ (section, "data")) {
|
|
|
022f11 |
+ if (parse_uint32 (&ret->xfs_sunit, buf) == -1)
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
+ } else if (STREQ (section, "log")) {
|
|
|
022f11 |
+ if (parse_uint32 (&ret->xfs_logsunit, buf) == -1)
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
+ }
|
|
|
022f11 |
+ }
|
|
|
022f11 |
}
|
|
|
022f11 |
if ((p = strstr (lines[i], "swidth="))) {
|
|
|
022f11 |
CLEANUP_FREE char *buf = split_strdup (p + 7);
|
|
|
022f11 |
--
|
|
|
022f11 |
1.8.3.1
|
|
|
022f11 |
|