[libvirt] [PATCH v3 10/12] hyperv: add hypervInitConnection.

Dawid Zamirski dzamirski at datto.com
Mon Apr 3 23:52:17 UTC 2017


This function detects hyperv version by issuing a simple query using
"v2" namespace and falling back to "v1".
---
 src/hyperv/hyperv_driver.c | 92 ++++++++++++++++++++++++++++------------------
 1 file changed, 56 insertions(+), 36 deletions(-)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 5d01c1f..0913517 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -55,7 +55,62 @@ hypervFreePrivate(hypervPrivate **priv)
     VIR_FREE(*priv);
 }
 
+static int
+hypervInitConnection(virConnectPtr conn, hypervPrivate *priv,
+                     char *username, char *password)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    hypervWqlQuery query = HYPERV_WQL_QUERY_INITIALIZER;
+    hypervObject *computerSystem = NULL;
+    int ret = -1;
 
+    /* Initialize the openwsman connection */
+    priv->client = wsmc_create(conn->uri->server, conn->uri->port, "/wsman",
+                               priv->parsedUri->transport, username, password);
+
+    if (priv->client == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not create openwsman client"));
+        goto cleanup;
+    }
+
+    if (wsmc_transport_init(priv->client, NULL) != 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not initialize openwsman transport"));
+        goto cleanup;
+    }
+
+    /* FIXME: Currently only basic authentication is supported  */
+    wsman_transport_set_auth_method(priv->client, "basic");
+
+    virBufferAddLit(&buf, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+    virBufferAddLit(&buf, "WHERE ");
+    virBufferAddLit(&buf, MSVM_COMPUTERSYSTEM_WQL_PHYSICAL);
+
+    query.query = virBufferContentAndReset(&buf);
+    query.info = Msvm_ComputerSystem_WmiInfo;
+
+    /* try query using V2 namespace (for Hyperv 2012+) */
+    priv->wmiVersion = HYPERV_WMI_VERSION_V2;
+
+    if (hypervEnumAndPull(priv, &query, &computerSystem) < 0) {
+        /* fall back to V1 namespace (for Hyper-v 2008) */
+        priv->wmiVersion = HYPERV_WMI_VERSION_V1;
+
+        if (hypervEnumAndPull(priv, &query, &computerSystem) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("%s is not a Hyper-V server"), conn->uri->server);
+            goto cleanup;
+        }
+    }
+
+    ret = 0;
+
+ cleanup:
+    hypervFreeObject(priv, computerSystem);
+
+    return ret;
+}
 
 static virDrvOpenStatus
 hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
@@ -67,8 +122,6 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
     hypervPrivate *priv = NULL;
     char *username = NULL;
     char *password = NULL;
-    virBuffer query = VIR_BUFFER_INITIALIZER;
-    Msvm_ComputerSystem *computerSystem = NULL;
 
     virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
 
@@ -147,41 +200,9 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
         goto cleanup;
     }
 
-    /* Initialize the openwsman connection */
-    priv->client = wsmc_create(conn->uri->server, conn->uri->port, "/wsman",
-                               priv->parsedUri->transport, username, password);
-
-    if (priv->client == NULL) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("Could not create openwsman client"));
-        goto cleanup;
-    }
-
-    if (wsmc_transport_init(priv->client, NULL) != 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("Could not initialize openwsman transport"));
-        goto cleanup;
-    }
-
-    /* FIXME: Currently only basic authentication is supported  */
-    wsman_transport_set_auth_method(priv->client, "basic");
-
-    /* Check if the connection can be established and if the server has the
-     * Hyper-V role installed. If the call to hypervGetMsvmComputerSystemList
-     * succeeds than the connection has been established. If the returned list
-     * is empty than the server isn't a Hyper-V server. */
-    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
-    virBufferAddLit(&query, "where ");
-    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_PHYSICAL);
-
-    if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0)
-        goto cleanup;
 
-    if (computerSystem == NULL) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("%s is not a Hyper-V server"), conn->uri->server);
+    if (hypervInitConnection(conn, priv, username, password) < 0)
         goto cleanup;
-    }
 
     conn->privateData = priv;
     priv = NULL;
@@ -191,7 +212,6 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
     hypervFreePrivate(&priv);
     VIR_FREE(username);
     VIR_FREE(password);
-    hypervFreeObject(priv, (hypervObject *)computerSystem);
 
     return result;
 }
-- 
2.9.3




More information about the libvir-list mailing list