From: Michal Privoznik <[email protected]>

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 <[email protected]>
---
 src/hypervisor/qemu_agent.c | 36 ++++++++++++++++++++++++++++++++++++
 src/hypervisor/qemu_agent.h |  5 +++++
 src/libvirt_private.syms    |  1 +
 src/qemu/qemu_driver.c      | 21 ++++++++++++++++++++-
 4 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/src/hypervisor/qemu_agent.c b/src/hypervisor/qemu_agent.c
index fbfaafc1bb..ae20ee2b22 100644
--- a/src/hypervisor/qemu_agent.c
+++ b/src/hypervisor/qemu_agent.c
@@ -2962,3 +2962,39 @@ qemuAgentGetGuestDeviceInfo(qemuAgent *agent,
     g_clear_pointer(info, g_free);
     return -1;
 }
+
+
+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);
+        }
+    }
+}
diff --git a/src/hypervisor/qemu_agent.h b/src/hypervisor/qemu_agent.h
index 35d2057bac..df1a7cce63 100644
--- a/src/hypervisor/qemu_agent.h
+++ b/src/hypervisor/qemu_agent.h
@@ -239,3 +239,8 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuAgentGuestDeviceInfo, 
qemuAgentGuestDeviceInfo
 int qemuAgentGetGuestDeviceInfo(qemuAgent *agent,
                                 qemuAgentGuestDeviceInfo ***info,
                                 bool report_unsupported);
+
+void
+qemuAgentGuestDeviceInfoFormatParams(qemuAgentGuestDeviceInfo **devices,
+                                     size_t ndevices,
+                                     virTypedParamList *list);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0bd8c6f781..6c6cc7b4ff 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1735,6 +1735,7 @@ qemuAgentGetTime;
 qemuAgentGetTimezone;
 qemuAgentGetUsers;
 qemuAgentGetVCPUs;
+qemuAgentGuestDeviceInfoFormatParams;
 qemuAgentGuestDeviceInfoFree;
 qemuAgentInterfaceFormatParams;
 qemuAgentNotifyClose;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 97d17952b7..a928e4a839 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19991,7 +19991,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,
@@ -20039,6 +20040,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();
 
@@ -20118,6 +20121,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);
 
@@ -20150,6 +20161,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;
 
@@ -20167,6 +20180,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

Reply via email to