qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 01/12] chardev: ringbuf: add optional save parameter


From: Anthony Liguori
Subject: [Qemu-devel] [PATCH 01/12] chardev: ringbuf: add optional save parameter to save state
Date: Wed, 19 Jun 2013 15:40:24 -0500

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 <address@hidden>
---
 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
 #
 # 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);
-- 
1.8.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]