qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 12/13] virtio-serial: convert save/load to visitors


From: Michael Roth
Subject: [Qemu-devel] [PATCH 12/13] virtio-serial: convert save/load to visitors
Date: Thu, 27 Oct 2011 13:17:24 -0500

Signed-off-by: Michael Roth <address@hidden>
---
 hw/virtio-serial-bus.c |  126 ++++++++++++++++++++++++++++++++++-------------
 1 files changed, 91 insertions(+), 35 deletions(-)

diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index a4825b9..78cd643 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -521,21 +521,28 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
     VirtIOSerialPort *port;
     uint32_t nr_active_ports;
     unsigned int i, max_nr_ports;
+    uint8_t *buf;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+
+    visit_start_struct(v, NULL, NULL, "virtio_serial", 0, &err);
 
     /* The virtio device */
     virtio_save(&s->vdev, f);
 
     /* The config space */
-    qemu_put_be16s(f, &s->config.cols);
-    qemu_put_be16s(f, &s->config.rows);
+    visit_type_uint16(v, &s->config.cols, "config.cols", &err);
+    visit_type_uint16(v, &s->config.rows, "config.rows", &err);
 
-    qemu_put_be32s(f, &s->config.max_nr_ports);
+    visit_type_uint32(v, &s->config.max_nr_ports, "config.max_nr_ports", &err);
 
     /* The ports map */
     max_nr_ports = tswap32(s->config.max_nr_ports);
+    visit_start_array(v, NULL, "ports_map", (max_nr_ports + 31) / 32, 4, &err);
     for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
-        qemu_put_be32s(f, &s->ports_map[i]);
+        visit_type_uint32(v, &s->ports_map[i], NULL, &err);
     }
+    visit_end_array(v, &err);
 
     /* Ports */
 
@@ -544,31 +551,46 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
         nr_active_ports++;
     }
 
-    qemu_put_be32s(f, &nr_active_ports);
+    visit_type_uint32(v, &nr_active_ports, "nr_active_ports", &err);
 
     /*
      * Items in struct VirtIOSerialPort.
      */
+    visit_start_list(v, "ports", &err);
     QTAILQ_FOREACH(port, &s->ports, next) {
         uint32_t elem_popped;
 
-        qemu_put_be32s(f, &port->id);
-        qemu_put_byte(f, port->guest_connected);
-        qemu_put_byte(f, port->host_connected);
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+
+        visit_type_uint32(v, &port->id, "id", &err);
+        visit_type_uint8(v, (uint8_t *)&port->guest_connected,
+                         "guest_connected", &err);
+        visit_type_uint8(v, (uint8_t *)&port->host_connected,
+                         "host_connected", &err);
 
-       elem_popped = 0;
+        elem_popped = 0;
         if (port->elem.out_num) {
             elem_popped = 1;
         }
-        qemu_put_be32s(f, &elem_popped);
+        visit_type_uint32(v, &elem_popped, "elem_popped", &err);
         if (elem_popped) {
-            qemu_put_be32s(f, &port->iov_idx);
-            qemu_put_be64s(f, &port->iov_offset);
-
-            qemu_put_buffer(f, (unsigned char *)&port->elem,
-                            sizeof(port->elem));
+            visit_type_uint32(v, &port->iov_idx, "iov_idx", &err);
+            visit_type_uint64(v, &port->iov_offset, "iov_offset", &err);
+
+            /* FIXME: migration badness, serializing structs as blobs */
+            visit_start_array(v, NULL, "elem", sizeof(port->elem), 1, &err);
+            buf = (uint8_t *)&port->elem;
+            for (i = 0; i < sizeof(port->elem); i++) {
+                visit_type_uint8(v, &buf[i], NULL, &err);
+            }
+            visit_end_array(v, &err);
         }
+
+        visit_end_struct(v, &err);
     }
+    visit_end_list(v, &err);
+
+    visit_end_struct(v, &err);
 }
 
 static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
@@ -577,56 +599,73 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, 
int version_id)
     VirtIOSerialPort *port;
     uint32_t max_nr_ports, nr_active_ports, ports_map;
     unsigned int i;
+    int ret = 0;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+    uint8_t *buf;
 
     if (version_id > 3) {
-        return -EINVAL;
+        ret = -EINVAL;
+        goto out;
     }
 
