summaryrefslogtreecommitdiffstats
path: root/migration/migration.c
diff options
context:
space:
mode:
Diffstat (limited to 'migration/migration.c')
-rw-r--r--migration/migration.c66
1 files changed, 36 insertions, 30 deletions
diff --git a/migration/migration.c b/migration/migration.c
index 4dcb511bb6..5a31b23bd6 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -180,6 +180,18 @@ static int migration_maybe_pause(MigrationState *s,
int new_state);
static void migrate_fd_cancel(MigrationState *s);
+static bool migrate_allow_multi_channels = true;
+
+void migrate_protocol_allow_multi_channels(bool allow)
+{
+ migrate_allow_multi_channels = allow;
+}
+
+bool migrate_multi_channels_is_allowed(void)
+{
+ return migrate_allow_multi_channels;
+}
+
static gint page_request_addr_cmp(gconstpointer ap, gconstpointer bp)
{
uintptr_t a = (uintptr_t) ap, b = (uintptr_t) bp;
@@ -469,12 +481,12 @@ static void qemu_start_incoming_migration(const char *uri, Error **errp)
{
const char *p = NULL;
- migrate_protocol_allow_multifd(false); /* reset it anyway */
+ migrate_protocol_allow_multi_channels(false); /* reset it anyway */
qapi_event_send_migration(MIGRATION_STATUS_SETUP);
if (strstart(uri, "tcp:", &p) ||
strstart(uri, "unix:", NULL) ||
strstart(uri, "vsock:", NULL)) {
- migrate_protocol_allow_multifd(true);
+ migrate_protocol_allow_multi_channels(true);
socket_start_incoming_migration(p ? p : uri, errp);
#ifdef CONFIG_RDMA
} else if (strstart(uri, "rdma:", &p)) {
@@ -659,19 +671,20 @@ void migration_incoming_process(void)
}
/* Returns true if recovered from a paused migration, otherwise false */
-static bool postcopy_try_recover(QEMUFile *f)
+static bool postcopy_try_recover(void)
{
MigrationIncomingState *mis = migration_incoming_get_current();
if (mis->state == MIGRATION_STATUS_POSTCOPY_PAUSED) {
/* Resumed from a paused postcopy migration */
- mis->from_src_file = f;
+ /* This should be set already in migration_incoming_setup() */
+ assert(mis->from_src_file);
/* Postcopy has standalone thread to do vm load */
- qemu_file_set_blocking(f, true);
+ qemu_file_set_blocking(mis->from_src_file, true);
/* Re-configure the return path */
- mis->to_src_file = qemu_file_get_return_path(f);
+ mis->to_src_file = qemu_file_get_return_path(mis->from_src_file);
migrate_set_state(&mis->state, MIGRATION_STATUS_POSTCOPY_PAUSED,
MIGRATION_STATUS_POSTCOPY_RECOVER);
@@ -692,11 +705,10 @@ static bool postcopy_try_recover(QEMUFile *f)
void migration_fd_process_incoming(QEMUFile *f, Error **errp)
{
- if (postcopy_try_recover(f)) {
+ if (!migration_incoming_setup(f, errp)) {
return;
}
-
- if (!migration_incoming_setup(f, errp)) {
+ if (postcopy_try_recover()) {
return;
}
migration_incoming_process();
@@ -712,11 +724,6 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
/* The first connection (multifd may have multiple) */
QEMUFile *f = qemu_fopen_channel_input(ioc);
- /* If it's a recovery, we're done */
- if (postcopy_try_recover(f)) {
- return;
- }
-
if (!migration_incoming_setup(f, errp)) {
return;
}
@@ -737,6 +744,10 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
}
if (start_migration) {
+ /* If it's a recovery, we're done */
+ if (postcopy_try_recover()) {
+ return;
+ }
migration_incoming_process();
}
}
@@ -1073,6 +1084,7 @@ static void populate_disk_info(MigrationInfo *info)
static void fill_source_migration_info(MigrationInfo *info)
{
MigrationState *s = migrate_get_current();
+ int state = qatomic_read(&s->state);
GSList *cur_blocker = migration_blockers;
info->blocked_reasons = NULL;
@@ -1092,7 +1104,7 @@ static void fill_source_migration_info(MigrationInfo *info)
}
info->has_blocked_reasons = info->blocked_reasons != NULL;
- switch (s->state) {
+ switch (state) {
case MIGRATION_STATUS_NONE:
/* no migration has happened ever */
/* do not overwrite destination migration status */
@@ -1137,7 +1149,7 @@ static void fill_source_migration_info(MigrationInfo *info)
info->has_status = true;
break;
}
- info->status = s->state;
+ info->status = state;
}
typedef enum WriteTrackingSupport {
@@ -1261,7 +1273,7 @@ static bool migrate_caps_check(bool *cap_list,
/* incoming side only */
if (runstate_check(RUN_STATE_INMIGRATE) &&
- !migrate_multifd_is_allowed() &&
+ !migrate_multi_channels_is_allowed() &&
cap_list[MIGRATION_CAPABILITY_MULTIFD]) {
error_setg(errp, "multifd is not supported by current protocol");
return false;
@@ -1809,6 +1821,9 @@ static void migrate_fd_cleanup(MigrationState *s)
qemu_bh_delete(s->cleanup_bh);
s->cleanup_bh = NULL;
+ g_free(s->hostname);
+ s->hostname = NULL;
+
qemu_savevm_state_cleanup();
if (s->to_dst_file) {
@@ -2148,11 +2163,8 @@ void qmp_migrate_recover(const char *uri, Error **errp)
return;
}
- if (qatomic_cmpxchg(&mis->postcopy_recover_triggered,
- false, true) == true) {
- error_setg(errp, "Migrate recovery is triggered already");
- return;
- }
+ /* If there's an existing transport, release it */
+ migration_incoming_transport_cleanup(mis);
/*
* Note that this call will never start a real migration; it will
@@ -2160,12 +2172,6 @@ void qmp_migrate_recover(const char *uri, Error **errp)
* to continue using that newly established channel.
*/
qemu_start_incoming_migration(uri, errp);
-
- /* Safe to dereference with the assert above */
- if (*errp) {
- /* Reset the flag so user could still retry */
- qatomic_set(&mis->postcopy_recover_triggered, false);
- }
}
void qmp_migrate_pause(Error **errp)
@@ -2319,11 +2325,11 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
}
}
- migrate_protocol_allow_multifd(false);
+ migrate_protocol_allow_multi_channels(false);
if (strstart(uri, "tcp:", &p) ||
strstart(uri, "unix:", NULL) ||
strstart(uri, "vsock:", NULL)) {
- migrate_protocol_allow_multifd(true);
+ migrate_protocol_allow_multi_channels(true);
socket_start_outgoing_migration(s, p ? p : uri, &local_err);
#ifdef CONFIG_RDMA
} else if (strstart(uri, "rdma:", &p)) {