From 2a8d40f4ecaff1e0c44da58dd244cbd23319dc69 Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Fri, 3 Jun 2016 16:59:59 +0200 Subject: [PATCH] qemu: Refactor qemuMonitorJSONGetCPUx86Data This patch splits qemuMonitorJSONGetCPUx86Data in three functions: - qemuMonitorJSONCheckCPUx86 checks if QEMU supports reporting CPUID features for a guest CPU - qemuMonitorJSONParseCPUx86Features parses CPUID features from a JSON array - qemuMonitorJSONGetCPUx86Data gets the requested guest CPU property from QOM and uses qemuMonitorJSONParseCPUx86Features to parse it Signed-off-by: Jiri Denemark --- src/qemu/qemu_monitor_json.c | 145 +++++++++++++++++++++-------------- src/qemu/qemu_monitor_json.h | 4 + 2 files changed, 90 insertions(+), 59 deletions(-) diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 874ed24b52..47894f2f65 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -6404,6 +6404,43 @@ qemuMonitorJSONParseCPUx86FeatureWord(virJSONValuePtr data, static int +qemuMonitorJSONParseCPUx86Features(virJSONValuePtr data, + virCPUDataPtr *cpudata) +{ + virCPUx86Data *x86Data = NULL; + virCPUx86CPUID cpuid; + size_t i; + ssize_t n; + int ret = -1; + + if ((n = virJSONValueArraySize(data)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("invalid array of CPUID features")); + return -1; + } + + if (VIR_ALLOC(x86Data) < 0) + return -1; + + for (i = 0; i < n; i++) { + if (qemuMonitorJSONParseCPUx86FeatureWord(virJSONValueArrayGet(data, i), + &cpuid) < 0 || + virCPUx86DataAddCPUID(x86Data, &cpuid) < 0) + goto cleanup; + } + + if (!(*cpudata = virCPUx86MakeData(VIR_ARCH_X86_64, &x86Data))) + goto cleanup; + + ret = 0; + + cleanup: + virCPUx86DataFree(x86Data); + return ret; +} + + +int qemuMonitorJSONGetCPUx86Data(qemuMonitorPtr mon, const char *property, virCPUDataPtr *cpudata) @@ -6411,104 +6448,87 @@ qemuMonitorJSONGetCPUx86Data(qemuMonitorPtr mon, virJSONValuePtr cmd = NULL; virJSONValuePtr reply = NULL; virJSONValuePtr data; - virJSONValuePtr element; - virCPUx86Data *x86Data = NULL; - virCPUx86CPUID cpuid; - size_t i; - ssize_t n; int ret = -1; - /* look up if the property exists before asking */ - if (!(cmd = qemuMonitorJSONMakeCommand("qom-list", + if (!(cmd = qemuMonitorJSONMakeCommand("qom-get", "s:path", QOM_CPU_PATH, + "s:property", property, NULL))) goto cleanup; if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) goto cleanup; - /* check if device exists */ - if ((data = virJSONValueObjectGet(reply, "error"))) { - const char *klass = virJSONValueObjectGetString(data, "class"); - if (STREQ_NULLABLE(klass, "DeviceNotFound") || - STREQ_NULLABLE(klass, "CommandNotFound")) { - ret = -2; - goto cleanup; - } - } - if (qemuMonitorJSONCheckError(cmd, reply)) goto cleanup; data = virJSONValueObjectGetArray(reply, "return"); + ret = qemuMonitorJSONParseCPUx86Features(data, cpudata); - 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; - } - + cleanup: virJSONValueFree(cmd); virJSONValueFree(reply); + return ret; +} - if (!(cmd = qemuMonitorJSONMakeCommand("qom-get", + +/* + * Returns -1 on error, 0 if QEMU does not support reporting CPUID features + * of a guest CPU, and 1 if the feature is supported. + */ +static int +qemuMonitorJSONCheckCPUx86(qemuMonitorPtr mon) +{ + virJSONValuePtr cmd = NULL; + virJSONValuePtr reply = NULL; + virJSONValuePtr data; + size_t i; + ssize_t n; + int ret = -1; + + if (!(cmd = qemuMonitorJSONMakeCommand("qom-list", "s:path", QOM_CPU_PATH, - "s:property", property, NULL))) goto cleanup; if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) goto cleanup; + if ((data = virJSONValueObjectGet(reply, "error"))) { + const char *klass = virJSONValueObjectGetString(data, "class"); + if (STREQ_NULLABLE(klass, "DeviceNotFound") || + STREQ_NULLABLE(klass, "CommandNotFound")) { + ret = 0; + goto cleanup; + } + } + if (qemuMonitorJSONCheckError(cmd, reply)) goto cleanup; - if (!(data = virJSONValueObjectGetArray(reply, "return"))) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("qom-get reply was missing return data")); - goto cleanup; - } + data = virJSONValueObjectGetArray(reply, "return"); if ((n = virJSONValueArraySize(data)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("%s CPU property did not return an array"), - property); + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("qom-list reply data was not an array")); goto cleanup; } - if (VIR_ALLOC(x86Data) < 0) - goto cleanup; - for (i = 0; i < n; i++) { - if (qemuMonitorJSONParseCPUx86FeatureWord(virJSONValueArrayGet(data, i), - &cpuid) < 0 || - virCPUx86DataAddCPUID(x86Data, &cpuid) < 0) - goto cleanup; + virJSONValuePtr element = virJSONValueArrayGet(data, i); + if (STREQ_NULLABLE(virJSONValueObjectGetString(element, "name"), + "feature-words")) + break; } - if (!(*cpudata = virCPUx86MakeData(VIR_ARCH_X86_64, &x86Data))) - goto cleanup; - - ret = 0; + if (i == n) + ret = 0; + else + ret = 1; cleanup: virJSONValueFree(cmd); virJSONValueFree(reply); - virCPUx86DataFree(x86Data); return ret; } @@ -6529,9 +6549,16 @@ qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon, virArch arch, virCPUDataPtr *data) { + int rc; + switch (arch) { case VIR_ARCH_X86_64: case VIR_ARCH_I686: + if ((rc = qemuMonitorJSONCheckCPUx86(mon)) < 0) + return -1; + else if (!rc) + return -2; + return qemuMonitorJSONGetCPUx86Data(mon, "feature-words", data); default: diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 76758dbfed..586a3637b8 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -457,6 +457,10 @@ int qemuMonitorJSONDetachCharDev(qemuMonitorPtr mon, int qemuMonitorJSONGetDeviceAliases(qemuMonitorPtr mon, char ***aliases); +int qemuMonitorJSONGetCPUx86Data(qemuMonitorPtr mon, + const char *property, + virCPUDataPtr *cpudata); + int qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon, virArch arch, virCPUDataPtr *data); -- GitLab