aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Kurz <gkurz@linux.vnet.ibm.com>2014-06-24 19:22:30 +0200
committerMichael S. Tsirkin <mst@redhat.com>2014-06-29 19:39:42 +0300
commit6b321a3df55de42ad349870a8793e33a69f9d1a3 (patch)
treee95bed13ef7aa0a01eceb5b0cc36feee7abc1b64
parent3902d49e13c2428bd6381cfdf183103ca4477c1f (diff)
virtio: add subsections to the migration stream
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, using the VMState code. 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 load of migration failed Suggested-by: Alexander Graf <agraf@suse.de> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> Reviewed-by: Alexander Graf <agraf@suse.de> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r--hw/virtio/virtio.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 7f9ac5e0b9..7b317ce279 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.
@@ -839,6 +840,16 @@ void virtio_notify_config(VirtIODevice *vdev)
virtio_notify_vector(vdev, vdev->config_vector);
}
+static const VMStateDescription vmstate_virtio = {
+ .name = "virtio",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_END_OF_LIST()
+ }
+};
+
void virtio_save(VirtIODevice *vdev, QEMUFile *f)
{
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
@@ -882,6 +893,9 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
if (vdc->save != NULL) {
vdc->save(vdev, f);
}
+
+ /* Subsections */
+ vmstate_save_state(f, &vmstate_virtio, vdev);
}
int virtio_set_features(VirtIODevice *vdev, uint32_t val)
@@ -991,10 +1005,13 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
if (vdc->load != NULL) {
- return vdc->load(vdev, f, version_id);
+ ret = vdc->load(vdev, f, version_id);
+ if (ret) {
+ return ret;
+ }
}
- return 0;
+ return vmstate_load_state(f, &vmstate_virtio, vdev, 1);
}
void virtio_cleanup(VirtIODevice *vdev)