|
|
9119d9 |
From d5d5ba920d29bfdaff0f92c4eaa12620daac4b5f Mon Sep 17 00:00:00 2001
|
|
|
9119d9 |
Message-Id: <d5d5ba920d29bfdaff0f92c4eaa12620daac4b5f@dist-git>
|
|
|
9119d9 |
From: John Ferlan <jferlan@redhat.com>
|
|
|
9119d9 |
Date: Thu, 18 Sep 2014 09:29:50 -0400
|
|
|
9119d9 |
Subject: [PATCH] qemu: Issue query-iothreads and to get list of active
|
|
|
9119d9 |
IOThreads
|
|
|
9119d9 |
|
|
|
9119d9 |
https://bugzilla.redhat.com/show_bug.cgi?id=1101574
|
|
|
9119d9 |
|
|
|
9119d9 |
Generate infrastructure and test to handle fetching the QMP
|
|
|
9119d9 |
IOThreads data.
|
|
|
9119d9 |
|
|
|
9119d9 |
(cherry picked from commit 4cf6bfab4cb9e47478e5e36f65bb3f3b9dd16fb8)
|
|
|
9119d9 |
Signed-off-by: John Ferlan <jferlan@redhat.com>
|
|
|
9119d9 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
9119d9 |
---
|
|
|
9119d9 |
src/qemu/qemu_monitor.c | 41 ++++++++++++++++++++
|
|
|
9119d9 |
src/qemu/qemu_monitor.h | 12 ++++++
|
|
|
9119d9 |
src/qemu/qemu_monitor_json.c | 91 ++++++++++++++++++++++++++++++++++++++++++++
|
|
|
9119d9 |
src/qemu/qemu_monitor_json.h | 4 ++
|
|
|
9119d9 |
tests/qemumonitorjsontest.c | 71 ++++++++++++++++++++++++++++++++++
|
|
|
9119d9 |
5 files changed, 219 insertions(+)
|
|
|
9119d9 |
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
|
|
|
9119d9 |
index 78f2a20..00f1d38 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_monitor.c
|
|
|
9119d9 |
+++ b/src/qemu/qemu_monitor.c
|
|
|
9119d9 |
@@ -4088,3 +4088,44 @@ qemuMonitorRTCResetReinjection(qemuMonitorPtr mon)
|
|
|
9119d9 |
|
|
|
9119d9 |
return qemuMonitorJSONRTCResetReinjection(mon);
|
|
|
9119d9 |
}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+/**
|
|
|
9119d9 |
+ * qemuMonitorGetIOThreads:
|
|
|
9119d9 |
+ * @mon: Pointer to the monitor
|
|
|
9119d9 |
+ * @iothreads: Location to return array of IOThreadInfo data
|
|
|
9119d9 |
+ *
|
|
|
9119d9 |
+ * Issue query-iothreads command.
|
|
|
9119d9 |
+ * Retrieve the list of iothreads defined/running for the machine
|
|
|
9119d9 |
+ *
|
|
|
9119d9 |
+ * Returns count of IOThreadInfo structures on success
|
|
|
9119d9 |
+ * -1 on error.
|
|
|
9119d9 |
+ */
|
|
|
9119d9 |
+int
|
|
|
9119d9 |
+qemuMonitorGetIOThreads(qemuMonitorPtr mon,
|
|
|
9119d9 |
+ qemuMonitorIOThreadsInfoPtr **iothreads)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ VIR_DEBUG("mon=%p iothreads=%p", mon, iothreads);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!mon) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
|
|
|
9119d9 |
+ _("monitor must not be NULL"));
|
|
|
9119d9 |
+ return -1;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!mon->json) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
|
|
9119d9 |
+ _("JSON monitor is required"));
|
|
|
9119d9 |
+ return -1;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ return qemuMonitorJSONGetIOThreads(mon, iothreads);
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+void qemuMonitorIOThreadsInfoFree(qemuMonitorIOThreadsInfoPtr iothread)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ if (!iothread)
|
|
|
9119d9 |
+ return;
|
|
|
9119d9 |
+ VIR_FREE(iothread->name);
|
|
|
9119d9 |
+ VIR_FREE(iothread);
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
|
|
|
9119d9 |
index ecba7e1..15aa1d4 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_monitor.h
|
|
|
9119d9 |
+++ b/src/qemu/qemu_monitor.h
|
|
|
9119d9 |
@@ -793,6 +793,18 @@ int qemuMonitorGetGuestCPU(qemuMonitorPtr mon,
|
|
|
9119d9 |
|
|
|
9119d9 |
int qemuMonitorRTCResetReinjection(qemuMonitorPtr mon);
|
|
|
9119d9 |
|
|
|
9119d9 |
+typedef struct _qemuMonitorIOThreadsInfo qemuMonitorIOThreadsInfo;
|
|
|
9119d9 |
+typedef qemuMonitorIOThreadsInfo *qemuMonitorIOThreadsInfoPtr;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+struct _qemuMonitorIOThreadsInfo {
|
|
|
9119d9 |
+ char *name;
|
|
|
9119d9 |
+ int thread_id;
|
|
|
9119d9 |
+};
|
|
|
9119d9 |
+int qemuMonitorGetIOThreads(qemuMonitorPtr mon,
|
|
|
9119d9 |
+ qemuMonitorIOThreadsInfoPtr **iothreads);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+void qemuMonitorIOThreadsInfoFree(qemuMonitorIOThreadsInfoPtr iothread);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
/**
|
|
|
9119d9 |
* When running two dd process and using <> redirection, we need a
|
|
|
9119d9 |
* shell that will not truncate files. These two strings serve that
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
|
|
|
9119d9 |
index 106d807..53e324e 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_monitor_json.c
|
|
|
9119d9 |
+++ b/src/qemu/qemu_monitor_json.c
|
|
|
9119d9 |
@@ -5974,3 +5974,94 @@ qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon)
|
|
|
9119d9 |
virJSONValueFree(reply);
|
|
|
9119d9 |
return ret;
|
|
|
9119d9 |
}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+/**
|
|
|
9119d9 |
+ * Query and parse returned array of data such as:
|
|
|
9119d9 |
+ *
|
|
|
9119d9 |
+ * {u'return': [{u'id': u'iothread1', u'thread-id': 30992}, \
|
|
|
9119d9 |
+ * {u'id': u'iothread2', u'thread-id': 30993}]}
|
|
|
9119d9 |
+ */
|
|
|
9119d9 |
+int
|
|
|
9119d9 |
+qemuMonitorJSONGetIOThreads(qemuMonitorPtr mon,
|
|
|
9119d9 |
+ qemuMonitorIOThreadsInfoPtr **iothreads)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ int ret = -1;
|
|
|
9119d9 |
+ virJSONValuePtr cmd;
|
|
|
9119d9 |
+ virJSONValuePtr reply = NULL;
|
|
|
9119d9 |
+ virJSONValuePtr data;
|
|
|
9119d9 |
+ qemuMonitorIOThreadsInfoPtr *infolist = NULL;
|
|
|
9119d9 |
+ int n = 0;
|
|
|
9119d9 |
+ size_t i;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ *iothreads = NULL;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!(cmd = qemuMonitorJSONMakeCommand("query-iothreads", NULL)))
|
|
|
9119d9 |
+ return ret;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (ret == 0)
|
|
|
9119d9 |
+ ret = qemuMonitorJSONCheckError(cmd, reply);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (ret < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ ret = -1;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!(data = virJSONValueObjectGet(reply, "return"))) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
9119d9 |
+ _("query-iothreads reply was missing return data"));
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if ((n = virJSONValueArraySize(data)) < 0) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
9119d9 |
+ _("query-iothreads reply data was not an array"));
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ /* null-terminated list */
|
|
|
9119d9 |
+ if (VIR_ALLOC_N(infolist, n + 1) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ for (i = 0; i < n; i++) {
|
|
|
9119d9 |
+ virJSONValuePtr child = virJSONValueArrayGet(data, i);
|
|
|
9119d9 |
+ const char *tmp;
|
|
|
9119d9 |
+ qemuMonitorIOThreadsInfoPtr info;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (VIR_ALLOC(info) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ infolist[i] = info;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!(tmp = virJSONValueObjectGetString(child, "id"))) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
9119d9 |
+ _("query-iothreads reply data was missing 'id'"));
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (VIR_STRDUP(info->name, tmp) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (virJSONValueObjectGetNumberInt(child, "thread-id",
|
|
|
9119d9 |
+ &info->thread_id) < 0) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
9119d9 |
+ _("query-iothreads reply has malformed "
|
|
|
9119d9 |
+ "'thread-id' data"));
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ ret = n;
|
|
|
9119d9 |
+ *iothreads = infolist;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ cleanup:
|
|
|
9119d9 |
+ if (ret < 0 && infolist) {
|
|
|
9119d9 |
+ for (i = 0; i < n; i++)
|
|
|
9119d9 |
+ qemuMonitorIOThreadsInfoFree(infolist[i]);
|
|
|
9119d9 |
+ VIR_FREE(infolist);
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ virJSONValueFree(cmd);
|
|
|
9119d9 |
+ virJSONValueFree(reply);
|
|
|
9119d9 |
+ return ret;
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
|
|
|
9119d9 |
index efa2330..dc5a059 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_monitor_json.h
|
|
|
9119d9 |
+++ b/src/qemu/qemu_monitor_json.h
|
|
|
9119d9 |
@@ -443,4 +443,8 @@ int qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon,
|
|
|
9119d9 |
virCPUDataPtr *data);
|
|
|
9119d9 |
|
|
|
9119d9 |
int qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+int qemuMonitorJSONGetIOThreads(qemuMonitorPtr mon,
|
|
|
9119d9 |
+ qemuMonitorIOThreadsInfoPtr **iothreads)
|
|
|
9119d9 |
+ ATTRIBUTE_NONNULL(2);
|
|
|
9119d9 |
#endif /* QEMU_MONITOR_JSON_H */
|
|
|
9119d9 |
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
|
|
|
9119d9 |
index e3fb4f7..d53ab05 100644
|
|
|
9119d9 |
--- a/tests/qemumonitorjsontest.c
|
|
|
9119d9 |
+++ b/tests/qemumonitorjsontest.c
|
|
|
9119d9 |
@@ -2217,6 +2217,76 @@ testQemuMonitorJSONGetNonExistingCPUData(const void *opaque)
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
static int
|
|
|
9119d9 |
+testQemuMonitorJSONGetIOThreads(const void *data)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
|
|
|
9119d9 |
+ qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt);
|
|
|
9119d9 |
+ qemuMonitorIOThreadsInfoPtr *info;
|
|
|
9119d9 |
+ int ninfo = 0;
|
|
|
9119d9 |
+ int ret = -1;
|
|
|
9119d9 |
+ size_t i;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!test)
|
|
|
9119d9 |
+ return -1;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (qemuMonitorTestAddItem(test, "query-iothreads",
|
|
|
9119d9 |
+ "{ "
|
|
|
9119d9 |
+ " \"return\": [ "
|
|
|
9119d9 |
+ " { "
|
|
|
9119d9 |
+ " \"id\": \"iothread1\", "
|
|
|
9119d9 |
+ " \"thread-id\": 30992 "
|
|
|
9119d9 |
+ " }, "
|
|
|
9119d9 |
+ " { "
|
|
|
9119d9 |
+ " \"id\": \"iothread2\", "
|
|
|
9119d9 |
+ " \"thread-id\": 30993 "
|
|
|
9119d9 |
+ " } "
|
|
|
9119d9 |
+ " ]"
|
|
|
9119d9 |
+ "}") < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if ((ninfo = qemuMonitorGetIOThreads(qemuMonitorTestGetMonitor(test),
|
|
|
9119d9 |
+ &info)) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (ninfo != 2) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
+ "ninfo %d is not 2", ninfo);
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+#define CHECK(i, wantname, wantthread_id) \
|
|
|
9119d9 |
+ do { \
|
|
|
9119d9 |
+ if (STRNEQ(info[i]->name, (wantname))) { \
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, \
|
|
|
9119d9 |
+ "name %s is not %s", \
|
|
|
9119d9 |
+ info[i]->name, (wantname)); \
|
|
|
9119d9 |
+ goto cleanup; \
|
|
|
9119d9 |
+ } \
|
|
|
9119d9 |
+ if (info[i]->thread_id != (wantthread_id)) { \
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, \
|
|
|
9119d9 |
+ "thread_id %d is not %d", \
|
|
|
9119d9 |
+ info[i]->thread_id, (wantthread_id)); \
|
|
|
9119d9 |
+ goto cleanup; \
|
|
|
9119d9 |
+ } \
|
|
|
9119d9 |
+ } while (0)
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ CHECK(0, "iothread1", 30992);
|
|
|
9119d9 |
+ CHECK(1, "iothread2", 30993);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+#undef CHECK
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ ret = 0;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ cleanup:
|
|
|
9119d9 |
+ qemuMonitorTestFree(test);
|
|
|
9119d9 |
+ for (i = 0; i < ninfo; i++)
|
|
|
9119d9 |
+ qemuMonitorIOThreadsInfoFree(info[i]);
|
|
|
9119d9 |
+ VIR_FREE(info);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ return ret;
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+static int
|
|
|
9119d9 |
mymain(void)
|
|
|
9119d9 |
{
|
|
|
9119d9 |
int ret = 0;
|
|
|
9119d9 |
@@ -2272,6 +2342,7 @@ mymain(void)
|
|
|
9119d9 |
DO_TEST(GetDeviceAliases);
|
|
|
9119d9 |
DO_TEST(CPU);
|
|
|
9119d9 |
DO_TEST(GetNonExistingCPUData);
|
|
|
9119d9 |
+ DO_TEST(GetIOThreads);
|
|
|
9119d9 |
DO_TEST_SIMPLE("qmp_capabilities", qemuMonitorJSONSetCapabilities);
|
|
|
9119d9 |
DO_TEST_SIMPLE("system_powerdown", qemuMonitorJSONSystemPowerdown);
|
|
|
9119d9 |
DO_TEST_SIMPLE("system_reset", qemuMonitorJSONSystemReset);
|
|
|
9119d9 |
--
|
|
|
9119d9 |
2.1.0
|
|
|
9119d9 |
|