From 84f69602143551433e3e0a5226dc572ecb33c059 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Mon, 11 Nov 2013 16:34:53 +0100 Subject: [PATCH] qemu: Check for presence of device and properities when getting CPUID The QOM path in qemu that contains the CPUID registers of a running VM may not be present (introduced in QEMU 1.5). Since commit d94b7817719 we have a regression with QEMU that don't support reporting of the CPUID register state via the monitor as the process startup code expects the path to exist. This patch adds code that checks with the monitor if the requested path already exists and uses it only in this case. --- src/qemu/qemu_monitor_json.c | 50 ++++++++++++++++++++++++++++++++++-- tests/qemumonitorjsontest.c | 16 ++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 87990e2f39..e716fb3763 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5508,20 +5508,66 @@ qemuMonitorJSONGetCPUx86Data(qemuMonitorPtr mon, const char *property, virCPUDataPtr *cpudata) { - virJSONValuePtr cmd; + virJSONValuePtr cmd = NULL; virJSONValuePtr reply = NULL; virJSONValuePtr data; + virJSONValuePtr element; virCPUx86Data *x86Data = NULL; virCPUx86CPUID cpuid; size_t i; int n; int ret = -1; + /* look up if the property exists before asking */ + if (!(cmd = qemuMonitorJSONMakeCommand("qom-list", + "s:path", QOM_CPU_PATH, + NULL))) + goto cleanup; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + /* check if device exists */ + if ((data = virJSONValueObjectGet(reply, "error")) && + STREQ_NULLABLE(virJSONValueObjectGetString(data, "class"), + "DeviceNotFound")) { + ret = -2; + goto cleanup; + } + + if (qemuMonitorJSONCheckError(cmd, reply)) + goto cleanup; + + data = virJSONValueObjectGet(reply, "return"); + + if ((n = virJSONValueArraySize(data)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("%s CPU property did not return an array"), + property); + goto cleanup; + } + + for (i = 0; i < n; i++) { + element = virJSONValueArrayGet(data, i); + if (STREQ_NULLABLE(virJSONValueObjectGetString(element, "name"), + property)) + break; + } + + /* "property" was not found */ + if (i == n) { + ret = -2; + goto cleanup; + } + + virJSONValueFree(cmd); + virJSONValueFree(reply); + if (!(cmd = qemuMonitorJSONMakeCommand("qom-get", "s:path", QOM_CPU_PATH, "s:property", property, NULL))) - return -1; + goto cleanup; if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) goto cleanup; diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 5636d951d2..4cdb938611 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1994,6 +1994,22 @@ testQemuMonitorJSONGetCPUData(const void *opaque) virtTestLoadFile(dataFile, &expected) < 0) goto cleanup; + if (qemuMonitorTestAddItem(test, "qom-list", + "{" + " \"return\": [" + " {" + " \"name\": \"filtered-features\"," + " \"type\": \"X86CPUFeatureWordInfo\"" + " }," + " {" + " \"name\": \"feature-words\"," + " \"type\": \"X86CPUFeatureWordInfo\"" + " }" + " ]," + " \"id\": \"libvirt-19\"" + "}") < 0) + goto cleanup; + if (qemuMonitorTestAddItem(test, "qom-get", jsonStr) < 0) goto cleanup;