@@ -102,7 +102,7 @@ static MigrationIncomingState *current_incoming;
static GSList *migration_blockers[MIG_MODE__MAX];
static bool migration_object_check(MigrationState *ms, Error **errp);
-static bool migration_switchover_start(MigrationState *s);
+static bool migration_switchover_start(MigrationState *s, Error **errp);
static void migrate_fd_cancel(MigrationState *s);
static bool close_return_path_on_source(MigrationState *s);
static void migration_completion_end(MigrationState *s);
@@ -2540,21 +2540,10 @@ static int postcopy_start(MigrationState *ms, Error **errp)
goto fail;
}
- if (!migration_switchover_start(ms)) {
- error_setg(errp, "migration_switchover_start() failed");
+ if (!migration_switchover_start(ms, errp)) {
goto fail;
}
- if (!migration_block_inactivate()) {
- error_setg(errp, "%s: Failed in bdrv_inactivate_all()", __func__);
- goto fail;
- }
-
- /* Switchover phase, switch to unlimited */
- migration_rate_set(RATE_LIMIT_DISABLED);
-
- precopy_notify_complete();
-
/*
* Cause any non-postcopiable, but iterative devices to
* send out their final data.
@@ -2686,7 +2675,7 @@ fail:
}
/**
- * @migration_switchover_start: Start VM switchover procedure
+ * @migration_switchover_prepare: Start VM switchover procedure
*
* @s: The migration state object pointer
*
@@ -2701,7 +2690,7 @@ fail:
*
* Returns: true on success, false on interruptions.
*/
-static bool migration_switchover_start(MigrationState *s)
+static bool migration_switchover_prepare(MigrationState *s)
{
/* Concurrent cancellation? Quit */
if (s->state == MIGRATION_STATUS_CANCELLING) {
@@ -2749,21 +2738,13 @@ static bool migration_switchover_start(MigrationState *s)
return s->state == MIGRATION_STATUS_DEVICE;
}
-static int migration_completion_precopy(MigrationState *s)
+static bool migration_switchover_start(MigrationState *s, Error **errp)
{
- int ret;
-
- bql_lock();
-
- if (!migrate_mode_is_cpr(s)) {
- ret = migration_stop_vm(s, RUN_STATE_FINISH_MIGRATE);
- if (ret < 0) {
- goto out_unlock;
- }
- }
+ ERRP_GUARD();
- if (!migration_switchover_start(s)) {
- goto out_unlock;
+ if (!migration_switchover_prepare(s)) {
+ error_setg(errp, "Switchover is interrupted");
+ return false;
}
/* Inactivate disks except in COLO */
@@ -2773,8 +2754,8 @@ static int migration_completion_precopy(MigrationState *s)
* bdrv_activate_all() on the other end won't fail.
*/
if (!migration_block_inactivate()) {
- ret = -EFAULT;
- goto out_unlock;
+ error_setg(errp, "Block inactivate failed during switchover");
+ return false;
}
}
@@ -2782,6 +2763,27 @@ static int migration_completion_precopy(MigrationState *s)
precopy_notify_complete();
+ return true;
+}
+
+static int migration_completion_precopy(MigrationState *s)
+{
+ int ret;
+
+ bql_lock();
+
+ if (!migrate_mode_is_cpr(s)) {
+ ret = migration_stop_vm(s, RUN_STATE_FINISH_MIGRATE);
+ if (ret < 0) {
+ goto out_unlock;
+ }
+ }
+
+ if (!migration_switchover_start(s, NULL)) {
+ ret = -EFAULT;
+ goto out_unlock;
+ }
+
ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false);
out_unlock:
bql_unlock();
Now after all the cleanups, finally we can merge the switchover startup phase into one single function for precopy/postcopy. Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/migration.c | 62 ++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 30 deletions(-)