On 10/04/2017 10:58 AM, Jiri Denemark wrote:
query-cpu-definitions QMP command returns a list of unavailable
features
which prevent CPU models from being usable on the current host. So far
we only checked whether the list was empty to mark CPU models as
(un)usable. This patch parses all unavailable features for each CPU
model and stores them in virDomainCapsCPUModel as a list of usability
blockers.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_capabilities.c | 2 +-
src/qemu/qemu_monitor.c | 2 +
src/qemu/qemu_monitor.h | 1 +
src/qemu/qemu_monitor_json.c | 26 +-
tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml | 1102 +++++++++++++++++++--
tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml | 236 ++++-
tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 154 ++-
tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 154 ++-
8 files changed, 1556 insertions(+), 121 deletions(-)
[...]
diff --git a/src/qemu/qemu_monitor_json.c
b/src/qemu/qemu_monitor_json.c
index c63d250d36..fcdd58b369 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -5076,6 +5076,8 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
if (virJSONValueObjectHasKey(child, "unavailable-features")) {
virJSONValuePtr blockers;
+ size_t j;
+ int len;
blockers = virJSONValueObjectGetArray(child,
"unavailable-features");
@@ -5086,10 +5088,32 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
goto cleanup;
}
- if (virJSONValueArraySize(blockers) > 0)
+ len = virJSONValueArraySize(blockers);
+
+ if (len != 0)
At this point len is either 0 (empty) or > 0 because if it was < 0 the
virJSONValueObjectGetArray would have already caused a failure, right?
So why not :
if (len == 0) {
cpu->usable = VIR_TRISTATE_BOOL_YES;
continue;
}
cpu->usable = VIR_TRISTATE_BOOL_NO;
if (VIR_ALLOC_N(cpu->blockers, len + 1) < 0)
...
cpu->usable = VIR_TRISTATE_BOOL_NO;
else
cpu->usable = VIR_TRISTATE_BOOL_YES;
+
+ if (len > 0 && VIR_ALLOC_N(cpu->blockers, len + 1) < 0)
+ goto cleanup;
+
+ for (j = 0; j < len; j++) {
+ virJSONValuePtr blocker = virJSONValueArrayGet(blockers, j);
+ char *name;
virJSONValueArrayGet can return NULL, but that shouldn't affect us since
blockers is an ARRAY and there's no way j >= len...
+
+ if (blocker->type != VIR_JSON_TYPE_STRING) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("unexpected value in unavailable-features
"
+ "array"));
+ goto cleanup;
+ }
...but because of this check...
+
+ if (VIR_STRDUP(name, virJSONValueGetString(blocker)) < 0)
...wouldn't virJSONValueGetString return a non NULL string, so...
+ goto cleanup;
+
+ cpu->blockers[j] = name;
...why not just go direct to cpu->blockers[j]? Or did you come across
something in testing that had a NULL return from the call to
virJSONValueGetString(blocker)?
Maybe a NULL entry should just be ignored so as to not tank the whole
thing using the logic that if a blocker isn't there, by name, then is it
a blocker?
+ }
}
}
Reviewed-by: John Ferlan <jferlan(a)redhat.com>
John