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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list