[libvirt] [PATCH 16/16] hyperv: introduce 2012 support

Jason Miesionczek jmiesionczek at datto.com
Tue Aug 9 12:39:24 UTC 2016


---
 src/Makefile.am                       |   1 +
 src/hyperv/hyperv_driver.c            |  62 ++++++-
 src/hyperv/hyperv_driver_2012.c       | 299 ++++++++++++++++++++++++++++++++++
 src/hyperv/hyperv_driver_2012.h       |  55 +++++++
 src/hyperv/hyperv_private.h           |   4 +
 src/hyperv/hyperv_wmi.h               |   3 +
 src/hyperv/hyperv_wmi_generator.input |  35 +++-
 src/hyperv/hyperv_wmi_generator.py    |  11 +-
 8 files changed, 462 insertions(+), 8 deletions(-)
 create mode 100644 src/hyperv/hyperv_driver_2012.c
 create mode 100644 src/hyperv/hyperv_driver_2012.h

diff --git a/src/Makefile.am b/src/Makefile.am
index d03e6b0..edc2db3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -888,6 +888,7 @@ ESX_DRIVER_EXTRA_DIST =							\
 HYPERV_DRIVER_SOURCES =									\
 		hyperv/hyperv_private.h							\
 		hyperv/hyperv_driver.c hyperv/hyperv_driver.h				\
+		hyperv/hyperv_driver_2012.c hyperv/hyperv_driver_2012.h \
 		hyperv/hyperv_network_driver.c hyperv/hyperv_network_driver.h \
 		hyperv/hyperv_util.c hyperv/hyperv_util.h				\
 		hyperv/hyperv_wmi.c hyperv/hyperv_wmi.h					\
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 716fadb..63baef8 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -30,6 +30,7 @@
 #include "virlog.h"
 #include "viruuid.h"
 #include "hyperv_driver.h"
+#include "hyperv_driver_2012.h"
 #include "hyperv_network_driver.h"
 #include "hyperv_private.h"
 #include "hyperv_util.h"
@@ -65,6 +66,35 @@ hypervFreePrivate(hypervPrivate **priv)
 
 /* Forward declaration of hypervCapsInit */
 static virCapsPtr hypervCapsInit(hypervPrivate *priv);
+static virHypervisorDriver hypervHypervisorDriver;
+
+static char *
+hypervNodeGetWindowsVersion(hypervPrivate *priv)
+{
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Win32_OperatingSystem *operatingSystem = NULL;
+
+    /* Get Win32_OperatingSystem */
+    virBufferAddLit(&query, WIN32_OPERATINGSYSTEM_WQL_SELECT);
+
+    if (hypervGetWin32OperatingSystemList(priv, &query, &operatingSystem) < 0) {
+        goto cleanup;
+    }
+
+    if (operatingSystem == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not get Win32_OperatingSystem"));
+        goto cleanup;
+    }
+
+    return operatingSystem->data->Version;
+
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *) operatingSystem);
+    virBufferFreeAndReset(&query);
+
+    return NULL;
+}
 
 static virDrvOpenStatus
 hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
@@ -78,6 +108,9 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
     char *password = NULL;
     virBuffer query = VIR_BUFFER_INITIALIZER;
     Msvm_ComputerSystem *computerSystem = NULL;
+    Msvm_ComputerSystem_2012 *computerSystem2012 = NULL;
+    char *windowsVersion = NULL;
+    char *hypervVersion = (char *)calloc(4, sizeof(char));
 
     virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
 
@@ -175,6 +208,16 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
     /* FIXME: Currently only basic authentication is supported  */
     wsman_transport_set_auth_method(priv->client, "basic");
 
