From nobody Wed May 15 20:36:13 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1695034548953506.3298631399432; Mon, 18 Sep 2023 03:55:48 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qiBtr-00051z-D6; Mon, 18 Sep 2023 06:54:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qiBtp-00051C-Oq for qemu-devel@nongnu.org; Mon, 18 Sep 2023 06:54:41 -0400 Received: from wout1-smtp.messagingengine.com ([64.147.123.24]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qiBtn-0000Cf-IM for qemu-devel@nongnu.org; Mon, 18 Sep 2023 06:54:41 -0400 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id 0782F3200392; Mon, 18 Sep 2023 06:54:37 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Mon, 18 Sep 2023 06:54:38 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 18 Sep 2023 06:54:35 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dxuuu.xyz; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1695034477; x= 1695120877; bh=lrwfeWhM9YciqVz2gysFObhZcZA9e3eJTJ8tXVBkz2A=; b=k uAXFcSuV47Y3owCSgE7afevoaGt8MXYRUpm+RgMqW9k0NOflP+759vcGSw5hyUZ7 6wqFm8duKiiKp9I4w+4EQQXUi2UGkHdsd8BncT9bXpfzt5MWpeh59NXhAyyAX3L3 F2OGvJkH4E93A4Ly/ttJQ+xvYENHZB7F6u1LXtbShN+wwY0yKoDaby7i+qURNCe0 J5z6MvxvkycmRNnATIebaywPPbILN2xhfdli6wYApGIceZytlVWGCtrpbLOi3j+N oUxP+LmsMPPfrud6FjKNSjkLO0wxmWFGmO4n9U33yymtd6PZS6V5uduEoBaSR/5m Mp+0QvaDOnR+RTzm+hmMA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1695034477; x= 1695120877; bh=lrwfeWhM9YciqVz2gysFObhZcZA9e3eJTJ8tXVBkz2A=; b=d 1NdIEv0NL5HxJbpCSGOfBMpcLQuJvrhftA6G/c8z5rr5vN8sTW0V2/FGI2tbdOyO NR8y//ILIHiFLFVD5hjQA9dwEGemkGLwqqBFC1A2GinVhPU49wYEioqwt1gGOKlA iryn8RRj6UdDtf+h9/FeLbEq+FghzaCLxNPe7ptPEJsnlTq6kpYnqLaxG6/MXGwF i1yEnya9cNYjNqogjM6DNA7wY1d7IdJZTUhls3HP7NwH9//V6I6ZSPK8uhXzUZFz yMSIoI+Cvs7rxY0MHkYQRBPXNkUxYG8JaIbAEkpdQswqajoX4xH5eHoWwKnbHJjN FgLAnVJULMHoP1KaytivA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedviedrudejkedgfeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucgfrhhlucfvnfffucdljedtmdenucfjughrpefhvf evufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpeffrghnihgvlhcuighuuceo ugiguhesugiguhhuuhdrgiihiieqnecuggftrfgrthhtvghrnhepgfefgfegjefhudeike dvueetffelieefuedvhfehjeeljeejkefgffeghfdttdetnecuvehluhhsthgvrhfuihii vgeptdenucfrrghrrghmpehmrghilhhfrhhomhepugiguhesugiguhhuuhdrgiihii X-ME-Proxy: Feedback-ID: i6a694271:Fastmail From: Daniel Xu To: kkostiuk@redhat.com, michael.roth@amd.com, berrange@redhat.com Cc: qemu-devel@nongnu.org, hmodi@aviatrix.com Subject: [PATCH 1/3] qga: Fix memory leak when output stream is unused Date: Mon, 18 Sep 2023 04:54:21 -0600 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=64.147.123.24; envelope-from=dxu@dxuuu.xyz; helo=wout1-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1695034550579100001 Content-Type: text/plain; charset="utf-8" If capture-output is requested but one of the channels goes unused (eg. we attempt to capture stderr but the command never writes to stderr), we can leak memory. guest_exec_output_watch() is (from what I understand) unconditionally called for both streams if output capture is requested. The first call will always pass the `p->size =3D=3D p->length` check b/c both values are 0. Then GUEST_EXEC_IO_SIZE bytes will be allocated for the stream. But when we reap the exited process there's a `gei->err.length > 0` check to actually free the buffer. Which does not get run if the command doesn't write to the stream. Fix by making free() unconditional. Signed-off-by: Daniel Xu --- qga/commands.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qga/commands.c b/qga/commands.c index 09c683e263..ce172edd2d 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -206,15 +206,15 @@ GuestExecStatus *qmp_guest_exec_status(int64_t pid, E= rror **errp) #endif if (gei->out.length > 0) { ges->out_data =3D g_base64_encode(gei->out.data, gei->out.leng= th); - g_free(gei->out.data); ges->has_out_truncated =3D gei->out.truncated; } + g_free(gei->out.data); =20 if (gei->err.length > 0) { ges->err_data =3D g_base64_encode(gei->err.data, gei->err.leng= th); - g_free(gei->err.data); ges->has_err_truncated =3D gei->err.truncated; } + g_free(gei->err.data); =20 QTAILQ_REMOVE(&guest_exec_state.processes, gei, next); g_free(gei); --=20 2.41.0 From nobody Wed May 15 20:36:13 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1695034531333218.59077360095353; Mon, 18 Sep 2023 03:55:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qiBtv-00052a-0h; Mon, 18 Sep 2023 06:54:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qiBts-000529-BQ for qemu-devel@nongnu.org; Mon, 18 Sep 2023 06:54:44 -0400 Received: from wout1-smtp.messagingengine.com ([64.147.123.24]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qiBtq-0000E9-Mv for qemu-devel@nongnu.org; Mon, 18 Sep 2023 06:54:44 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.west.internal (Postfix) with ESMTP id 226E03200919; Mon, 18 Sep 2023 06:54:41 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 18 Sep 2023 06:54:41 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 18 Sep 2023 06:54:38 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dxuuu.xyz; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1695034480; x= 1695120880; bh=VJ9GASl+fhQZvEW6RQqJ8ZOMhK5Q04EI7LzWsMFMn+Q=; b=e cxmr0z6OS9EU6pZfBvlyqO6oVD9Wktq2CCoMoX7tyYIsbzQa5cnqtKK3zdVQkoq3 aJ5F48GqEA/9vYrnOcEy6A6qu2wFjN54CbqJQHUWc1N3BDCZmNdKqILOq1F0/vi1 BJYUlSqcBRnzTP7z1gbIxuevFKVa2iBp0FUlRvVc0aM1B2a/pNkk8iTCJiP0Cpc8 jO/5CfvAmRH+hmcjwCsmQ1bVnlfhneGjcrFCMjl6wzBlKV35HmNjeHEgsR5sTN1R YLBJG7kkv1Ra7TzH1hkR/4s/jE/sBJpKun+y+ahr+nwQqYC+iAc9IK/Pwk2g3f37 m9Fa4ZikanrS7cGWe1Tpg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1695034480; x= 1695120880; bh=VJ9GASl+fhQZvEW6RQqJ8ZOMhK5Q04EI7LzWsMFMn+Q=; b=A h7N/HsosM2TKekJ0OaDQnAhhrd2gH5domWIRR2zF9vGsGxO4cgLt9T8bKkEUc6sY kyhyekjI2F8h78tcTqhC9CJM6GcTj9AQXq4lAMtK2hPp+EtsvQ+fdDeRkeps+uqw ikqy8LTOhdvVpCiX8ZXvd20v5nr1yU0OfaMrpfbb6iWGZiniGKNmSEDBLFNStXxY LcI2t2tiYyLpoFnu5xbuOmXeQCcL+qX9x5E+jjE1q4/56PFkNIv1k3F7qEeCYdLd 6FR6RI0qMRN/TuFSVPsnEtRkjPrA9UETTZUB5/J9jwku7KkX6FfjEdczyedcH1kr DCjlyX8vP9v17znRDCCmA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedviedrudejkedgfeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucgfrhhlucfvnfffucdljedtmdenucfjughrpefhvf evufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpeffrghnihgvlhcuighuuceo ugiguhesugiguhhuuhdrgiihiieqnecuggftrfgrthhtvghrnhepgfefgfegjefhudeike dvueetffelieefuedvhfehjeeljeejkefgffeghfdttdetnecuvehluhhsthgvrhfuihii vgeptdenucfrrghrrghmpehmrghilhhfrhhomhepugiguhesugiguhhuuhdrgiihii X-ME-Proxy: Feedback-ID: i6a694271:Fastmail From: Daniel Xu To: kkostiuk@redhat.com, michael.roth@amd.com, berrange@redhat.com Cc: qemu-devel@nongnu.org, hmodi@aviatrix.com Subject: [PATCH 2/3] qga: Add optional stream-output argument to guest-exec Date: Mon, 18 Sep 2023 04:54:22 -0600 Message-ID: <604ef5fd5bda8acdb837b5d28ec405e9fb0332a3.1695034158.git.dxu@dxuuu.xyz> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=64.147.123.24; envelope-from=dxu@dxuuu.xyz; helo=wout1-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1695034532918100001 Content-Type: text/plain; charset="utf-8" Currently, commands run through guest-exec are "silent" until they finish running. This is fine for short lived commands. But for commands that take a while, this is a bad user experience. Usually long running programs know that they will run for a while. To improve user experience, they will typically print some kind of status to output at a regular interval. So that the user knows that their command isn't just hanging. This commit adds support for an optional stream-output parameter to guest-exec. This causes subsequent calls to guest-exec-status to return all buffered output. This allows downstream applications to be able to relay "status" to the end user. If stream-output is requested, it is up to the guest-exec-status caller to keep track of the last seen output position and slice the returned output appropriately. This is fairly trivial for a client to do. And it is a more reliable design than having QGA internally keep track of position -- for the cases that the caller "loses" a response. Signed-off-by: Daniel Xu --- qga/commands.c | 12 ++++++++++++ qga/qapi-schema.json | 7 ++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/qga/commands.c b/qga/commands.c index ce172edd2d..8cabc2460f 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -97,6 +97,7 @@ struct GuestExecInfo { int64_t pid_numeric; gint status; bool has_output; + bool stream_output; bool finished; GuestExecIOData in; GuestExecIOData out; @@ -218,6 +219,15 @@ GuestExecStatus *qmp_guest_exec_status(int64_t pid, Er= ror **errp) =20 QTAILQ_REMOVE(&guest_exec_state.processes, gei, next); g_free(gei); + } else if (gei->stream_output) { + if (gei->out.length > 0) { + ges->out_data =3D g_base64_encode(gei->out.data, gei->out.leng= th); + ges->has_out_truncated =3D gei->out.truncated; + } + if (gei->err.length > 0) { + ges->err_data =3D g_base64_encode(gei->err.data, gei->err.leng= th); + ges->has_err_truncated =3D gei->err.truncated; + } } =20 return ges; @@ -410,6 +420,7 @@ GuestExec *qmp_guest_exec(const char *path, bool has_env, strList *env, const char *input_data, GuestExecCaptureOutput *capture_output, + bool has_stream_output, bool stream_output, Error **errp) { GPid pid; @@ -485,6 +496,7 @@ GuestExec *qmp_guest_exec(const char *path, =20 gei =3D guest_exec_info_add(pid); gei->has_output =3D has_output; + gei->stream_output =3D has_stream_output && stream_output; g_child_watch_add(pid, guest_exec_child_watch, gei); =20 if (input_data) { diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index b720dd4379..0a76e35082 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -1315,13 +1315,18 @@ # @capture-output: bool flag to enable capture of stdout/stderr of # running process. defaults to false. # +# @stream-output: causes future guest-exec-status calls to always +# return current captured output rather than waiting to return +# it all when the command exits. defaults to false. (since: 8.2) +# # Returns: PID on success. # # Since: 2.5 ## { 'command': 'guest-exec', 'data': { 'path': 'str', '*arg': ['str'], '*env': ['str'], - '*input-data': 'str', '*capture-output': 'GuestExecCaptureO= utput' }, + '*input-data': 'str', '*capture-output': 'GuestExecCaptureO= utput', + '*stream-output': 'bool' }, 'returns': 'GuestExec' } =20 =20 --=20 2.41.0 From nobody Wed May 15 20:36:13 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1695034522324992.510007977373; Mon, 18 Sep 2023 03:55:22 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qiBty-00053n-2V; Mon, 18 Sep 2023 06:54:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qiBtv-00052v-SC for qemu-devel@nongnu.org; Mon, 18 Sep 2023 06:54:47 -0400 Received: from wout1-smtp.messagingengine.com ([64.147.123.24]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qiBtu-0000Hb-5e for qemu-devel@nongnu.org; Mon, 18 Sep 2023 06:54:47 -0400 Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.west.internal (Postfix) with ESMTP id 8BA3B3200927; Mon, 18 Sep 2023 06:54:44 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 18 Sep 2023 06:54:45 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 18 Sep 2023 06:54:41 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dxuuu.xyz; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1695034484; x= 1695120884; bh=/ReuUamhZrjRKCw+iB41h+4VD72/iNv6vEVay7pP8Oc=; b=W HpCh6d3vddZEzMJUzlZ90U9MteEH/ZFGIlYfEuuF+H9/tw4/ryoM7onqRjKZ4Xy2 cRnWd6Wn9693fRkkviGjTsxxt9xUtw3vwmeohG9+x23y8Y5EpHSj5MS7C/GoqJJ6 qUOJh5dLAadn1JYWzhLUrHlngAB3dti+hSohmPCFRK+q4eAwWXDq4eXk5B+WdMT5 b3JozW7PBwACfz5PblWGEhCQGFS5rtApcS8yoK/XanefEiEFtNQx3oMPnKIeYoNC 4n8NJ240DUXvLMzaQtr1AGXreFk482YiOMs9E5xBZkTn6u/zMi21Z2KIioGTk9Ru dvuSbPQVYlXHZrv9QnnUQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1695034484; x= 1695120884; bh=/ReuUamhZrjRKCw+iB41h+4VD72/iNv6vEVay7pP8Oc=; b=k Pb40ns2qwaC3YDTVbwqNRF3zYu9aW2BOphdxPQ/vOVPclz5UuGm0n8+F7kKRT3jq CwEV2WRvZkHs6X8EZOdUE5Db3odzRSHwrlrgVpmZmpnrkmDzhAnuOnwiwD9HoEJ1 Bx3KiGOhpZVy3pe2wR57f4w85m8Ek1PFtRWsXKQgBGRxL4Alwbxy9R8rZLGTyBpW 3bo2U5PMqctCGE/FZawXf13wg3pxJkP85ifTjZFJxk29qw+1Vl7PO9Za7NQC51Qt lJ3X2N1kaivzQJktKSZaLkACi5Ouh+LZHS+TelgwtObZ+IESsqN1hgiyWFSDnOt3 DCq5NHKRCMo97l8V8f33A== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedviedrudejkedgfedvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucgfrhhlucfvnfffucdljedtmdenucfjughrpefhvf evufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpeffrghnihgvlhcuighuuceo ugiguhesugiguhhuuhdrgiihiieqnecuggftrfgrthhtvghrnhepgfefgfegjefhudeike dvueetffelieefuedvhfehjeeljeejkefgffeghfdttdetnecuvehluhhsthgvrhfuihii vgeptdenucfrrghrrghmpehmrghilhhfrhhomhepugiguhesugiguhhuuhdrgiihii X-ME-Proxy: Feedback-ID: i6a694271:Fastmail From: Daniel Xu To: kkostiuk@redhat.com, michael.roth@amd.com, berrange@redhat.com Cc: qemu-devel@nongnu.org, hmodi@aviatrix.com Subject: [PATCH 3/3] qga: test: Add test for guest-exec stream-output Date: Mon, 18 Sep 2023 04:54:23 -0600 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=64.147.123.24; envelope-from=dxu@dxuuu.xyz; helo=wout1-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1695034523338100003 Content-Type: text/plain; charset="utf-8" Add a test that simulates a long running process (by using a named pipe to synchronize). This test ensures that full output is returned with each call to guest-exec-status. Signed-off-by: Daniel Xu --- tests/unit/test-qga.c | 77 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/tests/unit/test-qga.c b/tests/unit/test-qga.c index 671e83cb86..455183e60b 100644 --- a/tests/unit/test-qga.c +++ b/tests/unit/test-qga.c @@ -952,6 +952,81 @@ static void test_qga_guest_exec_merged(gconstpointer f= ix) } #endif =20 +#if defined(G_OS_WIN32) +static void test_qga_guest_exec_stream(gconstpointer fix) +{ +} +#else +static void test_qga_guest_exec_stream(gconstpointer fix) +{ + const TestFixture *fixture =3D fix; + g_autoptr(QDict) ret =3D NULL; + g_autofree char *fifo_path =3D NULL; + g_autofree char *cmd =3D NULL; + QDict *val; + const gchar *out; + g_autofree guchar *decoded =3D NULL; + int64_t pid, exitcode; + bool exited; + gsize len; + int fifo; + + fifo_path =3D g_strdup_printf("%s/fifo", fixture->test_dir); + g_assert_cmpint(mkfifo(fifo_path, 0644), =3D=3D, 0); + + /* Echo two lines with a fifo barrier in between */ + cmd =3D g_strdup_printf("echo line1; cat %s; echo line2;", fifo_path); + ret =3D qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" + " 'path': '/bin/bash'," + " 'arg': [ '-c', %s ]," + " 'capture-output': 'stdout'," + " 'stream-output': true } }", + cmd); + g_assert_nonnull(ret); + qmp_assert_no_error(ret); + val =3D qdict_get_qdict(ret, "return"); + pid =3D qdict_get_int(val, "pid"); + g_assert_cmpint(pid, >, 0); + qobject_unref(ret); + + /* Give bash some time to run */ + usleep(G_USEC_PER_SEC / 20); + + /* Check first line comes out */ + ret =3D qmp_fd(fixture->fd, + "{'execute': 'guest-exec-status'," + " 'arguments': { 'pid': %" PRId64 " } }", pid); + g_assert_nonnull(ret); + val =3D qdict_get_qdict(ret, "return"); + exited =3D qdict_get_bool(val, "exited"); + g_assert_false(exited); + out =3D qdict_get_str(val, "out-data"); + decoded =3D g_base64_decode(out, &len); + g_assert_cmpint(len, =3D=3D, 6); + g_assert_cmpstr((char *)decoded, =3D=3D, "line1\n"); + g_free(decoded); + qobject_unref(ret); + + /* Trigger second line */ + fifo =3D open(fifo_path, O_WRONLY); + g_assert_cmpint(fifo, >=3D, 0); + close(fifo); + ret =3D wait_for_guest_exec_completion(fixture->fd, pid); + + /* Check second line comes out after process exits */ + val =3D qdict_get_qdict(ret, "return"); + exited =3D qdict_get_bool(val, "exited"); + g_assert_true(exited); + exitcode =3D qdict_get_int(val, "exitcode"); + g_assert_cmpint(exitcode, =3D=3D, 0); + out =3D qdict_get_str(val, "out-data"); + decoded =3D g_base64_decode(out, &len); + g_assert_cmpint(len, =3D=3D, 12); + g_assert_cmpstr((char *)decoded, =3D=3D, "line1\nline2\n"); + g_assert_cmpint(unlink(fifo_path), =3D=3D, 0); +} +#endif + static void test_qga_guest_exec_invalid(gconstpointer fix) { const TestFixture *fixture =3D fix; @@ -1127,6 +1202,8 @@ int main(int argc, char **argv) test_qga_guest_exec_separated); g_test_add_data_func("/qga/guest-exec-merged", &fix, test_qga_guest_exec_merged); + g_test_add_data_func("/qga/guest-exec-stream", &fix, + test_qga_guest_exec_stream); g_test_add_data_func("/qga/guest-exec-invalid", &fix, test_qga_guest_exec_invalid); g_test_add_data_func("/qga/guest-get-osinfo", &fix, --=20 2.41.0