Re: [libvirt] [PATCH v3 3/5] hyperv: add hypervInvokeMethod
2017-05-05 22:24 GMT+02:00: > On Tue, 2017-05-02 at 00:26 +0200, Matthias Bolte wrote: >> 2017-04-24 20:19 GMT+02:00 Sri Ramanujam : >> > This commit adds support for invoking methods on remote objects >> > via hypervInvokeMethod. >> > --- >> > src/hyperv/hyperv_wmi.c | 569 >> > >> > src/hyperv/hyperv_wmi.h | 3 + >> > src/hyperv/openwsman.h | 4 + >> > 3 files changed, 576 insertions(+) >> > >> > diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c >> > index 1960c4c..deea907 100644 >> > --- a/src/hyperv/hyperv_wmi.c >> > +++ b/src/hyperv/hyperv_wmi.c >> > @@ -24,6 +24,7 @@ >> > */ >> > >> > #include >> > +#include >> > >> > #include "internal.h" >> > #include "virerror.h" >> > @@ -34,11 +35,14 @@ >> > #include "hyperv_private.h" >> > #include "hyperv_wmi.h" >> > #include "virstring.h" >> > +#include "openwsman.h" >> > +#include "virlog.h" >> > >> > #define WS_SERIALIZER_FREE_MEM_WORKS 0 >> > >> > #define VIR_FROM_THIS VIR_FROM_HYPERV >> > >> > +VIR_LOG_INIT("hyperv.hyperv_wmi"); >> > >> > static int >> > hypervGetWmiClassInfo(hypervPrivate *priv, >> > hypervWmiClassInfoListPtr list, >> > @@ -406,6 +410,571 @@ >> > hypervAddEmbeddedParam(hypervInvokeParamsListPtr params, >> > hypervPrivate *priv, >> > } >> > >> > >> > +/* >> > + * Serializing parameters to XML and invoking methods >> > + */ >> > + >> > +static int >> > +hypervGetCimTypeInfo(hypervCimTypePtr typemap, const char *name, >> > +hypervCimTypePtr *property) >> > +{ >> > +size_t i = 0; >> > +while (typemap[i].name[0] != '\0') { >> > +if (STREQ(typemap[i].name, name)) { >> > +*property = [i]; >> > +return 0; >> > +} >> > +i++; >> > +} >> > + >> > +return -1; >> > +} >> > + >> > + >> > +static int >> > +hypervCreateInvokeXmlDoc(hypervInvokeParamsListPtr params, >> > WsXmlDocH *docRoot) >> > +{ >> > +int result = -1; >> > +char *method = NULL; >> > +WsXmlNodeH xmlNodeMethod = NULL; >> > + >> > +if (virAsprintf(, "%s_INPUT", params->method) < 0) >> > +goto error; >> > + >> > +*docRoot = ws_xml_create_doc(NULL, method); >> > +if (*docRoot == NULL) { >> > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", >> > +_("Could not instantiate XML document")); >> > +goto error; >> > +} >> > + >> > +xmlNodeMethod = xml_parser_get_root(*docRoot); >> > +if (xmlNodeMethod == NULL) { >> > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", >> > +_("Could not get root node of XML document")); >> > +goto error; >> > +} >> > + >> > +/* add resource URI as namespace */ >> > +ws_xml_set_ns(xmlNodeMethod, params->resourceUri, "p"); >> > + >> > +result = 0; >> > +goto cleanup; >> > + >> > + error: >> > +if (*docRoot != NULL) { >> > +ws_xml_destroy_doc(*docRoot); >> > +*docRoot = NULL; >> > +} >> > + cleanup: >> > +VIR_FREE(method); >> > +return result; >> >> The error and cleanup label could be merged: >> >> >> result = 0; >> >> cleanup: >> if (result < 0 && *docRoot != NULL) { >> ws_xml_destroy_doc(*docRoot); >> *docRoot = NULL; >> } >> >> VIR_FREE(method); >> return result; >> } >> >> >> > +} >> > + >> > +static int >> > +hypervSerializeSimpleParam(hypervParamPtr p, const char >> > *resourceUri, >> > +WsXmlNodeH *methodNode) >> > +{ >> > +int result = -1; >> > +WsXmlNodeH xmlNodeParam = NULL; >> > + >> > +xmlNodeParam = ws_xml_add_child(*methodNode, resourceUri, >> > +p->simple.name, p->simple.value); >> > +if (xmlNodeParam == NULL) { >> > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", >> > +_("Could not create simple param")); >> > +goto cleanup; >> >> There is no actual cleanup, just return -1 here. >> >> > +} >> > + >> > +result = 0; >> > + >> > + cleanup: >> > +return result; >> >> And just return 0 here. >> >> > +} >> > + >> > +static int >> > +hypervSerializeEprParam(hypervParamPtr p, hypervPrivate *priv, >> > +const char *resourceUri, WsXmlDocH doc, WsXmlNodeH >> > *methodNode) >> > +{ >> > +int result = -1; >> > +WsXmlNodeH xmlNodeParam = NULL, >> > + xmlNodeTemp = NULL, >> > + xmlNodeAddr = NULL, >> > + xmlNodeRef = NULL; >> > +xmlNodePtr xmlNodeAddrPtr = NULL, >> > + xmlNodeRefPtr = NULL; >> > +WsXmlDocH xmlDocResponse = NULL; >> > +xmlDocPtr docPtr = (xmlDocPtr) doc->parserDoc; >> > +WsXmlNsH ns = NULL; >> > +client_opt_t *options = NULL; >> > +filter_t *filter = NULL; >> > +char *enumContext = NULL; >> > +char *query_string = NULL; >> > + >> > +/* init and set up options */ >> > +options = wsmc_options_init(); >> > +if (!options) { >> > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
Re: [libvirt] [PATCH v3 3/5] hyperv: add hypervInvokeMethod
On Tue, 2017-05-02 at 00:26 +0200, Matthias Bolte wrote: > 2017-04-24 20:19 GMT+02:00 Sri Ramanujam: > > This commit adds support for invoking methods on remote objects > > via hypervInvokeMethod. > > --- > > src/hyperv/hyperv_wmi.c | 569 > > > > src/hyperv/hyperv_wmi.h | 3 + > > src/hyperv/openwsman.h | 4 + > > 3 files changed, 576 insertions(+) > > > > diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c > > index 1960c4c..deea907 100644 > > --- a/src/hyperv/hyperv_wmi.c > > +++ b/src/hyperv/hyperv_wmi.c > > @@ -24,6 +24,7 @@ > > */ > > > > #include > > +#include > > > > #include "internal.h" > > #include "virerror.h" > > @@ -34,11 +35,14 @@ > > #include "hyperv_private.h" > > #include "hyperv_wmi.h" > > #include "virstring.h" > > +#include "openwsman.h" > > +#include "virlog.h" > > > > #define WS_SERIALIZER_FREE_MEM_WORKS 0 > > > > #define VIR_FROM_THIS VIR_FROM_HYPERV > > > > +VIR_LOG_INIT("hyperv.hyperv_wmi"); > > > > static int > > hypervGetWmiClassInfo(hypervPrivate *priv, > > hypervWmiClassInfoListPtr list, > > @@ -406,6 +410,571 @@ > > hypervAddEmbeddedParam(hypervInvokeParamsListPtr params, > > hypervPrivate *priv, > > } > > > > > > +/* > > + * Serializing parameters to XML and invoking methods > > + */ > > + > > +static int > > +hypervGetCimTypeInfo(hypervCimTypePtr typemap, const char *name, > > +hypervCimTypePtr *property) > > +{ > > +size_t i = 0; > > +while (typemap[i].name[0] != '\0') { > > +if (STREQ(typemap[i].name, name)) { > > +*property = [i]; > > +return 0; > > +} > > +i++; > > +} > > + > > +return -1; > > +} > > + > > + > > +static int > > +hypervCreateInvokeXmlDoc(hypervInvokeParamsListPtr params, > > WsXmlDocH *docRoot) > > +{ > > +int result = -1; > > +char *method = NULL; > > +WsXmlNodeH xmlNodeMethod = NULL; > > + > > +if (virAsprintf(, "%s_INPUT", params->method) < 0) > > +goto error; > > + > > +*docRoot = ws_xml_create_doc(NULL, method); > > +if (*docRoot == NULL) { > > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > > +_("Could not instantiate XML document")); > > +goto error; > > +} > > + > > +xmlNodeMethod = xml_parser_get_root(*docRoot); > > +if (xmlNodeMethod == NULL) { > > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > > +_("Could not get root node of XML document")); > > +goto error; > > +} > > + > > +/* add resource URI as namespace */ > > +ws_xml_set_ns(xmlNodeMethod, params->resourceUri, "p"); > > + > > +result = 0; > > +goto cleanup; > > + > > + error: > > +if (*docRoot != NULL) { > > +ws_xml_destroy_doc(*docRoot); > > +*docRoot = NULL; > > +} > > + cleanup: > > +VIR_FREE(method); > > +return result; > > The error and cleanup label could be merged: > > > result = 0; > > cleanup: > if (result < 0 && *docRoot != NULL) { > ws_xml_destroy_doc(*docRoot); > *docRoot = NULL; > } > > VIR_FREE(method); > return result; > } > > > > +} > > + > > +static int > > +hypervSerializeSimpleParam(hypervParamPtr p, const char > > *resourceUri, > > +WsXmlNodeH *methodNode) > > +{ > > +int result = -1; > > +WsXmlNodeH xmlNodeParam = NULL; > > + > > +xmlNodeParam = ws_xml_add_child(*methodNode, resourceUri, > > +p->simple.name, p->simple.value); > > +if (xmlNodeParam == NULL) { > > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > > +_("Could not create simple param")); > > +goto cleanup; > > There is no actual cleanup, just return -1 here. > > > +} > > + > > +result = 0; > > + > > + cleanup: > > +return result; > > And just return 0 here. > > > +} > > + > > +static int > > +hypervSerializeEprParam(hypervParamPtr p, hypervPrivate *priv, > > +const char *resourceUri, WsXmlDocH doc, WsXmlNodeH > > *methodNode) > > +{ > > +int result = -1; > > +WsXmlNodeH xmlNodeParam = NULL, > > + xmlNodeTemp = NULL, > > + xmlNodeAddr = NULL, > > + xmlNodeRef = NULL; > > +xmlNodePtr xmlNodeAddrPtr = NULL, > > + xmlNodeRefPtr = NULL; > > +WsXmlDocH xmlDocResponse = NULL; > > +xmlDocPtr docPtr = (xmlDocPtr) doc->parserDoc; > > +WsXmlNsH ns = NULL; > > +client_opt_t *options = NULL; > > +filter_t *filter = NULL; > > +char *enumContext = NULL; > > +char *query_string = NULL; > > + > > +/* init and set up options */ > > +options = wsmc_options_init(); > > +if (!options) { > > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not > > init options")); > > +goto cleanup; > > +} > > +wsmc_set_action_option(options, FLAG_ENUMERATION_ENUM_EPR); > > + > > +/* Get query and create filter based on it */ > > +
Re: [libvirt] [PATCH v3 3/5] hyperv: add hypervInvokeMethod
2017-04-24 20:19 GMT+02:00 Sri Ramanujam: > This commit adds support for invoking methods on remote objects > via hypervInvokeMethod. > --- > src/hyperv/hyperv_wmi.c | 569 > > src/hyperv/hyperv_wmi.h | 3 + > src/hyperv/openwsman.h | 4 + > 3 files changed, 576 insertions(+) > > diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c > index 1960c4c..deea907 100644 > --- a/src/hyperv/hyperv_wmi.c > +++ b/src/hyperv/hyperv_wmi.c > @@ -24,6 +24,7 @@ > */ > > #include > +#include > > #include "internal.h" > #include "virerror.h" > @@ -34,11 +35,14 @@ > #include "hyperv_private.h" > #include "hyperv_wmi.h" > #include "virstring.h" > +#include "openwsman.h" > +#include "virlog.h" > > #define WS_SERIALIZER_FREE_MEM_WORKS 0 > > #define VIR_FROM_THIS VIR_FROM_HYPERV > > +VIR_LOG_INIT("hyperv.hyperv_wmi"); > > static int > hypervGetWmiClassInfo(hypervPrivate *priv, hypervWmiClassInfoListPtr list, > @@ -406,6 +410,571 @@ hypervAddEmbeddedParam(hypervInvokeParamsListPtr > params, hypervPrivate *priv, > } > > > +/* > + * Serializing parameters to XML and invoking methods > + */ > + > +static int > +hypervGetCimTypeInfo(hypervCimTypePtr typemap, const char *name, > +hypervCimTypePtr *property) > +{ > +size_t i = 0; > +while (typemap[i].name[0] != '\0') { > +if (STREQ(typemap[i].name, name)) { > +*property = [i]; > +return 0; > +} > +i++; > +} > + > +return -1; > +} > + > + > +static int > +hypervCreateInvokeXmlDoc(hypervInvokeParamsListPtr params, WsXmlDocH > *docRoot) > +{ > +int result = -1; > +char *method = NULL; > +WsXmlNodeH xmlNodeMethod = NULL; > + > +if (virAsprintf(, "%s_INPUT", params->method) < 0) > +goto error; > + > +*docRoot = ws_xml_create_doc(NULL, method); > +if (*docRoot == NULL) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > +_("Could not instantiate XML document")); > +goto error; > +} > + > +xmlNodeMethod = xml_parser_get_root(*docRoot); > +if (xmlNodeMethod == NULL) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > +_("Could not get root node of XML document")); > +goto error; > +} > + > +/* add resource URI as namespace */ > +ws_xml_set_ns(xmlNodeMethod, params->resourceUri, "p"); > + > +result = 0; > +goto cleanup; > + > + error: > +if (*docRoot != NULL) { > +ws_xml_destroy_doc(*docRoot); > +*docRoot = NULL; > +} > + cleanup: > +VIR_FREE(method); > +return result; The error and cleanup label could be merged: result = 0; cleanup: if (result < 0 && *docRoot != NULL) { ws_xml_destroy_doc(*docRoot); *docRoot = NULL; } VIR_FREE(method); return result; } > +} > + > +static int > +hypervSerializeSimpleParam(hypervParamPtr p, const char *resourceUri, > +WsXmlNodeH *methodNode) > +{ > +int result = -1; > +WsXmlNodeH xmlNodeParam = NULL; > + > +xmlNodeParam = ws_xml_add_child(*methodNode, resourceUri, > +p->simple.name, p->simple.value); > +if (xmlNodeParam == NULL) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > +_("Could not create simple param")); > +goto cleanup; There is no actual cleanup, just return -1 here. > +} > + > +result = 0; > + > + cleanup: > +return result; And just return 0 here. > +} > + > +static int > +hypervSerializeEprParam(hypervParamPtr p, hypervPrivate *priv, > +const char *resourceUri, WsXmlDocH doc, WsXmlNodeH *methodNode) > +{ > +int result = -1; > +WsXmlNodeH xmlNodeParam = NULL, > + xmlNodeTemp = NULL, > + xmlNodeAddr = NULL, > + xmlNodeRef = NULL; > +xmlNodePtr xmlNodeAddrPtr = NULL, > + xmlNodeRefPtr = NULL; > +WsXmlDocH xmlDocResponse = NULL; > +xmlDocPtr docPtr = (xmlDocPtr) doc->parserDoc; > +WsXmlNsH ns = NULL; > +client_opt_t *options = NULL; > +filter_t *filter = NULL; > +char *enumContext = NULL; > +char *query_string = NULL; > + > +/* init and set up options */ > +options = wsmc_options_init(); > +if (!options) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not init > options")); > +goto cleanup; > +} > +wsmc_set_action_option(options, FLAG_ENUMERATION_ENUM_EPR); > + > +/* Get query and create filter based on it */ > +query_string = virBufferContentAndReset(p->epr.query); > +filter = filter_create_simple(WSM_WQL_FILTER_DIALECT, query_string); > +if (!filter) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create WQL > filter")); > +goto cleanup; > +} > + > +/* enumerate based on the filter from this query */ > +xmlDocResponse = wsmc_action_enumerate(priv->client, > p->epr.info->rootUri, >
[libvirt] [PATCH v3 3/5] hyperv: add hypervInvokeMethod
This commit adds support for invoking methods on remote objects via hypervInvokeMethod. --- src/hyperv/hyperv_wmi.c | 569 src/hyperv/hyperv_wmi.h | 3 + src/hyperv/openwsman.h | 4 + 3 files changed, 576 insertions(+) diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c index 1960c4c..deea907 100644 --- a/src/hyperv/hyperv_wmi.c +++ b/src/hyperv/hyperv_wmi.c @@ -24,6 +24,7 @@ */ #include +#include #include "internal.h" #include "virerror.h" @@ -34,11 +35,14 @@ #include "hyperv_private.h" #include "hyperv_wmi.h" #include "virstring.h" +#include "openwsman.h" +#include "virlog.h" #define WS_SERIALIZER_FREE_MEM_WORKS 0 #define VIR_FROM_THIS VIR_FROM_HYPERV +VIR_LOG_INIT("hyperv.hyperv_wmi"); static int hypervGetWmiClassInfo(hypervPrivate *priv, hypervWmiClassInfoListPtr list, @@ -406,6 +410,571 @@ hypervAddEmbeddedParam(hypervInvokeParamsListPtr params, hypervPrivate *priv, } +/* + * Serializing parameters to XML and invoking methods + */ + +static int +hypervGetCimTypeInfo(hypervCimTypePtr typemap, const char *name, +hypervCimTypePtr *property) +{ +size_t i = 0; +while (typemap[i].name[0] != '\0') { +if (STREQ(typemap[i].name, name)) { +*property = [i]; +return 0; +} +i++; +} + +return -1; +} + + +static int +hypervCreateInvokeXmlDoc(hypervInvokeParamsListPtr params, WsXmlDocH *docRoot) +{ +int result = -1; +char *method = NULL; +WsXmlNodeH xmlNodeMethod = NULL; + +if (virAsprintf(, "%s_INPUT", params->method) < 0) +goto error; + +*docRoot = ws_xml_create_doc(NULL, method); +if (*docRoot == NULL) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +_("Could not instantiate XML document")); +goto error; +} + +xmlNodeMethod = xml_parser_get_root(*docRoot); +if (xmlNodeMethod == NULL) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +_("Could not get root node of XML document")); +goto error; +} + +/* add resource URI as namespace */ +ws_xml_set_ns(xmlNodeMethod, params->resourceUri, "p"); + +result = 0; +goto cleanup; + + error: +if (*docRoot != NULL) { +ws_xml_destroy_doc(*docRoot); +*docRoot = NULL; +} + cleanup: +VIR_FREE(method); +return result; +} + +static int +hypervSerializeSimpleParam(hypervParamPtr p, const char *resourceUri, +WsXmlNodeH *methodNode) +{ +int result = -1; +WsXmlNodeH xmlNodeParam = NULL; + +xmlNodeParam = ws_xml_add_child(*methodNode, resourceUri, +p->simple.name, p->simple.value); +if (xmlNodeParam == NULL) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +_("Could not create simple param")); +goto cleanup; +} + +result = 0; + + cleanup: +return result; +} + +static int +hypervSerializeEprParam(hypervParamPtr p, hypervPrivate *priv, +const char *resourceUri, WsXmlDocH doc, WsXmlNodeH *methodNode) +{ +int result = -1; +WsXmlNodeH xmlNodeParam = NULL, + xmlNodeTemp = NULL, + xmlNodeAddr = NULL, + xmlNodeRef = NULL; +xmlNodePtr xmlNodeAddrPtr = NULL, + xmlNodeRefPtr = NULL; +WsXmlDocH xmlDocResponse = NULL; +xmlDocPtr docPtr = (xmlDocPtr) doc->parserDoc; +WsXmlNsH ns = NULL; +client_opt_t *options = NULL; +filter_t *filter = NULL; +char *enumContext = NULL; +char *query_string = NULL; + +/* init and set up options */ +options = wsmc_options_init(); +if (!options) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not init options")); +goto cleanup; +} +wsmc_set_action_option(options, FLAG_ENUMERATION_ENUM_EPR); + +/* Get query and create filter based on it */ +query_string = virBufferContentAndReset(p->epr.query); +filter = filter_create_simple(WSM_WQL_FILTER_DIALECT, query_string); +if (!filter) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create WQL filter")); +goto cleanup; +} + +/* enumerate based on the filter from this query */ +xmlDocResponse = wsmc_action_enumerate(priv->client, p->epr.info->rootUri, +options, filter); +if (hypervVerifyResponse(priv->client, xmlDocResponse, "enumeration") < 0) +goto cleanup; + +/* Get context */ +enumContext = wsmc_get_enum_context(xmlDocResponse); +ws_xml_destroy_doc(xmlDocResponse); + +/* Pull using filter and enum context */ +xmlDocResponse = wsmc_action_pull(priv->client, resourceUri, options, +filter, enumContext); + +if (hypervVerifyResponse(priv->client, xmlDocResponse, "pull") < 0) +goto cleanup; + +/* drill down and extract EPR node children */ +if (!(xmlNodeTemp = ws_xml_get_soap_body(xmlDocResponse))) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s",