[Spice-devel] [spice PATCH 19/55] char device migration: marshall migration data

Yonit Halperin yhalperi at redhat.com
Wed Aug 15 00:55:59 PDT 2012


---
 server/char_device.c |   69 ++++++++++++++++++++++++++++++++++++++++++++++++++
 server/char_device.h |    5 +++
 2 files changed, 74 insertions(+), 0 deletions(-)

diff --git a/server/char_device.c b/server/char_device.c
index 419b7df..84121e6 100644
--- a/server/char_device.c
+++ b/server/char_device.c
@@ -790,3 +790,72 @@ void spice_char_device_wakeup(SpiceCharDeviceState *dev)
     spice_char_device_read_from_device(dev);
 }
 
+/*************
+ * Migration *
+ * **********/
+
+void spice_char_device_state_migrate_data_marshall_empty(SpiceMarshaller *m)
+{
+    SpiceMigrateDataCharDevice mig_data;
+
+    memset(&mig_data, 0, sizeof(mig_data));
+    mig_data.version = SPICE_MIGRATE_DATA_CHAR_DEVICE_VERSION;
+    mig_data.connected = FALSE;
+    spice_marshaller_add_ref(m, (uint8_t *)&mig_data, sizeof(SpiceMigrateDataCharDevice));
+}
+
+void spice_char_device_state_migrate_data_marshall(SpiceCharDeviceState *dev,
+                                                   SpiceMarshaller *m)
+{
+    SpiceCharDeviceClientState *client_state;
+    RingItem *item;
+    uint32_t *write_to_dev_size_ptr;
+    uint32_t *write_to_dev_tokens_ptr;
+    SpiceMarshaller *m2;
+
+    /* multi-clients are not supported */
+    spice_assert(dev->num_clients == 1);
+    client_state = SPICE_CONTAINEROF(ring_get_tail(&dev->clients),
+                                     SpiceCharDeviceClientState,
+                                     link);
+    /* FIXME: if there were more than one client before the marshalling,
+     * it is possible that the send_queue_size > 0, and the send data
+     * should be migrated as well */
+    spice_assert(client_state->send_queue_size == 0);
+    spice_marshaller_add_uint32(m, SPICE_MIGRATE_DATA_CHAR_DEVICE_VERSION);
+    spice_marshaller_add_uint8(m, 1); /* connected */
+    spice_marshaller_add_uint32(m, client_state->num_client_tokens);
+    spice_marshaller_add_uint32(m, client_state->num_send_tokens);
+    write_to_dev_size_ptr = (uint32_t *)spice_marshaller_reserve_space(m, sizeof(uint32_t));
+    write_to_dev_tokens_ptr = (uint32_t *)spice_marshaller_reserve_space(m, sizeof(uint32_t));
+    *write_to_dev_size_ptr = 0;
+    *write_to_dev_tokens_ptr = 0;
+
+    m2 = spice_marshaller_get_ptr_submarshaller(m, 0);
+    if (dev->cur_write_buf) {
+        uint32_t buf_remaining = dev->cur_write_buf->buf + dev->cur_write_buf->buf_used -
+                                 dev->cur_write_buf_pos;
+
+        spice_marshaller_add_ref(m2, dev->cur_write_buf_pos, buf_remaining);
+        *write_to_dev_size_ptr += buf_remaining;
+        if (dev->cur_write_buf->origin == WRITE_BUFFER_ORIGIN_CLIENT) {
+            spice_assert(dev->cur_write_buf->client == client_state->client);
+            (*write_to_dev_tokens_ptr) += dev->cur_write_buf->token_price;
+        }
+    }
+
+    RING_FOREACH_REVERSED(item, &dev->write_queue) {
+        SpiceCharDeviceWriteBuffer *write_buf;
+
+        write_buf = SPICE_CONTAINEROF(item, SpiceCharDeviceWriteBuffer, link);
+        spice_marshaller_add_ref(m2, write_buf->buf, write_buf->buf_used);
+        *write_to_dev_size_ptr += write_buf->buf_used;
+        if (write_buf->origin == WRITE_BUFFER_ORIGIN_CLIENT) {
+            spice_assert(write_buf->client == client_state->client);
+            (*write_to_dev_tokens_ptr) += write_buf->token_price;
+        }
+    }
+    spice_debug("migration data dev %p: write_queue size %u tokens %u",
+                dev, *write_to_dev_size_ptr, *write_to_dev_tokens_ptr);
+}
+
diff --git a/server/char_device.h b/server/char_device.h
index 9b70219..186b1f1 100644
--- a/server/char_device.h
+++ b/server/char_device.h
@@ -3,6 +3,7 @@
 
 #include "spice.h"
 #include "red_channel.h"
+#include "migration_protocol.h"
 
 /*
  * Shared code for char devices, mainly for flow control.
@@ -120,6 +121,10 @@ void spice_char_device_state_destroy(SpiceCharDeviceState *dev);
 
 void *spice_char_device_state_opaque_get(SpiceCharDeviceState *dev);
 
+/* only one client is supported */
+void spice_char_device_state_migrate_data_marshall(SpiceCharDeviceState *dev,
+                                                  SpiceMarshaller *m);
+void spice_char_device_state_migrate_data_marshall_empty(SpiceMarshaller *m);
 
 /*
  * Resets write/read queues, and moves that state to being stopped.
-- 
1.7.7.6



More information about the Spice-devel mailing list