Patchwork [01/12] chardev: ringbuf: add optional save parameter to save state

login
register
mail settings
Submitter Anthony Liguori
Date June 19, 2013, 8:40 p.m.
Message ID <1371674435-14973-2-git-send-email-aliguori@us.ibm.com>
Download mbox | patch
Permalink /patch/252655/
State New
Headers show

Comments

Anthony Liguori - June 19, 2013, 8:40 p.m.
It is very useful to use the ringbuf chardev for writing test
cases and even more useful if the state of the ringbuf is migrated
with the guest.  Otherwise it's hard to detect data loss in a test
case.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 qapi-schema.json |  3 ++-
 qemu-char.c      | 45 +++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 45 insertions(+), 3 deletions(-)
Eric Blake - June 20, 2013, 7:49 p.m.
On 06/19/2013 09:40 PM, Anthony Liguori wrote:
> It is very useful to use the ringbuf chardev for writing test
> cases and even more useful if the state of the ringbuf is migrated
> with the guest.  Otherwise it's hard to detect data loss in a test
> case.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  qapi-schema.json |  3 ++-
>  qemu-char.c      | 45 +++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 45 insertions(+), 3 deletions(-)
> 
> diff --git a/qapi-schema.json b/qapi-schema.json
> index a80ee40..90602d1 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -3280,10 +3280,11 @@
>  # Configuration info for memory chardevs
>  #
>  # @size: #optional Ringbuffer size, must be power of two, default is 65536
> +# @save: #optional Register a savevm handler, default false

Useful to have a '(since 1.6)' notation on the added field.

>  #
>  # Since: 1.5
>  ##
> -{ 'type': 'ChardevMemory', 'data': { '*size'  : 'int' } }
> +{ 'type': 'ChardevMemory', 'data': { '*size'  : 'int', '*save': 'bool' } }

Yet another case for introspection discovering an added feature to an
existing command.

Patch

diff --git a/qapi-schema.json b/qapi-schema.json
index a80ee40..90602d1 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3280,10 +3280,11 @@ 
 # Configuration info for memory chardevs
 #
 # @size: #optional Ringbuffer size, must be power of two, default is 65536
+# @save: #optional Register a savevm handler, default false
 #
 # Since: 1.5
 ##
-{ 'type': 'ChardevMemory', 'data': { '*size'  : 'int' } }
+{ 'type': 'ChardevMemory', 'data': { '*size'  : 'int', '*save': 'bool' } }
 
 ##
 # @ChardevBackend:
diff --git a/qemu-char.c b/qemu-char.c
index 2c3cfe6..87ba24f 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2793,7 +2793,32 @@  static void ringbuf_chr_close(struct CharDriverState *chr)
     chr->opaque = NULL;
 }
 
-static CharDriverState *qemu_chr_open_memory(ChardevMemory *opts,
+static void ringbuf_save(QEMUFile *f, void *opaque)
+{
+    CharDriverState *chr = opaque;
+    RingBufCharDriver *d = chr->opaque;
+
+    qemu_put_be32(f, d->prod);
+    qemu_put_be32(f, d->cons);
+    qemu_put_be32(f, d->size);
+    qemu_put_buffer(f, d->cbuf, d->size);
+}
+
+static int ringbuf_load(QEMUFile *f, void *opaque, int version_id)
+{
+    CharDriverState *chr = opaque;
+    RingBufCharDriver *d = chr->opaque;
+
+    d->prod = qemu_get_be32(f);
+    d->cons = qemu_get_be32(f);
+    d->size = qemu_get_be32(f);
+    qemu_get_buffer(f, d->cbuf, d->size);
+
+    return 0;
+}
+
+static CharDriverState *qemu_chr_open_memory(const char *id,
+                                             ChardevMemory *opts,
                                              Error **errp)
 {
     CharDriverState *chr;
@@ -2804,6 +2829,14 @@  static CharDriverState *qemu_chr_open_memory(ChardevMemory *opts,
 
     d->size = opts->has_size ? opts->size : 65536;
 
+    if (opts->has_save && opts->save) {
+        char *idstr;
+
+        g_assert(id != NULL);
+        idstr = g_strdup_printf("memchar-%s", id);
+        register_savevm(NULL, idstr, 0, 1, ringbuf_save, ringbuf_load, chr);
+    }
+
     /* The size must be power of 2 */
     if (d->size & (d->size - 1)) {
         error_setg(errp, "size of memory chardev must be power of two");
@@ -3120,6 +3153,11 @@  static void qemu_chr_parse_memory(QemuOpts *opts, ChardevBackend *backend,
         backend->memory->has_size = true;
         backend->memory->size = val;
     }
+
+    if (qemu_opt_get_bool(opts, "save", false)) {
+        backend->memory->has_save = true;
+        backend->memory->save = true;
+    }
 }
 
 typedef struct CharDriver {
@@ -3489,6 +3527,9 @@  QemuOptsList qemu_chardev_opts = {
         },{
             .name = "size",
             .type = QEMU_OPT_SIZE,
+        }, {
+            .name = "save",
+            .type = QEMU_OPT_BOOL,
         },
         { /* end of list */ }
     },
@@ -3711,7 +3752,7 @@  ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
         chr = vc_init(backend->vc);
         break;
     case CHARDEV_BACKEND_KIND_MEMORY:
-        chr = qemu_chr_open_memory(backend->memory, errp);
+        chr = qemu_chr_open_memory(id, backend->memory, errp);
         break;
     default:
         error_setg(errp, "unknown chardev backend (%d)", backend->kind);