+    windowsVersion = hypervNodeGetWindowsVersion(priv);
+    if (windowsVersion == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("Could not determine Windows version"));
+        goto cleanup;
+    }
+
+    strncpy(hypervVersion, windowsVersion, 3);
+    priv->hypervVersion = hypervVersion;
+
     /* 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
@@ -183,15 +226,25 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
     virBufferAddLit(&query, "where ");
     virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_PHYSICAL);
 
-    if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0)
-        goto cleanup;
+    if (strcmp(priv->hypervVersion, HYPERV_VERSION_2008) == 0) {
+        if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0)
+            goto cleanup;
+    } else if (strcmp(priv->hypervVersion, HYPERV_VERSION_2012) == 0) {
+        if (hypervGetMsvmComputerSystem2012List(priv, &query, &computerSystem2012) < 0)
+            goto cleanup;
+    }
 
-    if (computerSystem == NULL) {
+    if (computerSystem == NULL && computerSystem2012 == NULL) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("%s is not a Hyper-V server"), conn->uri->server);
         goto cleanup;
     }
 
+    if (computerSystem2012 != NULL) {
+        hypervHypervisorDriver.connectListAllDomains = hypervConnectListAllDomains2012;
+        hypervHypervisorDriver.domainGetState = hypervDomainGetState2012;
+    }
+
     /* Setup capabilities */
     priv->caps = hypervCapsInit(priv);
     if (priv->caps == NULL) {
@@ -209,8 +262,9 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
     hypervFreePrivate(&priv);
     VIR_FREE(username);
     VIR_FREE(password);
+    free(hypervVersion);
     hypervFreeObject(priv, (hypervObject *)computerSystem);
-
+    hypervFreeObject(priv, (hypervObject *)computerSystem2012);
     return result;
 }
 
