Signed-off-by: Michael Roth <mdr...@linux.vnet.ibm.com> --- hw/virtio-blk.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 68 insertions(+), 8 deletions(-)
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index 2a5d1a9..2ddcc1e 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -511,37 +511,97 @@ static void virtio_blk_save(QEMUFile *f, void *opaque) { VirtIOBlock *s = opaque; VirtIOBlockReq *req = s->rq; + Visitor *v = qemu_file_get_visitor(f); + Error *err = NULL; + uint8_t *buf, marker; + int i; + + visit_start_struct(v, NULL, NULL, "virtio_blk", 0, &err); virtio_save(&s->vdev, f); + visit_start_list(v, "requests", &err); while (req) { - qemu_put_sbyte(f, 1); - qemu_put_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem)); + visit_start_struct(v, NULL, NULL, NULL, 0, &err); + + marker = 1; + visit_type_uint8(v, &marker, "marker", &err); + visit_start_array(v, NULL, "elem", sizeof(req->elem), 1, &err); + buf = (uint8_t *)&req->elem; + for (i = 0; i < sizeof(req->elem); i++) { + visit_type_uint8(v, &buf[i], NULL, &err); + } + visit_end_array(v, &err); + + visit_end_struct(v, &err); req = req->next; } - qemu_put_sbyte(f, 0); + visit_start_struct(v, NULL, NULL, NULL, 0, &err); + marker = 0; + visit_type_uint8(v, &marker, "marker", &err); + visit_end_struct(v, &err); + visit_end_list(v, &err); + + visit_end_struct(v, &err); + + if (err) { + error_report("error saving virtio-blk state: %s", error_get_pretty(err)); + error_free(err); + } } static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id) { VirtIOBlock *s = opaque; + Visitor *v = qemu_file_get_visitor(f); + Error *err = NULL; + uint8_t marker, *buf; + int i; - if (version_id != 2) + if (version_id != 2) { return -EINVAL; + } + + visit_start_struct(v, NULL, NULL, "virtio_blk", 0, &err); virtio_load(&s->vdev, f); - while (qemu_get_sbyte(f)) { + + visit_start_list(v, "requests", &err); + while (1) { + visit_start_struct(v, NULL, NULL, NULL, 0, &err); + + visit_type_uint8(v, &marker, "marker", &err); + if (!marker) { + visit_end_struct(v, &err); + break; + } VirtIOBlockReq *req = virtio_blk_alloc_request(s); - qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem)); + visit_start_array(v, NULL, "elem", sizeof(req->elem), 1, &err); + buf = (uint8_t *)&req->elem; + for (i = 0; i < sizeof(req->elem); i++) { + visit_type_uint8(v, &buf[i], NULL, &err); + } + visit_end_array(v, &err); + + visit_end_struct(v, &err); + req->next = s->rq; s->rq = req; virtqueue_map_sg(req->elem.in_sg, req->elem.in_addr, - req->elem.in_num, 1); + req->elem.in_num, 1); virtqueue_map_sg(req->elem.out_sg, req->elem.out_addr, - req->elem.out_num, 0); + req->elem.out_num, 0); } + visit_end_list(v, &err); + visit_end_struct(v, &err); + + if (err) { + error_report("error loading virtio-blk state: %s", error_get_pretty(err)); + error_free(err); + return -1; + } return 0; } -- 1.7.4.1