+    visit_start_struct(v, NULL, NULL, "virtio_serial", 0, &err);
+
     /* The virtio device */
     virtio_load(&s->vdev, f);
 
     if (version_id < 2) {
-        return 0;
+        goto out;
     }
 
     /* The config space */
-    qemu_get_be16s(f, &s->config.cols);
-    qemu_get_be16s(f, &s->config.rows);
+    visit_type_uint16(v, &s->config.cols, "config.cols", &err);
+    visit_type_uint16(v, &s->config.rows, "config.rows", &err);
 
-    qemu_get_be32s(f, &max_nr_ports);
+    visit_type_uint32(v, &max_nr_ports, "config.max_nr_ports", &err);
     tswap32s(&max_nr_ports);
     if (max_nr_ports > tswap32(s->config.max_nr_ports)) {
         /* Source could have had more ports than us. Fail migration. */
-        return -EINVAL;
+        ret = -EINVAL;
+        goto out;
     }
 
+    visit_start_array(v, NULL, "ports_map", (max_nr_ports + 31) / 32, 4, &err);
     for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
-        qemu_get_be32s(f, &ports_map);
+        visit_type_uint32(v, &ports_map, NULL, &err);
 
         if (ports_map != s->ports_map[i]) {
             /*
              * Ports active on source and destination don't
              * match. Fail migration.
              */
-            return -EINVAL;
+            ret = -EINVAL;
+            goto out;
         }
     }
+    visit_end_array(v, &err);
 
-    qemu_get_be32s(f, &nr_active_ports);
+    visit_type_uint32(v, &nr_active_ports, "nr_active_ports", &err);
 
     /* Items in struct VirtIOSerialPort */
+    visit_start_list(v, "ports", &err);
     for (i = 0; i < nr_active_ports; i++) {
         uint32_t id;
-        bool host_connected;
+        uint8_t host_connected;
+
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
 
-        id = qemu_get_be32(f);
+        visit_type_uint32(v, &id, "id", &err);
         port = find_port_by_id(s, id);
         if (!port) {
-            return -EINVAL;
+            ret = -EINVAL;
+            goto out;
         }
 
-        port->guest_connected = qemu_get_byte(f);
-        host_connected = qemu_get_byte(f);
+        visit_type_uint8(v, (uint8_t *)&port->guest_connected,
+                         "guest_connected", &err);
+        visit_type_uint8(v, (uint8_t *)&host_connected,
+                         "host_connected", &err);
         if (host_connected != port->host_connected) {
             /*
              * We have to let the guest know of the host connection
@@ -639,13 +678,19 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, 
int version_id)
         if (version_id > 2) {
             uint32_t elem_popped;
 
-            qemu_get_be32s(f, &elem_popped);
+            visit_type_uint32(v, &elem_popped, "elem_popped", &err);
             if (elem_popped) {
-                qemu_get_be32s(f, &port->iov_idx);
-                qemu_get_be64s(f, &port->iov_offset);
+                visit_type_uint32(v, &port->iov_idx, "iov_idx", &err);
+                visit_type_uint64(v, &port->iov_offset, "iov_offset", &err);
+
+                /* FIXME: migration badness, serializing structs as blobs */
+                visit_start_array(v, NULL, "elem", sizeof(port->elem), 1, 
&err);
+                buf = (uint8_t *)&port->elem;
+                for (i = 0; i < sizeof(port->elem); i++) {
+                    visit_type_uint8(v, &buf[i], NULL, &err);
+                }
+                visit_end_array(v, &err);
 
-                qemu_get_buffer(f, (unsigned char *)&port->elem,
-                                sizeof(port->elem));
                 virtqueue_map_sg(port->elem.in_sg, port->elem.in_addr,
                                  port->elem.in_num, 1);
                 virtqueue_map_sg(port->elem.out_sg, port->elem.out_addr,
@@ -658,8 +703,19 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, 
int version_id)
                 virtio_serial_throttle_port(port, false);
             }
         }
+        visit_end_struct(v, &err);
     }
-    return 0;
+    visit_end_list(v, &err);
+
+    visit_end_struct(v, &err);
+
+    if (err) {
+        error_report("error loading virtio-net state: %s", 
error_get_pretty(err));
+        ret = -EINVAL;
+    }
+out:
+    error_free(err);
+    return ret;
 }
 
 static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
-- 
1.7.4.1




reply via email to

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