All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Daniel Xu <dxu@dxuuu.xyz>
Cc: michael.roth@amd.com, kkostiuk@redhat.com,
	marcandre.lureau@gmail.com, qemu-devel@nongnu.org
Subject: Re: [PATCH v5 2/3] qga: Add `merged` variant to GuestExecCaptureOutputMode
Date: Fri, 10 Mar 2023 09:24:38 +0000	[thread overview]
Message-ID: <ZAr3VuuP7s0ka0rt@redhat.com> (raw)
In-Reply-To: <c73263127c3533c9da06042a57bed2f334c5ea2e.1678401400.git.dxu@dxuuu.xyz>

On Thu, Mar 09, 2023 at 03:40:57PM -0700, Daniel Xu wrote:
> 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 <dxu@dxuuu.xyz>
> ---
>  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 status, gpointer data)
>      g_spawn_close_pid(pid);
>  }
>  
> -/** Reset ignored signals back to default. */
>  static void guest_exec_task_setup(gpointer data)
>  {
>  #if !defined(G_OS_WIN32)
> +    bool has_merge = *(bool *)data;
>      struct sigaction sigact;
>  
> +    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) != 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 = SIG_DFL;
>  
> @@ -409,6 +423,7 @@ GuestExec *qmp_guest_exec(const char *path,
>      GIOChannel *in_ch, *out_ch, *err_ch;
>      GSpawnFlags flags;
>      bool has_output = false;
> +    bool has_merge = false;

Wrap in  #ifndef _WIN32

>      GuestExecCaptureOutputMode output_mode;
>      g_autofree uint8_t *input = NULL;
>      size_t ninput = 0;
> @@ -445,13 +460,25 @@ GuestExec *qmp_guest_exec(const char *path,
>      case GUEST_EXEC_CAPTURE_OUTPUT_MODE_SEPARATED:
>          has_output = true;
>          break;
> +    case GUEST_EXEC_CAPTURE_OUTPUT_MODE_MERGED:
> +        has_output = true;
> +        has_merge = true;
> +        break;

Wrap in  #ifndef _WIN32

>      case GUEST_EXEC_CAPTURE_OUTPUT_MODE__MAX:
>          /* Silence warning; impossible branch */
>          break;
>      }
>  
> +#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

THis can be dropped, since 'has_merge' won't exist for
Win32 builds.

> +
>      ret = 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, &gerr);
>      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' ] }

Actually, I've just realized we can make this conditional:


 'data': [ 'none', 'stdout', 'stderr', 'separated',
           { 'name': 'merged', 'if': 'CONFIG_WIN32' } ] }

so the constant doesn't even exist in Win32 builds.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



  parent reply	other threads:[~2023-03-10  9:25 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-09 22:40 [PATCH v5 0/3] qga: Support merging output streams in guest-exec Daniel Xu
2023-03-09 22:40 ` [PATCH v5 1/3] qga: Refactor guest-exec capture-output to take enum Daniel Xu
2023-03-10  9:20   ` Daniel P. Berrangé
2023-03-09 22:40 ` [PATCH v5 2/3] qga: Add `merged` variant to GuestExecCaptureOutputMode Daniel Xu
2023-03-10  9:21   ` Daniel P. Berrangé
2023-03-10  9:24   ` Daniel P. Berrangé [this message]
2023-03-23  0:15     ` Daniel Xu
2023-03-09 22:40 ` [PATCH v5 3/3] qga: test: Add tests for `merged` flag Daniel Xu
2023-03-10  9:36   ` Daniel P. Berrangé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZAr3VuuP7s0ka0rt@redhat.com \
    --to=berrange@redhat.com \
    --cc=dxu@dxuuu.xyz \
    --cc=kkostiuk@redhat.com \
    --cc=marcandre.lureau@gmail.com \
    --cc=michael.roth@amd.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.