[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 09/18] COLO: Load VMState into QIOChannelBuffer befor
From: |
Amit Shah |
Subject: |
[Qemu-devel] [PULL 09/18] COLO: Load VMState into QIOChannelBuffer before restore it |
Date: |
Sun, 30 Oct 2016 16:17:01 +0530 |
From: zhanghailiang <address@hidden>
We should not destroy the state of SVM (Secondary VM) until we receive
the complete data of PVM's state, in case the primary fails in the process
of sending the state, so we cache the VM's state in secondary side before
load it into SVM.
Besides, we should call qemu_system_reset() before load VM state,
which can ensure the data is intact.
Signed-off-by: zhanghailiang <address@hidden>
Signed-off-by: Li Zhijian <address@hidden>
Signed-off-by: Gonglei <address@hidden>
Reviewed-by: Dr. David Alan Gilbert <address@hidden>
Cc: Dr. David Alan Gilbert <address@hidden>
Reviewed-by: Amit Shah <address@hidden>
Signed-off-by: Amit Shah <address@hidden>
---
migration/colo.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 65 insertions(+), 2 deletions(-)
diff --git a/migration/colo.c b/migration/colo.c
index 9dc54fc..bb9b870 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -115,6 +115,28 @@ static void colo_receive_check_message(QEMUFile *f,
COLOMessage expect_msg,
}
}
+static uint64_t colo_receive_message_value(QEMUFile *f, uint32_t expect_msg,
+ Error **errp)
+{
+ Error *local_err = NULL;
+ uint64_t value;
+ int ret;
+
+ colo_receive_check_message(f, expect_msg, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return 0;
+ }
+
+ value = qemu_get_be64(f);
+ ret = qemu_file_get_error(f);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to get value for COLO message:
%s",
+ COLOMessage_lookup[expect_msg]);
+ }
+ return value;
+}
+
static int colo_do_checkpoint_transaction(MigrationState *s,
QIOChannelBuffer *bioc,
QEMUFile *fb)
@@ -288,6 +310,10 @@ static void colo_wait_handle_message(QEMUFile *f, int
*checkpoint_request,
void *colo_process_incoming_thread(void *opaque)
{
MigrationIncomingState *mis = opaque;
+ QEMUFile *fb = NULL;
+ QIOChannelBuffer *bioc = NULL; /* Cache incoming device state */
+ uint64_t total_size;
+ uint64_t value;
Error *local_err = NULL;
migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
@@ -306,6 +332,10 @@ void *colo_process_incoming_thread(void *opaque)
*/
qemu_file_set_blocking(mis->from_src_file, true);
+ bioc = qio_channel_buffer_new(COLO_BUFFER_BASE_SIZE);
+ fb = qemu_fopen_channel_input(QIO_CHANNEL(bioc));
+ object_unref(OBJECT(bioc));
+
colo_send_message(mis->to_src_file, COLO_MESSAGE_CHECKPOINT_READY,
&local_err);
if (local_err) {
@@ -333,7 +363,29 @@ void *colo_process_incoming_thread(void *opaque)
goto out;
}
- /* TODO: read migration data into colo buffer */
+ value = colo_receive_message_value(mis->from_src_file,
+ COLO_MESSAGE_VMSTATE_SIZE, &local_err);
+ if (local_err) {
+ goto out;
+ }
+
+ /*
+ * Read VM device state data into channel buffer,
+ * It's better to re-use the memory allocated.
+ * Here we need to handle the channel buffer directly.
+ */
+ if (value > bioc->capacity) {
+ bioc->capacity = value;
+ bioc->data = g_realloc(bioc->data, bioc->capacity);
+ }
+ total_size = qemu_get_buffer(mis->from_src_file, bioc->data, value);
+ if (total_size != value) {
+ error_report("Got %" PRIu64 " VMState data, less than expected"
+ " %" PRIu64, total_size, value);
+ goto out;
+ }
+ bioc->usage = total_size;
+ qio_channel_io_seek(QIO_CHANNEL(bioc), 0, 0, NULL);
colo_send_message(mis->to_src_file, COLO_MESSAGE_VMSTATE_RECEIVED,
&local_err);
@@ -341,7 +393,14 @@ void *colo_process_incoming_thread(void *opaque)
goto out;
}
- /* TODO: load vm state */
+ qemu_mutex_lock_iothread();
+ qemu_system_reset(VMRESET_SILENT);
+ if (qemu_loadvm_state(fb) < 0) {
+ error_report("COLO: loadvm failed");
+ qemu_mutex_unlock_iothread();
+ goto out;
+ }
+ qemu_mutex_unlock_iothread();
colo_send_message(mis->to_src_file, COLO_MESSAGE_VMSTATE_LOADED,
&local_err);
@@ -356,6 +415,10 @@ out:
error_report_err(local_err);
}
+ if (fb) {
+ qemu_fclose(fb);
+ }
+
if (mis->to_src_file) {
qemu_fclose(mis->to_src_file);
}
--
2.7.4
- [Qemu-devel] [PULL 02/18] COLO: migrate COLO related info to secondary node, (continued)
- [Qemu-devel] [PULL 02/18] COLO: migrate COLO related info to secondary node, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 03/18] migration: Enter into COLO mode after migration if COLO is enabled, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 04/18] migration: Switch to COLO process after finishing loadvm, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 05/18] COLO: Establish a new communicating path for COLO, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 06/18] COLO: Introduce checkpointing protocol, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 07/18] COLO: Add a new RunState RUN_STATE_COLO, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 08/18] COLO: Send PVM state to secondary side when do checkpoint, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 09/18] COLO: Load VMState into QIOChannelBuffer before restore it,
Amit Shah <=
- [Qemu-devel] [PULL 10/18] COLO: Add checkpoint-delay parameter for migrate-set-parameters, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 11/18] COLO: Synchronize PVM's state to SVM periodically, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 12/18] COLO: Add 'x-colo-lost-heartbeat' command to trigger failover, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 13/18] COLO: Introduce state to record failover process, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 14/18] COLO: Implement the process of failover for primary VM, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 15/18] COLO: Implement failover work for secondary VM, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 16/18] docs: Add documentation for COLO feature, Amit Shah, 2016/10/30
- [Qemu-devel] [PULL 17/18] configure: Support enable/disable COLO feature, Amit Shah, 2016/10/30