From 3b565d3f46a947ac9b51f1546ccf5c8664f15301 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 22 Aug 2012 10:48:41 +0100 Subject: [PATCH] Add a qemuMonitorGetEvents() method for QMP query-events command Add a new qemuMonitorGetEvents() method to support invocation of the 'query-events' JSON monitor command. No HMP equivalent is required, since this will only be used when JSON is available The existing qemuMonitorJSONCheckEvents() method is refactored to use this new method Signed-off-by: Daniel P. Berrange --- src/qemu/qemu_monitor.c | 22 +++++++ src/qemu/qemu_monitor.h | 2 + src/qemu/qemu_monitor_json.c | 120 ++++++++++++++++++++++++----------- src/qemu/qemu_monitor_json.h | 3 + 4 files changed, 111 insertions(+), 36 deletions(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 5f6699e021..ee0672d09a 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3119,3 +3119,25 @@ int qemuMonitorGetCommands(qemuMonitorPtr mon, return qemuMonitorJSONGetCommands(mon, commands); } + + +int qemuMonitorGetEvents(qemuMonitorPtr mon, + char ***events) +{ + VIR_DEBUG("mon=%p events=%p", + mon, events); + + 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 qemuMonitorJSONGetEvents(mon, events); +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 511d1688a4..73c80ada4d 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -598,6 +598,8 @@ int qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon, int qemuMonitorGetCommands(qemuMonitorPtr mon, char ***commands); +int qemuMonitorGetEvents(qemuMonitorPtr mon, + char ***events); /** diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 63090042a5..e135cca356 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1007,49 +1007,23 @@ int qemuMonitorJSONCheckEvents(qemuMonitorPtr mon, qemuCapsPtr caps) { - int ret = -1; - virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-events", NULL); - virJSONValuePtr reply = NULL; - virJSONValuePtr data; - int i, n; - - if (!cmd) - return ret; - - if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) - goto cleanup; - - if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { - ret = 0; - goto cleanup; - } - - if (qemuMonitorJSONCheckError(cmd, reply) < 0) - goto cleanup; - - if (!(data = virJSONValueObjectGet(reply, "return")) || - data->type != VIR_JSON_TYPE_ARRAY || - (n = virJSONValueArraySize(data)) <= 0) - goto cleanup; + char **events = NULL; + int nevents; + size_t i; - for (i = 0; i < n; i++) { - virJSONValuePtr entry; - const char *name; + if ((nevents = qemuMonitorJSONGetEvents(mon, &events)) < 0) + return -1; - if (!(entry = virJSONValueArrayGet(data, i)) || - !(name = virJSONValueObjectGetString(entry, "name"))) - goto cleanup; + for (i = 0 ; i < nevents ; i++) { + char *name = events[i]; if (STREQ(name, "BALLOON_CHANGE")) qemuCapsSet(caps, QEMU_CAPS_BALLOON_EVENT); + VIR_FREE(name); } + VIR_FREE(events); - ret = 0; - -cleanup: - virJSONValueFree(cmd); - virJSONValueFree(reply); - return ret; + return 0; } @@ -4170,3 +4144,77 @@ cleanup: virJSONValueFree(reply); return ret; } + + +int qemuMonitorJSONGetEvents(qemuMonitorPtr mon, + char ***events) +{ + int ret; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + virJSONValuePtr data; + char **eventlist = NULL; + int n = 0; + size_t i; + + *events = NULL; + + if (!(cmd = qemuMonitorJSONMakeCommand("query-events", 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-events reply was missing return data")); + goto cleanup; + } + + if ((n = virJSONValueArraySize(data)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-events reply data was not an array")); + goto cleanup; + } + + if (VIR_ALLOC_N(eventlist, 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-events reply data was missing 'name'")); + goto cleanup; + } + + if (!(eventlist[i] = strdup(tmp))) { + virReportOOMError(); + goto cleanup; + } + } + + ret = n; + *events = eventlist; + +cleanup: + if (ret < 0 && eventlist) { + for (i = 0 ; i < n ; i++) + VIR_FREE(eventlist[i]); + VIR_FREE(eventlist); + } + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 54aaf0b91c..19c03a98d8 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -301,5 +301,8 @@ int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon, int qemuMonitorJSONGetCommands(qemuMonitorPtr mon, char ***commands) ATTRIBUTE_NONNULL(2); +int qemuMonitorJSONGetEvents(qemuMonitorPtr mon, + char ***events) + ATTRIBUTE_NONNULL(2); #endif /* QEMU_MONITOR_JSON_H */ -- GitLab