Blame SOURCES/0037-daemon-Fix-xfs_info-parser-because-of-new-format.patch

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