From: Peter Krempa <[email protected]>

Strictly validating qemu replies and rejecting unknown values can have
bad consequences in case qemu adds a new value.

Refactor the code parsing 'io-status' field from 'query-block' to be
tolerant to new values to avoid failure.

Signed-off-by: Peter Krempa <[email protected]>
---
 src/qemu/qemu_monitor.c      | 42 --------------------------------
 src/qemu/qemu_monitor.h      |  3 ---
 src/qemu/qemu_monitor_json.c | 47 +++++++++++++++++++++++++++++++++---
 3 files changed, 43 insertions(+), 49 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 6acc80832c..1434da7f70 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -177,21 +177,6 @@ VIR_ENUM_IMPL(qemuMonitorVMStatus,
               "guest-panicked",
 );

-typedef enum {
-    QEMU_MONITOR_BLOCK_IO_STATUS_OK,
-    QEMU_MONITOR_BLOCK_IO_STATUS_FAILED,
-    QEMU_MONITOR_BLOCK_IO_STATUS_NOSPACE,
-
-    QEMU_MONITOR_BLOCK_IO_STATUS_LAST
-} qemuMonitorBlockIOStatus;
-
-VIR_ENUM_DECL(qemuMonitorBlockIOStatus);
-
-VIR_ENUM_IMPL(qemuMonitorBlockIOStatus,
-              QEMU_MONITOR_BLOCK_IO_STATUS_LAST,
-              "ok", "failed", "nospace",
-);
-
 VIR_ENUM_IMPL(qemuMonitorDumpStatus,
               QEMU_MONITOR_DUMP_STATUS_LAST,
               "none", "active", "completed", "failed",
@@ -1915,33 +1900,6 @@ qemuMonitorSetMemoryStatsPeriod(qemuMonitor *mon,
 }


-int
-qemuMonitorBlockIOStatusToError(const char *status)
-{
-    int st = qemuMonitorBlockIOStatusTypeFromString(status);
-
-    if (st < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("unknown block IO status: %1$s"), status);
-        return -1;
-    }
-
-    switch ((qemuMonitorBlockIOStatus) st) {
-    case QEMU_MONITOR_BLOCK_IO_STATUS_OK:
-        return VIR_DOMAIN_DISK_ERROR_NONE;
-    case QEMU_MONITOR_BLOCK_IO_STATUS_FAILED:
-        return VIR_DOMAIN_DISK_ERROR_UNSPEC;
-    case QEMU_MONITOR_BLOCK_IO_STATUS_NOSPACE:
-        return VIR_DOMAIN_DISK_ERROR_NO_SPACE;
-
-    /* unreachable */
-    case QEMU_MONITOR_BLOCK_IO_STATUS_LAST:
-        break;
-    }
-    return -1;
-}
-
-
 static void
 qemuDomainDiskInfoFree(void *value)
 {
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 041aa7bc12..a35dbe560f 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -783,9 +783,6 @@ qemuMonitorSetMemoryStatsPeriod(qemuMonitor *mon,
                                 virDomainMemballoonDef *balloon,
                                 int period);

-int
-qemuMonitorBlockIOStatusToError(const char *status);
-
 GHashTable *
 qemuMonitorGetBlockInfo(qemuMonitor *mon);

diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 328e32533d..50e0497385 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2317,6 +2317,24 @@ qemuMonitorJSONBlockInfoAdd(GHashTable *table,
 }


+typedef enum {
+    QEMU_MONITOR_BLOCK_IO_STATUS_OK,
+    QEMU_MONITOR_BLOCK_IO_STATUS_FAILED,
+    QEMU_MONITOR_BLOCK_IO_STATUS_NOSPACE,
+
+    QEMU_MONITOR_BLOCK_IO_STATUS_LAST
+} qemuMonitorBlockIOStatus;
+
+VIR_ENUM_DECL(qemuMonitorBlockIOStatus);
+
+VIR_ENUM_IMPL(qemuMonitorBlockIOStatus,
+              QEMU_MONITOR_BLOCK_IO_STATUS_LAST,
+              "ok",
+              "failed",
+              "nospace",
+);
+
+
 int
 qemuMonitorJSONGetBlockInfo(qemuMonitor *mon,
                             GHashTable *table)
@@ -2329,7 +2347,7 @@ qemuMonitorJSONGetBlockInfo(qemuMonitor *mon,

     for (i = 0; i < virJSONValueArraySize(devices); i++) {
         virJSONValue *dev;
-        struct qemuDomainDiskInfo info = { false };
+        struct qemuDomainDiskInfo info = { .io_status = 
VIR_DOMAIN_DISK_ERROR_NONE };
         const char *thisdev;
         const char *status;
         const char *qdev;
@@ -2358,9 +2376,30 @@ qemuMonitorJSONGetBlockInfo(qemuMonitor *mon,

         /* Missing io-status indicates no error */
         if ((status = virJSONValueObjectGetString(dev, "io-status"))) {
-            info.io_status = qemuMonitorBlockIOStatusToError(status);
-            if (info.io_status < 0)
-                return -1;
+            int st = qemuMonitorBlockIOStatusTypeFromString(status);
+
+            if (st < 0) {
+                VIR_WARN("Unhandled value '%s' of 'io-status' field in 
'query-block' reply",
+                         status);
+                info.io_status = VIR_DOMAIN_DISK_ERROR_UNSPEC;
+            } else {
+                switch ((qemuMonitorBlockIOStatus) st) {
+                case QEMU_MONITOR_BLOCK_IO_STATUS_OK:
+                    info.io_status = VIR_DOMAIN_DISK_ERROR_NONE;
+                    break;
+
+                case QEMU_MONITOR_BLOCK_IO_STATUS_FAILED:
+                    info.io_status = VIR_DOMAIN_DISK_ERROR_UNSPEC;
+                    break;
+
+                case QEMU_MONITOR_BLOCK_IO_STATUS_NOSPACE:
+                    info.io_status = VIR_DOMAIN_DISK_ERROR_NO_SPACE;
+                    break;
+
+                case QEMU_MONITOR_BLOCK_IO_STATUS_LAST:
+                    break;
+                }
+            }
         }

         if (thisdev &&
-- 
2.53.0

Reply via email to