@@ -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;
}
@@ -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);
@@ -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
*/
@@ -3651,7 +3649,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)
@@ -3666,7 +3663,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;
}
@@ -3840,8 +3836,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)