From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Add a new qemuMonitorGetCPUDefinitions() method to support invocation of the 'query-cpu-definitions' JSON monitor command. No HMP equivalent is required, since this will only be present for QEMU >= 1.2 Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/qemu/qemu_monitor.c | 21 +++++++++++++ src/qemu/qemu_monitor.h | 4 +++ src/qemu/qemu_monitor_json.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 4 +++ tests/qemumonitorjsontest.c | 63 +++++++++++++++++++++++++++++++++++++ 5 files changed, 167 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 581fe41..45bb32e 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3051,3 +3051,24 @@ void qemuMonitorMachineInfoFree(qemuMonitorMachineInfoPtr machine) VIR_FREE(machine->alias); VIR_FREE(machine); } + +int qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon, + char ***cpus) +{ + VIR_DEBUG("mon=%p cpus=%p", + mon, cpus); + + if (!mon) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("monitor must not be NULL")); + return -1; + } + + if (!mon->json) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("JSON monitor is required")); + return -1; + } + + return qemuMonitorJSONGetCPUDefinitions(mon, cpus); +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 20ff742..fa192d4 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -591,6 +591,10 @@ int qemuMonitorGetMachines(qemuMonitorPtr mon, void qemuMonitorMachineInfoFree(qemuMonitorMachineInfoPtr machine); +int qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon, + char ***cpus); + + /** * When running two dd process and using <> redirection, we need a * shell that will not truncate files. These two strings serve that diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index b4ae893..876188d 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -3990,3 +3990,78 @@ cleanup: virJSONValueFree(reply); return ret; } + + +int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon, + char ***cpus) +{ + int ret; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + virJSONValuePtr data; + char **cpulist = NULL; + int n = 0; + size_t i; + + *cpus = NULL; + + if (!(cmd = qemuMonitorJSONMakeCommand("query-cpu-definitions", NULL))) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + if (ret < 0) + goto cleanup; + + ret = -1; + + if (!(data = virJSONValueObjectGet(reply, "return"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-cpu-definitions reply was missing return data")); + goto cleanup; + } + + if ((n = virJSONValueArraySize(data)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-cpu-definitions reply data was not an array")); + goto cleanup; + } + + if (VIR_ALLOC_N(cpulist, n) < 0) { + virReportOOMError(); + goto cleanup; + } + + for (i = 0 ; i < n ; i++) { + virJSONValuePtr child = virJSONValueArrayGet(data, i); + const char *tmp; + + if (!(tmp = virJSONValueObjectGetString(child, "name"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-cpu-definitions reply data was missing 'name'")); + goto cleanup; + } + + if (!(cpulist[i] = strdup(tmp))) { + virReportOOMError(); + goto cleanup; + } + } + + ret = n; + *cpus = cpulist; + +cleanup: + if (ret < 0 && cpulist) { + for (i = 0 ; i < n ; i++) + VIR_FREE(cpulist[i]); + VIR_FREE(cpulist); + } + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} + diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index f71f11c..218cd02 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -291,4 +291,8 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon, qemuMonitorMachineInfoPtr **machines) ATTRIBUTE_NONNULL(2); +int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon, + char ***cpus) + ATTRIBUTE_NONNULL(2); + #endif /* QEMU_MONITOR_JSON_H */ diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index ad095b1..1346441 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -290,6 +290,68 @@ testQemuMonitorJSONGetMachines(const void *data) CHECK(1, "pc-1.1", false, null); CHECK(2, "pc-1.2", true, "pc"); +#undef CHECK + ret = 0; + +cleanup: + qemuMonitorTestFree(test); + return ret; +} + + +static int +testQemuMonitorJSONGetCPUDefinitions(const void *data) +{ + virCapsPtr caps = (virCapsPtr)data; + qemuMonitorTestPtr test = qemuMonitorTestNew(true, caps); + int ret = -1; + char **cpus = NULL; + int ncpus; + + if (!test) + return -1; + + if (qemuMonitorTestAddItem(test, "query-cpu-definitions", + "{ " + " \"return\": [ " + " { " + " \"name\": \"qemu64\" " + " }, " + " { " + " \"name\": \"Opteron_G4\" " + " }, " + " { " + " \"name\": \"Westmere\" " + " } " + " ]" + "}") < 0) + goto cleanup; + + if ((ncpus = qemuMonitorGetCPUDefinitions(qemuMonitorTestGetMonitor(test), + &cpus)) < 0) + goto cleanup; + + if (ncpus != 3) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "ncpus %d is not 3", ncpus); + goto cleanup; + } + +#define CHECK(i, wantname) \ + do { \ + if (STRNEQ(cpus[i], (wantname))) { \ + virReportError(VIR_ERR_INTERNAL_ERROR, \ + "name %s is not %s", \ + cpus[i], (wantname)); \ + goto cleanup; \ + } \ + } while (0) + + CHECK(0, "qemu64"); + CHECK(1, "Opteron_G4"); + CHECK(2, "Westmere"); + +#undef CHECK ret = 0; cleanup: @@ -319,6 +381,7 @@ mymain(void) DO_TEST(GetStatus); DO_TEST(GetVersion); DO_TEST(GetMachines); + DO_TEST(GetCPUDefinitions); virCapabilitiesFree(caps); -- 1.7.11.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list