aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonah Palmer <jonah.palmer@oracle.com>2023-09-26 18:41:05 -0400
committerMichael S. Tsirkin <mst@redhat.com>2023-10-04 04:54:24 -0400
commitb532c684e0d71bc69fa56a30f1c7588101aa086a (patch)
treed374795bbddec1c12fbc23e01ccb13a427b549db
parentb0de17a2e28de477e09e77a587fcbeafbbc897c4 (diff)
downloadqemu-b532c684e0d71bc69fa56a30f1c7588101aa086a.zip
qemu-b532c684e0d71bc69fa56a30f1c7588101aa086a.tar.gz
qemu-b532c684e0d71bc69fa56a30f1c7588101aa086a.tar.bz2
qmp: remove virtio_list, search QOM tree instead
The virtio_list duplicates information about virtio devices that already exist in the QOM composition tree. Instead of creating this list of realized virtio devices, search the QOM composition tree instead. This patch modifies the QMP command qmp_x_query_virtio to instead recursively search the QOM composition tree for devices of type 'TYPE_VIRTIO_DEVICE'. The device is also checked to ensure it's realized. Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-Id: <20230926224107.2951144-2-jonah.palmer@oracle.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r--hw/virtio/virtio-qmp.c85
-rw-r--r--hw/virtio/virtio-qmp.h7
-rw-r--r--hw/virtio/virtio.c6
3 files changed, 29 insertions, 69 deletions
diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c
index 7515b09..adebf87 100644
--- a/hw/virtio/virtio-qmp.c
+++ b/hw/virtio/virtio-qmp.c
@@ -667,70 +667,43 @@ VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap)
return features;
}
+static int query_dev_child(Object *child, void *opaque)
+{
+ VirtioInfoList **vdevs = opaque;
+ Object *dev = object_dynamic_cast(child, TYPE_VIRTIO_DEVICE);
+ if (dev != NULL && DEVICE(dev)->realized) {
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VirtioInfo *info = g_new(VirtioInfo, 1);
+
+ /* Get canonical path & name of device */
+ info->path = object_get_canonical_path(dev);
+ info->name = g_strdup(vdev->name);
+ QAPI_LIST_PREPEND(*vdevs, info);
+ }
+ return 0;
+}
+
VirtioInfoList *qmp_x_query_virtio(Error **errp)
{
- VirtioInfoList *list = NULL;
- VirtioInfo *node;
- VirtIODevice *vdev;
+ VirtioInfoList *vdevs = NULL;
- QTAILQ_FOREACH(vdev, &virtio_list, next) {
- DeviceState *dev = DEVICE(vdev);
- Error *err = NULL;
- QObject *obj = qmp_qom_get(dev->canonical_path, "realized", &err);
-
- if (err == NULL) {
- GString *is_realized = qobject_to_json_pretty(obj, true);
- /* virtio device is NOT realized, remove it from list */
- if (!strncmp(is_realized->str, "false", 4)) {
- QTAILQ_REMOVE(&virtio_list, vdev, next);
- } else {
- node = g_new(VirtioInfo, 1);
- node->path = g_strdup(dev->canonical_path);
- node->name = g_strdup(vdev->name);
- QAPI_LIST_PREPEND(list, node);
- }
- g_string_free(is_realized, true);
- }
- qobject_unref(obj);
+ /* Query the QOM composition tree recursively for virtio devices */
+ object_child_foreach_recursive(object_get_root(), query_dev_child, &vdevs);
+ if (vdevs == NULL) {
+ error_setg(errp, "No virtio devices found");
}
-
- return list;
+ return vdevs;
}
VirtIODevice *qmp_find_virtio_device(const char *path)
{
- VirtIODevice *vdev;
-
- QTAILQ_FOREACH(vdev, &virtio_list, next) {
- DeviceState *dev = DEVICE(vdev);
-
- if (strcmp(dev->canonical_path, path) != 0) {
- continue;
- }
-
- Error *err = NULL;
- QObject *obj = qmp_qom_get(dev->canonical_path, "realized", &err);
- if (err == NULL) {
- GString *is_realized = qobject_to_json_pretty(obj, true);
- /* virtio device is NOT realized, remove it from list */
- if (!strncmp(is_realized->str, "false", 4)) {
- g_string_free(is_realized, true);
- qobject_unref(obj);
- QTAILQ_REMOVE(&virtio_list, vdev, next);
- return NULL;
- }
- g_string_free(is_realized, true);
- } else {
- /* virtio device doesn't exist in QOM tree */
- QTAILQ_REMOVE(&virtio_list, vdev, next);
- qobject_unref(obj);
- return NULL;
- }
- /* device exists in QOM tree & is realized */
- qobject_unref(obj);
- return vdev;
+ /* Verify the canonical path is a realized virtio device */
+ Object *dev = object_dynamic_cast(object_resolve_path(path, NULL),
+ TYPE_VIRTIO_DEVICE);
+ if (!dev || !DEVICE(dev)->realized) {
+ return NULL;
}
- return NULL;
+ return VIRTIO_DEVICE(dev);
}
VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp)
@@ -740,7 +713,7 @@ VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp)
vdev = qmp_find_virtio_device(path);
if (vdev == NULL) {
- error_setg(errp, "Path %s is not a VirtIODevice", path);
+ error_setg(errp, "Path %s is not a realized VirtIODevice", path);
return NULL;
}
diff --git a/hw/virtio/virtio-qmp.h b/hw/virtio/virtio-qmp.h
index 8af5f5e..245a446 100644
--- a/hw/virtio/virtio-qmp.h
+++ b/hw/virtio/virtio-qmp.h
@@ -15,13 +15,6 @@
#include "hw/virtio/virtio.h"
#include "hw/virtio/vhost.h"
-#include "qemu/queue.h"
-
-typedef QTAILQ_HEAD(QmpVirtIODeviceList, VirtIODevice) QmpVirtIODeviceList;
-
-/* QAPI list of realized VirtIODevices */
-extern QmpVirtIODeviceList virtio_list;
-
VirtIODevice *qmp_find_virtio_device(const char *path);
VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap);
VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap);
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index d3a22e3..c727e92 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -45,8 +45,6 @@
#include "standard-headers/linux/virtio_mem.h"
#include "standard-headers/linux/virtio_vsock.h"
-QmpVirtIODeviceList virtio_list;
-
/*
* Maximum size of virtio device config space
*/
@@ -3659,7 +3657,6 @@ static void virtio_device_realize(DeviceState *dev, Error **errp)
vdev->listener.commit = virtio_memory_listener_commit;
vdev->listener.name = "virtio";
memory_listener_register(&vdev->listener, vdev->dma_as);
- QTAILQ_INSERT_TAIL(&virtio_list, vdev, next);
}
static void virtio_device_unrealize(DeviceState *dev)
@@ -3674,7 +3671,6 @@ static void virtio_device_unrealize(DeviceState *dev)
vdc->unrealize(dev);
}
- QTAILQ_REMOVE(&virtio_list, vdev, next);
g_free(vdev->bus_name);
vdev->bus_name = NULL;
}
@@ -3848,8 +3844,6 @@ static void virtio_device_class_init(ObjectClass *klass, void *data)
vdc->stop_ioeventfd = virtio_device_stop_ioeventfd_impl;
vdc->legacy_features |= VIRTIO_LEGACY_FEATURES;
-
- QTAILQ_INIT(&virtio_list);
}
bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev)