From: Greg Kurz <gkurz@linux.vnet.ibm.com>
To: Kevin Wolf <kwolf@redhat.com>,
Anthony Liguori <aliguori@amazon.com>,
"Michael S. Tsirkin" <mst@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>,
Amit Shah <amit.shah@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>
Cc: "Juan Quintela" <quintela@redhat.com>,
"Fam Zheng" <famz@redhat.com>, "Alexander Graf" <agraf@suse.de>,
"Andreas Färber" <afaerber@suse.de>,
qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH RFC 7/8] virtio: add subsections to the migration stream
Date: Mon, 19 May 2014 10:39:01 +0200 [thread overview]
Message-ID: <20140519083901.22955.65323.stgit@bahia.local> (raw)
In-Reply-To: <20140519063132.22955.63563.stgit@bahia.local>
There is a need to add some more fields to VirtIODevice that should be
migrated (broken status, endianness). The problem is that we do not
want to break compatibility while adding a new feature... This issue has
been addressed in the generic VMState code with the use of optional
subsections. As a *temporary* alternative to port the whole virtio
migration code to VMState, this patch mimics a similar subsectionning
ability for virtio.
Since each virtio device is streamed in its own section, the idea is to
stream subsections between the end of the device section and the start
of the next sections. This allows an older QEMU to complain and exit
when fed with subsections:
Unknown savevm section type 5
Error -22 while loading VM state
The virtio subsections honor the same protocol than the VMState ones:
+-------------------------+
|QEMU_VM_SUBSECTION (byte)| 1 byte
+-------------------------+
| subsection name length | 1 byte
+-------------------------+
| |
: subsection name buffer : length bytes
| |
+-------------------------+
| version_id | 4 bytes (be32)
+-------------------------+
| |
: subsection data :
| |
+-------------------------+
The model differs from VMState though as we don't describe the fields in
the subsections. As a consequence, there is no "field exists" concept and
this impacts backwards migration.
Suggested-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
hw/virtio/virtio.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 77 insertions(+), 1 deletion(-)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index cf87b44..7fbad29 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -19,6 +19,7 @@
#include "hw/virtio/virtio.h"
#include "qemu/atomic.h"
#include "hw/virtio/virtio-bus.h"
+#include "migration/migration.h"
/*
* The alignment to use between consumer and producer parts of vring.
@@ -833,6 +834,79 @@ void virtio_notify_config(VirtIODevice *vdev)
virtio_notify_vector(vdev, vdev->config_vector);
}
+typedef struct VirtIOSubsection {
+ const char *name;
+ int version_id;
+ void (*save)(VirtIODevice *vdev, QEMUFile *f);
+ int (*load)(VirtIODevice *vdev, QEMUFile *f);
+ int (*needed)(VirtIODevice *vdev);
+} VirtIOSubsection;
+
+static const VirtIOSubsection virtio_subsection[] = {
+ { .name = NULL }
+};
+
+static void virtio_save_subsections(VirtIODevice *vdev, QEMUFile *f)
+{
+ int i;
+
+ for (i = 0; virtio_subsection[i].name; i++) {
+ VirtIOSubsection sub = virtio_subsection[i];
+
+ if (sub.needed != NULL && (*sub.needed)(vdev)) {
+ const char *name = sub.name;
+ uint8_t len = strlen(name);
+
+ qemu_put_byte(f, QEMU_VM_SUBSECTION);
+ qemu_put_byte(f, len);
+ qemu_put_buffer(f, (uint8_t *) name, len);
+ qemu_put_be32(f, sub.version_id);
+ (*sub.save)(vdev, f);
+ }
+ }
+}
+
+static int virtio_load_subsections(VirtIODevice *vdev, QEMUFile *f)
+{
+ while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) {
+ char idstr[256];
+ uint8_t len, size;
+ int i;
+
+ len = qemu_peek_byte(f, 1);
+ size = qemu_peek_buffer(f, (uint8_t *) idstr, len, 2);
+ if (size != len) {
+ break;
+ }
+
+ idstr[size] = 0;
+
+ for (i = 0; virtio_subsection[i].name; i++) {
+ VirtIOSubsection sub = virtio_subsection[i];
+
+ if (strcmp(sub.name, idstr) == 0) {
+ uint32_t version_id;
+ int ret;
+
+ qemu_file_skip(f, 1); /* subsection */
+ qemu_file_skip(f, 1); /* len */
+ qemu_file_skip(f, len); /* idstr */
+
+ version_id = qemu_get_be32(f);
+ if (version_id > sub.version_id) {
+ return -EINVAL;
+ }
+ ret = (*sub.load)(vdev, f);
+ if (ret) {
+ return ret;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
void virtio_save(VirtIODevice *vdev, QEMUFile *f)
{
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
@@ -876,6 +950,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
if (vdc->save != NULL) {
vdc->save(vdev, f);
}
+
+ virtio_save_subsections(vdev, f);
}
int virtio_set_features(VirtIODevice *vdev, uint32_t val)
@@ -967,7 +1043,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
return vdc->load(vdev, f, version_id);
}
- return 0;
+ return virtio_load_subsections(vdev, f);
}
void virtio_cleanup(VirtIODevice *vdev)
next prev parent reply other threads:[~2014-05-19 8:39 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-19 8:38 [Qemu-devel] [PATCH RFC V2 0/8] virtio: migrate new properties Greg Kurz
2014-05-19 8:38 ` [Qemu-devel] [PATCH RFC 1/8] virtio: introduce device specific migration calls Greg Kurz
2014-05-19 8:38 ` [Qemu-devel] [PATCH RFC 2/8] virtio-net: implement per-device " Greg Kurz
2014-05-19 8:38 ` [Qemu-devel] [PATCH RFC 3/8] virtio-blk: " Greg Kurz
2014-05-19 8:38 ` [Qemu-devel] [PATCH RFC 4/8] virtio-serial: " Greg Kurz
2014-05-19 8:38 ` [Qemu-devel] [PATCH RFC 5/8] virtio-balloon: " Greg Kurz
2014-05-19 8:38 ` [Qemu-devel] [PATCH RFC 6/8] virtio-rng: " Greg Kurz
2014-05-19 8:39 ` Greg Kurz [this message]
2014-05-19 8:39 ` [Qemu-devel] [PATCH RFC 8/8] virtio: add endian-ambivalent support to VirtIODevice Greg Kurz
2014-05-19 13:06 ` Greg Kurz
2014-05-19 17:06 ` Andreas Färber
2014-05-19 17:32 ` Greg Kurz
2014-05-19 18:07 ` Dr. David Alan Gilbert
2014-05-19 12:02 ` [Qemu-devel] [PATCH RFC V2 0/8] virtio: migrate new properties Alexander Graf
2014-05-19 12:45 ` Greg Kurz
2014-05-19 13:07 ` Alexander Graf
2014-05-19 15:10 ` Michael S. Tsirkin
2014-05-19 15:36 ` Alexander Graf
2014-05-19 15:50 ` Michael S. Tsirkin
2014-05-19 15:40 ` Andreas Färber
2014-05-19 15:53 ` Michael S. Tsirkin
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=20140519083901.22955.65323.stgit@bahia.local \
--to=gkurz@linux.vnet.ibm.com \
--cc=afaerber@suse.de \
--cc=agraf@suse.de \
--cc=aliguori@amazon.com \
--cc=amit.shah@redhat.com \
--cc=famz@redhat.com \
--cc=kwolf@redhat.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
--cc=stefanha@redhat.com \
/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.