[Spice-devel] [spice PATCH 21/55] char device migration: restore state at destination from migration data

Yonit Halperin yhalperi at redhat.com
Wed Aug 15 00:56:01 PDT 2012


---
 server/char_device.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 server/char_device.h |    3 +++
 2 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/server/char_device.c b/server/char_device.c
index d97c6dd..b85a24d 100644
--- a/server/char_device.c
+++ b/server/char_device.c
@@ -873,3 +873,52 @@ void spice_char_device_state_migrate_data_marshall(SpiceCharDeviceState *dev,
                 dev, *write_to_dev_size_ptr, *write_to_dev_tokens_ptr);
 }
 
+int spice_char_device_state_restore(SpiceCharDeviceState *dev,
+                                    SpiceMigrateDataCharDevice *mig_data)
+{
+    SpiceCharDeviceClientState *client_state;
+    uint32_t client_tokens_window;
+
+    spice_assert(dev->num_clients == 1 && dev->wait_for_migrate_data);
+
+    client_state = SPICE_CONTAINEROF(ring_get_tail(&dev->clients),
+                                     SpiceCharDeviceClientState,
+                                     link);
+    if (mig_data->version > SPICE_MIGRATE_DATA_CHAR_DEVICE_VERSION) {
+        spice_error("dev %p error: migration data version %u is bigger than self %u",
+                    dev, mig_data->version, SPICE_MIGRATE_DATA_CHAR_DEVICE_VERSION);
+        return FALSE;
+    }
+    spice_assert(!dev->cur_write_buf && ring_is_empty(&dev->write_queue));
+    spice_assert(mig_data->connected);
+
+    client_tokens_window = client_state->num_client_tokens; /* initial state of tokens */
+    client_state->num_client_tokens = mig_data->num_client_tokens;
+    /* assumption: client_tokens_window stays the same across severs */
+    client_state->num_client_tokens_free = client_tokens_window -
+                                           mig_data->num_client_tokens -
+                                           mig_data->write_num_client_tokens;
+    client_state->num_send_tokens = mig_data->num_send_tokens;
+
+    if (mig_data->write_size > 0) {
+        if (mig_data->write_num_client_tokens) {
+            dev->cur_write_buf = __spice_char_device_write_buffer_get(dev, client_state->client,
+                                                                      mig_data->write_size,
+                                                                      mig_data->write_num_client_tokens);
+        } else {
+            dev->cur_write_buf = __spice_char_device_write_buffer_get(dev, NULL, mig_data->write_size,
+                                                                      0);
+        }
+        /* the first write buffer contains all the data that was saved for migration */
+        memcpy(dev->cur_write_buf->buf,
+               ((uint8_t *)mig_data) + mig_data->write_data_ptr - sizeof(SpiceMigrateDataHeader),
+               mig_data->write_size);
+        dev->cur_write_buf->buf_used = mig_data->write_size;
+        dev->cur_write_buf_pos = dev->cur_write_buf->buf;
+    }
+    dev->wait_for_migrate_data = FALSE;
+    spice_char_device_write_to_device(dev);
+    spice_char_device_read_from_device(dev);
+    return TRUE;
+}
+
diff --git a/server/char_device.h b/server/char_device.h
index f3278e3..6688e91 100644
--- a/server/char_device.h
+++ b/server/char_device.h
@@ -126,6 +126,9 @@ void spice_char_device_state_migrate_data_marshall(SpiceCharDeviceState *dev,
                                                   SpiceMarshaller *m);
 void spice_char_device_state_migrate_data_marshall_empty(SpiceMarshaller *m);
 
+int spice_char_device_state_restore(SpiceCharDeviceState *dev,
+                                    SpiceMigrateDataCharDevice *mig_data);
+
 /*
  * Resets write/read queues, and moves that state to being stopped.
  * This routine is a workaround for a bad tokens management in the vdagent
-- 
1.7.7.6



More information about the Spice-devel mailing list