[libvirt] [PATCH 03/21] Added basic implementation for virConnectGetCapabilities (required Win32_ComputerSystemProduct class)

Yves Vinter yves.vinter at bull.net
Wed Oct 8 12:33:48 UTC 2014


From: yvinter <yves.vinter at bull.net>

---
 src/hyperv/hyperv_driver.c            | 112 ++++++++++++++++++++++++++++++++++
 src/hyperv/hyperv_private.h           |   2 +
 src/hyperv/hyperv_wmi_generator.input |  12 ++++
 3 files changed, 126 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index f2017c3..dd56fb0 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -58,12 +58,19 @@ hypervFreePrivate(hypervPrivate **priv)
         wsmc_release((*priv)->client);
     }
 
+    if ((*priv)->caps != NULL)
+        virObjectUnref((*priv)->caps);
+
     hypervFreeParsedUri(&(*priv)->parsedUri);
     VIR_FREE(*priv);
 }
 
 
 
+/* Forward declaration of hypervCapsInit */
+static virCapsPtr hypervCapsInit(hypervPrivate *priv);
+
+
 static virDrvOpenStatus
 hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags)
 {
@@ -192,6 +199,12 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags
         goto cleanup;
     }
 
+    /* Setup capabilities */
+    priv->caps = hypervCapsInit(priv);
+    if (priv->caps == NULL) {
+        goto cleanup;
+    }
+
     conn->privateData = priv;
     priv = NULL;
     result = VIR_DRV_OPEN_SUCCESS;
@@ -1420,6 +1433,104 @@ hypervConnectGetVersion(virConnectPtr conn, unsigned long *version)
 }
 
 
+/* Retrieves host system UUID  */
+static int
+hypervLookupHostSystemBiosUuid(hypervPrivate *priv, unsigned char *uuid)
+{
+    Win32_ComputerSystemProduct *computerSystem = NULL;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    int result = -1;
+    
+    virBufferAddLit(&query, WIN32_COMPUTERSYSTEMPRODUCT_WQL_SELECT);
+    
+    if (hypervGetWin32ComputerSystemProductList(priv, &query, &computerSystem) < 0) {
+        goto cleanup;
+    }
+    
+    if (computerSystem == NULL) {
+        virReportError(VIR_ERR_NO_DOMAIN,
+                       _("Unable to get Win32_ComputerSystemProduct"));
+        goto cleanup;
+    }
+    
+    if (virUUIDParse(computerSystem->data->UUID, uuid) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not parse UUID from string '%s'"),
+                       computerSystem->data->UUID);
+        goto cleanup;
+    }
+    
+    result = 0;
+    
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *)computerSystem);
+    virBufferFreeAndReset(&query);
+
+    return result;
+}
+
+
+
+static virCapsPtr hypervCapsInit(hypervPrivate *priv)
+{
+    virCapsPtr caps = NULL;
+    virCapsGuestPtr guest = NULL;
+    
+    caps = virCapabilitiesNew(VIR_ARCH_X86_64, 1, 1);
+    
+    if (caps == NULL) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    /* virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 }); */
+    
+    if (hypervLookupHostSystemBiosUuid(priv,caps->host.host_uuid) < 0) {
+        goto failure;
+    }
+    
+    /* i686 */
+    guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_I686, NULL, NULL, 0, NULL);
+    if (guest == NULL) {
+        goto failure;
+    }
+    if (virCapabilitiesAddGuestDomain(guest, "hyperv", NULL, NULL, 0, NULL) == NULL) {
+        goto failure;
+    }
+
+    /* x86_64 */
+    guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_X86_64, NULL, NULL, 0, NULL);
+    if (guest == NULL) {
+        goto failure;
+    }
+    if (virCapabilitiesAddGuestDomain(guest, "hyperv", NULL, NULL, 0, NULL) == NULL) {
+        goto failure;
+    }
+
+    return caps;
+    
+ failure:
+    virObjectUnref(caps);
+    return NULL;
+}
+
+
+
+static char*
+hypervConnectGetCapabilities(virConnectPtr conn)
+{
+    hypervPrivate *priv = conn->privateData;
+    char *xml = virCapabilitiesFormatXML(priv->caps);
+    
+    if (xml == NULL) {
+        virReportOOMError();
+        return NULL;
+    }
+    
+    return xml;
+}
+
+
 
 static virDriver hypervDriver = {
     .no = VIR_DRV_HYPERV,
@@ -1457,6 +1568,7 @@ static virDriver hypervDriver = {
     .domainManagedSaveRemove = hypervDomainManagedSaveRemove, /* 0.9.5 */
     .connectIsAlive = hypervConnectIsAlive, /* 0.9.8 */
     .connectGetVersion = hypervConnectGetVersion, /* 1.2.10 */
+    .connectGetCapabilities = hypervConnectGetCapabilities, /* 1.2.10 */
 };
 
 
diff --git a/src/hyperv/hyperv_private.h b/src/hyperv/hyperv_private.h
index 574bb5f..d9aa0bd 100644
--- a/src/hyperv/hyperv_private.h
+++ b/src/hyperv/hyperv_private.h
@@ -26,6 +26,7 @@
 # include "internal.h"
 # include "virerror.h"
 # include "hyperv_util.h"
+# include "capabilities.h"
 # include "openwsman.h"
 
 typedef struct _hypervPrivate hypervPrivate;
@@ -33,6 +34,7 @@ typedef struct _hypervPrivate hypervPrivate;
 struct _hypervPrivate {
     hypervParsedUri *parsedUri;
     WsManClient *client;
+    virCapsPtr caps;
 };
 
 #endif /* __HYPERV_PRIVATE_H__ */
diff --git a/src/hyperv/hyperv_wmi_generator.input b/src/hyperv/hyperv_wmi_generator.input
index 6b969df..f1e0c81 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -333,3 +333,15 @@ class CIM_DataFile
 	string   Version
 	boolean  Writeable
 end
+
+
+class Win32_ComputerSystemProduct
+	string 	Caption
+	string 	Description
+	string 	IdentifyingNumber
+	string 	Name
+	string 	SKUNumber
+	string 	UUID
+	string 	Vendor
+	string 	Version
+end
-- 
1.9.1




More information about the libvir-list mailing list