[PATCH 0/5] Add guest device info to virDomainGetGuestInfo
*** BLURB HERE *** Michal Prívozník (5): Add guest device info to virDomainGetGuestInfo qemu_agent: Introduce guest-get-info qemuagenttest: Introduce GetGuestDeviceInfo test case qemu: Implement device info for virDomainGetGuestInfo() API virsh: Add support for VIR_DOMAIN_GUEST_INFO_DEVICES docs/manpages/virsh.rst | 17 ++++- include/libvirt/libvirt-domain.h | 78 ++++++++++++++++++++ src/hypervisor/qemu_agent.c | 119 ++++++++++++++++++++++++++++++ src/hypervisor/qemu_agent.h | 21 ++++++ src/libvirt-domain.c | 5 ++ src/libvirt_private.syms | 2 + src/qemu/qemu_driver.c | 58 ++++++++++++++- tests/qemuagenttest.c | 123 +++++++++++++++++++++++++++++++ tools/virsh-domain.c | 6 ++ 9 files changed, 424 insertions(+), 5 deletions(-) -- 2.54.0
From: Michal Privoznik <mprivozn@redhat.com> QEMU guest agent has 'guest-get-devices` command, which returns information on guest devices (driver name, version, release date, and so on). In this commit the public API part is introduced. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- include/libvirt/libvirt-domain.h | 78 ++++++++++++++++++++++++++++++++ src/libvirt-domain.c | 5 ++ 2 files changed, 83 insertions(+) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index f4dfe9fb1a..874fc4b455 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -8867,6 +8867,83 @@ int virDomainSetLaunchSecurityState(virDomainPtr domain, */ # define VIR_DOMAIN_GUEST_INFO_LOAD_15M "load.15m" +/** + * VIR_DOMAIN_GUEST_INFO_DEVICE_COUNT: + * + * The number of guest devices that detailed information is fetched for as + * unsigned int. + * + * Since: 12.7.0 + */ +# define VIR_DOMAIN_GUEST_INFO_DEVICE_COUNT "device.count" + +/** + * VIR_DOMAIN_GUEST_INFO_DEVICE_PREFIX: + * + * The parameter name prefix to access each device entry. Concatenate the + * prefix, the entry number formatted as an unsigned integer and one of the + * device suffix parameters to form a complete parameter name. + * + * Since: 12.7.0 + */ +# define VIR_DOMAIN_GUEST_INFO_DEVICE_PREFIX "device." + +/** + * VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_DRIVER_NAME: + * + * Name of the device driver (e.g. ``VirtIO Balloon Driver``) as a string. + * + * Since: 12.7.0 + */ +# define VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_DRIVER_NAME ".driverName" + +/** + * VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_DRIVER_DATE: + * + * Driver release date in seconds since the epoch (e.g. 1736726400000) as long long. + * + * Since: 12.7.0 + */ +# define VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_DRIVER_DATE ".driverDate" + +/** + * VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_DRIVER_VERSION: + * + * Driver version (e.g. ``100.100.104.27100``) as a string. + * + * Since: 12.7.0 + */ +# define VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_DRIVER_VERSION ".driverVersion" + +/** + * VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_ID_TYPE: + * + * Device identification (e.g. ``pci``) as a string. + * + * Since: 12.7.0 + */ +# define VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_ID_TYPE ".idType" + +/** + * VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_PCI_VENDOR: + * + * PCI device (a device with VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_ID_TYPE equal + * to ``pci``) vendor id (e.g. 6900) as a unsigned int. + * + * Since: 12.7.0 + */ +# define VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_PCI_VENDOR ".pciVendor" + +/** + * VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_PCI_DEVICE: + * + * PCI device (a device with VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_ID_TYPE equal + * to ``pci``) device id (e.g. 4165) as a unsigned int. + * + * Since: 12.7.0 + */ +# define VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_PCI_DEVICE ".pciDevice" + /** * virDomainGuestInfoTypes: * @@ -8881,6 +8958,7 @@ typedef enum { VIR_DOMAIN_GUEST_INFO_DISKS = (1 << 5), /* return disks information (Since: 7.0.0) */ VIR_DOMAIN_GUEST_INFO_INTERFACES = (1 << 6), /* return interfaces information (Since: 7.10.0) */ VIR_DOMAIN_GUEST_INFO_LOAD = (1 << 7), /* return load averages (Since: 11.2.0) */ + VIR_DOMAIN_GUEST_INFO_DEVICES = (1 << 8), /* return devices information (Since: 12.7.0) */ } virDomainGuestInfoTypes; int virDomainGetGuestInfo(virDomainPtr domain, diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 60d84b24a1..acd9ffc44b 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -13260,6 +13260,11 @@ virDomainSetVcpu(virDomainPtr domain, * The VIR_DOMAIN_GUEST_INFO_LOAD_* constants define the known typed parameter * keys. * + * VIR_DOMAIN_GUEST_INFO_DEVICES: + * Returns information on guest devices. + * The VIR_DOMAIN_GUEST_INFO_DEVICE_* constants define the known typed + * parameter keys. + * * Using 0 for @types returns all information groups supported by the given * hypervisor. * -- 2.54.0
From: Michal Privoznik <mprivozn@redhat.com> QEMU agent has 'guest-get-info` command. Even though it's currently implemented only for Windows, it shows some interesting information from inside the guest, like device drivers, their versions, and so on. Looking at the command definition in qga/qapi-schema.json the only non-optional field in returned data is 'driver-name'. The rest is optional. Although looking at the current implementation either all fields are set or device is ignored completely. Nevertheless, our code should follow QMP schema. New qemuAgentGuestDeviceInfo structure is introduced among with qemuAgentGetGuestDeviceInfo() function which parses reply from agent and fills the structure. Optional fields are either set to NULL or -1, if missing. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/hypervisor/qemu_agent.c | 119 ++++++++++++++++++++++++++++++++++++ src/hypervisor/qemu_agent.h | 21 +++++++ src/libvirt_private.syms | 2 + 3 files changed, 142 insertions(+) diff --git a/src/hypervisor/qemu_agent.c b/src/hypervisor/qemu_agent.c index e549947fbf..e11507326f 100644 --- a/src/hypervisor/qemu_agent.c +++ b/src/hypervisor/qemu_agent.c @@ -2681,3 +2681,122 @@ qemuAgentFSInfoFormat(qemuAgentFSInfo **agentinfo, } return ret; } + + +void +qemuAgentGuestDeviceInfoFree(qemuAgentGuestDeviceInfo *info) +{ + if (!info) + return; + + g_free(info->driverName); + g_free(info->driverVersion); + g_free(info->pci); + g_free(info); +} + + +int +qemuAgentGetGuestDeviceInfo(qemuAgent *agent, + qemuAgentGuestDeviceInfo ***info, + bool report_unsupported) +{ + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) reply = NULL; + virJSONValue *data = NULL; + size_t ndata; + size_t i; + int rc; + + if (!(cmd = qemuAgentMakeCommand("guest-get-devices", NULL))) + return -1; + + if ((rc = qemuAgentCommandFull(agent, cmd, &reply, agent->timeout, + report_unsupported)) < 0) + return rc; + + if (!(data = virJSONValueObjectGetArray(reply, "return"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("qemu agent didn't return an array of devices")); + return -1; + } + + ndata = virJSONValueArraySize(data); + + *info = g_new0(qemuAgentGuestDeviceInfo *, ndata); + + for (i = 0; i < ndata; i++) { + g_autoptr(qemuAgentGuestDeviceInfo) oneInfo = NULL; + virJSONValue *entry = virJSONValueArrayGet(data, i); + virJSONValue *dDate = NULL; + virJSONValue *idObj = NULL; + + if (!entry) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("array element missing in guest-get-devices return value")); + goto error; + } + + oneInfo = g_new0(qemuAgentGuestDeviceInfo, 1); + + oneInfo->driverName = g_strdup(virJSONValueObjectGetString(entry, "driver-name")); + if (!oneInfo->driverName) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("'driver-name' missing in reply of guest-get-devices")); + goto error; + } + + if ((dDate = virJSONValueObjectGet(entry, "driver-date"))) { + if (virJSONValueGetNumberLong(dDate, &oneInfo->driverDate) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("malformed 'driver-date' in reply of guest-get-devices")); + goto error; + } + } else { + oneInfo->driverDate = -1; + } + + oneInfo->driverVersion = g_strdup(virJSONValueObjectGetString(entry, "driver-version")); + + if ((idObj = virJSONValueObjectGet(entry, "id"))) { + const char *type = NULL; + + if (!(type = virJSONValueObjectGetString(idObj, "type"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing 'type' in reply of guest-get-devices")); + goto error; + } + + if (STREQ("pci", type)) { + g_autofree qemuAgentGuestDeviceInfoPCI *pci = NULL; + + pci = g_new0(qemuAgentGuestDeviceInfoPCI, 1); + + if (virJSONValueObjectGetNumberUint(idObj, "vendor-id", &pci->vendorID) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing or malformed 'vendor-id' in reply of guest-get-devices")); + goto error; + } + + if (virJSONValueObjectGetNumberUint(idObj, "device-id", &pci->deviceID) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing or malformed 'device-id' in reply of guest-get-devices")); + goto error; + } + + oneInfo->pci = g_steal_pointer(&pci); + } + } + + (*info)[i] = g_steal_pointer(&oneInfo); + } + + return ndata; + + error: + for (i = 0; i < ndata; i++) { + qemuAgentGuestDeviceInfoFree((*info)[i]); + } + g_clear_pointer(info, g_free); + return -1; +} diff --git a/src/hypervisor/qemu_agent.h b/src/hypervisor/qemu_agent.h index 3dbc3baec1..c55cfeb99b 100644 --- a/src/hypervisor/qemu_agent.h +++ b/src/hypervisor/qemu_agent.h @@ -201,3 +201,24 @@ int qemuAgentFSInfoFormat(qemuAgentFSInfo **agentinfo, int nagentinfo, virDomainDef *vmdef, virDomainFSInfoPtr **info); + +typedef struct _qemuAgentGuestDeviceInfoPCI qemuAgentGuestDeviceInfoPCI; +struct _qemuAgentGuestDeviceInfoPCI { + unsigned int vendorID; + unsigned int deviceID; +}; + +typedef struct _qemuAgentGuestDeviceInfo qemuAgentGuestDeviceInfo; +struct _qemuAgentGuestDeviceInfo { + char *driverName; + long long driverDate; + char *driverVersion; + qemuAgentGuestDeviceInfoPCI *pci; +}; + +void qemuAgentGuestDeviceInfoFree(qemuAgentGuestDeviceInfo *info); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuAgentGuestDeviceInfo, qemuAgentGuestDeviceInfoFree); + +int qemuAgentGetGuestDeviceInfo(qemuAgent *agent, + qemuAgentGuestDeviceInfo ***info, + bool report_unsupported); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c76e5cb08a..9d1bac27f5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1724,6 +1724,7 @@ qemuAgentFSThaw; qemuAgentFSTrim; qemuAgentGetDisks; qemuAgentGetFSInfo; +qemuAgentGetGuestDeviceInfo; qemuAgentGetHostname; qemuAgentGetInterfaces; qemuAgentGetLoadAvg; @@ -1732,6 +1733,7 @@ qemuAgentGetTime; qemuAgentGetTimezone; qemuAgentGetUsers; qemuAgentGetVCPUs; +qemuAgentGuestDeviceInfoFree; qemuAgentNotifyClose; qemuAgentNotifyEvent; qemuAgentOpen; -- 2.54.0
From: Michal Privoznik <mprivozn@redhat.com> Introduce a test case for newly introduced qemuAgentGetGuestDeviceInfo(). The expected data started as a genuine reply from a qemu-ga running inside a Windows VM. But then was modified to cover more cases (like an optional key missing). Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemuagenttest.c | 123 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c index 74cd317e74..7c726a6b85 100644 --- a/tests/qemuagenttest.c +++ b/tests/qemuagenttest.c @@ -1394,6 +1394,128 @@ testQemuAgentGetLoadAvg(const void *data) } +static const char *testQemuAgentGetGuestDeviceInfoResponse = +"{" +" \"return\": [" +" {" +" \"driver-date\": 1736726400000000000," +" \"driver-name\": \"Red Hat VirtIO Ethernet Adapter\"," +" \"driver-version\": \"100.100.104.27100\"," +" \"id\": {" +" \"device-id\": 4161," +" \"vendor-id\": 6900," +" \"type\": \"pci\"" +" }" +" }," +" {" +" \"driver-name\": \"VirtIO Serial Driver\"," +" \"driver-version\": \"100.100.104.27100\"," +" \"id\": {" +" \"device-id\": 4163," +" \"vendor-id\": 6900," +" \"type\": \"pci\"" +" }" +" }," +" {" +" \"driver-date\": 1736726400000000000," +" \"driver-name\": \"VirtIO Balloon Driver\"," +" \"id\": {" +" \"device-id\": 4165," +" \"vendor-id\": 6900," +" \"type\": \"pci\"" +" }" +" }," +" {" +" \"driver-date\": 1736726400000000000," +" \"driver-name\": \"Red Hat VirtIO GPU DOD controller\"," +" \"driver-version\": \"100.100.104.27100\"" +" }" +" ]" +"}"; + + +static int +testQemuAgentGetGuestDeviceInfo(const void *data) +{ + virDomainXMLOption *xmlopt = (virDomainXMLOption *)data; + g_autoptr(qemuMonitorTest) test = qemuMonitorTestNewAgent(xmlopt); + qemuAgentGuestDeviceInfo **devices = NULL; + int ret = -1; + size_t i; + int ndevices; + + if (!test) + return -1; + + if (qemuMonitorTestAddAgentSyncResponse(test) < 0) + return -1; + + if (qemuMonitorTestAddItem(test, "guest-get-devices", + testQemuAgentGetGuestDeviceInfoResponse) < 0) + return -1; + + ndevices = qemuAgentGetGuestDeviceInfo(qemuMonitorTestGetAgent(test), + &devices, true); + + if (ndevices < 0) + return -1; + + if (ndevices != 4) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "unexpected number of guest devices returned (%d), expected 4", + ndevices); + goto cleanup; + } + + if (STRNEQ(devices[0]->driverName, "Red Hat VirtIO Ethernet Adapter") || + STRNEQ(devices[0]->driverVersion, "100.100.104.27100") || + devices[0]->driverDate != 1736726400000000000LL || + devices[0]->pci->vendorID != 6900 || + devices[0]->pci->deviceID != 4161) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "unexpected device info returned for device #0"); + goto cleanup; + } + + if (STRNEQ(devices[1]->driverName, "VirtIO Serial Driver") || + STRNEQ(devices[1]->driverVersion, "100.100.104.27100") || + devices[1]->driverDate != -1LL || + devices[1]->pci->vendorID != 6900 || + devices[1]->pci->deviceID != 4163) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "unexpected device info returned for device #1"); + goto cleanup; + } + + if (STRNEQ(devices[2]->driverName, "VirtIO Balloon Driver") || + devices[2]->driverVersion || + devices[2]->driverDate != 1736726400000000000LL || + devices[2]->pci->vendorID != 6900 || + devices[2]->pci->deviceID != 4165) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "unexpected device info returned for device #2"); + goto cleanup; + } + + if (STRNEQ(devices[3]->driverName, "Red Hat VirtIO GPU DOD controller") || + STRNEQ(devices[3]->driverVersion, "100.100.104.27100") || + devices[3]->driverDate != 1736726400000000000LL || + devices[3]->pci) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "unexpected device info returned for device #3"); + goto cleanup; + } + + ret = 0; + cleanup: + for (i = 0; i < ndevices; i++) { + qemuAgentGuestDeviceInfoFree(devices[i]); + } + g_free(devices); + return ret; +} + + static int mymain(void) { @@ -1431,6 +1553,7 @@ mymain(void) DO_TEST(SSHKeys); DO_TEST(GetDisks); DO_TEST(GetLoadAvg); + DO_TEST(GetGuestDeviceInfo); DO_TEST(Timeout); /* Timeout should always be called last */ -- 2.54.0
From: Michal Privoznik <mprivozn@redhat.com> Use freshly introduced qemuAgentGetGuestDeviceInfo() to implement support of VIR_DOMAIN_GUEST_INFO_DEVICES type of virDomainGetGuestInfo() API in the QEMU driver. Resolves: https://redhat.atlassian.net/browse/RHEL-235731 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_driver.c | 58 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 44b41726fb..c568a418d5 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -19987,7 +19987,8 @@ static const unsigned int qemuDomainGetGuestInfoSupportedTypes = VIR_DOMAIN_GUEST_INFO_FILESYSTEM | VIR_DOMAIN_GUEST_INFO_DISKS | VIR_DOMAIN_GUEST_INFO_INTERFACES | - VIR_DOMAIN_GUEST_INFO_LOAD; + VIR_DOMAIN_GUEST_INFO_LOAD | + VIR_DOMAIN_GUEST_INFO_DEVICES; static int qemuDomainGetGuestInfoCheckSupport(unsigned int types, @@ -20171,6 +20172,43 @@ virDomainInterfaceFormatParams(virDomainInterfacePtr *ifaces, } } + +static void +qemuAgentGuestDeviceInfoFormatParams(qemuAgentGuestDeviceInfo **devices, + size_t ndevices, + virTypedParamList *list) +{ + size_t i; + + virTypedParamListAddUInt(list, ndevices, VIR_DOMAIN_GUEST_INFO_DEVICE_COUNT); + + for (i = 0; i < ndevices; i++) { + virTypedParamListAddString(list, devices[i]->driverName, + VIR_DOMAIN_GUEST_INFO_DEVICE_PREFIX "%zu" VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_DRIVER_NAME, i); + + if (devices[i]->driverDate != -1) { + /* Guest agent reports this in nanoseconds, our API in seconds. */ + virTypedParamListAddLLong(list, devices[i]->driverDate / 1000000, + VIR_DOMAIN_GUEST_INFO_DEVICE_PREFIX "%zu" VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_DRIVER_DATE, i); + } + + if (devices[i]->driverVersion) { + virTypedParamListAddString(list, devices[i]->driverVersion, + VIR_DOMAIN_GUEST_INFO_DEVICE_PREFIX "%zu" VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_DRIVER_VERSION, i); + } + + if (devices[i]->pci) { + virTypedParamListAddString(list, "pci", + VIR_DOMAIN_GUEST_INFO_DEVICE_PREFIX "%zu" VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_ID_TYPE, i); + virTypedParamListAddUInt(list, devices[i]->pci->vendorID, + VIR_DOMAIN_GUEST_INFO_DEVICE_PREFIX "%zu" VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_PCI_VENDOR, i); + virTypedParamListAddUInt(list, devices[i]->pci->deviceID, + VIR_DOMAIN_GUEST_INFO_DEVICE_PREFIX "%zu" VIR_DOMAIN_GUEST_INFO_DEVICE_SUFFIX_PCI_DEVICE, i); + } + } +} + + static int qemuDomainGetGuestInfo(virDomainPtr dom, unsigned int types, @@ -20195,6 +20233,8 @@ qemuDomainGetGuestInfo(virDomainPtr dom, double load5m = 0; double load15m = 0; bool format_load = false; + qemuAgentGuestDeviceInfo **devices = NULL; + size_t ndevices = 0; size_t i; g_autoptr(virTypedParamList) list = virTypedParamListNew(); @@ -20274,6 +20314,14 @@ qemuDomainGetGuestInfo(virDomainPtr dom, format_load = true; } + if (supportedTypes & VIR_DOMAIN_GUEST_INFO_DEVICES) { + rc = qemuAgentGetGuestDeviceInfo(agent, &devices, report_unsupported); + if (rc == -1) + goto exitagent; + if (rc >= 0) + ndevices = rc; + } + qemuDomainObjExitAgent(vm, agent); virDomainObjEndAgentJob(vm); @@ -20306,6 +20354,8 @@ qemuDomainGetGuestInfo(virDomainPtr dom, virTypedParamListAddDouble(list, load15m, VIR_DOMAIN_GUEST_INFO_LOAD_15M); } + qemuAgentGuestDeviceInfoFormatParams(devices, ndevices, list); + if (virTypedParamListSteal(list, params, nparams) < 0) goto cleanup; @@ -20323,6 +20373,12 @@ qemuDomainGetGuestInfo(virDomainPtr dom, virDomainInterfaceFree(ifaces[i]); } g_free(ifaces); + if (devices && ndevices > 0) { + for (i = 0; i < ndevices; i++) { + qemuAgentGuestDeviceInfoFree(devices[i]); + } + g_free(devices); + } virDomainObjEndAPI(&vm); return ret; -- 2.54.0
From: Michal Privoznik <mprivozn@redhat.com> The virDomainGetGuestInfo() API is exposed as 'guestinfo' command. Introduce new --devices option for it to reflect introduction of VIR_DOMAIN_GUEST_INFO_DEVICES type. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/manpages/virsh.rst | 17 +++++++++++++---- tools/virsh-domain.c | 6 ++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index a10d29e0ea..6803bbb57a 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -3277,7 +3277,7 @@ guestinfo :: guestinfo domain [--user] [--os] [--timezone] [--hostname] [--filesystem] - [--disk] [--interface] + [--disk] [--interface] [--devices] Print information about the guest from the point of view of the guest agent. Note that this command requires a guest agent to be configured and running in @@ -3289,9 +3289,9 @@ Success is always reported in this case. You can limit the types of information that are returned by specifying one or more flags. Available information types flags are *--user*, *--os*, -*--timezone*, *--hostname*, *--filesystem*, *--disk*, *--interface* and *--load*. -If an explicitly requested information type is not supported by the guest agent -at that point, the processes will provide an exit code of 1. +*--timezone*, *--hostname*, *--filesystem*, *--disk*, *--interface*, *--load* +and *--devices*. If an explicitly requested information type is not supported +by the guest agent at that point, the processes will provide an exit code of 1. Note that depending on the hypervisor type and the version of the guest agent running within the domain, not all of the following information may be @@ -3374,6 +3374,15 @@ returned: * ``load.5m`` - average load in guest for last 5 minutes * ``load.15m`` - average load in guest for last 15 minutes +*--devices* returns: +* ``device.count`` - the number of devices that info is returned for +* ``device.<num>.driverName`` - name of the driver associated with device +* ``device.<num>.driverDate`` - driver release date in seconds since the epoch +* ``device.<num>.driverVersion`` - version of the driver associated with the device +* ``device.<num>.idType`` - device identification type (e.g. pci) +* ``device.<num>.pciVendor`` - vendor ID for PCI device +* ``device.<num>.pciDevice`` - device ID for PCI device + guestvcpus ---------- diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 0f177fb69a..563f69c939 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -13749,6 +13749,10 @@ static const vshCmdOptDef opts_guestinfo[] = { .type = VSH_OT_BOOL, .help = N_("report load averages information"), }, + {.name = "devices", + .type = VSH_OT_BOOL, + .help = N_("report devices information"), + }, {.name = NULL} }; @@ -13778,6 +13782,8 @@ cmdGuestInfo(vshControl *ctl, const vshCmd *cmd) types |= VIR_DOMAIN_GUEST_INFO_INTERFACES; if (vshCommandOptBool(cmd, "load")) types |= VIR_DOMAIN_GUEST_INFO_LOAD; + if (vshCommandOptBool(cmd, "devices")) + types |= VIR_DOMAIN_GUEST_INFO_DEVICES; if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) return false; -- 2.54.0
participants (1)
-
Michal Privoznik