diff --git a/src/hyperv/hyperv_driver_2012.c b/src/hyperv/hyperv_driver_2012.c
new file mode 100644
index 0000000..6c2b3b6
--- /dev/null
+++ b/src/hyperv/hyperv_driver_2012.c
@@ -0,0 +1,299 @@
+#include "hyperv_driver_2012.h"
+
+static int
+hypervMsvmComputerSystemEnabledStateToDomainState2012(
+    Msvm_ComputerSystem_2012 *computerSystem)
+{
+    switch (computerSystem->data->EnabledState) {
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_UNKNOWN:
+        return VIR_DOMAIN_NOSTATE;
+
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_ENABLED:
+        return VIR_DOMAIN_RUNNING;
+
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_DISABLED:
+        return VIR_DOMAIN_SHUTOFF;
+
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSED:
+        return VIR_DOMAIN_PAUSED;
+
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SUSPENDED: /* managed save */
+        return VIR_DOMAIN_SHUTOFF;
+
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_STARTING:
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SNAPSHOTTING:
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SAVING:
+        return VIR_DOMAIN_RUNNING;
+
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_STOPPING:
+        return VIR_DOMAIN_SHUTDOWN;
+
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSING:
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_RESUMING:
+        return VIR_DOMAIN_RUNNING;
+
+      default:
+        return VIR_DOMAIN_NOSTATE;
+    }
+}
+
+static int
+hypervMsvmComputerSystemFromDomain2012(virDomainPtr domain,
+                                   Msvm_ComputerSystem_2012 **computerSystem)
+{
+    hypervPrivate *priv = domain->conn->privateData;
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+
+    if (computerSystem == NULL || *computerSystem != NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+        return -1;
+    }
+
+    virUUIDFormat(domain->uuid, uuid_string);
+
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+    virBufferAddLit(&query, "where ");
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
+    virBufferAsprintf(&query, "and Name = \"%s\"", uuid_string);
+
+    if (hypervGetMsvmComputerSystem2012List(priv, &query, computerSystem) < 0)
+        return -1;
+
+    if (*computerSystem == NULL) {
+        virReportError(VIR_ERR_NO_DOMAIN,
+                       _("No domain with UUID %s"), uuid_string);
+        return -1;
+    }
+
+    return 0;
+}
+
+static bool
+hypervIsMsvmComputerSystemActive2012(Msvm_ComputerSystem_2012 *computerSystem,
+                                 bool *in_transition)
+{
+    if (in_transition != NULL)
+        *in_transition = false;
+
+    switch (computerSystem->data->EnabledState) {
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_UNKNOWN:
+        return false;
+
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_ENABLED:
+        return true;
+
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_DISABLED:
+        return false;
+
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSED:
+        return true;
+
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SUSPENDED: /* managed save */
+        return false;
+
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_STARTING:
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SNAPSHOTTING:
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SAVING:
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_STOPPING:
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSING:
+      case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_RESUMING:
+        if (in_transition != NULL)
+            *in_transition = true;
+
+        return true;
+
+      default:
+        return false;
+    }
+}
+
+static int
+hypervMsvmComputerSystemToDomain2012(virConnectPtr conn,
+                                 Msvm_ComputerSystem_2012 *computerSystem,
+                                 virDomainPtr *domain)
+{
+    unsigned char uuid[VIR_UUID_BUFLEN];
+
+    if (domain == NULL || *domain != NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+        return -1;
+    }
+
+    if (virUUIDParse(computerSystem->data->Name, uuid) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not parse UUID from string '%s'"),
+                       computerSystem->data->Name);
+        return -1;
+    }
+
+    *domain = virGetDomain(conn, computerSystem->data->ElementName, uuid);
+
+    if (*domain == NULL)
+        return -1;
+
+    if (hypervIsMsvmComputerSystemActive2012(computerSystem, NULL)) {
+        (*domain)->id = computerSystem->data->ProcessID;
+    } else {
+        (*domain)->id = -1;
+    }
+
+    return 0;
+}
+
+int
+hypervDomainGetState2012(virDomainPtr domain, int *state, int *reason,
+                     unsigned int flags)
+{
+    int result = -1;
+    hypervPrivate *priv = domain->conn->privateData;
+    Msvm_ComputerSystem_2012 *computerSystem = NULL;
+
+    virCheckFlags(0, -1);
+
+    if (hypervMsvmComputerSystemFromDomain2012(domain, &computerSystem) < 0)
+        goto cleanup;
+
+    *state = hypervMsvmComputerSystemEnabledStateToDomainState2012(computerSystem);
+
+    if (reason != NULL)
+        *reason = 0;
+
+    result = 0;
+
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+    return result;
+}
+
+#define MATCH(FLAG) (flags & (FLAG))
+int
+hypervConnectListAllDomains2012(virConnectPtr conn,
+                            virDomainPtr **domains,
+                            unsigned int flags)
+{
+    hypervPrivate *priv = conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_ComputerSystem_2012 *computerSystemList = NULL;
+    Msvm_ComputerSystem_2012 *computerSystem = NULL;
+    size_t ndoms;
+    virDomainPtr domain;
+    virDomainPtr *doms = NULL;
+    int count = 0;
+    int ret = -1;
+    size_t i;
+
+    virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL, -1);
+
+    /* check for filter combinations that return no results:
+     * persistent: all hyperv guests are persistent
+     * snapshot: the driver does not support snapshot management
+     * autostart: the driver does not support autostarting guests
+     */
+    if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) &&
+         !MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT)) ||
+        (MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) &&
+         !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)) ||
+        (MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) &&
+         !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT))) {
+        if (domains && VIR_ALLOC_N(*domains, 1) < 0)
+            goto cleanup;
+
+        ret = 0;
+        goto cleanup;
+    }
+
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+    virBufferAddLit(&query, "where ");
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
+
+    /* construct query with filter depending on flags */
+    if (!(MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE) &&
+          MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE))) {
+        if (MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE)) {
+            virBufferAddLit(&query, "and ");
+            virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_ACTIVE);
+        }
+
+        if (MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE)) {
+            virBufferAddLit(&query, "and ");
+            virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_INACTIVE);
+        }
+    }
+
+    if (hypervGetMsvmComputerSystem2012List(priv, &query,
+                                        &computerSystemList) < 0)
+        goto cleanup;
+
+    if (domains) {
+        if (VIR_ALLOC_N(doms, 1) < 0)
+            goto cleanup;
+        ndoms = 1;
+    }
+
+    for (computerSystem = computerSystemList; computerSystem != NULL;
+         computerSystem = computerSystem->next) {
+
+        /* filter by domain state */
+        if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE)) {
+            int st = hypervMsvmComputerSystemEnabledStateToDomainState2012(computerSystem);
+            if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) &&
+                   st == VIR_DOMAIN_RUNNING) ||
+                  (MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) &&
+                   st == VIR_DOMAIN_PAUSED) ||
+                  (MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) &&
+                   st == VIR_DOMAIN_SHUTOFF) ||
+                  (MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) &&
+                   (st != VIR_DOMAIN_RUNNING &&
+                    st != VIR_DOMAIN_PAUSED &&
+                    st != VIR_DOMAIN_SHUTOFF))))
+                continue;
+        }
+
+        /* managed save filter */
+        if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_MANAGEDSAVE)) {
+            bool mansave = computerSystem->data->EnabledState ==
+                           MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SUSPENDED;
+
+            if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) && mansave) ||
+                  (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE) && !mansave)))
+                continue;
+        }
+
+        if (!doms) {
+            count++;
+            continue;
+        }
+
+        if (VIR_RESIZE_N(doms, ndoms, count, 2) < 0)
+            goto cleanup;
+
+        domain = NULL;
+
+        if (hypervMsvmComputerSystemToDomain2012(conn, computerSystem,
+                                             &domain) < 0)
+            goto cleanup;
+
+        doms[count++] = domain;
+    }
+
+    if (doms)
+        *domains = doms;
+    doms = NULL;
+    ret = count;
+
+ cleanup:
+    if (doms) {
+        for (i = 0; i < count; ++i)
+            virObjectUnref(doms[i]);
+
+        VIR_FREE(doms);
+    }
+
+    hypervFreeObject(priv, (hypervObject *)computerSystemList);
+
+    return ret;
+}
+
+#undef MATCH
diff --git a/src/hyperv/hyperv_driver_2012.h b/src/hyperv/hyperv_driver_2012.h
new file mode 100644
index 0000000..45eb15b
--- /dev/null
+++ b/src/hyperv/hyperv_driver_2012.h
@@ -0,0 +1,55 @@
+/*
+ * hyperv_driver.h: core driver functions for managing Microsoft Hyper-V hosts
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte at googlemail.com>
+ * Copyright (C) 2009 Michael Sievers <msievers83 at googlemail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __HYPERV_DRIVER_2012_H__
+# define __HYPERV_DRIVER_2012_H__
+
+#include <config.h>
+
+#include "internal.h"
+#include "datatypes.h"
+#include "virdomainobjlist.h"
+#include "virauth.h"
+#include "viralloc.h"
+#include "virlog.h"
+#include "viruuid.h"
+#include "hyperv_driver.h"
+#include "hyperv_network_driver.h"
+#include "hyperv_private.h"
+#include "hyperv_util.h"
+#include "hyperv_wmi.h"
+#include "openwsman.h"
+#include "virstring.h"
+#include "virtypedparam.h"
+
+#define VIR_FROM_THIS VIR_FROM_HYPERV
+
+int
+hypervConnectListAllDomains2012(virConnectPtr conn,
+                            virDomainPtr **domains,
+                            unsigned int flags);
+
+int
+hypervDomainGetState2012(virDomainPtr domain, int *state, int *reason,
+                     unsigned int flags);
+
+#endif /* __HYPERV_DRIVER_2012_H__ */
diff --git a/src/hyperv/hyperv_private.h b/src/hyperv/hyperv_private.h
index 2dfce6e..db4e15a 100644
--- a/src/hyperv/hyperv_private.h
+++ b/src/hyperv/hyperv_private.h
@@ -37,6 +37,10 @@ struct _hypervPrivate {
     WsManClient *client;
     virCapsPtr caps;
     virDomainXMLOptionPtr xmlopt;
+    char *hypervVersion;
 };
 
