From patchwork Thu Mar 23 00:19:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Daniel Xu X-Patchwork-Id: 1760059 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=dxuuu.xyz header.i=@dxuuu.xyz header.a=rsa-sha256 header.s=fm1 header.b=ZzVegQd8; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.a=rsa-sha256 header.s=fm2 header.b=g6tYeJfm; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PhmG53dNwz247J for ; Thu, 23 Mar 2023 11:20:45 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pf8gS-0007eK-Qx; Wed, 22 Mar 2023 20:20:01 -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 1pf8gH-0007dE-TB for qemu-devel@nongnu.org; Wed, 22 Mar 2023 20:19:51 -0400 Received: from out5-smtp.messagingengine.com ([66.111.4.29]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pf8gG-0005fW-4y for qemu-devel@nongnu.org; Wed, 22 Mar 2023 20:19:49 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id B3D7B5C00E9; Wed, 22 Mar 2023 20:19:47 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Wed, 22 Mar 2023 20:19:47 -0400 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=fm1; t= 1679530787; x=1679617187; bh=O86jAUROcuMAf5eThlp+O6BhkjqpUq6KDyY eULVJdb4=; b=ZzVegQd8uRfM9rc+4xjwN/biV9GS3n8rU2BkiD/3Fu4W6RmZw+e GNPeD1fjLwuio6BJwbfQdP74K+L2IZsLJefkpPz1F97Xt+HvQE0DHFyN2Otg3e3e DfKPs8op9aZ1ZtS74tIUOi6NX65MU/aqcMQyYPO9h853QLIg81+46XF7RmpLAR3P aR8NAmsxzVPLdpPbvD9LQehE80igYr+ZpCUaT7y+bcGJCJI7BPPWRtewATrp7WCp 89+euEg43H+RpY4Yjlq3Y0J0isZ2vpfcvzhoEv6e9mxFs4XjaBRMGxlC5cq2diPk JnOFr+USl3wbInMHMur0lbCfz3EnJU2uBBA== 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=fm2; t= 1679530787; x=1679617187; bh=O86jAUROcuMAf5eThlp+O6BhkjqpUq6KDyY eULVJdb4=; b=g6tYeJfmfJm9v5ftxzYIjH1K7LLPLoCCjZ4Hlt0r/5f1vIeu8eJ qpP4RfTbEa6vv7t00Tbw0i8ZGbou1iDqgw6/694MTEDA1CU/tDMMMEhTO3fwzxAo OkFnN/sXOFlFMzHsDqt0Uc1NIiByA0zjcrAfOpRgZFVrlwMGDvI78a8kICxaBHOJ hBglFRyiPaHSlRpV8mj2Uyaoq2CwAOahH6OiVEziWkkkA1t+++v16Z7fC4yXzUdF fQvJsrULichWqu4+y/VurIoMWuMDPU3Di2vEEgQNwXY9LrVGB+/HS4bFOvr6djcO 82nWnEKlpR2bK/BG8CqJ1TZUR63XVxIKdwg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrvdegfedgvddtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucgfrhhlucfvnfffucdlfeehmdenucfjughrpefhvf evufffkffojghfgggtgfesthekredtredtjeenucfhrhhomhepffgrnhhivghlucgiuhcu oegugihusegugihuuhhurdighiiiqeenucggtffrrghtthgvrhhnpeetheekkefggfeive dvtefgleeiffdtleegfeeuledvuddtvdduhfekgfdutdevkeenucevlhhushhtvghrufhi iigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpegugihusegugihuuhhurdighiii X-ME-Proxy: Feedback-ID: i6a694271:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 22 Mar 2023 20:19:46 -0400 (EDT) From: Daniel Xu To: kkostiuk@redhat.com, michael.roth@amd.com, marcandre.lureau@gmail.com, berrange@redhat.com Cc: qemu-devel@nongnu.org Subject: [PATCH v6 1/3] qga: Refactor guest-exec capture-output to take enum Date: Wed, 22 Mar 2023 18:19:26 -0600 Message-Id: X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=66.111.4.29; envelope-from=dxu@dxuuu.xyz; helo=out5-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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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é Reviewed-by: Daniel P. Berrangé Signed-off-by: Daniel Xu --- 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; } +static GuestExecCaptureOutputMode ga_parse_capture_output( + GuestExecCaptureOutput *capture_output) +{ + if (!capture_output) + return GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE; + else if (capture_output->type == QTYPE_QBOOL) + return capture_output->u.flag ? GUEST_EXEC_CAPTURE_OUTPUT_MODE_SEPARATED + : GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE; + 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 = (has_capture_output && capture_output); + bool has_output = false; + GuestExecCaptureOutputMode output_mode; g_autofree uint8_t *input = NULL; size_t ninput = 0; @@ -415,8 +428,26 @@ GuestExec *qmp_guest_exec(const char *path, flags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH_FROM_ENVP; - if (!has_output) { + + output_mode = ga_parse_capture_output(capture_output); + switch (output_mode) { + case GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE: flags |= G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL; + break; + case GUEST_EXEC_CAPTURE_OUTPUT_MODE_STDOUT: + has_output = true; + flags |= G_SPAWN_STDERR_TO_DEV_NULL; + break; + case GUEST_EXEC_CAPTURE_OUTPUT_MODE_STDERR: + has_output = true; + flags |= G_SPAWN_STDOUT_TO_DEV_NULL; + break; + case GUEST_EXEC_CAPTURE_OUTPUT_MODE_SEPARATED: + has_output = true; + break; + case GUEST_EXEC_CAPTURE_OUTPUT_MODE__MAX: + /* Silence warning; impossible branch */ + break; } ret = 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'} } +## +# @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': 'GuestExecCaptureOutput' }, 'returns': 'GuestExec' }