mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-11 03:24:58 -06:00
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>
This commit is contained in:
parent
b0de17a2e2
commit
b532c684e0
3 changed files with 29 additions and 69 deletions
|
@ -667,70 +667,43 @@ VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap)
|
||||||
return features;
|
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 *qmp_x_query_virtio(Error **errp)
|
||||||
{
|
{
|
||||||
VirtioInfoList *list = NULL;
|
VirtioInfoList *vdevs = NULL;
|
||||||
VirtioInfo *node;
|
|
||||||
VirtIODevice *vdev;
|
|
||||||
|
|
||||||
QTAILQ_FOREACH(vdev, &virtio_list, next) {
|
/* Query the QOM composition tree recursively for virtio devices */
|
||||||
DeviceState *dev = DEVICE(vdev);
|
object_child_foreach_recursive(object_get_root(), query_dev_child, &vdevs);
|
||||||
Error *err = NULL;
|
if (vdevs == NULL) {
|
||||||
QObject *obj = qmp_qom_get(dev->canonical_path, "realized", &err);
|
error_setg(errp, "No virtio devices found");
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
return vdevs;
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtIODevice *qmp_find_virtio_device(const char *path)
|
VirtIODevice *qmp_find_virtio_device(const char *path)
|
||||||
{
|
{
|
||||||
VirtIODevice *vdev;
|
/* Verify the canonical path is a realized virtio device */
|
||||||
|
Object *dev = object_dynamic_cast(object_resolve_path(path, NULL),
|
||||||
QTAILQ_FOREACH(vdev, &virtio_list, next) {
|
TYPE_VIRTIO_DEVICE);
|
||||||
DeviceState *dev = DEVICE(vdev);
|
if (!dev || !DEVICE(dev)->realized) {
|
||||||
|
return NULL;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return VIRTIO_DEVICE(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp)
|
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);
|
vdev = qmp_find_virtio_device(path);
|
||||||
if (vdev == NULL) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,13 +15,6 @@
|
||||||
#include "hw/virtio/virtio.h"
|
#include "hw/virtio/virtio.h"
|
||||||
#include "hw/virtio/vhost.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);
|
VirtIODevice *qmp_find_virtio_device(const char *path);
|
||||||
VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap);
|
VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap);
|
||||||
VhostDeviceProtocols *qmp_decode_protocols(uint64_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_mem.h"
|
||||||
#include "standard-headers/linux/virtio_vsock.h"
|
#include "standard-headers/linux/virtio_vsock.h"
|
||||||
|
|
||||||
QmpVirtIODeviceList virtio_list;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum size of virtio device config space
|
* 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.commit = virtio_memory_listener_commit;
|
||||||
vdev->listener.name = "virtio";
|
vdev->listener.name = "virtio";
|
||||||
memory_listener_register(&vdev->listener, vdev->dma_as);
|
memory_listener_register(&vdev->listener, vdev->dma_as);
|
||||||
QTAILQ_INSERT_TAIL(&virtio_list, vdev, next);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_device_unrealize(DeviceState *dev)
|
static void virtio_device_unrealize(DeviceState *dev)
|
||||||
|
@ -3674,7 +3671,6 @@ static void virtio_device_unrealize(DeviceState *dev)
|
||||||
vdc->unrealize(dev);
|
vdc->unrealize(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTAILQ_REMOVE(&virtio_list, vdev, next);
|
|
||||||
g_free(vdev->bus_name);
|
g_free(vdev->bus_name);
|
||||||
vdev->bus_name = NULL;
|
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->stop_ioeventfd = virtio_device_stop_ioeventfd_impl;
|
||||||
|
|
||||||
vdc->legacy_features |= VIRTIO_LEGACY_FEATURES;
|
vdc->legacy_features |= VIRTIO_LEGACY_FEATURES;
|
||||||
|
|
||||||
QTAILQ_INIT(&virtio_list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev)
|
bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue