From nobody Sun May 19 20:47:35 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 1678401745789278.06952338966437; Thu, 9 Mar 2023 14:42:25 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1paOwl-0002ae-F1; Thu, 09 Mar 2023 17:41:15 -0500 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 1paOwi-0002ZN-Dt for qemu-devel@nongnu.org; Thu, 09 Mar 2023 17:41:12 -0500 Received: from out1-smtp.messagingengine.com ([66.111.4.25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1paOwe-0003ms-Iw for qemu-devel@nongnu.org; Thu, 09 Mar 2023 17:41:12 -0500 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id 17D355C019C; Thu, 9 Mar 2023 17:41:08 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Thu, 09 Mar 2023 17:41:08 -0500 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 9 Mar 2023 17:41:07 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dxuuu.xyz; h=cc :cc:content-transfer-encoding:content-type: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=fm3; t= 1678401668; x=1678488068; bh=911bRxRHfZhJbhh0SFAD0XuN3d4jdEvPV0L FIHE2YVc=; b=oW01ICI8YO2wwJOGsq0fE1C/tt/HR4G4ZmG/iddexJmGItpYALF LokIuNJSE0096sVEucUgg2EzHVWsEII21vyR6i9nBAGHEBEfdihHJ5o/qHMQoSqI WtXxd3cV7j41uP4aHmHxxrlTD07UvkUnB2wN+Hs35kvJuEgP00ezYCUcB7BnaUKi MLZgO1PObnENtiPgw4WuctXwPPZJyqB0qIbd+I6FYqTOzdOf2V4E1+mZ4gnUFA4y Q/P9D84pg+TVCa5VXxOqD6SL3Nseld+BMJAKsbafBz4E5ie56u5bg+jRE8TXOv/W zGMfO8gR4Zk0Up1Uw+TgN/yraYca3cqbTsw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type: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=fm1; t= 1678401668; x=1678488068; bh=911bRxRHfZhJbhh0SFAD0XuN3d4jdEvPV0L FIHE2YVc=; b=SzIPkT5g8ZkCyhZPvptfPVMFLH44kAIpm9NrE0N7SO5esXSlE17 w7qYXVXOA0gFxCh+bUqwaufxsTwjPqb8yocfme574IWdrn4Bs7XPRLq165AjuHA4 /02HU5cJgpCn3GG919nJKJtQUCjlM7Aa4DlLnmiDG1FGo0G2/49Uq5fSsudA+dxi qUsR5cmdzOI4DyEWQNQQ8Ss+v5jgeJ+92rrssZqSXxZzdZlAPRcvC48CyAco3K4B aXibJSAbKhAuoqB0wKh6YLhVk1oCd4JMGDEtsDY8GjDZTc+FlMfmUTO/vJMo2+hr 5E8y7pe8Nwtro0k1K6Ba88UQ1qmR52WmWBQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrvdduiedgudeitdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecufghrlhcuvffnffculdefhedmnecujfgurhephf fvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeffrghnihgvlhcuighu uceougiguhesugiguhhuuhdrgiihiieqnecuggftrfgrthhtvghrnhepteehkeekgffgie evvdetgfeliefftdelgeefueelvddutddvudfhkefguddtveeknecuvehluhhsthgvrhfu ihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepugiguhesugiguhhuuhdrgiihii X-ME-Proxy: Feedback-ID: i6a694271:Fastmail From: Daniel Xu To: michael.roth@amd.com, kkostiuk@redhat.com, marcandre.lureau@gmail.com, berrange@redhat.com Cc: qemu-devel@nongnu.org Subject: [PATCH v5 1/3] qga: Refactor guest-exec capture-output to take enum Date: Thu, 9 Mar 2023 15:40:56 -0700 Message-Id: <23a0e6273bb21895b0937f60c03c2e3ffdb83d67.1678401400.git.dxu@dxuuu.xyz> X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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=66.111.4.25; envelope-from=dxu@dxuuu.xyz; helo=out1-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, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, 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: 1678401747795100007 Previously capture-output was an optional boolean flag that either captured all output or captured none. While this is OK in most cases, it lacks flexibility for more advanced capture cases, such as wanting to only capture stdout. This commits refactors guest-exec qapi to take an enum for capture mode instead while preserving backwards compatibility. Suggested-by: Daniel P. Berrang=C3=A9 Signed-off-by: Daniel Xu Reviewed-by: Daniel P. Berrang=C3=A9 --- qga/commands.c | 37 ++++++++++++++++++++++++++++++++++--- qga/qapi-schema.json | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/qga/commands.c b/qga/commands.c index 172826f8f8..01f68b45ab 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -379,11 +379,23 @@ close: return false; } =20 +static GuestExecCaptureOutputMode ga_parse_capture_output( + GuestExecCaptureOutput *capture_output) +{ + if (!capture_output) + return GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE; + else if (capture_output->type =3D=3D QTYPE_QBOOL) + return capture_output->u.flag ? GUEST_EXEC_CAPTURE_OUTPUT_MODE_SEP= ARATED + : GUEST_EXEC_CAPTURE_OUTPUT_MODE_NON= E; + else + return capture_output->u.mode; +} + GuestExec *qmp_guest_exec(const char *path, bool has_arg, strList *arg, bool has_env, strList *env, const char *input_data, - bool has_capture_output, bool capture_output, + GuestExecCaptureOutput *capture_output, Error **errp) { GPid pid; @@ -396,7 +408,8 @@ GuestExec *qmp_guest_exec(const char *path, gint in_fd, out_fd, err_fd; GIOChannel *in_ch, *out_ch, *err_ch; GSpawnFlags flags; - bool has_output =3D (has_capture_output && capture_output); + bool has_output =3D false; + GuestExecCaptureOutputMode output_mode; g_autofree uint8_t *input =3D NULL; size_t ninput =3D 0; =20 @@ -415,8 +428,26 @@ GuestExec *qmp_guest_exec(const char *path, =20 flags =3D G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH_FROM_ENVP; - if (!has_output) { + + output_mode =3D ga_parse_capture_output(capture_output); + switch (output_mode) { + case GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE: flags |=3D G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL; + break; + case GUEST_EXEC_CAPTURE_OUTPUT_MODE_STDOUT: + has_output =3D true; + flags |=3D G_SPAWN_STDERR_TO_DEV_NULL; + break; + case GUEST_EXEC_CAPTURE_OUTPUT_MODE_STDERR: + has_output =3D true; + flags |=3D G_SPAWN_STDOUT_TO_DEV_NULL; + break; + case GUEST_EXEC_CAPTURE_OUTPUT_MODE_SEPARATED: + has_output =3D true; + break; + case GUEST_EXEC_CAPTURE_OUTPUT_MODE__MAX: + /* Silence warning; impossible branch */ + break; } =20 ret =3D g_spawn_async_with_pipes(NULL, argv, envp, flags, diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index 796434ed34..d1e00a4234 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -1200,6 +1200,37 @@ { 'struct': 'GuestExec', 'data': { 'pid': 'int'} } =20 +## +# @GuestExecCaptureOutputMode: +# +# An enumeration of guest-exec capture modes. +# +# @none: do not capture any output +# @stdout: only capture stdout +# @stderr: only capture stderr +# @separated: capture both stdout and stderr, but separated into +# GuestExecStatus out-data and err-data, respectively +# +# Since: 8.0 +## + { 'enum': 'GuestExecCaptureOutputMode', + 'data': [ 'none', 'stdout', 'stderr', 'separated' ] } + +## +# @GuestExecCaptureOutput: +# +# Controls what guest-exec output gets captures. +# +# @flag: captures both stdout and stderr if true. Equivalent +# to GuestExecCaptureOutputMode::all. (since 2.5) +# @mode: capture mode; preferred interface +# +# Since: 8.0 +## + { 'alternate': 'GuestExecCaptureOutput', + 'data': { 'flag': 'bool', + 'mode': 'GuestExecCaptureOutputMode'} } + ## # @guest-exec: # @@ -1218,7 +1249,7 @@ ## { 'command': 'guest-exec', 'data': { 'path': 'str', '*arg': ['str'], '*env': ['str'], - '*input-data': 'str', '*capture-output': 'bool' }, + '*input-data': 'str', '*capture-output': 'GuestExecCaptureO= utput' }, 'returns': 'GuestExec' } =20 =20 --=20 2.39.1 From nobody Sun May 19 20:47:35 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 1678401744539527.2640591161858; Thu, 9 Mar 2023 14:42:24 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1paOwj-0002a2-Mx; Thu, 09 Mar 2023 17:41:13 -0500 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 1paOwi-0002ZO-Ay for qemu-devel@nongnu.org; Thu, 09 Mar 2023 17:41:12 -0500 Received: from out1-smtp.messagingengine.com ([66.111.4.25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1paOwf-0003my-EK for qemu-devel@nongnu.org; Thu, 09 Mar 2023 17:41:12 -0500 Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id DE9FC5C019D; Thu, 9 Mar 2023 17:41:08 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute1.internal (MEProxy); Thu, 09 Mar 2023 17:41:08 -0500 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 9 Mar 2023 17:41:08 -0500 (EST) 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=fm3; t=1678401668; x= 1678488068; bh=MCTKejwprUp8X263Wn8YvjYNgYFizbZ1OawyvOFQw7w=; b=g H7i1zuNKLilJ01A8tKxuCvsIBImlGMNn4iR59skrQhNo5kWDm+wrNm4dK/VECRAm Twgq5WEkLSVxNaiocmQeCX0Gg/pHjTKXwrmQ/RfUWwTD1GlwBT7VPVA8C+MRFU+j /uysA0ZK6ODU/lWI4ZIS9h6M+qDtC/3qiNK/tTDlcb5BBuaTg/aCEn3zjYzMnoA4 BaisN3LOsBtyELkIwCtVYs/WE1dLT1ysFJjDPOhi2HK0tOanGwmqrhBAUcAkRKP3 d8DCBbp/n0KhhPGpTJWUice9tFyNhV8aCQqv/M6IMb3j6SxVgck9VB6KZx2uYrJ3 L5C3+1geU9YOrzy6NwUxQ== 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=fm1; t=1678401668; x= 1678488068; bh=MCTKejwprUp8X263Wn8YvjYNgYFizbZ1OawyvOFQw7w=; b=n HFCH4g0FawXydy0BW0ljmV4UBrbSeNRpxxyz2dI1N8njvrya03xAioHzZmdDp37Q Q/G9m8Rvqdd8xZsc8+cqfYPo5LlPRLosyJ5o7h3I9WemLlcMFSPn4j1C44m1P8uA /dj+1QZW2G4OL3AQM32s6ZFJh3XBOqTNPLwneC2MYG5A//cPVIs514p8U+rfxHUp q088kHVhYTjdQL4cJMNiDyxkmKVAIAHRUkOgEAJ5pA6FcYzzS4qnvalamAadVFAS RXHaZCRqBpLxObfmCghpLPbT3PNcCBDGwcuyBQn6ko2BQs4THL06vMvy40ED2hHr tNyxllvyiDbcW7++zf9DA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrvddujedgtdduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucgfrhhlucfvnfffucdljedtmdenucfjughrpefhvf evufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpeffrghnihgvlhcuighuuceo ugiguhesugiguhhuuhdrgiihiieqnecuggftrfgrthhtvghrnhepgfefgfegjefhudeike dvueetffelieefuedvhfehjeeljeejkefgffeghfdttdetnecuvehluhhsthgvrhfuihii vgeptdenucfrrghrrghmpehmrghilhhfrhhomhepugiguhesugiguhhuuhdrgiihii X-ME-Proxy: Feedback-ID: i6a694271:Fastmail From: Daniel Xu To: michael.roth@amd.com, kkostiuk@redhat.com, marcandre.lureau@gmail.com, berrange@redhat.com Cc: qemu-devel@nongnu.org Subject: [PATCH v5 2/3] qga: Add `merged` variant to GuestExecCaptureOutputMode Date: Thu, 9 Mar 2023 15:40:57 -0700 Message-Id: X-Mailer: git-send-email 2.39.1 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=66.111.4.25; envelope-from=dxu@dxuuu.xyz; helo=out1-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, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, 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: 1678401745838100003 Content-Type: text/plain; charset="utf-8" Currently, any captured output (via `capture-output`) is segregated into separate GuestExecStatus fields (`out-data` and `err-data`). This means that downstream consumers have no way to reassemble the captured data back into the original stream. This is relevant for chatty and semi-interactive (ie. read only) CLI tools. Such tools may deliberately interleave stdout and stderr for visual effect. If segregated, the output becomes harder to visually understand. This commit adds a new enum variant to the GuestExecCaptureOutputMode qapi to merge the output streams such that consumers can have a pristine view of the original command output. Signed-off-by: Daniel Xu Reviewed-by: Daniel P. Berrang=C3=A9 --- qga/commands.c | 31 +++++++++++++++++++++++++++++-- qga/qapi-schema.json | 4 +++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/qga/commands.c b/qga/commands.c index 01f68b45ab..c347d434ed 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -270,12 +270,26 @@ static void guest_exec_child_watch(GPid pid, gint sta= tus, gpointer data) g_spawn_close_pid(pid); } =20 -/** Reset ignored signals back to default. */ static void guest_exec_task_setup(gpointer data) { #if !defined(G_OS_WIN32) + bool has_merge =3D *(bool *)data; struct sigaction sigact; =20 + if (has_merge) { + /* + * FIXME: When `GLIB_VERSION_MIN_REQUIRED` is bumped to 2.58+, use + * g_spawn_async_with_fds() to be portable on windows. The current + * logic does not work on windows b/c `GSpawnChildSetupFunc` is run + * inside the parent, not the child. + */ + if (dup2(STDOUT_FILENO, STDERR_FILENO) !=3D 0) { + slog("dup2() failed to merge stderr into stdout: %s", + strerror(errno)); + } + } + + /* Reset ignored signals back to default. */ memset(&sigact, 0, sizeof(struct sigaction)); sigact.sa_handler =3D SIG_DFL; =20 @@ -409,6 +423,7 @@ GuestExec *qmp_guest_exec(const char *path, GIOChannel *in_ch, *out_ch, *err_ch; GSpawnFlags flags; bool has_output =3D false; + bool has_merge =3D false; GuestExecCaptureOutputMode output_mode; g_autofree uint8_t *input =3D NULL; size_t ninput =3D 0; @@ -445,13 +460,25 @@ GuestExec *qmp_guest_exec(const char *path, case GUEST_EXEC_CAPTURE_OUTPUT_MODE_SEPARATED: has_output =3D true; break; + case GUEST_EXEC_CAPTURE_OUTPUT_MODE_MERGED: + has_output =3D true; + has_merge =3D true; + break; case GUEST_EXEC_CAPTURE_OUTPUT_MODE__MAX: /* Silence warning; impossible branch */ break; } =20 +#if defined(G_OS_WIN32) + /* FIXME: see comment in guest_exec_task_setup() */ + if (has_merge) { + error_setg(errp, "merged unsupported on windows"); + return NULL; + } +#endif + ret =3D g_spawn_async_with_pipes(NULL, argv, envp, flags, - guest_exec_task_setup, NULL, &pid, input_data ? &in_fd : NULL, + guest_exec_task_setup, &has_merge, &pid, input_data ? &in_fd := NULL, has_output ? &out_fd : NULL, has_output ? &err_fd : NULL, &ger= r); if (!ret) { error_setg(errp, QERR_QGA_COMMAND_FAILED, gerr->message); diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index d1e00a4234..b4782525ae 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -1210,11 +1210,13 @@ # @stderr: only capture stderr # @separated: capture both stdout and stderr, but separated into # GuestExecStatus out-data and err-data, respectively +# @merged: capture both stdout and stderr, but merge together +# into out-data. not effective on windows guests. # # Since: 8.0 ## { 'enum': 'GuestExecCaptureOutputMode', - 'data': [ 'none', 'stdout', 'stderr', 'separated' ] } + 'data': [ 'none', 'stdout', 'stderr', 'separated', 'merged' ] } =20 ## # @GuestExecCaptureOutput: --=20 2.39.1 From nobody Sun May 19 20:47:35 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 1678401727541185.7589671616547; Thu, 9 Mar 2023 14:42:07 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1paOwj-0002a7-US; Thu, 09 Mar 2023 17:41:13 -0500 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 1paOwi-0002ZV-KE for qemu-devel@nongnu.org; Thu, 09 Mar 2023 17:41:12 -0500 Received: from out1-smtp.messagingengine.com ([66.111.4.25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1paOwg-0003n7-HZ for qemu-devel@nongnu.org; Thu, 09 Mar 2023 17:41:12 -0500 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id AFFF85C00A4; Thu, 9 Mar 2023 17:41:09 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Thu, 09 Mar 2023 17:41:09 -0500 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 9 Mar 2023 17:41:08 -0500 (EST) 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=fm3; t=1678401669; x= 1678488069; bh=G+KSlsfGlpZ/1Z8LFsIUAIleZDnHwF2yylN0T2NQI1s=; b=X L2hMjkYuPTN9V5WF2Qd/68Pr43Orl6wwdzsvcmcCucEh+SZqfRMPH0pXC5Sz6uMu FdaDcZl0BvliJyNJ8dA6hmwwnUMfmHJ6RtEuf07/6dbTohQVxQ8bxJjUHfQAvedY tShSCPR6WTuH61Ub+HN4W45pQL2q5sepeSogu87MNYI9R+JF4NrSw+A64OH7UEpa /nM9GxEZcT2Um7/VugcM6p5pr47B8awUJ3Kve6bhNwu6CUj68qvFnEkB3HVmBCfU 4hNwhvK3xcFXYKJOCKUUV2V9KfpanE1fg8fNStd/iUkLfplDhJhj7tEoDyVVAgV4 mDin86zzJY40xdM8FcvCg== 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=fm1; t=1678401669; x= 1678488069; bh=G+KSlsfGlpZ/1Z8LFsIUAIleZDnHwF2yylN0T2NQI1s=; b=s uyyGX+JvokmdzBeQVLPaGKQPp25Fr2pL6Rov8HUpSU04k0ACmH//g/yT2QnNrueE vcGx9YuMpcpHs+8akn+/pAAFtx2IJ2kJrx70zs5F2qepdH2RYFraK913+OlF/hxX uH1iQtvpIIf/+DKxHc0btQCmvJKkle60AFjRTP/crm5e4JcznQNz5phEh+BHX6+T Qm01oA+femsULBUTTreQsvV93329m15Tl+rCJYHjGWI/aTBooTLKHurYiDYs0y+z ifPO6fWT6vtfF9UcFDzviyey4n+/Pwb8PHAqwRklLjQHRe8rS0mvRaQHhn5ivo27 KZOlK2uE/xyXkl4lp69Yw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrvddujecutefuodetggdotefrodftvfcurf hrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecuuegr ihhlohhuthemuceftddtnecufghrlhcuvffnffculdejtddmnecujfgurhephffvvefuff fkofgjfhgggfestdekredtredttdenucfhrhhomhepffgrnhhivghlucgiuhcuoegugihu segugihuuhhurdighiiiqeenucggtffrrghtthgvrhhnpefgfefggeejhfduieekvdeute ffleeifeeuvdfhheejleejjeekgfffgefhtddtteenucevlhhushhtvghrufhiiigvpedt necurfgrrhgrmhepmhgrihhlfhhrohhmpegugihusegugihuuhhurdighiii X-ME-Proxy: Feedback-ID: i6a694271:Fastmail From: Daniel Xu To: michael.roth@amd.com, kkostiuk@redhat.com, marcandre.lureau@gmail.com, berrange@redhat.com Cc: qemu-devel@nongnu.org Subject: [PATCH v5 3/3] qga: test: Add tests for `merged` flag Date: Thu, 9 Mar 2023 15:40:58 -0700 Message-Id: <20a27290153aa05c4076d71c665f1090112765aa.1678401400.git.dxu@dxuuu.xyz> X-Mailer: git-send-email 2.39.1 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=66.111.4.25; envelope-from=dxu@dxuuu.xyz; helo=out1-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, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, 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: 1678401730004100003 Content-Type: text/plain; charset="utf-8" This commit adds a test to ensure `merged` functions as expected. We also add a negative test to ensure we haven't regressed previous functionality. Signed-off-by: Daniel Xu Reviewed-by: Daniel P. Berrang=C3=A9 --- tests/unit/test-qga.c | 158 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 141 insertions(+), 17 deletions(-) diff --git a/tests/unit/test-qga.c b/tests/unit/test-qga.c index b4e0a14573..360b4cab23 100644 --- a/tests/unit/test-qga.c +++ b/tests/unit/test-qga.c @@ -755,6 +755,31 @@ static void test_qga_fsfreeze_status(gconstpointer fix) g_assert_cmpstr(status, =3D=3D, "thawed"); } =20 +static QDict *wait_for_guest_exec_completion(int fd, int64_t pid) +{ + QDict *ret =3D NULL; + int64_t now; + bool exited; + QDict *val; + + now =3D g_get_monotonic_time(); + do { + ret =3D qmp_fd(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"); + if (!exited) { + qobject_unref(ret); + } + } while (!exited && + g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND); + g_assert(exited); + + return ret; +} + static void test_qga_guest_exec(gconstpointer fix) { const TestFixture *fixture =3D fix; @@ -762,9 +787,8 @@ static void test_qga_guest_exec(gconstpointer fix) QDict *val; const gchar *out; g_autofree guchar *decoded =3D NULL; - int64_t pid, now, exitcode; + int64_t pid, exitcode; gsize len; - bool exited; =20 /* exec 'echo foo bar' */ ret =3D qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" @@ -777,23 +801,10 @@ static void test_qga_guest_exec(gconstpointer fix) g_assert_cmpint(pid, >, 0); qobject_unref(ret); =20 - /* wait for completion */ - now =3D g_get_monotonic_time(); - do { - 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"); - if (!exited) { - qobject_unref(ret); - } - } while (!exited && - g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND); - g_assert(exited); + ret =3D wait_for_guest_exec_completion(fixture->fd, pid); =20 /* check stdout */ + val =3D qdict_get_qdict(ret, "return"); exitcode =3D qdict_get_int(val, "exitcode"); g_assert_cmpint(exitcode, =3D=3D, 0); out =3D qdict_get_str(val, "out-data"); @@ -802,6 +813,115 @@ static void test_qga_guest_exec(gconstpointer fix) g_assert_cmpstr((char *)decoded, =3D=3D, "\" test_str \""); } =20 +#if defined(G_OS_WIN32) +static void test_qga_guest_exec_separated(gconstpointer fix) +{ +} +static void test_qga_guest_exec_merged(gconstpointer fix) +{ + const TestFixture *fixture =3D fix; + g_autoptr(QDict) ret =3D NULL; + QDict *val; + const gchar *class, *desc; + g_autofree guchar *decoded =3D NULL; + + /* exec 'echo foo bar' */ + ret =3D qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" + " 'path': 'echo'," + " 'arg': [ 'execution never reaches here' ]," + " 'capture-output': 'merged' } }"); + + g_assert_nonnull(ret); + val =3D qdict_get_qdict(ret, "error"); + g_assert_nonnull(val); + class =3D qdict_get_str(val, "class"); + desc =3D qdict_get_str(val, "desc"); + g_assert_cmpstr(class, =3D=3D, "GenericError"); + g_assert_cmpint(strlen(desc), >, 0); +} +#else +static void test_qga_guest_exec_separated(gconstpointer fix) +{ + const TestFixture *fixture =3D fix; + g_autoptr(QDict) ret =3D NULL; + QDict *val; + const gchar *out, *err; + g_autofree guchar *out_decoded =3D NULL; + g_autofree guchar *err_decoded =3D NULL; + int64_t pid, exitcode; + gsize len; + + /* exec 'echo foo bar' */ + ret =3D qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" + " 'path': '/bin/bash'," + " 'arg': [ '-c', 'for i in $(seq 4); do if (( $i %% 2 ));= then echo stdout; else echo stderr 1>&2; fi; done;' ]," + " 'capture-output': 'separated' } }"); + 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); + + ret =3D wait_for_guest_exec_completion(fixture->fd, pid); + + val =3D qdict_get_qdict(ret, "return"); + exitcode =3D qdict_get_int(val, "exitcode"); + g_assert_cmpint(exitcode, =3D=3D, 0); + + /* check stdout */ + out =3D qdict_get_str(val, "out-data"); + out_decoded =3D g_base64_decode(out, &len); + g_assert_cmpint(len, =3D=3D, 14); + g_assert_cmpstr((char *)out_decoded, =3D=3D, "stdout\nstdout\n"); + + /* check stderr */ + err =3D qdict_get_try_str(val, "err-data"); + err_decoded =3D g_base64_decode(err, &len); + g_assert_cmpint(len, =3D=3D, 14); + g_assert_cmpstr((char *)err_decoded, =3D=3D, "stderr\nstderr\n"); +} + +static void test_qga_guest_exec_merged(gconstpointer fix) +{ + const TestFixture *fixture =3D fix; + g_autoptr(QDict) ret =3D NULL; + QDict *val; + const gchar *out, *err; + g_autofree guchar *decoded =3D NULL; + int64_t pid, exitcode; + gsize len; + + /* exec 'echo foo bar' */ + ret =3D qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" + " 'path': '/bin/bash'," + " 'arg': [ '-c', 'for i in $(seq 4); do if (( $i %% 2 ));= then echo stdout; else echo stderr 1>&2; fi; done;' ]," + " 'capture-output': 'merged' } }"); + 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); + + ret =3D wait_for_guest_exec_completion(fixture->fd, pid); + + val =3D qdict_get_qdict(ret, "return"); + exitcode =3D qdict_get_int(val, "exitcode"); + g_assert_cmpint(exitcode, =3D=3D, 0); + + /* check stdout */ + out =3D qdict_get_str(val, "out-data"); + decoded =3D g_base64_decode(out, &len); + g_assert_cmpint(len, =3D=3D, 28); + g_assert_cmpstr((char *)decoded, =3D=3D, "stdout\nstderr\nstdout\nstde= rr\n"); + + /* check stderr */ + err =3D qdict_get_try_str(val, "err-data"); + g_assert_null(err); +} +#endif + static void test_qga_guest_exec_invalid(gconstpointer fix) { const TestFixture *fixture =3D fix; @@ -972,6 +1092,10 @@ int main(int argc, char **argv) g_test_add_data_func("/qga/blockedrpcs", NULL, test_qga_blockedrpcs); g_test_add_data_func("/qga/config", NULL, test_qga_config); g_test_add_data_func("/qga/guest-exec", &fix, test_qga_guest_exec); + g_test_add_data_func("/qga/guest-exec-separated", &fix, + 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-invalid", &fix, test_qga_guest_exec_invalid); g_test_add_data_func("/qga/guest-get-osinfo", &fix, --=20 2.39.1