+#define HYPERV_VERSION_2008 "6.1"
+#define HYPERV_VERSION_2012 "6.3"
+
 #endif /* __HYPERV_PRIVATE_H__ */
diff --git a/src/hyperv/hyperv_wmi.h b/src/hyperv/hyperv_wmi.h
index 67f45fb..be2f429 100644
--- a/src/hyperv/hyperv_wmi.h
+++ b/src/hyperv/hyperv_wmi.h
@@ -35,6 +35,9 @@
 #define ROOT_VIRTUALIZATION \
     "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/*"
 
+#define ROOT_VIRTUALIZATION_V2 \
+    "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/v2/*"
+
 typedef struct _hypervObject hypervObject;
 
 int hyperyVerifyResponse(WsManClient *client, WsXmlDocH response,
diff --git a/src/hyperv/hyperv_wmi_generator.input b/src/hyperv/hyperv_wmi_generator.input
index 28a5bdc..cf136ca 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -55,6 +55,37 @@ class Msvm_ComputerSystem
     uint16   AssignedNumaNodeList[]
 end
 
+class Msvm_ComputerSystem_2012
+    string   Caption
+    string   Description
+    string   ElementName
+    datetime InstallDate
+    uint16   OperationalStatus[]
+    string   StatusDescriptions[]
+    string   Status
+    uint16   HealthState
+    uint16   EnabledState
+    string   OtherEnabledState
+    uint16   RequestedState
+    uint16   EnabledDefault
+    datetime TimeOfLastStateChange
+    string   CreationClassName
+    string   Name
+    string   PrimaryOwnerName
+    string   PrimaryOwnerContact
+    string   Roles[]
+    string   NameFormat
+    string   OtherIdentifyingInfo[]
+    string   IdentifyingDescriptions[]
+    uint16   Dedicated[]
+    string   OtherDedicatedDescriptions[]
+    uint16   ResetCapability
+    uint16   PowerManagementCapabilities[]
+    uint64   OnTimeInMilliseconds
+    datetime TimeOfLastConfigurationChange
+    uint32   ProcessID
+    uint16   AssignedNumaNodeList[]
+end
 
 class Msvm_ConcreteJob
     string   Caption
@@ -196,7 +227,7 @@ class Win32_ComputerSystem
     string   Caption
     uint16   ChassisBootupState
     string   CreationClassName
-    int16    CurrentTimeZone
+#    uint16    CurrentTimeZone
     boolean  DaylightInEffect
     string   Description
     string   DNSHostName
@@ -466,7 +497,7 @@ class Win32_OperatingSystem
   	string   CSCreationClassName
   	string   CSDVersion
   	string   CSName
-  	uint16   CurrentTimeZone
+#  	uint16   CurrentTimeZone
   	boolean  DataExecutionPrevention_Available
   	boolean  DataExecutionPrevention_32BitApplications
   	boolean  DataExecutionPrevention_Drivers
diff --git a/src/hyperv/hyperv_wmi_generator.py b/src/hyperv/hyperv_wmi_generator.py
index 8384634..ed40a79 100755
--- a/src/hyperv/hyperv_wmi_generator.py
+++ b/src/hyperv/hyperv_wmi_generator.py
@@ -61,6 +61,9 @@ class Class:
 
     def generate_classes_header(self):
         name_upper = self.name.upper()
+        class_name = self.name
+        if self.name.endswith("_2012"):
+            class_name = class_name[:-5]
 
         header = separator
         header += " * %s\n" % self.name
@@ -70,15 +73,17 @@ class Class:
 
         if self.name.startswith("Win32_") or self.name.startswith("CIM_DataFile"):
             header += "    \"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/%s\"\n" % self.name
+        elif self.name.endswith("_2012"):
+            header += "    \"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/v2/%s\"\n" % class_name
         else:
             header += "    \"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/%s\"\n" % self.name
 
         header += "\n"
         header += "#define %s_CLASSNAME \\\n" % name_upper
-        header += "    \"%s\"\n" % self.name
+        header += "    \"%s\"\n" % class_name
         header += "\n"
         header += "#define %s_WQL_SELECT \\\n" % name_upper
-        header += "    \"select * from %s \"\n" % self.name
+        header += "    \"select * from %s \"\n" % class_name
         header += "\n"
         header += "struct _%s_Data {\n" % self.name
 
@@ -134,6 +139,8 @@ class Class:
 
         if self.name.startswith("Win32_") or self.name.startswith("CIM_DataFile"):
             source += "    return hypervEnumAndPull(priv, query, ROOT_CIMV2,\n"
+        elif self.name.endswith("_2012"):
+            source += "    return hypervEnumAndPull(priv, query, ROOT_VIRTUALIZATION_V2,\n"
         else:
             source += "    return hypervEnumAndPull(priv, query, ROOT_VIRTUALIZATION,\n"
 
-- 
2.7.4




More information about the libvir-list mailing list