[PATCH v2 05/10] hyperv: implement connectGetCapabilities

Matt Coleman mcoleman at datto.com
Mon Oct 5 16:20:10 UTC 2020


Co-authored-by: Sri Ramanujam <sramanujam at datto.com>
Signed-off-by: Matt Coleman <matt at datto.com>
---
 src/hyperv/hyperv_driver.c  | 90 +++++++++++++++++++++++++++++++++++++
 src/hyperv/hyperv_private.h |  2 +
 2 files changed, 92 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 3e4563252e..93e08c54c0 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -36,6 +36,7 @@
 #include "openwsman.h"
 #include "virstring.h"
 #include "virkeycode.h"
+#include "domain_conf.h"
 
 #define VIR_FROM_THIS VIR_FROM_HYPERV
 
@@ -283,6 +284,76 @@ hypervGetMemSDByVSSDInstanceId(hypervPrivate *priv, const char *id,
 
 
 
+/*
+ * API-specific utility functions
+ */
+
+static int
+hypervLookupHostSystemBiosUuid(hypervPrivate *priv, unsigned char *uuid)
+{
+    Win32_ComputerSystemProduct *computerSystem = NULL;
+    g_auto(virBuffer) query = VIR_BUFFER_INITIALIZER;
+    int result = -1;
+
+    virBufferAddLit(&query, WIN32_COMPUTERSYSTEMPRODUCT_WQL_SELECT);
+    if (hypervGetWmiClass(Win32_ComputerSystemProduct, &computerSystem) < 0)
+        goto cleanup;
+
+    if (virUUIDParse(computerSystem->data.common->UUID, uuid) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not parse UUID from string '%s'"),
+                       computerSystem->data.common->UUID);
+        goto cleanup;
+    }
+    result = 0;
+
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *) computerSystem);
+
+    return result;
+}
+
+static virCapsPtr
+hypervCapsInit(hypervPrivate *priv)
+{
+    virCapsPtr caps = NULL;
+    virCapsGuestPtr guest = NULL;
+
+    caps = virCapabilitiesNew(VIR_ARCH_X86_64, 1, 1);
+
+    if (!caps)
+        return NULL;
+
+    if (hypervLookupHostSystemBiosUuid(priv, caps->host.host_uuid) < 0)
+        goto error;
+
+    /* i686 caps */
+    guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_I686,
+                                    NULL, NULL, 0, NULL);
+    if (!guest)
+        goto error;
+
+    if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_HYPERV, NULL, NULL, 0, NULL))
+        goto error;
+
+    /* x86_64 caps */
+    guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_X86_64,
+                                    NULL, NULL, 0, NULL);
+    if (!guest)
+        goto error;
+
+    if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_HYPERV, NULL, NULL, 0, NULL))
+        goto error;
+
+    return caps;
+
+ error:
+    virObjectUnref(caps);
+    return NULL;
+}
+
+
+
 /*
  * Driver functions
  */
@@ -298,6 +369,9 @@ hypervFreePrivate(hypervPrivate **priv)
         wsmc_release((*priv)->client);
     }
 
+    if ((*priv)->caps)
+        virObjectUnref((*priv)->caps);
+
     hypervFreeParsedUri(&(*priv)->parsedUri);
     VIR_FREE(*priv);
 }
@@ -408,6 +482,11 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
     if (hypervInitConnection(conn, priv, username, password) < 0)
         goto cleanup;
 
+    /* set up capabilities */
+    priv->caps = hypervCapsInit(priv);
+    if (!priv->caps)
+        goto cleanup;
+
     conn->privateData = priv;
     priv = NULL;
     result = VIR_DRV_OPEN_SUCCESS;
@@ -464,6 +543,16 @@ hypervConnectGetHostname(virConnectPtr conn)
 
 
 
+static char*
+hypervConnectGetCapabilities(virConnectPtr conn)
+{
+    hypervPrivate *priv = conn->privateData;
+
+    return virCapabilitiesFormatXML(priv->caps);
+}
+
+
+
 static int
 hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
 {
@@ -1601,6 +1690,7 @@ static virHypervisorDriver hypervHypervisorDriver = {
     .connectGetType = hypervConnectGetType, /* 0.9.5 */
     .connectGetHostname = hypervConnectGetHostname, /* 0.9.5 */
     .nodeGetInfo = hypervNodeGetInfo, /* 0.9.5 */
+    .connectGetCapabilities = hypervConnectGetCapabilities, /* 6.9.0 */
     .connectListDomains = hypervConnectListDomains, /* 0.9.5 */
     .connectNumOfDomains = hypervConnectNumOfDomains, /* 0.9.5 */
     .connectListAllDomains = hypervConnectListAllDomains, /* 0.10.2 */
diff --git a/src/hyperv/hyperv_private.h b/src/hyperv/hyperv_private.h
index b502e71d83..cf08bf542b 100644
--- a/src/hyperv/hyperv_private.h
+++ b/src/hyperv/hyperv_private.h
@@ -26,6 +26,7 @@
 #include "virerror.h"
 #include "hyperv_util.h"
 #include "openwsman.h"
+#include "capabilities.h"
 
 typedef enum _hypervWmiVersion hypervWmiVersion;
 enum _hypervWmiVersion {
@@ -38,4 +39,5 @@ struct _hypervPrivate {
     hypervParsedUri *parsedUri;
     WsManClient *client;
     hypervWmiVersion wmiVersion;
+    virCapsPtr caps;
 };
-- 
2.27.0





More information about the libvir-list mailing list