summaryrefslogtreecommitdiffstats
path: root/server/reds.c
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2012-08-05 15:57:44 +0300
committerYonit Halperin <yhalperi@redhat.com>2012-08-27 09:13:07 +0300
commit3af4b7235d23e9d0be2da780d5da9b3fcb29466f (patch)
treeed5003644f97db35ac29a57791651c0f5180cd4b /server/reds.c
parentc617379821feb0c2cf990394163765498ae1bda1 (diff)
downloadspice-3af4b7235d23e9d0be2da780d5da9b3fcb29466f.tar.gz
spice-3af4b7235d23e9d0be2da780d5da9b3fcb29466f.tar.xz
spice-3af4b7235d23e9d0be2da780d5da9b3fcb29466f.zip
main: send MSG_MIGRATE upon vm migration completion
Before sending the above msg, if there is a pending partial msg that has been read from the agent, we send it to the client. The alternative was to keep the msg as part of the migration data, and then to send it to the destination server via the client and to wait there for the msg chunk completion, before sending it to the client. Of course, the latter is less efficient.
Diffstat (limited to 'server/reds.c')
-rw-r--r--server/reds.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/server/reds.c b/server/reds.c
index f1cc2f27..1deceb42 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -1219,6 +1219,50 @@ void reds_on_main_mouse_mode_request(void *message, size_t size)
}
}
+/*
+ * Push partial agent data, even if not all the chunk was consumend,
+ * in order to avoid the roundtrip (src-server->client->dest-server)
+ */
+void reds_on_main_channel_migrate(MainChannelClient *mcc)
+{
+ VDIPortState *agent_state = &reds->agent_state;
+ uint32_t read_data_len;
+
+ spice_assert(reds->num_clients == 1);
+
+ if (agent_state->read_state != VDI_PORT_READ_STATE_READ_DATA) {
+ return;
+ }
+ spice_assert(agent_state->current_read_buf->data &&
+ agent_state->recive_pos > agent_state->current_read_buf->data);
+ read_data_len = agent_state->recive_pos - agent_state->current_read_buf->data;
+
+ if (agent_state->read_filter.msg_data_to_read ||
+ read_data_len > sizeof(VDAgentMessage)) { /* msg header has been read */
+ VDIReadBuf *read_buf = agent_state->current_read_buf;
+
+ spice_debug("push partial read %u (msg first chunk? %d)", read_data_len,
+ !agent_state->read_filter.msg_data_to_read);
+
+ read_buf->len = read_data_len;
+ if (vdi_port_read_buf_process(agent_state->vdi_chunk_header.port, read_buf)) {
+ main_channel_client_push_agent_data(mcc,
+ read_buf->data,
+ read_buf->len,
+ vdi_port_read_buf_release,
+ read_buf);
+ } else {
+ vdi_port_read_buf_unref(read_buf);
+ }
+
+ spice_assert(agent_state->recive_len);
+ agent_state->message_recive_len += agent_state->recive_len;
+ agent_state->read_state = VDI_PORT_READ_STATE_GET_BUFF;
+ agent_state->current_read_buf = NULL;
+ agent_state->recive_pos = NULL;
+ }
+}
+
#define MAIN_CHANNEL_MIG_DATA_VERSION 1
typedef struct WriteQueueInfo {