**3.** On Secondary VM's QEMU monitor, issue command::
{"execute":"qmp_capabilities"}
- {"execute": "migrate-set-capabilities", "arguments": {"capabilities": [ {"capability": "x-colo", "state": true } ] } }
+ {"execute": "migrate-set-capabilities", "arguments": {"capabilities": [ {"capability": "return-path", "state": true }, {"capability": "x-colo", "state": true } ] } }
{"execute": "nbd-server-start", "arguments": {"addr": {"type": "inet", "data": {"host": "0.0.0.0", "port": "9999"} } } }
{"execute": "nbd-server-add", "arguments": {"device": "parent0", "writable": true } }
{"execute":"qmp_capabilities"}
{"execute": "blockdev-add", "arguments": {"driver": "nbd", "node-name": "nbd0", "server": {"type": "inet", "host": "127.0.0.2", "port": "9999"}, "export": "parent0", "detect-zeroes": "on"} }
{"execute": "x-blockdev-change", "arguments":{"parent": "colo-disk0", "node": "nbd0" } }
- {"execute": "migrate-set-capabilities", "arguments": {"capabilities": [ {"capability": "x-colo", "state": true } ] } }
+ {"execute": "migrate-set-capabilities", "arguments": {"capabilities": [ {"capability": "return-path", "state": true }, {"capability": "x-colo", "state": true } ] } }
{"execute": "migrate", "arguments": {"uri": "tcp:127.0.0.2:9998" } }
Note:
Error *local_err = NULL;
int ret;
+ assert(s->rp_state.from_dst_file);
+ assert(!s->rp_state.rp_thread_created);
if (get_colo_mode() != COLO_MODE_PRIMARY) {
error_report("COLO mode must be COLO_MODE_PRIMARY");
return;
failover_init_state();
- s->rp_state.from_dst_file = qemu_file_get_return_path(s->to_dst_file);
- if (!s->rp_state.from_dst_file) {
- error_report("Open QEMUFile from_dst_file failed");
- goto out;
- }
-
packets_compare_notifier.notify = colo_compare_notify_checkpoint;
colo_compare_register_notifier(&packets_compare_notifier);
colo_compare_unregister_notifier(&packets_compare_notifier);
timer_free(s->colo_delay_timer);
qemu_event_destroy(&s->colo_checkpoint_event);
-
- /*
- * Must be called after failover BH is completed,
- * Or the failover BH may shutdown the wrong fd that
- * re-used by other threads after we release here.
- */
- if (s->rp_state.from_dst_file) {
- qemu_fclose(s->rp_state.from_dst_file);
- s->rp_state.from_dst_file = NULL;
- }
}
void migrate_start_colo_process(MigrationState *s)
migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
MIGRATION_STATUS_COLO);
+ assert(mis->to_src_file);
if (get_colo_mode() != COLO_MODE_SECONDARY) {
error_report("COLO mode must be COLO_MODE_SECONDARY");
return NULL;
failover_init_state();
- mis->to_src_file = qemu_file_get_return_path(mis->from_src_file);
/*
* Note: the communication between Primary side and Secondary side
* should be sequential, we set the fd to unblocked in migration incoming
goto out;
}
+ /*
+ * rp thread still running on primary side, shut it down to go into
+ * colo state.
+ */
+ migrate_send_rp_shut(mis, 0);
+
colo_incoming_start_dirty_log();
bioc = qio_channel_buffer_new(COLO_BUFFER_BASE_SIZE);
ERRP_GUARD();
MigrationIncomingState *mis = migration_incoming_get_current();
-#ifndef CONFIG_REPLICATION
+#ifdef CONFIG_REPLICATION
+ if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
+ if (!new_caps[MIGRATION_CAPABILITY_RETURN_PATH]) {
+ error_setg(errp, "Capability 'x-colo' requires capability "
+ "'return-path'");
+ return false;
+ }
+ }
+#else
if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
error_setg(errp, "QEMU compiled without replication module"
" can't enable COLO");
* used in production.
*/
args->start.oob = true;
+ args->start.caps[MIGRATION_CAPABILITY_RETURN_PATH] = true;
args->start.caps[MIGRATION_CAPABILITY_X_COLO] = true;
if (migrate_start(&from, &to, args->listen_uri, &args->start)) {
* MigrationCapability_lookup and MIGRATION_CAPABILITY_ constants
* are from qapi-types-migration.h.
*/
+
+ /*
+ * Enable return path first, since other features depend on it.
+ */
+ if (args->caps[MIGRATION_CAPABILITY_RETURN_PATH]) {
+ if (from) {
+ migrate_set_capability(from, "return-path", true);
+ }
+ if (to) {
+ migrate_set_capability(to, "return-path", true);
+ }
+ }
+
for (uint8_t i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
if (!args->caps[i]) {
continue;