From: Peter Krempa <pkrempa@redhat.com>
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 <pkrempa@redhat.com>
---
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