[libvirt PATCH 4/9] qemu: implement virConnectGetHypervisorCPUModelNames API

Tim Wiederhake posted 9 patches 3 years, 7 months ago
[libvirt PATCH 4/9] qemu: implement virConnectGetHypervisorCPUModelNames API
Posted by Tim Wiederhake 3 years, 7 months ago
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
---
 src/qemu/qemu_driver.c | 52 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3b5c3db67c..538a35d327 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -17311,6 +17311,57 @@ qemuConnectGetCPUModelNames(virConnectPtr conn,
     return virCPUGetModels(arch, models);
 }
 
+static int
+qemuConnectGetHypervisorCPUModelNames(virConnectPtr conn,
+                                      const char *archName,
+                                      char ***names,
+                                      char ***aliases,
+                                      unsigned int flags)
+{
+    size_t i;
+    virQEMUDriver *driver = conn->privateData;
+    g_autoptr(qemuMonitorCPUDefs) cpuDefs = NULL;
+    g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+    g_autoptr(qemuProcessQMP) proc = NULL;
+    g_autoptr(virQEMUCaps) qemuCaps = NULL;
+
+    virCheckFlags(0, -1);
+    if (virConnectGetHypervisorCPUModelNamesEnsureACL(conn) < 0)
+        return -1;
+
+    qemuCaps = virQEMUCapsCacheLookupDefault(driver->qemuCapsCache, NULL,
+                                             archName, NULL, NULL, NULL,
+                                             NULL, NULL);
+
+    if (!(proc = qemuProcessQMPNew(virQEMUCapsGetBinary(qemuCaps), cfg->libDir,
+                                   cfg->user, cfg->group, false)))
+        return -1;
+
+    if (qemuProcessQMPStart(proc) < 0)
+        return -1;
+
+    if (qemuMonitorGetCPUDefinitions(proc->mon, &cpuDefs) < 0)
+        return -1;
+
+    // plus one to NULL terminate the lists
+    *names = g_new(char*, cpuDefs->ncpus + 1);
+    *aliases = g_new(char*, cpuDefs->ncpus + 1);
+
+    for (i = 0; i < cpuDefs->ncpus; ++i) {
+        if (cpuDefs->cpus[i].name)
+            (*names)[i] = g_strdup(cpuDefs->cpus[i].name);
+        else
+            (*names)[i] = g_strdup("");
+
+        if (cpuDefs->cpus[i].alias)
+            (*aliases)[i] = g_strdup(cpuDefs->cpus[i].alias);
+        else
+            (*aliases)[i] = g_strdup("");
+    }
+
+    return cpuDefs->ncpus;
+}
+
 
 static int
 qemuDomainGetHostnameAgent(virQEMUDriver *driver,
@@ -21324,6 +21375,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
     .domainGetMessages = qemuDomainGetMessages, /* 7.1.0 */
     .domainStartDirtyRateCalc = qemuDomainStartDirtyRateCalc, /* 7.2.0 */
     .domainSetLaunchSecurityState = qemuDomainSetLaunchSecurityState, /* 8.0.0 */
+    .connectGetHypervisorCPUModelNames = qemuConnectGetHypervisorCPUModelNames, /* 8.5.0 */
 };
 
 
-- 
2.31.1
Re: [libvirt PATCH 4/9] qemu: implement virConnectGetHypervisorCPUModelNames API
Posted by Daniel P. Berrangé 3 years, 6 months ago
On Tue, Jun 28, 2022 at 06:09:41PM +0200, Tim Wiederhake wrote:
> Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
> ---
>  src/qemu/qemu_driver.c | 52 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 52 insertions(+)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 3b5c3db67c..538a35d327 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -17311,6 +17311,57 @@ qemuConnectGetCPUModelNames(virConnectPtr conn,
>      return virCPUGetModels(arch, models);
>  }
>  
> +static int
> +qemuConnectGetHypervisorCPUModelNames(virConnectPtr conn,
> +                                      const char *archName,
> +                                      char ***names,
> +                                      char ***aliases,
> +                                      unsigned int flags)
> +{
> +    size_t i;
> +    virQEMUDriver *driver = conn->privateData;
> +    g_autoptr(qemuMonitorCPUDefs) cpuDefs = NULL;
> +    g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
> +    g_autoptr(qemuProcessQMP) proc = NULL;
> +    g_autoptr(virQEMUCaps) qemuCaps = NULL;
> +
> +    virCheckFlags(0, -1);
> +    if (virConnectGetHypervisorCPUModelNamesEnsureACL(conn) < 0)
> +        return -1;
> +
> +    qemuCaps = virQEMUCapsCacheLookupDefault(driver->qemuCapsCache, NULL,
> +                                             archName, NULL, NULL, NULL,
> +                                             NULL, NULL);
> +
> +    if (!(proc = qemuProcessQMPNew(virQEMUCapsGetBinary(qemuCaps), cfg->libDir,
> +                                   cfg->user, cfg->group, false)))
> +        return -1;
> +
> +    if (qemuProcessQMPStart(proc) < 0)
> +        return -1;
> +
> +    if (qemuMonitorGetCPUDefinitions(proc->mon, &cpuDefs) < 0)
> +        return -1;
> +
> +    // plus one to NULL terminate the lists
> +    *names = g_new(char*, cpuDefs->ncpus + 1);
> +    *aliases = g_new(char*, cpuDefs->ncpus + 1);
> +
> +    for (i = 0; i < cpuDefs->ncpus; ++i) {
> +        if (cpuDefs->cpus[i].name)
> +            (*names)[i] = g_strdup(cpuDefs->cpus[i].name);
> +        else
> +            (*names)[i] = g_strdup("");

Why would there be a case where 'name' is NULL ?  I would have
thought that's an error scenario and qemu_monitor_json.c should
have reported a fatal error for that ? Or am i missing something ?

> +
> +        if (cpuDefs->cpus[i].alias)
> +            (*aliases)[i] = g_strdup(cpuDefs->cpus[i].alias);
> +        else
> +            (*aliases)[i] = g_strdup("");

I'd expect us to use NULL for the "no alias" marker.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|