mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-04-26 15:14:42 +00:00
hyperv: Add OpenWSMAN based client for the Hyper-V WMI API
Add a generator script to generate the structs and serialization information for OpenWSMAN. openwsman.h collects workarounds for problems in OpenWSMAN <= 2.2.6. There are also disabled sections that would use ws_serializer_free_mem but can't because it's broken in OpenWSMAN <= 2.2.6. Patches to fix this have been posted upstream.
This commit is contained in:
parent
4d6e6f4aa9
commit
e224b6f8fb
1
.gitignore
vendored
1
.gitignore
vendored
@ -54,6 +54,7 @@
|
|||||||
/proxy/
|
/proxy/
|
||||||
/python/generator.py.stamp
|
/python/generator.py.stamp
|
||||||
/sc_*
|
/sc_*
|
||||||
|
/src/hyperv/*.generated.*
|
||||||
/src/libvirt_iohelper
|
/src/libvirt_iohelper
|
||||||
/src/locking/qemu-sanlock.conf
|
/src/locking/qemu-sanlock.conf
|
||||||
/src/remote/*_client_bodies.h
|
/src/remote/*_client_bodies.h
|
||||||
|
@ -29,6 +29,7 @@ src/esx/esx_vi_methods.c
|
|||||||
src/esx/esx_vi_types.c
|
src/esx/esx_vi_types.c
|
||||||
src/fdstream.c
|
src/fdstream.c
|
||||||
src/hyperv/hyperv_driver.c
|
src/hyperv/hyperv_driver.c
|
||||||
|
src/hyperv/hyperv_wmi.c
|
||||||
src/interface/netcf_driver.c
|
src/interface/netcf_driver.c
|
||||||
src/internal.h
|
src/internal.h
|
||||||
src/libvirt.c
|
src/libvirt.c
|
||||||
|
@ -411,7 +411,23 @@ HYPERV_DRIVER_SOURCES = \
|
|||||||
hyperv/hyperv_storage_driver.c hyperv/hyperv_storage_driver.h \
|
hyperv/hyperv_storage_driver.c hyperv/hyperv_storage_driver.h \
|
||||||
hyperv/hyperv_device_monitor.c hyperv/hyperv_device_monitor.h \
|
hyperv/hyperv_device_monitor.c hyperv/hyperv_device_monitor.h \
|
||||||
hyperv/hyperv_secret_driver.c hyperv/hyperv_secret_driver.h \
|
hyperv/hyperv_secret_driver.c hyperv/hyperv_secret_driver.h \
|
||||||
hyperv/hyperv_nwfilter_driver.c hyperv/hyperv_nwfilter_driver.h
|
hyperv/hyperv_nwfilter_driver.c hyperv/hyperv_nwfilter_driver.h \
|
||||||
|
hyperv/hyperv_wmi.c hyperv/hyperv_wmi.h \
|
||||||
|
hyperv/hyperv_wmi_classes.c hyperv/hyperv_wmi_classes.h \
|
||||||
|
hyperv/openwsman.h
|
||||||
|
|
||||||
|
HYPERV_DRIVER_GENERATED = \
|
||||||
|
hyperv/hyperv_wmi.generated.c \
|
||||||
|
hyperv/hyperv_wmi.generated.h \
|
||||||
|
hyperv/hyperv_wmi_classes.generated.c \
|
||||||
|
hyperv/hyperv_wmi_classes.generated.h \
|
||||||
|
hyperv/hyperv_wmi_classes.generated.typedef
|
||||||
|
|
||||||
|
HYPERV_DRIVER_EXTRA_DIST = \
|
||||||
|
hyperv/hyperv_wmi_generator.input \
|
||||||
|
hyperv/hyperv_wmi_generator.py \
|
||||||
|
$(HYPERV_DRIVER_GENERATED)
|
||||||
|
|
||||||
NETWORK_DRIVER_SOURCES = \
|
NETWORK_DRIVER_SOURCES = \
|
||||||
network/bridge_driver.h network/bridge_driver.c
|
network/bridge_driver.h network/bridge_driver.c
|
||||||
|
|
||||||
@ -845,6 +861,12 @@ libvirt_driver_esx_la_DEPENDENCIES = $(ESX_DRIVER_GENERATED)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
BUILT_SOURCES += $(HYPERV_DRIVER_GENERATED)
|
||||||
|
|
||||||
|
$(HYPERV_DRIVER_GENERATED): $(srcdir)/hyperv/hyperv_wmi_generator.input \
|
||||||
|
$(srcdir)/hyperv/hyperv_wmi_generator.py
|
||||||
|
$(AM_V_GEN)srcdir=$(srcdir) $(PYTHON) $(srcdir)/hyperv/hyperv_wmi_generator.py
|
||||||
|
|
||||||
if WITH_HYPERV
|
if WITH_HYPERV
|
||||||
if WITH_DRIVER_MODULES
|
if WITH_DRIVER_MODULES
|
||||||
mod_LTLIBRARIES += libvirt_driver_hyperv.la
|
mod_LTLIBRARIES += libvirt_driver_hyperv.la
|
||||||
@ -1058,6 +1080,7 @@ EXTRA_DIST += \
|
|||||||
$(ESX_DRIVER_SOURCES) \
|
$(ESX_DRIVER_SOURCES) \
|
||||||
$(ESX_DRIVER_EXTRA_DIST) \
|
$(ESX_DRIVER_EXTRA_DIST) \
|
||||||
$(HYPERV_DRIVER_SOURCES) \
|
$(HYPERV_DRIVER_SOURCES) \
|
||||||
|
$(HYPERV_DRIVER_EXTRA_DIST) \
|
||||||
$(NETWORK_DRIVER_SOURCES) \
|
$(NETWORK_DRIVER_SOURCES) \
|
||||||
$(INTERFACE_DRIVER_SOURCES) \
|
$(INTERFACE_DRIVER_SOURCES) \
|
||||||
$(STORAGE_DRIVER_SOURCES) \
|
$(STORAGE_DRIVER_SOURCES) \
|
||||||
|
@ -26,9 +26,16 @@
|
|||||||
|
|
||||||
# include "internal.h"
|
# include "internal.h"
|
||||||
# include "virterror_internal.h"
|
# include "virterror_internal.h"
|
||||||
|
# include "openwsman.h"
|
||||||
|
|
||||||
# define HYPERV_ERROR(code, ...) \
|
# define HYPERV_ERROR(code, ...) \
|
||||||
virReportErrorHelper(VIR_FROM_HYPERV, code, __FILE__, __FUNCTION__, \
|
virReportErrorHelper(VIR_FROM_HYPERV, code, __FILE__, __FUNCTION__, \
|
||||||
__LINE__, __VA_ARGS__)
|
__LINE__, __VA_ARGS__)
|
||||||
|
|
||||||
|
typedef struct _hypervPrivate hypervPrivate;
|
||||||
|
|
||||||
|
struct _hypervPrivate {
|
||||||
|
WsManClient *client;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __HYPERV_PRIVATE_H__ */
|
#endif /* __HYPERV_PRIVATE_H__ */
|
||||||
|
688
src/hyperv/hyperv_wmi.c
Normal file
688
src/hyperv/hyperv_wmi.c
Normal file
@ -0,0 +1,688 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* hyperv_wmi.h: general WMI over WSMAN related functions and structures for
|
||||||
|
* managing Microsoft Hyper-V hosts
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Matthias Bolte <matthias.bolte@googlemail.com>
|
||||||
|
* Copyright (C) 2009 Michael Sievers <msievers83@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, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
#include "virterror_internal.h"
|
||||||
|
#include "datatypes.h"
|
||||||
|
#include "logging.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "uuid.h"
|
||||||
|
#include "buf.h"
|
||||||
|
#include "hyperv_private.h"
|
||||||
|
#include "hyperv_wmi.h"
|
||||||
|
|
||||||
|
#define WS_SERIALIZER_FREE_MEM_WORKS 0
|
||||||
|
|
||||||
|
#define ROOT_CIMV2 \
|
||||||
|
"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/*"
|
||||||
|
|
||||||
|
#define ROOT_VIRTUALIZATION \
|
||||||
|
"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/*"
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_HYPERV
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
hyperyVerifyResponse(WsManClient *client, WsXmlDocH response,
|
||||||
|
const char *detail)
|
||||||
|
{
|
||||||
|
int lastError = wsmc_get_last_error(client);
|
||||||
|
int responseCode = wsmc_get_response_code(client);
|
||||||
|
WsManFault *fault;
|
||||||
|
|
||||||
|
if (lastError != WS_LASTERR_OK) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Transport error during %s: %s (%d)"),
|
||||||
|
detail, wsman_transport_get_last_error_string(lastError),
|
||||||
|
lastError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the HTTP response code and report an error if it's not 200 (OK),
|
||||||
|
* 400 (Bad Request) or 500 (Internal Server Error) */
|
||||||
|
if (responseCode != 200 && responseCode != 400 && responseCode != 500) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unexpected HTTP response during %s: %d"),
|
||||||
|
detail, responseCode);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response == NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Empty response during %s"), detail);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wsmc_check_for_fault(response)) {
|
||||||
|
fault = wsmc_fault_new();
|
||||||
|
|
||||||
|
if (fault == NULL) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wsmc_get_fault_data(response, fault);
|
||||||
|
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("SOAP fault during %s: code '%s', subcode '%s', "
|
||||||
|
"reason '%s', detail '%s'"),
|
||||||
|
detail, NULLSTR(fault->code), NULLSTR(fault->subcode),
|
||||||
|
NULLSTR(fault->reason), NULLSTR(fault->fault_detail));
|
||||||
|
|
||||||
|
wsmc_fault_destroy(fault);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Object
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query, const char *root,
|
||||||
|
XmlSerializerInfo *serializerInfo, const char *resourceUri,
|
||||||
|
const char *className, hypervObject **list)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
WsSerializerContextH serializerContext;
|
||||||
|
client_opt_t *options = NULL;
|
||||||
|
char *query_string = NULL;
|
||||||
|
filter_t *filter = NULL;
|
||||||
|
WsXmlDocH response = NULL;
|
||||||
|
char *enumContext = NULL;
|
||||||
|
hypervObject *head = NULL;
|
||||||
|
hypervObject *tail = NULL;
|
||||||
|
WsXmlNodeH node = NULL;
|
||||||
|
XML_TYPE_PTR data = NULL;
|
||||||
|
hypervObject *object;
|
||||||
|
|
||||||
|
if (list == NULL || *list != NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virBufferError(query)) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
serializerContext = wsmc_get_serialization_context(priv->client);
|
||||||
|
|
||||||
|
options = wsmc_options_init();
|
||||||
|
|
||||||
|
if (options == NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Could not initialize options"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
query_string = virBufferContentAndReset(query);
|
||||||
|
filter = filter_create_simple(WSM_WQL_FILTER_DIALECT, query_string);
|
||||||
|
|
||||||
|
if (filter == NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Could not create filter"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
response = wsmc_action_enumerate(priv->client, root, options, filter);
|
||||||
|
|
||||||
|
if (hyperyVerifyResponse(priv->client, response, "enumeration") < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
enumContext = wsmc_get_enum_context(response);
|
||||||
|
|
||||||
|
ws_xml_destroy_doc(response);
|
||||||
|
response = NULL;
|
||||||
|
|
||||||
|
while (enumContext != NULL && *enumContext != '\0' ) {
|
||||||
|
response = wsmc_action_pull(priv->client, resourceUri, options,
|
||||||
|
filter, enumContext);
|
||||||
|
|
||||||
|
if (hyperyVerifyResponse(priv->client, response, "pull") < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = ws_xml_get_soap_body(response);
|
||||||
|
|
||||||
|
if (node == NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Could not lookup SOAP body"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_PULL_RESP);
|
||||||
|
|
||||||
|
if (node == NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Could not lookup pull response"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_ITEMS);
|
||||||
|
|
||||||
|
if (node == NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Could not lookup pull response items"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws_xml_get_child(node, 0, resourceUri, className) == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = ws_deserialize(serializerContext, node, serializerInfo,
|
||||||
|
className, resourceUri, NULL, 0, 0);
|
||||||
|
|
||||||
|
if (data == NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Could not deserialize pull response item"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC(object) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
object->serializerInfo = serializerInfo;
|
||||||
|
object->data = data;
|
||||||
|
|
||||||
|
data = NULL;
|
||||||
|
|
||||||
|
if (head == NULL) {
|
||||||
|
head = object;
|
||||||
|
} else {
|
||||||
|
tail->next = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
tail = object;
|
||||||
|
|
||||||
|
VIR_FREE(enumContext);
|
||||||
|
enumContext = wsmc_get_enum_context(response);
|
||||||
|
|
||||||
|
ws_xml_destroy_doc(response);
|
||||||
|
response = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*list = head;
|
||||||
|
head = NULL;
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (options != NULL) {
|
||||||
|
wsmc_options_destroy(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter != NULL) {
|
||||||
|
filter_destroy(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data != NULL) {
|
||||||
|
#if WS_SERIALIZER_FREE_MEM_WORKS
|
||||||
|
/* FIXME: ws_serializer_free_mem is broken in openwsman <= 2.2.6,
|
||||||
|
* see hypervFreeObject for a detailed explanation. */
|
||||||
|
if (ws_serializer_free_mem(serializerContext, data,
|
||||||
|
serializerInfo) < 0) {
|
||||||
|
VIR_ERROR(_("Could not free deserialized data"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_FREE(query_string);
|
||||||
|
ws_xml_destroy_doc(response);
|
||||||
|
VIR_FREE(enumContext);
|
||||||
|
hypervFreeObject(priv, head);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hypervFreeObject(hypervPrivate *priv ATTRIBUTE_UNUSED, hypervObject *object)
|
||||||
|
{
|
||||||
|
hypervObject *next;
|
||||||
|
#if WS_SERIALIZER_FREE_MEM_WORKS
|
||||||
|
WsSerializerContextH serializerContext;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (object == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if WS_SERIALIZER_FREE_MEM_WORKS
|
||||||
|
serializerContext = wsmc_get_serialization_context(priv->client);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (object != NULL) {
|
||||||
|
next = object->next;
|
||||||
|
|
||||||
|
#if WS_SERIALIZER_FREE_MEM_WORKS
|
||||||
|
/* FIXME: ws_serializer_free_mem is broken in openwsman <= 2.2.6,
|
||||||
|
* but this is not that critical, because openwsman keeps
|
||||||
|
* track of all allocations of the deserializer and frees
|
||||||
|
* them in wsmc_release. So this doesn't result in a real
|
||||||
|
* memory leak, but just in piling up unused memory until
|
||||||
|
* the connection is closed. */
|
||||||
|
if (ws_serializer_free_mem(serializerContext, object->data,
|
||||||
|
object->serializerInfo) < 0) {
|
||||||
|
VIR_ERROR(_("Could not free deserialized data"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VIR_FREE(object);
|
||||||
|
|
||||||
|
object = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* CIM/Msvm_ReturnCode
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char *
|
||||||
|
hypervReturnCodeToString(int returnCode)
|
||||||
|
{
|
||||||
|
switch (returnCode) {
|
||||||
|
case CIM_RETURNCODE_COMPLETED_WITH_NO_ERROR:
|
||||||
|
return _("Completed with no error");
|
||||||
|
|
||||||
|
case CIM_RETURNCODE_NOT_SUPPORTED:
|
||||||
|
return _("Not supported");
|
||||||
|
|
||||||
|
case CIM_RETURNCODE_UNKNOWN_ERROR:
|
||||||
|
return _("Unknown error");
|
||||||
|
|
||||||
|
case CIM_RETURNCODE_CANNOT_COMPLETE_WITHIN_TIMEOUT_PERIOD:
|
||||||
|
return _("Cannot complete within timeout period");
|
||||||
|
|
||||||
|
case CIM_RETURNCODE_FAILED:
|
||||||
|
return _("Failed");
|
||||||
|
|
||||||
|
case CIM_RETURNCODE_INVALID_PARAMETER:
|
||||||
|
return _("Invalid parameter");
|
||||||
|
|
||||||
|
case CIM_RETURNCODE_IN_USE:
|
||||||
|
return _("In use");
|
||||||
|
|
||||||
|
case CIM_RETURNCODE_TRANSITION_STARTED:
|
||||||
|
return _("Transition started");
|
||||||
|
|
||||||
|
case CIM_RETURNCODE_INVALID_STATE_TRANSITION:
|
||||||
|
return _("Invalid state transition");
|
||||||
|
|
||||||
|
case CIM_RETURNCODE_TIMEOUT_PARAMETER_NOT_SUPPORTED:
|
||||||
|
return _("Timeout parameter not supported");
|
||||||
|
|
||||||
|
case CIM_RETURNCODE_BUSY:
|
||||||
|
return _("Busy");
|
||||||
|
|
||||||
|
case MSVM_RETURNCODE_FAILED:
|
||||||
|
return _("Failed");
|
||||||
|
|
||||||
|
case MSVM_RETURNCODE_ACCESS_DENIED:
|
||||||
|
return _("Access denied");
|
||||||
|
|
||||||
|
case MSVM_RETURNCODE_NOT_SUPPORTED:
|
||||||
|
return _("Not supported");
|
||||||
|
|
||||||
|
case MSVM_RETURNCODE_STATUS_IS_UNKNOWN:
|
||||||
|
return _("Status is unknown");
|
||||||
|
|
||||||
|
case MSVM_RETURNCODE_TIMEOUT:
|
||||||
|
return _("Timeout");
|
||||||
|
|
||||||
|
case MSVM_RETURNCODE_INVALID_PARAMETER:
|
||||||
|
return _("Invalid parameter");
|
||||||
|
|
||||||
|
case MSVM_RETURNCODE_SYSTEM_IS_IN_USE:
|
||||||
|
return _("System is in use");
|
||||||
|
|
||||||
|
case MSVM_RETURNCODE_INVALID_STATE_FOR_THIS_OPERATION:
|
||||||
|
return _("Invalid state for this operation");
|
||||||
|
|
||||||
|
case MSVM_RETURNCODE_INCORRECT_DATA_TYPE:
|
||||||
|
return _("Incorrect data type");
|
||||||
|
|
||||||
|
case MSVM_RETURNCODE_SYSTEM_IS_NOT_AVAILABLE:
|
||||||
|
return _("System is not available");
|
||||||
|
|
||||||
|
case MSVM_RETURNCODE_OUT_OF_MEMORY:
|
||||||
|
return _("Out of memory");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return _("Unknown return code");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Msvm_ComputerSystem
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
hypervInvokeMsvmComputerSystemRequestStateChange(virDomainPtr domain,
|
||||||
|
int requestedState)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
hypervPrivate *priv = domain->conn->privateData;
|
||||||
|
char uuid_string[VIR_UUID_STRING_BUFLEN];
|
||||||
|
WsXmlDocH response = NULL;
|
||||||
|
client_opt_t *options = NULL;
|
||||||
|
char *selector = NULL;
|
||||||
|
char *properties = NULL;
|
||||||
|
char *returnValue = NULL;
|
||||||
|
int returnCode;
|
||||||
|
char *instanceID = NULL;
|
||||||
|
virBuffer query = VIR_BUFFER_INITIALIZER;
|
||||||
|
Msvm_ConcreteJob *concreteJob = NULL;
|
||||||
|
bool completed = false;
|
||||||
|
|
||||||
|
virUUIDFormat(domain->uuid, uuid_string);
|
||||||
|
|
||||||
|
if (virAsprintf(&selector, "Name=%s&CreationClassName=Msvm_ComputerSystem",
|
||||||
|
uuid_string) < 0 ||
|
||||||
|
virAsprintf(&properties, "RequestedState=%d", requestedState) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
options = wsmc_options_init();
|
||||||
|
|
||||||
|
if (options == NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Could not initialize options"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
wsmc_add_selectors_from_str(options, selector);
|
||||||
|
wsmc_add_prop_from_str(options, properties);
|
||||||
|
|
||||||
|
/* Invoke method */
|
||||||
|
response = wsmc_action_invoke(priv->client, MSVM_COMPUTERSYSTEM_RESOURCE_URI,
|
||||||
|
options, "RequestStateChange", NULL);
|
||||||
|
|
||||||
|
if (hyperyVerifyResponse(priv->client, response, "invocation") < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check return value */
|
||||||
|
returnValue = ws_xml_get_xpath_value(response, (char *)"/s:Envelope/s:Body/p:RequestStateChange_OUTPUT/p:ReturnValue");
|
||||||
|
|
||||||
|
if (returnValue == NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Could not lookup %s for %s invocation"),
|
||||||
|
"ReturnValue", "RequestStateChange");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virStrToLong_i(returnValue, NULL, 10, &returnCode) < 0) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Could not parse return code from '%s'"), returnValue);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnCode == CIM_RETURNCODE_TRANSITION_STARTED) {
|
||||||
|
/* Get concrete job object */
|
||||||
|
instanceID = ws_xml_get_xpath_value(response, (char *)"/s:Envelope/s:Body/p:RequestStateChange_OUTPUT/p:Job/a:ReferenceParameters/w:SelectorSet/w:Selector[@Name='InstanceID']");
|
||||||
|
|
||||||
|
if (instanceID == NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Could not lookup %s for %s invocation"),
|
||||||
|
"InstanceID", "RequestStateChange");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Poll every 100ms until the job completes or fails. There
|
||||||
|
* seems to be no other way than polling. */
|
||||||
|
while (!completed) {
|
||||||
|
virBufferAddLit(&query, MSVM_CONCRETEJOB_WQL_SELECT);
|
||||||
|
virBufferAsprintf(&query, "where InstanceID = \"%s\"", instanceID);
|
||||||
|
|
||||||
|
if (hypervGetMsvmConcreteJobList(priv, &query, &concreteJob) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (concreteJob == NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Could not lookup %s for %s invocation"),
|
||||||
|
"Msvm_ConcreteJob", "RequestStateChange");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (concreteJob->data->JobState) {
|
||||||
|
case MSVM_CONCRETEJOB_JOBSTATE_NEW:
|
||||||
|
case MSVM_CONCRETEJOB_JOBSTATE_STARTING:
|
||||||
|
case MSVM_CONCRETEJOB_JOBSTATE_RUNNING:
|
||||||
|
case MSVM_CONCRETEJOB_JOBSTATE_SHUTTING_DOWN:
|
||||||
|
hypervFreeObject(priv, (hypervObject *)concreteJob);
|
||||||
|
concreteJob = NULL;
|
||||||
|
|
||||||
|
usleep(100 * 1000);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case MSVM_CONCRETEJOB_JOBSTATE_COMPLETED:
|
||||||
|
completed = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSVM_CONCRETEJOB_JOBSTATE_TERMINATED:
|
||||||
|
case MSVM_CONCRETEJOB_JOBSTATE_KILLED:
|
||||||
|
case MSVM_CONCRETEJOB_JOBSTATE_EXCEPTION:
|
||||||
|
case MSVM_CONCRETEJOB_JOBSTATE_SERVICE:
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Concrete job for %s invocation is in error state"),
|
||||||
|
"RequestStateChange");
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
default:
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Concrete job for %s invocation is in unknown state"),
|
||||||
|
"RequestStateChange");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (returnCode != CIM_RETURNCODE_COMPLETED_WITH_NO_ERROR) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Invocation of %s returned an error: %s (%d)"),
|
||||||
|
"RequestStateChange", hypervReturnCodeToString(returnCode),
|
||||||
|
returnCode);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (options != NULL) {
|
||||||
|
wsmc_options_destroy(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
ws_xml_destroy_doc(response);
|
||||||
|
VIR_FREE(selector);
|
||||||
|
VIR_FREE(properties);
|
||||||
|
VIR_FREE(returnValue);
|
||||||
|
VIR_FREE(instanceID);
|
||||||
|
hypervFreeObject(priv, (hypervObject *)concreteJob);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hypervMsvmComputerSystemEnabledStateToDomainState
|
||||||
|
(Msvm_ComputerSystem *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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
hypervIsMsvmComputerSystemActive(Msvm_ComputerSystem *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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hypervMsvmComputerSystemToDomain(virConnectPtr conn,
|
||||||
|
Msvm_ComputerSystem *computerSystem,
|
||||||
|
virDomainPtr *domain)
|
||||||
|
{
|
||||||
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||||
|
|
||||||
|
if (domain == NULL || *domain != NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virUUIDParse(computerSystem->data->Name, uuid) < 0) {
|
||||||
|
HYPERV_ERROR(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 (hypervIsMsvmComputerSystemActive(computerSystem, NULL)) {
|
||||||
|
(*domain)->id = computerSystem->data->ProcessID;
|
||||||
|
} else {
|
||||||
|
(*domain)->id = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
|
||||||
|
Msvm_ComputerSystem **computerSystem)
|
||||||
|
{
|
||||||
|
hypervPrivate *priv = domain->conn->privateData;
|
||||||
|
char uuid_string[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virBuffer query = VIR_BUFFER_INITIALIZER;
|
||||||
|
|
||||||
|
if (computerSystem == NULL || *computerSystem != NULL) {
|
||||||
|
HYPERV_ERROR(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 (hypervGetMsvmComputerSystemList(priv, &query, computerSystem) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*computerSystem == NULL) {
|
||||||
|
HYPERV_ERROR(VIR_ERR_NO_DOMAIN,
|
||||||
|
_("No domain with UUID %s"), uuid_string);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "hyperv_wmi.generated.c"
|
121
src/hyperv/hyperv_wmi.h
Normal file
121
src/hyperv/hyperv_wmi.h
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* hyperv_wmi.h: general WMI over WSMAN related functions and structures for
|
||||||
|
* managing Microsoft Hyper-V hosts
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Matthias Bolte <matthias.bolte@googlemail.com>
|
||||||
|
* Copyright (C) 2009 Michael Sievers <msievers83@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, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __HYPERV_WMI_H__
|
||||||
|
# define __HYPERV_WMI_H__
|
||||||
|
|
||||||
|
# include "buf.h"
|
||||||
|
# include "hyperv_private.h"
|
||||||
|
# include "hyperv_wmi_classes.h"
|
||||||
|
# include "openwsman.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _hypervObject hypervObject;
|
||||||
|
|
||||||
|
int hyperyVerifyResponse(WsManClient *client, WsXmlDocH response,
|
||||||
|
const char *detail);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Object
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct _hypervObject {
|
||||||
|
XmlSerializerInfo *serializerInfo;
|
||||||
|
XML_TYPE_PTR data;
|
||||||
|
hypervObject *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
int hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query,
|
||||||
|
const char *root, XmlSerializerInfo *serializerInfo,
|
||||||
|
const char *resourceUri, const char *className,
|
||||||
|
hypervObject **list);
|
||||||
|
|
||||||
|
void hypervFreeObject(hypervPrivate *priv, hypervObject *object);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* CIM/Msvm_ReturnCode
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum _CIM_ReturnCode {
|
||||||
|
CIM_RETURNCODE_COMPLETED_WITH_NO_ERROR = 0,
|
||||||
|
CIM_RETURNCODE_NOT_SUPPORTED = 1,
|
||||||
|
CIM_RETURNCODE_UNKNOWN_ERROR = 2,
|
||||||
|
CIM_RETURNCODE_CANNOT_COMPLETE_WITHIN_TIMEOUT_PERIOD = 3,
|
||||||
|
CIM_RETURNCODE_FAILED = 4,
|
||||||
|
CIM_RETURNCODE_INVALID_PARAMETER = 5,
|
||||||
|
CIM_RETURNCODE_IN_USE = 6,
|
||||||
|
CIM_RETURNCODE_TRANSITION_STARTED = 4096,
|
||||||
|
CIM_RETURNCODE_INVALID_STATE_TRANSITION = 4097,
|
||||||
|
CIM_RETURNCODE_TIMEOUT_PARAMETER_NOT_SUPPORTED = 4098,
|
||||||
|
CIM_RETURNCODE_BUSY = 4099,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum _Msvm_ReturnCode {
|
||||||
|
MSVM_RETURNCODE_FAILED = 32768,
|
||||||
|
MSVM_RETURNCODE_ACCESS_DENIED = 32769,
|
||||||
|
MSVM_RETURNCODE_NOT_SUPPORTED = 32770,
|
||||||
|
MSVM_RETURNCODE_STATUS_IS_UNKNOWN = 32771,
|
||||||
|
MSVM_RETURNCODE_TIMEOUT = 32772,
|
||||||
|
MSVM_RETURNCODE_INVALID_PARAMETER = 32773,
|
||||||
|
MSVM_RETURNCODE_SYSTEM_IS_IN_USE = 32774,
|
||||||
|
MSVM_RETURNCODE_INVALID_STATE_FOR_THIS_OPERATION = 32775,
|
||||||
|
MSVM_RETURNCODE_INCORRECT_DATA_TYPE = 32776,
|
||||||
|
MSVM_RETURNCODE_SYSTEM_IS_NOT_AVAILABLE = 32777,
|
||||||
|
MSVM_RETURNCODE_OUT_OF_MEMORY = 32778,
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *hypervReturnCodeToString(int returnCode);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Msvm_ComputerSystem
|
||||||
|
*/
|
||||||
|
|
||||||
|
int hypervInvokeMsvmComputerSystemRequestStateChange(virDomainPtr domain,
|
||||||
|
int requestedState);
|
||||||
|
|
||||||
|
int hypervMsvmComputerSystemEnabledStateToDomainState
|
||||||
|
(Msvm_ComputerSystem *computerSystem);
|
||||||
|
|
||||||
|
bool hypervIsMsvmComputerSystemActive(Msvm_ComputerSystem *computerSystem,
|
||||||
|
bool *in_transition);
|
||||||
|
|
||||||
|
int hypervMsvmComputerSystemToDomain(virConnectPtr conn,
|
||||||
|
Msvm_ComputerSystem *computerSystem,
|
||||||
|
virDomainPtr *domain);
|
||||||
|
|
||||||
|
int hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
|
||||||
|
Msvm_ComputerSystem **computerSystem);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# include "hyperv_wmi.generated.h"
|
||||||
|
|
||||||
|
#endif /* __HYPERV_WMI_H__ */
|
37
src/hyperv/hyperv_wmi_classes.c
Normal file
37
src/hyperv/hyperv_wmi_classes.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* hyperv_wmi_classes.c: WMI classes for managing Microsoft Hyper-V hosts
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Matthias Bolte <matthias.bolte@googlemail.com>
|
||||||
|
* Copyright (C) 2009 Michael Sievers <msievers83@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, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "hyperv_wmi_classes.h"
|
||||||
|
|
||||||
|
SER_TYPEINFO_BOOL;
|
||||||
|
SER_TYPEINFO_STRING;
|
||||||
|
SER_TYPEINFO_INT8;
|
||||||
|
SER_TYPEINFO_INT16;
|
||||||
|
SER_TYPEINFO_INT32;
|
||||||
|
SER_TYPEINFO_UINT8;
|
||||||
|
SER_TYPEINFO_UINT16;
|
||||||
|
SER_TYPEINFO_UINT32;
|
||||||
|
|
||||||
|
#include "hyperv_wmi_classes.generated.c"
|
94
src/hyperv/hyperv_wmi_classes.h
Normal file
94
src/hyperv/hyperv_wmi_classes.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* hyperv_wmi_classes.h: WMI classes for managing Microsoft Hyper-V hosts
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Matthias Bolte <matthias.bolte@googlemail.com>
|
||||||
|
* Copyright (C) 2009 Michael Sievers <msievers83@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, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __HYPERV_WMI_CLASSES_H__
|
||||||
|
# define __HYPERV_WMI_CLASSES_H__
|
||||||
|
|
||||||
|
# include "openwsman.h"
|
||||||
|
|
||||||
|
# include "hyperv_wmi_classes.generated.typedef"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Msvm_ComputerSystem
|
||||||
|
*/
|
||||||
|
|
||||||
|
# define MSVM_COMPUTERSYSTEM_WQL_VIRTUAL \
|
||||||
|
"Description = \"Microsoft Virtual Machine\" "
|
||||||
|
|
||||||
|
# define MSVM_COMPUTERSYSTEM_WQL_PHYSICAL \
|
||||||
|
"Description = \"Microsoft Hosting Computer System\" "
|
||||||
|
|
||||||
|
# define MSVM_COMPUTERSYSTEM_WQL_ACTIVE \
|
||||||
|
"(EnabledState != 0 and EnabledState != 3 and EnabledState != 32769) "
|
||||||
|
|
||||||
|
# define MSVM_COMPUTERSYSTEM_WQL_INACTIVE \
|
||||||
|
"(EnabledState = 0 or EnabledState = 3 or EnabledState = 32769) "
|
||||||
|
|
||||||
|
enum _Msvm_ComputerSystem_EnabledState {
|
||||||
|
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_UNKNOWN = 0, /* inactive */
|
||||||
|
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_ENABLED = 2, /* active */
|
||||||
|
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_DISABLED = 3, /* inactive */
|
||||||
|
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSED = 32768, /* active */
|
||||||
|
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SUSPENDED = 32769, /* inactive */
|
||||||
|
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_STARTING = 32770, /* active */
|
||||||
|
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SNAPSHOTTING = 32771, /* active */
|
||||||
|
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SAVING = 32773, /* active */
|
||||||
|
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_STOPPING = 32774, /* active */
|
||||||
|
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSING = 32776, /* active */
|
||||||
|
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_RESUMING = 32777 /* active */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum _Msvm_ComputerSystem_RequestedState {
|
||||||
|
MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_ENABLED = 2,
|
||||||
|
MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_DISABLED = 3,
|
||||||
|
MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_REBOOT = 10,
|
||||||
|
MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_PAUSED = 32768,
|
||||||
|
MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_SUSPENDED = 32769,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Msvm_ConcreteJob
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum _Msvm_ConcreteJob_JobState {
|
||||||
|
MSVM_CONCRETEJOB_JOBSTATE_NEW = 2,
|
||||||
|
MSVM_CONCRETEJOB_JOBSTATE_STARTING = 3,
|
||||||
|
MSVM_CONCRETEJOB_JOBSTATE_RUNNING = 4,
|
||||||
|
MSVM_CONCRETEJOB_JOBSTATE_SUSPENDED = 5,
|
||||||
|
MSVM_CONCRETEJOB_JOBSTATE_SHUTTING_DOWN = 6,
|
||||||
|
MSVM_CONCRETEJOB_JOBSTATE_COMPLETED = 7,
|
||||||
|
MSVM_CONCRETEJOB_JOBSTATE_TERMINATED = 8,
|
||||||
|
MSVM_CONCRETEJOB_JOBSTATE_KILLED = 9,
|
||||||
|
MSVM_CONCRETEJOB_JOBSTATE_EXCEPTION = 10,
|
||||||
|
MSVM_CONCRETEJOB_JOBSTATE_SERVICE = 11,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# include "hyperv_wmi_classes.generated.h"
|
||||||
|
|
||||||
|
#endif /* __HYPERV_WMI_CLASSES_H__ */
|
298
src/hyperv/hyperv_wmi_generator.input
Normal file
298
src/hyperv/hyperv_wmi_generator.input
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
#
|
||||||
|
# Definitions of WMI classes used as input for the hyperv_wmi_generator.py
|
||||||
|
# script.
|
||||||
|
#
|
||||||
|
# This format is line-based, so end-of-line is important.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Class definition:
|
||||||
|
#
|
||||||
|
# class <name>
|
||||||
|
# <type> <name>
|
||||||
|
# ...
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# Allowed values for <type> are: boolean, string, datetime, int8, int16,
|
||||||
|
# int32, int64, uint8, uint16, uint32 and uint64
|
||||||
|
#
|
||||||
|
# The property <name> can be followed by [] to define a dynamic array.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Based on MSDN Hyper-V WMI Classes:
|
||||||
|
# http://msdn.microsoft.com/en-us/library/cc136986%28v=vs.85%29.aspx
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
class Msvm_ComputerSystem
|
||||||
|
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
|
||||||
|
string Description
|
||||||
|
string ElementName
|
||||||
|
datetime InstallDate
|
||||||
|
uint16 OperationalStatus[]
|
||||||
|
string StatusDescriptions[]
|
||||||
|
string Status
|
||||||
|
uint16 HealthState
|
||||||
|
string JobStatus
|
||||||
|
datetime TimeSubmitted
|
||||||
|
datetime ScheduledStartTime
|
||||||
|
datetime StartTime
|
||||||
|
datetime ElapsedTime
|
||||||
|
uint32 JobRunTimes
|
||||||
|
uint8 RunMonth
|
||||||
|
int8 RunDay
|
||||||
|
int8 RunDayOfWeek
|
||||||
|
datetime RunStartInterval
|
||||||
|
uint16 LocalOrUtcTime
|
||||||
|
datetime UntilTime
|
||||||
|
string Notify
|
||||||
|
string Owner
|
||||||
|
uint32 Priority
|
||||||
|
uint16 PercentComplete
|
||||||
|
boolean DeleteOnCompletion
|
||||||
|
uint16 ErrorCode
|
||||||
|
string ErrorDescription
|
||||||
|
string ErrorSummaryDescription
|
||||||
|
uint16 RecoveryAction
|
||||||
|
string OtherRecoveryAction
|
||||||
|
string InstanceID
|
||||||
|
string Name
|
||||||
|
uint16 JobState
|
||||||
|
datetime TimeOfLastStateChange
|
||||||
|
datetime TimeBeforeRemoval
|
||||||
|
boolean Cancellable
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
class Msvm_MemorySettingData
|
||||||
|
string Caption
|
||||||
|
string Description
|
||||||
|
string InstanceID
|
||||||
|
string ElementName
|
||||||
|
uint16 ResourceType
|
||||||
|
string OtherResourceType
|
||||||
|
string ResourceSubType
|
||||||
|
string PoolID
|
||||||
|
uint16 ConsumerVisibility
|
||||||
|
string HostResource[]
|
||||||
|
string AllocationUnits
|
||||||
|
uint64 VirtualQuantity
|
||||||
|
uint64 Reservation
|
||||||
|
uint64 Limit
|
||||||
|
uint32 Weight
|
||||||
|
boolean AutomaticAllocation
|
||||||
|
boolean AutomaticDeallocation
|
||||||
|
string Parent
|
||||||
|
string Connection[]
|
||||||
|
string Address
|
||||||
|
uint16 MappingBehavior
|
||||||
|
boolean IsVirtualized
|
||||||
|
string DeviceID
|
||||||
|
string DeviceIDFormat
|
||||||
|
boolean DynamicMemoryEnabled
|
||||||
|
# uint32 TargetMemoryBuffer # Available only on Windows Server 2008 R2 SP1
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
class Msvm_ProcessorSettingData
|
||||||
|
string Caption
|
||||||
|
string Description
|
||||||
|
string InstanceID
|
||||||
|
string ElementName
|
||||||
|
uint16 ResourceType
|
||||||
|
string OtherResourceType
|
||||||
|
string ResourceSubType
|
||||||
|
string PoolID
|
||||||
|
uint16 ConsumerVisibility
|
||||||
|
string HostResource[]
|
||||||
|
string AllocationUnits
|
||||||
|
uint64 VirtualQuantity
|
||||||
|
uint64 Reservation
|
||||||
|
uint64 Limit
|
||||||
|
uint32 Weight
|
||||||
|
boolean AutomaticAllocation
|
||||||
|
boolean AutomaticDeallocation
|
||||||
|
string Parent
|
||||||
|
string Connection[]
|
||||||
|
string Address
|
||||||
|
uint16 MappingBehavior
|
||||||
|
boolean IsVirtualized
|
||||||
|
string DeviceID
|
||||||
|
string DeviceIDFormat
|
||||||
|
uint16 ProcessorsPerSocket
|
||||||
|
uint16 SocketCount
|
||||||
|
boolean ThreadsEnabled
|
||||||
|
boolean LimitCPUID
|
||||||
|
boolean LimitProcessorFeatures
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
class Msvm_VirtualSystemSettingData
|
||||||
|
string Caption
|
||||||
|
string Description
|
||||||
|
string ElementName
|
||||||
|
string InstanceID
|
||||||
|
string SystemName
|
||||||
|
uint16 SettingType
|
||||||
|
uint16 VirtualSystemType
|
||||||
|
string OtherVirtualSystemType
|
||||||
|
boolean AutoActivate
|
||||||
|
datetime CreationTime
|
||||||
|
string Notes
|
||||||
|
string BIOSGUID
|
||||||
|
string BIOSSerialNumber
|
||||||
|
string BaseBoardSerialNumber
|
||||||
|
string ChassisSerialNumber
|
||||||
|
string ChassisAssetTag
|
||||||
|
boolean BIOSNumLock
|
||||||
|
uint16 BootOrder[]
|
||||||
|
string Parent
|
||||||
|
uint16 NumaNodeList[]
|
||||||
|
boolean NumaNodesAreRequired
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
class Win32_ComputerSystem
|
||||||
|
uint16 AdminPasswordStatus
|
||||||
|
boolean AutomaticManagedPagefile
|
||||||
|
boolean AutomaticResetBootOption
|
||||||
|
boolean AutomaticResetCapability
|
||||||
|
uint16 BootOptionOnLimit
|
||||||
|
uint16 BootOptionOnWatchDog
|
||||||
|
boolean BootROMSupported
|
||||||
|
string BootupState
|
||||||
|
string Caption
|
||||||
|
uint16 ChassisBootupState
|
||||||
|
string CreationClassName
|
||||||
|
int16 CurrentTimeZone
|
||||||
|
boolean DaylightInEffect
|
||||||
|
string Description
|
||||||
|
string DNSHostName
|
||||||
|
string Domain
|
||||||
|
uint16 DomainRole
|
||||||
|
boolean EnableDaylightSavingsTime
|
||||||
|
uint16 FrontPanelResetStatus
|
||||||
|
boolean InfraredSupported
|
||||||
|
# string InitialLoadInfo # MSDN documents it, but it's not there
|
||||||
|
datetime InstallDate
|
||||||
|
uint16 KeyboardPasswordStatus
|
||||||
|
string LastLoadInfo
|
||||||
|
string Manufacturer
|
||||||
|
string Model
|
||||||
|
string Name
|
||||||
|
string NameFormat
|
||||||
|
boolean NetworkServerModeEnabled
|
||||||
|
uint32 NumberOfLogicalProcessors
|
||||||
|
uint32 NumberOfProcessors
|
||||||
|
uint8 OEMLogoBitmap[]
|
||||||
|
string OEMStringArray[]
|
||||||
|
boolean PartOfDomain
|
||||||
|
int64 PauseAfterReset
|
||||||
|
uint16 PCSystemType
|
||||||
|
uint16 PowerManagementCapabilities[]
|
||||||
|
boolean PowerManagementSupported
|
||||||
|
uint16 PowerOnPasswordStatus
|
||||||
|
uint16 PowerState
|
||||||
|
uint16 PowerSupplyState
|
||||||
|
string PrimaryOwnerContact
|
||||||
|
string PrimaryOwnerName
|
||||||
|
uint16 ResetCapability
|
||||||
|
int16 ResetCount
|
||||||
|
int16 ResetLimit
|
||||||
|
string Roles[]
|
||||||
|
string Status
|
||||||
|
string SupportContactDescription[]
|
||||||
|
uint16 SystemStartupDelay
|
||||||
|
string SystemStartupOptions[]
|
||||||
|
uint8 SystemStartupSetting
|
||||||
|
string SystemType
|
||||||
|
uint16 ThermalState
|
||||||
|
uint64 TotalPhysicalMemory
|
||||||
|
string UserName
|
||||||
|
uint16 WakeUpType
|
||||||
|
string Workgroup
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
class Win32_Processor
|
||||||
|
uint16 AddressWidth
|
||||||
|
uint16 Architecture
|
||||||
|
uint16 Availability
|
||||||
|
string Caption
|
||||||
|
uint32 ConfigManagerErrorCode
|
||||||
|
boolean ConfigManagerUserConfig
|
||||||
|
uint16 CpuStatus
|
||||||
|
string CreationClassName
|
||||||
|
uint32 CurrentClockSpeed
|
||||||
|
uint16 CurrentVoltage
|
||||||
|
uint16 DataWidth
|
||||||
|
string Description
|
||||||
|
string DeviceID
|
||||||
|
boolean ErrorCleared
|
||||||
|
string ErrorDescription
|
||||||
|
uint32 ExtClock
|
||||||
|
uint16 Family
|
||||||
|
datetime InstallDate
|
||||||
|
uint32 L2CacheSize
|
||||||
|
uint32 L2CacheSpeed
|
||||||
|
uint32 L3CacheSize
|
||||||
|
uint32 L3CacheSpeed
|
||||||
|
uint32 LastErrorCode
|
||||||
|
uint16 Level
|
||||||
|
uint16 LoadPercentage
|
||||||
|
string Manufacturer
|
||||||
|
uint32 MaxClockSpeed
|
||||||
|
string Name
|
||||||
|
uint32 NumberOfCores
|
||||||
|
uint32 NumberOfLogicalProcessors
|
||||||
|
string OtherFamilyDescription
|
||||||
|
string PNPDeviceID
|
||||||
|
uint16 PowerManagementCapabilities[]
|
||||||
|
boolean PowerManagementSupported
|
||||||
|
string ProcessorId
|
||||||
|
uint16 ProcessorType
|
||||||
|
uint16 Revision
|
||||||
|
string Role
|
||||||
|
string SocketDesignation
|
||||||
|
string Status
|
||||||
|
uint16 StatusInfo
|
||||||
|
string Stepping
|
||||||
|
string SystemCreationClassName
|
||||||
|
string SystemName
|
||||||
|
string UniqueId
|
||||||
|
uint16 UpgradeMethod
|
||||||
|
string Version
|
||||||
|
uint32 VoltageCaps
|
||||||
|
end
|
311
src/hyperv/hyperv_wmi_generator.py
Executable file
311
src/hyperv/hyperv_wmi_generator.py
Executable file
@ -0,0 +1,311 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#
|
||||||
|
# hyperv_wmi_generator.py: generates most of the WMI type mapping code
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 Matthias Bolte <matthias.bolte@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, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
separator = "/* " + ("* " * 37) + "*\n"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Class:
|
||||||
|
def __init__(self, name, properties):
|
||||||
|
self.name = name
|
||||||
|
self.properties = properties
|
||||||
|
|
||||||
|
|
||||||
|
def generate_header(self):
|
||||||
|
name_upper = self.name.upper()
|
||||||
|
|
||||||
|
header = separator
|
||||||
|
header += " * %s\n" % self.name
|
||||||
|
header += " */\n"
|
||||||
|
header += "\n"
|
||||||
|
header += "int hypervGet%sList(hypervPrivate *priv, virBufferPtr query, %s **list);\n" \
|
||||||
|
% (self.name.replace("_", ""), self.name)
|
||||||
|
header += "\n"
|
||||||
|
header += "\n"
|
||||||
|
header += "\n"
|
||||||
|
|
||||||
|
return header
|
||||||
|
|
||||||
|
|
||||||
|
def generate_classes_typedef(self):
|
||||||
|
typedef = "typedef struct _%s_Data %s_Data;\n" % (self.name, self.name)
|
||||||
|
typedef += "typedef struct _%s %s;\n" % (self.name, self.name)
|
||||||
|
|
||||||
|
return typedef
|
||||||
|
|
||||||
|
|
||||||
|
def generate_classes_header(self):
|
||||||
|
name_upper = self.name.upper()
|
||||||
|
|
||||||
|
header = separator
|
||||||
|
header += " * %s\n" % self.name
|
||||||
|
header += " */\n"
|
||||||
|
header += "\n"
|
||||||
|
header += "#define %s_RESOURCE_URI \\\n" % name_upper
|
||||||
|
|
||||||
|
if self.name.startswith("Win32_"):
|
||||||
|
header += " \"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/%s\"\n" % self.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 += "\n"
|
||||||
|
header += "#define %s_WQL_SELECT \\\n" % name_upper
|
||||||
|
header += " \"select * from %s \"\n" % self.name
|
||||||
|
header += "\n"
|
||||||
|
header += "struct _%s_Data {\n" % self.name
|
||||||
|
|
||||||
|
for property in self.properties:
|
||||||
|
header += property.generate_classes_header()
|
||||||
|
|
||||||
|
header += "};\n"
|
||||||
|
header += "\n"
|
||||||
|
header += "SER_DECLARE_TYPE(%s_Data);\n" % self.name
|
||||||
|
header += "\n"
|
||||||
|
header += "struct _%s {\n" % self.name
|
||||||
|
header += " XmlSerializerInfo *serializerInfo;\n"
|
||||||
|
header += " %s_Data *data;\n" % self.name
|
||||||
|
header += " %s *next;\n" % self.name
|
||||||
|
header += "};\n"
|
||||||
|
header += "\n"
|
||||||
|
header += "\n"
|
||||||
|
header += "\n"
|
||||||
|
|
||||||
|
return header
|
||||||
|
|
||||||
|
|
||||||
|
def generate_source(self):
|
||||||
|
name_upper = self.name.upper()
|
||||||
|
|
||||||
|
source = separator
|
||||||
|
source += " * %s\n" % self.name
|
||||||
|
source += " */\n"
|
||||||
|
source += "\n"
|
||||||
|
source += "int\n"
|
||||||
|
source += "hypervGet%sList(hypervPrivate *priv, virBufferPtr query, %s **list)\n" \
|
||||||
|
% (self.name.replace("_", ""), self.name)
|
||||||
|
source += "{\n"
|
||||||
|
|
||||||
|
if self.name.startswith("Win32_"):
|
||||||
|
source += " return hypervEnumAndPull(priv, query, ROOT_CIMV2,\n"
|
||||||
|
else:
|
||||||
|
source += " return hypervEnumAndPull(priv, query, ROOT_VIRTUALIZATION,\n"
|
||||||
|
|
||||||
|
source += " %s_Data_TypeInfo,\n" % self.name
|
||||||
|
source += " %s_RESOURCE_URI,\n" % name_upper
|
||||||
|
source += " %s_CLASSNAME,\n" % name_upper
|
||||||
|
source += " (hypervObject **)list);\n"
|
||||||
|
source += "}\n"
|
||||||
|
source += "\n"
|
||||||
|
source += "\n"
|
||||||
|
source += "\n"
|
||||||
|
|
||||||
|
return source
|
||||||
|
|
||||||
|
|
||||||
|
def generate_classes_source(self):
|
||||||
|
name_upper = self.name.upper()
|
||||||
|
|
||||||
|
source = separator
|
||||||
|
source += " * %s\n" % self.name
|
||||||
|
source += " */\n"
|
||||||
|
source += "\n"
|
||||||
|
source += "SER_START_ITEMS(%s_Data)\n" % self.name
|
||||||
|
|
||||||
|
for property in self.properties:
|
||||||
|
source += property.generate_classes_source(self.name)
|
||||||
|
|
||||||
|
source += "SER_END_ITEMS(%s_Data);\n" % self.name
|
||||||
|
source += "\n"
|
||||||
|
source += "\n"
|
||||||
|
source += "\n"
|
||||||
|
|
||||||
|
return source
|
||||||
|
|
||||||
|
|
||||||
|
class Property:
|
||||||
|
typemap = {"boolean" : "BOOL",
|
||||||
|
"string" : "STR",
|
||||||
|
"datetime" : "STR",
|
||||||
|
"int8" : "INT8",
|
||||||
|
"int16" : "INT16",
|
||||||
|
"int32" : "INT32",
|
||||||
|
"int64" : "INT64",
|
||||||
|
"uint8" : "UINT8",
|
||||||
|
"uint16" : "UINT16",
|
||||||
|
"uint32" : "UINT32",
|
||||||
|
"uint64" : "UINT64"}
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self, type, name, is_array):
|
||||||
|
if type not in Property.typemap:
|
||||||
|
report_error("unhandled property type %s" % type)
|
||||||
|
|
||||||
|
self.type = type
|
||||||
|
self.name = name
|
||||||
|
self.is_array = is_array
|
||||||
|
|
||||||
|
|
||||||
|
def generate_classes_header(self):
|
||||||
|
if self.is_array:
|
||||||
|
return " XML_TYPE_DYN_ARRAY %s;\n" % self.name
|
||||||
|
else:
|
||||||
|
return " XML_TYPE_%s %s;\n" \
|
||||||
|
% (Property.typemap[self.type], self.name)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_classes_source(self, class_name):
|
||||||
|
if self.is_array:
|
||||||
|
return " SER_NS_DYN_ARRAY(%s_RESOURCE_URI, \"%s\", 0, 0, %s),\n" \
|
||||||
|
% (class_name.upper(), self.name, self.type)
|
||||||
|
else:
|
||||||
|
return " SER_NS_%s(%s_RESOURCE_URI, \"%s\", 1),\n" \
|
||||||
|
% (Property.typemap[self.type], class_name.upper(), self.name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def open_and_print(filename):
|
||||||
|
if filename.startswith("./"):
|
||||||
|
print " GEN " + filename[2:]
|
||||||
|
else:
|
||||||
|
print " GEN " + filename
|
||||||
|
|
||||||
|
return open(filename, "wb")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def report_error(message):
|
||||||
|
print "error: " + message
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def parse_class(block):
|
||||||
|
# expected format: class <name>
|
||||||
|
header_items = block[0][1].split()
|
||||||
|
|
||||||
|
if len(header_items) != 2:
|
||||||
|
report_error("line %d: invalid block header" % (number))
|
||||||
|
|
||||||
|
assert header_items[0] == "class"
|
||||||
|
|
||||||
|
name = header_items[1]
|
||||||
|
|
||||||
|
properties = []
|
||||||
|
|
||||||
|
for line in block[1:]:
|
||||||
|
# expected format: <type> <name>
|
||||||
|
items = line[1].split()
|
||||||
|
|
||||||
|
if len(items) != 2:
|
||||||
|
report_error("line %d: invalid property" % line[0])
|
||||||
|
|
||||||
|
if items[1].endswith("[]"):
|
||||||
|
items[1] = items[1][:-2]
|
||||||
|
is_array = True
|
||||||
|
else:
|
||||||
|
is_array = False
|
||||||
|
|
||||||
|
properties.append(Property(type=items[0], name=items[1],
|
||||||
|
is_array=is_array))
|
||||||
|
|
||||||
|
return Class(name=name, properties=properties)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if "srcdir" in os.environ:
|
||||||
|
input_filename = os.path.join(os.environ["srcdir"], "hyperv/hyperv_wmi_generator.input")
|
||||||
|
output_dirname = os.path.join(os.environ["srcdir"], "hyperv")
|
||||||
|
else:
|
||||||
|
input_filename = os.path.join(os.getcwd(), "hyperv_wmi_generator.input")
|
||||||
|
output_dirname = os.getcwd()
|
||||||
|
|
||||||
|
header = open_and_print(os.path.join(output_dirname, "hyperv_wmi.generated.h"))
|
||||||
|
source = open_and_print(os.path.join(output_dirname, "hyperv_wmi.generated.c"))
|
||||||
|
classes_typedef = open_and_print(os.path.join(output_dirname, "hyperv_wmi_classes.generated.typedef"))
|
||||||
|
classes_header = open_and_print(os.path.join(output_dirname, "hyperv_wmi_classes.generated.h"))
|
||||||
|
classes_source = open_and_print(os.path.join(output_dirname, "hyperv_wmi_classes.generated.c"))
|
||||||
|
|
||||||
|
# parse input file
|
||||||
|
number = 0
|
||||||
|
classes_by_name = {}
|
||||||
|
block = None
|
||||||
|
|
||||||
|
for line in file(input_filename, "rb").readlines():
|
||||||
|
number += 1
|
||||||
|
|
||||||
|
if "#" in line:
|
||||||
|
line = line[:line.index("#")]
|
||||||
|
|
||||||
|
line = line.lstrip().rstrip()
|
||||||
|
|
||||||
|
if len(line) < 1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line.startswith("class"):
|
||||||
|
if block is not None:
|
||||||
|
report_error("line %d: nested block found" % (number))
|
||||||
|
else:
|
||||||
|
block = []
|
||||||
|
|
||||||
|
if block is not None:
|
||||||
|
if line == "end":
|
||||||
|
if block[0][1].startswith("class"):
|
||||||
|
cls = parse_class(block)
|
||||||
|
classes_by_name[cls.name] = cls
|
||||||
|
|
||||||
|
block = None
|
||||||
|
else:
|
||||||
|
block.append((number, line))
|
||||||
|
|
||||||
|
# write output files
|
||||||
|
notice = "/* Generated by hyperv_wmi_generator.py */\n\n\n\n"
|
||||||
|
|
||||||
|
header.write(notice)
|
||||||
|
source.write(notice)
|
||||||
|
classes_typedef.write(notice)
|
||||||
|
classes_header.write(notice)
|
||||||
|
classes_source.write(notice)
|
||||||
|
|
||||||
|
names = classes_by_name.keys()
|
||||||
|
names.sort()
|
||||||
|
|
||||||
|
for name in names:
|
||||||
|
header.write(classes_by_name[name].generate_header())
|
||||||
|
source.write(classes_by_name[name].generate_source())
|
||||||
|
classes_typedef.write(classes_by_name[name].generate_classes_typedef())
|
||||||
|
classes_header.write(classes_by_name[name].generate_classes_header())
|
||||||
|
classes_source.write(classes_by_name[name].generate_classes_source())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
47
src/hyperv/openwsman.h
Normal file
47
src/hyperv/openwsman.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* openwsman.h: workarounds for bugs in openwsman
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Matthias Bolte <matthias.bolte@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, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __OPENWSMAN_H__
|
||||||
|
# define __OPENWSMAN_H__
|
||||||
|
|
||||||
|
/* Workaround openwsman <= 2.2.6 unconditionally defining optarg. Just pretend
|
||||||
|
* that u/os.h was already included. Need to explicitly include time.h because
|
||||||
|
* wsman-xml-serializer.h needs it and u/os.h would have included it. */
|
||||||
|
# include <time.h>
|
||||||
|
# define _LIBU_OS_H_
|
||||||
|
# include <wsman-api.h>
|
||||||
|
|
||||||
|
/* wsman-xml-serializer.h in openwsman <= 2.2.6 is missing this defines */
|
||||||
|
# ifndef SER_NS_INT8
|
||||||
|
# define SER_NS_INT8(ns, n, x) SER_NS_INT8_FLAGS(ns, n, x, 0)
|
||||||
|
# endif
|
||||||
|
# ifndef SER_NS_INT16
|
||||||
|
# define SER_NS_INT16(ns, n, x) SER_NS_INT16_FLAGS(ns, n, x, 0)
|
||||||
|
# endif
|
||||||
|
# ifndef SER_NS_INT32
|
||||||
|
# define SER_NS_INT32(ns, n, x) SER_NS_INT32_FLAGS(ns, n, x, 0)
|
||||||
|
# endif
|
||||||
|
# ifndef SER_NS_INT64
|
||||||
|
# define SER_NS_INT64(ns, n, x) SER_NS_INT64_FLAGS(ns, n, x, 0)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif /* __OPENWSMAN_H__ */
|
Loading…
x
Reference in New Issue
Block a user