Message ID | 20200402100302.833267-3-lvivier@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | hmp,qmp: Add some commands to introspect virtio devices | expand |
On 4/2/20 5:02 AM, Laurent Vivier wrote: > This new command shows the status of a VirtIODevice > (features, endianness and number of virtqueues) > > Signed-off-by: Laurent Vivier <lvivier@redhat.com> > --- > +++ b/qapi/virtio.json > @@ -52,3 +52,68 @@ > ## > > { 'command': 'query-virtio', 'returns': ['VirtioInfo'] } > + > +## > +# @VirtioStatus: > +# > +# @device_id: VirtIODevice status As this is a new API, it should stick to our naming conventions: device-id > +# > +# @device_endian: VirtIODevice device_endian device-endian > +# > +# @guest_features: VirtIODevice guest_features guest-features > +# > +# @host_features: VirtIODevice host_features host-features > +# > +# @backend_features: VirtIODevice backend_features backend-features > +# > +# @num_vqs: number of VirtIODevice queues num-vqs > +# > +# Since: 5.1 > +# > +## > + > +{ 'struct': 'VirtioStatus', > + 'data': { > + 'device_id': 'int', > + 'device_endian': 'str', > + 'guest_features': 'uint64', > + 'host_features': 'uint64', > + 'backend_features': 'uint64', A bare int requires subsequent decoding. Can this instead be an array of enum values, with enum values naming each enabled feature? > + 'num_vqs': 'uint16' > + } > +} > + > +## > +# @virtio-status: > +# > +# Return the status of virtio device > +# > +# @path: QOBject path of the VirtIODevice > +# > +# Returns: status of the VirtIODevice > +# > +# Since: 5.1 > +# > +# Example: > +# > +# -> { "execute": "virtio-status", > +# "arguments": { > +# "path": "/machine/peripheral-anon/device[3]/virtio-backend" > +# } > +# } > +# <- { "return": { > +# "backend_features": 0, > +# "guest_features": 5111807911, again, this means nothing to me. "guest-features": ["feature-a","feature-b"] is vastly more usable if I'm inspecting the query output, compared to decoding the decimal number back into bits then doing a lookup into the documentation of which bits mean which features. > +# "num_vqs": 3, > +# "host_features": 6337593319, > +# "device_endian": "little", > +# "device_id": 1 > +# } > +# } > +# > +## > + > +{ 'command': 'virtio-status', > + 'data': { 'path': 'str' }, > + 'returns': 'VirtioStatus' > +} >
diff --git a/hw/virtio/virtio-stub.c b/hw/virtio/virtio-stub.c index d9e4a815ecf1..8fe2d6cd8892 100644 --- a/hw/virtio/virtio-stub.c +++ b/hw/virtio/virtio-stub.c @@ -12,3 +12,8 @@ VirtioInfoList *qmp_query_virtio(Error **errp) { return qmp_virtio_unsupported(errp); } + +VirtioStatus *qmp_virtio_status(const char* path, Error **errp) +{ + return qmp_virtio_unsupported(errp); +} diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 3cebc3d169c8..7f6e21e4ab2c 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -3839,6 +3839,57 @@ VirtioInfoList *qmp_query_virtio(Error **errp) return list; } +static VirtIODevice *virtio_device_find(const char *path) +{ + VirtIODevice *vdev; + + QTAILQ_FOREACH(vdev, &virtio_list, next) { + DeviceState *dev = DEVICE(vdev); + + if (strcmp(dev->canonical_path, path) != 0) { + continue; + } + return vdev; + } + + return NULL; +} + +VirtioStatus *qmp_virtio_status(const char* path, Error **errp) +{ + VirtIODevice *vdev; + VirtioStatus *status; + + vdev = virtio_device_find(path); + if (vdev == NULL) { + error_setg(errp, "Path %s is not a VirtIO device", path); + return NULL; + } + + status = g_new0(VirtioStatus, 1); + status->guest_features = vdev->guest_features; + status->host_features = vdev->host_features; + status->backend_features = vdev->backend_features; + status->device_id = vdev->device_id; + + switch (vdev->device_endian) { + case VIRTIO_DEVICE_ENDIAN_LITTLE: + status->device_endian = g_strdup("little"); + break; + case VIRTIO_DEVICE_ENDIAN_BIG: + status->device_endian = g_strdup("big"); + break; + case VIRTIO_DEVICE_ENDIAN_UNKNOWN: + default: + status->device_endian = g_strdup("unknown"); + break; + } + + status->num_vqs = virtio_get_num_queues(vdev); + + return status; +} + static const TypeInfo virtio_device_info = { .name = TYPE_VIRTIO_DEVICE, .parent = TYPE_DEVICE, diff --git a/qapi/virtio.json b/qapi/virtio.json index 2a95d08a8b9e..2af4d95b9893 100644 --- a/qapi/virtio.json +++ b/qapi/virtio.json @@ -52,3 +52,68 @@ ## { 'command': 'query-virtio', 'returns': ['VirtioInfo'] } + +## +# @VirtioStatus: +# +# @device_id: VirtIODevice status +# +# @device_endian: VirtIODevice device_endian +# +# @guest_features: VirtIODevice guest_features +# +# @host_features: VirtIODevice host_features +# +# @backend_features: VirtIODevice backend_features +# +# @num_vqs: number of VirtIODevice queues +# +# Since: 5.1 +# +## + +{ 'struct': 'VirtioStatus', + 'data': { + 'device_id': 'int', + 'device_endian': 'str', + 'guest_features': 'uint64', + 'host_features': 'uint64', + 'backend_features': 'uint64', + 'num_vqs': 'uint16' + } +} + +## +# @virtio-status: +# +# Return the status of virtio device +# +# @path: QOBject path of the VirtIODevice +# +# Returns: status of the VirtIODevice +# +# Since: 5.1 +# +# Example: +# +# -> { "execute": "virtio-status", +# "arguments": { +# "path": "/machine/peripheral-anon/device[3]/virtio-backend" +# } +# } +# <- { "return": { +# "backend_features": 0, +# "guest_features": 5111807911, +# "num_vqs": 3, +# "host_features": 6337593319, +# "device_endian": "little", +# "device_id": 1 +# } +# } +# +## + +{ 'command': 'virtio-status', + 'data': { 'path': 'str' }, + 'returns': 'VirtioStatus' +}
This new command shows the status of a VirtIODevice (features, endianness and number of virtqueues) Signed-off-by: Laurent Vivier <lvivier@redhat.com> --- hw/virtio/virtio-stub.c | 5 ++++ hw/virtio/virtio.c | 51 ++++++++++++++++++++++++++++++++ qapi/virtio.json | 65 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+)