[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