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
