From nobody Sun Apr 5 18:02:07 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1774380029; cv=none; d=zohomail.com; s=zohoarc; b=ia/ktepB90x8t9LV4W/ZDckRVe2+ZVX52tPhsMJRJ6fijbXijENx7lYtiiDKH71MnVrJSplhuGPvhuE2MUUXkZtSQLY0+/lXH9MIuU3e5uCn5RT9xawf1swj5E/sCgl4mghOD3nBQQlpzNHn4jlTsajKV6t/+53HE1uzZ4l+CMY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774380029; h=Content-Type:Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id:Cc; bh=1tomSzMOFEXZEcpOPGCUEpua1y6Qrre24bLde6X0kW8=; b=iU2Pc3iAHiCfmQTGxjHfMczLkjPM48DUSWNvc0F7C+FxiZa/8n71RoBEwz1X58k9CygjemU7Z8rVFtMpggkFMCs8Or1Wb+uGBMRjIv+vH/d+j7FIwb08aENSM6/1wwCzc2Eux+Ul73s3Cy5uqLicZkXbmGxKPPj1GHkqq1GqP50= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1774380029700141.145936420496; Tue, 24 Mar 2026 12:20:29 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id F380B3F8A1; Tue, 24 Mar 2026 15:20:28 -0400 (EDT) Received: from [172.19.199.12] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id 1B3CB4198A; Tue, 24 Mar 2026 15:17:54 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id DEDCF3F359; Tue, 24 Mar 2026 15:17:32 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id EFEF73F27C for ; Tue, 24 Mar 2026 15:17:31 -0400 (EDT) Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-593-Csm3a6dVNjiVY6U2AkLdYg-1; Tue, 24 Mar 2026 15:17:29 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3E437195609E for ; Tue, 24 Mar 2026 19:17:28 +0000 (UTC) Received: from himantopus.redhat.com (unknown [10.22.89.231]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CE2B319560B1 for ; Tue, 24 Mar 2026 19:17:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HELO_MISC_IP,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_SBL_CSS,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1774379851; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1tomSzMOFEXZEcpOPGCUEpua1y6Qrre24bLde6X0kW8=; b=QcmZmHTkFZQDapB6X+vSie6nn4asJNwOftKuldvjm99tmoX7pGOqcGZjFOyt8WRvICbixO npsct97i5GYonGEhpqM+Y5Y5UhJRKI/W7Z/cABFGSC48Ln3f2FBA7iel48JAsHU8BRXFty tRW8WnaoIMkLUB3pnsQrR3U8BZtdf3Q= X-MC-Unique: Csm3a6dVNjiVY6U2AkLdYg-1 X-Mimecast-MFC-AGG-ID: Csm3a6dVNjiVY6U2AkLdYg_1774379848 To: devel@lists.libvirt.org Subject: [PATCH v2 3/4] hyperv: Add a utility function for getting method output params Date: Tue, 24 Mar 2026 14:17:23 -0500 Message-ID: <20260324191724.2628460-4-jjongsma@redhat.com> In-Reply-To: <20260324191724.2628460-1-jjongsma@redhat.com> References: <20260324191724.2628460-1-jjongsma@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: CheQyCOvu305M1nmjGGFxrMjHFIspMWhvv_0h7EnSW0_1774379848 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: KXJ6TSXLGTYEQP7NZHBXEPQE3Z3CQD6E X-Message-ID-Hash: KXJ6TSXLGTYEQP7NZHBXEPQE3Z3CQD6E X-MailFrom: jjongsma@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Jonathon Jongsma via Devel Reply-To: Jonathon Jongsma X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1774380032932154100 Content-Type: text/plain; charset="utf-8"; x-default="true" When invoking a method in WMI, it can either return synchronously or asynchronously (with return value 4096). In the latter case, the output parameters of the method are not present in the method response xml document. We have to fetch the output parameters via associations with the Job object that is returned in the method response. the hypervInvokeMethod() function already partially handles the async case by polling the job until it fails, completes successfully, or times out. This patch adds a utility function to fetch a named output parameter from a given method response xml document. It handles both synchronous and asynchronous cases. Signed-off-by: Jonathon Jongsma --- src/hyperv/hyperv_wmi.c | 139 ++++++++++++++++++++++++++++++++++++++++ src/hyperv/hyperv_wmi.h | 6 ++ 2 files changed, 145 insertions(+) diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c index 3e161429d5..1329d03262 100644 --- a/src/hyperv/hyperv_wmi.c +++ b/src/hyperv/hyperv_wmi.c @@ -866,6 +866,145 @@ hypervInvokeMethod(hypervPrivate *priv, return 0; } =20 +static char* +hypervOutputParamReferenceId(WsXmlNodeH node) +{ + WsXmlNodeH selector_set =3D NULL; + WsXmlNodeH selector =3D NULL; + int i =3D 0; + + if (node) + selector_set =3D ws_xml_find_in_tree(node, XML_NS_WS_MAN, "Selecto= rSet", TRUE); + + if (selector_set) { + for (i =3D 0; (selector =3D ws_xml_get_child(selector_set, i, XML_= NS_WS_MAN, "Selector")) !=3D NULL; i++) { + if (STREQ_NULLABLE(ws_xml_find_attr_value(selector, NULL, "Nam= e"), "InstanceID")) { + return ws_xml_get_node_text(selector); + } + } + } + return NULL; +} + + +/* + * hypervResponseGetOutputParam() + * + * Extracts an output parameter from a WMI method response and retrieves t= he + * referenced object. + * + * Handles both synchronous and asynchronous cases. When a method is + * synchronous, the parameter will be directly present in the response doc= ument. + * When the method returns asynchronously, we need to fetch the result par= ameter + * via its associations with the Msvm_ConcreteJob object referenced in the + * response document. + * + * Parameters: + * @priv: hypervPrivate object associated with the connection + * response: The WMI method response document + * paramName: The output parameter name (e.g., "ResultingSnapshot") + * paramClass: The WMI class info for the expected result type + * outParam: return location for the named output parameter + * + * Returns 0 on success, -1 on failure. + */ +int +hypervResponseGetOutputParam(hypervPrivate *priv, + WsXmlDocH response, + const char *paramName, + hypervWmiClassInfo *paramClassInfo, + hypervObject **outParam) +{ + g_auto(virBuffer) query =3D VIR_BUFFER_INITIALIZER; + WsXmlNodeH body =3D NULL; + WsXmlNodeH output_node =3D NULL; + char *output_name =3D NULL; + char *provider_ns =3D NULL; + const char *rv_str =3D NULL; + int return_code; + int i =3D 0; + + body =3D ws_xml_get_soap_body(response); + if (!body) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not find SOAP Body in response")); + return -1; + } + + /* Find the $(METHOD)_OUTPUT node in the SOAP Body */ + for (i =3D 0; (output_node =3D ws_xml_get_child(body, i, NULL, NULL)) = !=3D NULL; i++) { + output_name =3D ws_xml_get_node_local_name(output_node); + if (output_name && g_str_has_suffix(output_name, "_OUTPUT")) + break; + output_node =3D NULL; + } + + if (!output_node) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not find _OUTPUT node in method response")= ); + return -1; + } + + provider_ns =3D ws_xml_get_node_name_ns(output_node); + + rv_str =3D ws_xml_get_node_text(ws_xml_get_child(output_node, 0, provi= der_ns, "ReturnValue")); + if (!rv_str || virStrToLong_i(rv_str, NULL, 10, &return_code) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not get ReturnValue from method response")= ); + return -1; + } + + if (return_code =3D=3D CIM_RETURNCODE_COMPLETED_WITH_NO_ERROR) { + /* if this was a synchronous response, the output parameter should= contain + * the id of an object, so we can simply look it up by its instanc= e ID */ + WsXmlNodeH param_node =3D ws_xml_get_child(output_node, 0, provide= r_ns, paramName); + const char *out_param_id =3D NULL; + + if (param_node) + out_param_id =3D hypervOutputParamReferenceId(param_node); + + if (!out_param_id) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not find output parameter '%1$s' in re= sponse"), + paramName); + return -1; + } + VIR_DEBUG("Method response was synchronous: %1$s =3D %2$s", paramN= ame, out_param_id); + virBufferAsprintf(&query, "SELECT * FROM %s ", paramClassInfo->nam= e); + virBufferEscapeSQL(&query, "WHERE InstanceID=3D'%s'", out_param_id= ); + } else if (return_code =3D=3D CIM_RETURNCODE_TRANSITION_STARTED) { + /* if this was an asynchronous response, we have to get the output + * parameter from its association with the async job */ + WsXmlNodeH job_node =3D ws_xml_get_child(output_node, 0, provider_= ns, "Job"); + const char *job_id =3D NULL; + + if (job_node) + job_id =3D hypervOutputParamReferenceId(job_node); + + if (!job_id) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not find Job ID in async method respon= se")); + return -1; + } + VIR_DEBUG("Method response was asynchronous. Job ID =3D %1$s", job= _id); + virBufferEscapeSQL(&query, + "ASSOCIATORS OF {Msvm_ConcreteJob.InstanceID=3D'%s'} ", + job_id); + virBufferAsprintf(&query, + "WHERE AssocClass =3D Msvm_AffectedJobElement " + "ResultClass =3D %s", + paramClassInfo->name); + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unexpected return code %1$d in method response"), + return_code); + return -1; + } + + hypervGetWmiClassList(priv, paramClassInfo, &query, outParam); + return 0; +} + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *= * * * Object */ diff --git a/src/hyperv/hyperv_wmi.h b/src/hyperv/hyperv_wmi.h index 0560f83e0d..36ca85a592 100644 --- a/src/hyperv/hyperv_wmi.h +++ b/src/hyperv/hyperv_wmi.h @@ -166,6 +166,12 @@ int hypervInvokeMethod(hypervPrivate *priv, hypervInvokeParamsList **paramsPtr, WsXmlDocH *res); =20 +int hypervResponseGetOutputParam(hypervPrivate *priv, + WsXmlDocH response, + const char *paramName, + hypervWmiClassInfo *paramClassInfo, + hypervObject **outParam); + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *= * * * CIM/Msvm_ReturnCode */ --=20 2.53.0