File libvirt-qemu-Introduce-qemuMonitorGetDeviceAliases.patch of Package libvirt
From a18438bda04fd1ad6f7eab81cc1305fb691c17c3 Mon Sep 17 00:00:00 2001
Message-Id: <a18438bda04fd1ad6f7eab81cc1305fb691c17c3@dist-git>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 19 Jul 2013 15:01:38 +0200
Subject: [PATCH] qemu: Introduce qemuMonitorGetDeviceAliases
Mostly RHEL-only, see downstream changes below.
This API provides a NULL-terminated list of devices which are currently
attached to a QEMU domain.
https://bugzilla.redhat.com/show_bug.cgi?id=807023
(cherry picked from commit 58b147ad07c9432b53e66ca20aff74d812647c57)
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Conflicts:
src/qemu/qemu_monitor.c,
src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.h,
tests/qemumonitorjsontest.c -- context
Downstream changes:
- qemuMonitorJSONGetDeviceAliases had to be completely rewritten
using query-pci instead of qom-list since the latter is not
backportable to QEMU. RHEL-6.6 only supports PCI device hotplug so
asking for a list of PCI devices (instead of all devices) is fine
- the associated test had to be adapted for query-pci
---
src/qemu/qemu_monitor.c | 21 ++++
src/qemu/qemu_monitor.h | 3 +
src/qemu/qemu_monitor_json.c | 96 +++++++++++++++
src/qemu/qemu_monitor_json.h | 3 +
tests/qemumonitorjsontest.c | 274 +++++++++++++++++++++++++++++++++++++++++++
5 files changed, 397 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index adefc27..b4aacfc 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3387,3 +3387,24 @@ char *qemuMonitorGetTargetArch(qemuMonitorPtr mon)
return qemuMonitorJSONGetTargetArch(mon);
}
+
+int
+qemuMonitorGetDeviceAliases(qemuMonitorPtr mon,
+ char ***aliases)
+{
+ VIR_DEBUG("mon=%p, aliases=%p", mon, aliases);
+
+ if (!mon) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("monitor must not be NULL"));
+ return -1;
+ }
+
+ if (!mon->json) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("JSON monitor is required"));
+ return -1;
+ }
+
+ return qemuMonitorJSONGetDeviceAliases(mon, aliases);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 38bdd46..ac887db 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -645,6 +645,9 @@ int qemuMonitorGetObjectProps(qemuMonitorPtr mon,
char ***props);
char *qemuMonitorGetTargetArch(qemuMonitorPtr mon);
+int qemuMonitorGetDeviceAliases(qemuMonitorPtr mon,
+ char ***aliases);
+
/**
* 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 0f6281a..8e23c46 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -4748,3 +4748,99 @@ cleanup:
virJSONValueFree(reply);
return ret;
}
+
+
+int
+qemuMonitorJSONGetDeviceAliases(qemuMonitorPtr mon,
+ char ***aliases)
+{
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+ virJSONValuePtr data;
+ char **list = NULL;
+ char *alias;
+ int nbuses;
+ int ndevices;
+ int ret = -1;
+ size_t i, j;
+ size_t n = 0;
+ int rv;
+
+ *aliases = NULL;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("query-pci", NULL)))
+ return -1;
+
+ rv = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (rv == 0)
+ rv = qemuMonitorJSONCheckError(cmd, reply);
+
+ if (rv < 0)
+ goto cleanup;
+
+ if (!(data = virJSONValueObjectGet(reply, "return"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-pci reply was missing return data"));
+ goto cleanup;
+ }
+
+ if ((nbuses = virJSONValueArraySize(data)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-pci reply data was not an array"));
+ goto cleanup;
+ }
+
+ for (i = 0; i < nbuses; i++) {
+ virJSONValuePtr child = virJSONValueArrayGet(data, i);
+ virJSONValuePtr devices;
+
+ if (!(devices = virJSONValueObjectGet(child, "devices")) ||
+ (ndevices = virJSONValueArraySize(devices)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-pci bus is missing array of devices"));
+ goto cleanup;
+ }
+
+ for (j = 0; j < ndevices; j++) {
+ virJSONValuePtr device = virJSONValueArrayGet(devices, j);
+ const char *tmp;
+
+ if (!(tmp = virJSONValueObjectGetString(device, "qdev_id"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-pci device is missing qdev_id"));
+ goto cleanup;
+ }
+
+ if (*tmp == '\0')
+ continue;
+
+ if (!(alias = strdup(tmp)) ||
+ VIR_APPEND_ELEMENT(list, n, alias) < 0) {
+ VIR_FREE(alias);
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+ }
+
+ alias = NULL;
+ if (VIR_APPEND_ELEMENT(list, n, alias) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ *aliases = list;
+ list = NULL;
+ ret = 0;
+
+cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ if (list) {
+ for (i = 0; i < n; i++)
+ VIR_FREE(list[i]);
+ VIR_FREE(list);
+ }
+ return ret;
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 0966a76..ae66b9d 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -340,4 +340,7 @@ int qemuMonitorJSONGetObjectProps(qemuMonitorPtr mon,
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
char *qemuMonitorJSONGetTargetArch(qemuMonitorPtr mon);
+int qemuMonitorJSONGetDeviceAliases(qemuMonitorPtr mon,
+ char ***aliases);
+
#endif /* QEMU_MONITOR_JSON_H */
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 264c140..530e46d 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -24,6 +24,7 @@
#include "qemumonitortestutils.h"
#include "threads.h"
#include "virterror_internal.h"
+#include "virstring.h"
#define VIR_FROM_THIS VIR_FROM_NONE
@@ -424,6 +425,278 @@ cleanup:
static int
+testQemuMonitorJSONGetDeviceAliases(const void *data)
+{
+ virCapsPtr caps = (virCapsPtr)data;
+ qemuMonitorTestPtr test = qemuMonitorTestNew(true, caps);
+ int ret = -1;
+ char **aliases = NULL;
+ char **alias;
+ const char *expected[] = {
+ "usb", "video0", "net0", "balloon0", "scsi0",
+ "virtio-disk1", "virtio-disk2", NULL };
+
+ if (!test)
+ return -1;
+
+ if (qemuMonitorTestAddItem(test,
+ "query-pci",
+ "{\"return\": ["
+ " {\"bus\": 0,"
+ " \"devices\": ["
+ " {\"bus\": 0,"
+ " \"qdev_id\": \"\","
+ " \"slot\": 0,"
+ " \"class_info\": {"
+ " \"class\": 1536,"
+ " \"desc\": \"Host bridge\" },"
+ " \"id\": {"
+ " \"device\": 4663,"
+ " \"vendor\": 32902 },"
+ " \"function\": 0,"
+ " \"regions\": [ ] },"
+ " {\"bus\": 0,"
+ " \"qdev_id\": \"\","
+ " \"slot\": 1,"
+ " \"class_info\": {"
+ " \"class\": 1537,"
+ " \"desc\": \"ISA bridge\" },"
+ " \"id\": {"
+ " \"device\": 28672,"
+ " \"vendor\": 32902 },"
+ " \"function\": 0,"
+ " \"regions\": [ ] },"
+ " {\"bus\": 0,"
+ " \"qdev_id\": \"\","
+ " \"slot\": 1,"
+ " \"class_info\": {"
+ " \"class\": 257,"
+ " \"desc\": \"IDE controller\" },"
+ " \"id\": {"
+ " \"device\": 28688,"
+ " \"vendor\": 32902 },"
+ " \"function\": 1,"
+ " \"regions\": ["
+ " {\"bar\": 4,"
+ " \"size\": 16,"
+ " \"address\": 49632,"
+ " \"type\": \"io\" }"
+ " ] },"
+ " {\"bus\": 0,"
+ " \"qdev_id\": \"usb\","
+ " \"irq\": 11,"
+ " \"slot\": 1,"
+ " \"class_info\": {"
+ " \"class\": 3075,"
+ " \"desc\": \"USB controller\" },"
+ " \"id\": {"
+ " \"device\": 28704,"
+ " \"vendor\": 32902 },"
+ " \"function\": 2,"
+ " \"regions\": ["
+ " {\"bar\": 4,"
+ " \"size\": 32,"
+ " \"address\": 49536,"
+ " \"type\": \"io\" }"
+ " ] },"
+ " {\"bus\": 0,"
+ " \"qdev_id\": \"\","
+ " \"irq\": 9,"
+ " \"slot\": 1,"
+ " \"class_info\": {"
+ " \"class\": 1664,"
+ " \"desc\": \"Bridge\" },"
+ " \"id\": {"
+ " \"device\": 28947,"
+ " \"vendor\": 32902 },"
+ " \"function\": 3,"
+ " \"regions\": [ ] },"
+ " {\"bus\": 0,"
+ " \"qdev_id\": \"video0\","
+ " \"slot\": 2,"
+ " \"class_info\": {"
+ " \"class\": 768,"
+ " \"desc\": \"VGA controller\" },"
+ " \"id\": {"
+ " \"device\": 184,"
+ " \"vendor\": 4115 },"
+ " \"function\": 0,"
+ " \"regions\": ["
+ " {\"prefetch\": true,"
+ " \"mem_type_64\": false,"
+ " \"bar\": 0,"
+ " \"size\": 33554432,"
+ " \"address\": 4227858432,"
+ " \"type\": \"memory\" },"
+ " {\"prefetch\": false,"
+ " \"mem_type_64\": false,"
+ " \"bar\": 1,"
+ " \"size\": 4096,"
+ " \"address\": 4273807360,"
+ " \"type\": \"memory\" },"
+ " {\"prefetch\": false,"
+ " \"mem_type_64\": false,"
+ " \"bar\": 6,"
+ " \"size\": 65536,"
+ " \"address\": -1,"
+ " \"type\": \"memory\" }"
+ " ] },"
+ " {\"bus\": 0,"
+ " \"qdev_id\": \"net0\","
+ " \"irq\": 11,"
+ " \"slot\": 3,"
+ " \"class_info\": {"
+ " \"class\": 512,"
+ " \"desc\": \"Ethernet controller\" },"
+ " \"id\": {"
+ " \"device\": 4096,"
+ " \"vendor\": 6900 },"
+ " \"function\": 0,"
+ " \"regions\": ["
+ " {\"bar\": 0,"
+ " \"size\": 32,"
+ " \"address\": 49568,"
+ " \"type\": \"io\" },"
+ " {\"prefetch\": false,"
+ " \"mem_type_64\": false,"
+ " \"bar\": 1,"
+ " \"size\": 4096,"
+ " \"address\": 4273811456,"
+ " \"type\": \"memory\" },"
+ " {\"prefetch\": false,"
+ " \"mem_type_64\": false,"
+ " \"bar\": 6,"
+ " \"size\": 262144,"
+ " \"address\": -1,"
+ " \"type\": \"memory\" }"
+ " ] },"
+ " {\"bus\": 0,"
+ " \"qdev_id\": \"balloon0\","
+ " \"irq\": 10,"
+ " \"slot\": 5,"
+ " \"class_info\": {"
+ " \"class\": 255 },"
+ " \"id\": {"
+ " \"device\": 4098,"
+ " \"vendor\": 6900 },"
+ " \"function\": 0,"
+ " \"regions\": ["
+ " {\"bar\": 0,"
+ " \"size\": 32,"
+ " \"address\": 49600,"
+ " \"type\": \"io\" }"
+ " ] },"
+ " {\"bus\": 0,"
+ " \"qdev_id\": \"scsi0\","
+ " \"irq\": 10,"
+ " \"slot\": 6,"
+ " \"class_info\": {"
+ " \"class\": 256,"
+ " \"desc\": \"SCSI controller\" },"
+ " \"id\": {"
+ " \"device\": 18,"
+ " \"vendor\": 4096 },"
+ " \"function\": 0,"
+ " \"regions\": ["
+ " {\"bar\": 0,"
+ " \"size\": 256,"
+ " \"address\": 49152,"
+ " \"type\": \"io\" },"
+ " {\"prefetch\": false,"
+ " \"mem_type_64\": false,"
+ " \"bar\": 1,"
+ " \"size\": 1024,"
+ " \"address\": 4273815552,"
+ " \"type\": \"memory\" },"
+ " {\"prefetch\": false,"
+ " \"mem_type_64\": false,"
+ " \"bar\": 2,"
+ " \"size\": 8192,"
+ " \"address\": 4273799168,"
+ " \"type\": \"memory\" }"
+ " ] },"
+ " {\"bus\": 0,"
+ " \"qdev_id\": \"virtio-disk1\","
+ " \"irq\": 11,"
+ " \"slot\": 7,"
+ " \"class_info\": {"
+ " \"class\": 256,"
+ " \"desc\": \"SCSI controller\" },"
+ " \"id\": {"
+ " \"device\": 4097,"
+ " \"vendor\": 6900 },"
+ " \"function\": 0,"
+ " \"regions\": ["
+ " {\"bar\": 0,"
+ " \"size\": 64,"
+ " \"address\": 49408,"
+ " \"type\": \"io\" },"
+ " {\"prefetch\": false,"
+ " \"mem_type_64\": false,"
+ " \"bar\": 1,"
+ " \"size\": 4096,"
+ " \"address\": 4273819648,"
+ " \"type\": \"memory\" }"
+ " ] },"
+ " {\"bus\": 0,"
+ " \"qdev_id\": \"virtio-disk2\","
+ " \"irq\": 11,"
+ " \"slot\": 8,"
+ " \"class_info\": {"
+ " \"class\": 256,"
+ " \"desc\": \"SCSI controller\" },"
+ " \"id\": {"
+ " \"device\": 4097,"
+ " \"vendor\": 6900 },"
+ " \"function\": 0,"
+ " \"regions\": ["
+ " {\"bar\": 0,"
+ " \"size\": 64,"
+ " \"address\": 49472,"
+ " \"type\": \"io\" },"
+ " {\"prefetch\": false,"
+ " \"mem_type_64\": false,"
+ " \"bar\": 1,"
+ " \"size\": 4096,"
+ " \"address\": 4273823744,"
+ " \"type\": \"memory\" }"
+ " ] }"
+ " ] }"
+ " ],"
+ " \"id\": \"libvirt-9\"}") < 0)
+ goto cleanup;
+
+ if (qemuMonitorGetDeviceAliases(qemuMonitorTestGetMonitor(test),
+ &aliases) < 0)
+ goto cleanup;
+
+ if (!aliases) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", "no aliases returned");
+ goto cleanup;
+ }
+
+ ret = 0;
+ for (alias = aliases; *alias; alias++) {
+ if (!virStringArrayHasString((char **) expected, *alias)) {
+ fprintf(stderr, "got unexpected device alias '%s'\n", *alias);
+ ret = -1;
+ }
+ }
+ for (alias = (char **) expected; *alias; alias++) {
+ if (!virStringArrayHasString(aliases, *alias)) {
+ fprintf(stderr, "missing expected alias '%s'\n", *alias);
+ ret = -1;
+ }
+ }
+
+cleanup:
+ virStringFreeList(aliases);
+ qemuMonitorTestFree(test);
+ return ret;
+}
+
+
+static int
mymain(void)
{
int ret = 0;
@@ -447,6 +720,7 @@ mymain(void)
DO_TEST(GetCPUDefinitions);
DO_TEST(GetCommands);
+ DO_TEST(GetDeviceAliases);
virCapabilitiesFree(caps);
return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
--
2.0.0