render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
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