All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <aliguori@us.ibm.com>
To: Alon Levy <alevy@redhat.com>, qemu-devel@nongnu.org
Cc: airlied@redhat.com, kraxel@redhat.com
Subject: Re: [Qemu-devel] [PATCH] make screendump an async command
Date: Fri, 14 Jun 2013 13:21:26 -0500	[thread overview]
Message-ID: <87mwqspn89.fsf@codemonkey.ws> (raw)
In-Reply-To: <1371151644-22308-1-git-send-email-alevy@redhat.com>

Alon Levy <alevy@redhat.com> writes:

> This fixes the broken screendump behavior for qxl devices in native mode
> since 81fb6f1504fb9ef71f2382f44af34756668296e8.
>
> Note: due to QAPI not generating async commands yet I had to remove the
> schema screendump definition.
>
> Related RHBZ: 973374
> This patch is not enough to fix said bz, with the linux qxl driver you get garbage still, just not out of date garbage.
>
> Signed-off-by: Alon Levy <alevy@redhat.com>

Async commands are badly broken with respect to error handling.

This needs to be done after we get the new QMP server.

Why is QXL unable to do a synchronous screendump?

Regards,

Anthony Liguori

> ---
>  hmp.c                     |  2 +-
>  hw/display/qxl-render.c   |  1 +
>  hw/display/vga.c          |  1 +
>  include/qapi/qmp/qerror.h |  6 +++++
>  include/ui/console.h      | 10 ++++++++
>  qapi-schema.json          | 13 -----------
>  qmp-commands.hx           |  3 ++-
>  ui/console.c              | 58 ++++++++++++++++++++++++++++++++++++++++++++++-
>  8 files changed, 78 insertions(+), 16 deletions(-)
>
> diff --git a/hmp.c b/hmp.c
> index 494a9aa..2a37975 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -1346,7 +1346,7 @@ void hmp_screen_dump(Monitor *mon, const QDict *qdict)
>      const char *filename = qdict_get_str(qdict, "filename");
>      Error *err = NULL;
>  
> -    qmp_screendump(filename, &err);
> +    hmp_screen_dump_helper(filename, &err);
>      hmp_handle_error(mon, &err);
>  }
>  
> diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
> index f511a62..d719448 100644
> --- a/hw/display/qxl-render.c
> +++ b/hw/display/qxl-render.c
> @@ -139,6 +139,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
>                         qxl->dirty[i].bottom - qxl->dirty[i].top);
>      }
>      qxl->num_dirty_rects = 0;
> +    console_screendump_complete(vga->con);
>  }
>  
>  /*
> diff --git a/hw/display/vga.c b/hw/display/vga.c
> index 21a108d..1fc52eb 100644
> --- a/hw/display/vga.c
> +++ b/hw/display/vga.c
> @@ -1922,6 +1922,7 @@ static void vga_update_display(void *opaque)
>              break;
>          }
>      }
> +    console_screendump_complete(s->con);
>  }
>  
>  /* force a full display refresh */
> diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
> index 6c0a18d..1bd7efa 100644
> --- a/include/qapi/qmp/qerror.h
> +++ b/include/qapi/qmp/qerror.h
> @@ -237,6 +237,12 @@ void assert_no_error(Error *err);
>  #define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
>      ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when VirtFS export path '%s' is mounted in the guest using mount_tag '%s'"
>  
> +#define QERR_SCREENDUMP_NOT_AVAILABLE \
> +    ERROR_CLASS_GENERIC_ERROR, "There is no QemuConsole I can screendump from"
> +
> +#define QERR_SCREENDUMP_IN_PROGRESS \
> +    ERROR_CLASS_GENERIC_ERROR, "Existing screendump in progress"
> +
>  #define QERR_SOCKET_CONNECT_FAILED \
>      ERROR_CLASS_GENERIC_ERROR, "Failed to connect to socket"
>  
> diff --git a/include/ui/console.h b/include/ui/console.h
> index 4307b5f..643da45 100644
> --- a/include/ui/console.h
> +++ b/include/ui/console.h
> @@ -341,4 +341,14 @@ int index_from_keycode(int code);
>  void early_gtk_display_init(void);
>  void gtk_display_init(DisplayState *ds);
>  
> +/* hw/display/vga.c hw/display/qxl.c */
> +void console_screendump_complete(QemuConsole *con);
> +
> +/* monitor.c */
> +int qmp_screendump(Monitor *mon, const QDict *qdict,
> +                   MonitorCompletion cb, void *opaque);
> +
> +/* hmp.c */
> +void hmp_screen_dump_helper(const char *filename, Error **errp);
> +
>  #endif
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 5ad6894..f5fdc2f 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -3112,19 +3112,6 @@
>    'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } }
>  
>  ##
> -# @screendump:
> -#
> -# Write a PPM of the VGA screen to a file.
> -#
> -# @filename: the path of a new PPM file to store the image
> -#
> -# Returns: Nothing on success
> -#
> -# Since: 0.14.0
> -##
> -{ 'command': 'screendump', 'data': {'filename': 'str'} }
> -
> -##
>  # @nbd-server-start:
>  #
>  # Start an NBD server listening on the given host and port.  Block
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 8cea5e5..bde8f43 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -146,7 +146,8 @@ EQMP
>      {
>          .name       = "screendump",
>          .args_type  = "filename:F",
> -        .mhandler.cmd_new = qmp_marshal_input_screendump,
> +        .mhandler.cmd_async = qmp_screendump,
> +        .flags      = MONITOR_CMD_ASYNC,
>      },
>  
>  SQMP
> diff --git a/ui/console.c b/ui/console.c
> index 28bba6d..0efd588 100644
> --- a/ui/console.c
> +++ b/ui/console.c
> @@ -116,6 +116,12 @@ typedef enum {
>  struct QemuConsole {
>      Object parent;
>  
> +    struct {
> +        char *filename;
> +        MonitorCompletion *completion_cb;
> +        void *completion_opaque;
> +    } screendump;
> +
>      int index;
>      console_type_t console_type;
>      DisplayState *ds;
> @@ -313,11 +319,61 @@ write_err:
>      goto out;
>  }
>  
> -void qmp_screendump(const char *filename, Error **errp)
> +int qmp_screendump(Monitor *mon, const QDict *qdict,
> +                   MonitorCompletion cb, void *opaque)
>  {
>      QemuConsole *con = qemu_console_lookup_by_index(0);
> +    const char *filename = qdict_get_str(qdict, "filename");
> +
> +    if (con == NULL) {
> +        qerror_report(QERR_SCREENDUMP_NOT_AVAILABLE);
> +        return -1;
> +    }
> +    if (filename == NULL) {
> +        qerror_report(QERR_MISSING_PARAMETER, "filename");
> +        return -1;
> +    }
> +    if (con->screendump.filename != NULL) {
> +        qerror_report(QERR_SCREENDUMP_IN_PROGRESS);
> +        return -1;
> +    }
> +    con->screendump.filename = g_strdup(filename);
> +    con->screendump.completion_cb = cb;
> +    con->screendump.completion_opaque = opaque;
> +
> +    graphic_hw_update(con);
> +    return 0;
> +}
> +
> +void console_screendump_complete(QemuConsole *con)
> +{
> +    Error *errp = NULL;
>      DisplaySurface *surface;
>  
> +    if (!con->screendump.filename) {
> +        return;
> +    }
> +    assert(con->screendump.completion_cb);
> +    surface = qemu_console_surface(con);
> +    ppm_save(con->screendump.filename, surface, &errp);
> +    if (errp) {
> +        /*
> +         * TODO: return data? raise error somehow? read qmp-spec for async
> +         * error reporting.
> +         */
> +    }
> +    con->screendump.completion_cb(con->screendump.completion_opaque, NULL);
> +    g_free(con->screendump.filename);
> +    con->screendump.filename = NULL;
> +    con->screendump.completion_cb = NULL;
> +    con->screendump.completion_opaque = NULL;
> +}
> +
> +void hmp_screen_dump_helper(const char *filename, Error **errp)
> +{
> +    DisplaySurface *surface;
> +    QemuConsole *con = qemu_console_lookup_by_index(0);
> +
>      if (con == NULL) {
>          error_setg(errp, "There is no QemuConsole I can screendump from.");
>          return;
> -- 
> 1.8.2.1

  parent reply	other threads:[~2013-06-14 18:22 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-13 19:27 [Qemu-devel] [PATCH] make screendump an async command Alon Levy
2013-06-13 20:08 ` Paolo Bonzini
2013-06-13 20:35   ` Alon Levy
2013-06-14 11:18 ` Gerd Hoffmann
2013-06-14 18:02   ` Alon Levy
2013-06-14 18:07     ` Alon Levy
2013-06-14 18:21 ` Anthony Liguori [this message]
2013-06-14 23:55   ` Alon Levy
2013-06-17 13:41     ` Luiz Capitulino
2013-06-17  6:06   ` Gerd Hoffmann
2013-06-17  9:30     ` Alon Levy
2013-06-17 14:00       ` Gerd Hoffmann
2013-06-17 13:54     ` Luiz Capitulino

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=87mwqspn89.fsf@codemonkey.ws \
    --to=aliguori@us.ibm.com \
    --cc=airlied@redhat.com \
    --cc=alevy@redhat.com \
    --cc=kraxel@redhat.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.