mirror of https://github.com/xemu-project/xemu.git
Migration Pull request (20230601)
Hi In this series: - improve background migration (fiona) - improve vmstate failure states (vladimir) - dropped all the RDMA cleanups Please, apply. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmR5LAoACgkQ9IfvGFhy 1yPOuxAA5QzUfswCIWehrkY8FApDjsecPDq5R6hS1p5pDZkHTF5y6j49J93I65o2 E4qr4l0+DJvBvnxTW29JQ1i0RPqJHnJBFC9Ib4o0NaA/7iRP1sTwYxIN4wWZz6H/ pqG3oQC0WPPqgj9tHSgDW4TNkFjETYaezTN8nddNmyiaO9UxNuR5ZKbeYMroVlfp KbnAYfXV6CyXKUZFT32BYcajYBDZAqBCO6y3gEn77KPlT1/TqnucoYEVuNudq5SE jeCamTzoAQ6SIRFM/eY+aASxdsSryqDS/WLqBFsleXs1kkJ6mkDnNels4HqS+xs9 p2Vhv/59ktoC57XsRgTgzEklAaSHunZivcQkc5szyGVE5TZyKtWg8WhA6rvlqbjK lb3kKpvtVi73+pAWU0hhKFdnCrB6ieCHI70CJ5mpiIu3MzLUyrNJOK4FoKNoJDOD Dp45DK+W/EMg51pXyHJZZqHM1p0GGj0fmhv5T05nJ590fIWV4iqDdHFxsMZ9vEPN iEvAB7/pXz+yECznDFrp2e047rshOGaKKNSW3zl3/7D32Ds2FKur76dL4BoymztW HHLxmRWn8HmHMoKYLoawWVmCBsDqy8BFct+rHbA6h/0nSCPYIUCmMrSYVqajUbXD Ulkh4KNQGoBCzp5Toa0dYEXVc891wVOw4k8PTARwf2OYskSkT88= =Km5X -----END PGP SIGNATURE----- Merge tag 'migration-20230601-pull-request' of https://gitlab.com/juan.quintela/qemu into staging Migration Pull request (20230601) Hi In this series: - improve background migration (fiona) - improve vmstate failure states (vladimir) - dropped all the RDMA cleanups Please, apply. # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmR5LAoACgkQ9IfvGFhy # 1yPOuxAA5QzUfswCIWehrkY8FApDjsecPDq5R6hS1p5pDZkHTF5y6j49J93I65o2 # E4qr4l0+DJvBvnxTW29JQ1i0RPqJHnJBFC9Ib4o0NaA/7iRP1sTwYxIN4wWZz6H/ # pqG3oQC0WPPqgj9tHSgDW4TNkFjETYaezTN8nddNmyiaO9UxNuR5ZKbeYMroVlfp # KbnAYfXV6CyXKUZFT32BYcajYBDZAqBCO6y3gEn77KPlT1/TqnucoYEVuNudq5SE # jeCamTzoAQ6SIRFM/eY+aASxdsSryqDS/WLqBFsleXs1kkJ6mkDnNels4HqS+xs9 # p2Vhv/59ktoC57XsRgTgzEklAaSHunZivcQkc5szyGVE5TZyKtWg8WhA6rvlqbjK # lb3kKpvtVi73+pAWU0hhKFdnCrB6ieCHI70CJ5mpiIu3MzLUyrNJOK4FoKNoJDOD # Dp45DK+W/EMg51pXyHJZZqHM1p0GGj0fmhv5T05nJ590fIWV4iqDdHFxsMZ9vEPN # iEvAB7/pXz+yECznDFrp2e047rshOGaKKNSW3zl3/7D32Ds2FKur76dL4BoymztW # HHLxmRWn8HmHMoKYLoawWVmCBsDqy8BFct+rHbA6h/0nSCPYIUCmMrSYVqajUbXD # Ulkh4KNQGoBCzp5Toa0dYEXVc891wVOw4k8PTARwf2OYskSkT88= # =Km5X # -----END PGP SIGNATURE----- # gpg: Signature made Thu 01 Jun 2023 04:38:50 PM PDT # gpg: using RSA key 1899FF8EDEBF58CCEE034B82F487EF185872D723 # gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [unknown] # gpg: aka "Juan Quintela <quintela@trasno.org>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723 * tag 'migration-20230601-pull-request' of https://gitlab.com/juan.quintela/qemu: migration: stop tracking ram writes when cancelling background migration migration: restore vmstate on migration failure migration: switch from .vm_was_running to .vm_old_state runstate: drop unused runstate_store() migration: never fail in global_state_store() runstate: add runstate_get() Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
a86d7b9ec0
|
@ -16,7 +16,7 @@
|
|||
#include "qapi/qapi-types-run-state.h"
|
||||
|
||||
void register_global_state(void);
|
||||
int global_state_store(void);
|
||||
void global_state_store(void);
|
||||
void global_state_store_running(void);
|
||||
bool global_state_received(void);
|
||||
RunState global_state_get_runstate(void);
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
bool runstate_check(RunState state);
|
||||
void runstate_set(RunState new_state);
|
||||
RunState runstate_get(void);
|
||||
bool runstate_is_running(void);
|
||||
bool runstate_needs_reset(void);
|
||||
bool runstate_store(char *str, size_t size);
|
||||
|
||||
typedef void VMChangeStateHandler(void *opaque, bool running, RunState state);
|
||||
|
||||
|
|
|
@ -29,23 +29,22 @@ typedef struct {
|
|||
|
||||
static GlobalState global_state;
|
||||
|
||||
int global_state_store(void)
|
||||
static void global_state_do_store(RunState state)
|
||||
{
|
||||
if (!runstate_store((char *)global_state.runstate,
|
||||
sizeof(global_state.runstate))) {
|
||||
error_report("runstate name too big: %s", global_state.runstate);
|
||||
trace_migrate_state_too_big();
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
const char *state_str = RunState_str(state);
|
||||
assert(strlen(state_str) < sizeof(global_state.runstate));
|
||||
strpadcpy((char *)global_state.runstate, sizeof(global_state.runstate),
|
||||
state_str, '\0');
|
||||
}
|
||||
|
||||
void global_state_store(void)
|
||||
{
|
||||
global_state_do_store(runstate_get());
|
||||
}
|
||||
|
||||
void global_state_store_running(void)
|
||||
{
|
||||
const char *state = RunState_str(RUN_STATE_RUNNING);
|
||||
assert(strlen(state) < sizeof(global_state.runstate));
|
||||
strpadcpy((char *)global_state.runstate, sizeof(global_state.runstate),
|
||||
state, '\0');
|
||||
global_state_do_store(RUN_STATE_RUNNING);
|
||||
}
|
||||
|
||||
bool global_state_received(void)
|
||||
|
|
|
@ -1402,7 +1402,7 @@ void migrate_init(MigrationState *s)
|
|||
|
||||
s->start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
|
||||
s->total_time = 0;
|
||||
s->vm_was_running = false;
|
||||
s->vm_old_state = -1;
|
||||
s->iteration_initial_bytes = 0;
|
||||
s->threshold_size = 0;
|
||||
}
|
||||
|
@ -2287,28 +2287,28 @@ static void migration_completion(MigrationState *s)
|
|||
qemu_mutex_lock_iothread();
|
||||
s->downtime_start = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
|
||||
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
|
||||
s->vm_was_running = runstate_is_running();
|
||||
ret = global_state_store();
|
||||
|
||||
if (!ret) {
|
||||
ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
|
||||
trace_migration_completion_vm_stop(ret);
|
||||
if (ret >= 0) {
|
||||
ret = migration_maybe_pause(s, ¤t_active_state,
|
||||
MIGRATION_STATUS_DEVICE);
|
||||
}
|
||||
if (ret >= 0) {
|
||||
/*
|
||||
* Inactivate disks except in COLO, and track that we
|
||||
* have done so in order to remember to reactivate
|
||||
* them if migration fails or is cancelled.
|
||||
*/
|
||||
s->block_inactive = !migrate_colo();
|
||||
migration_rate_set(RATE_LIMIT_DISABLED);
|
||||
ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false,
|
||||
s->block_inactive);
|
||||
}
|
||||
s->vm_old_state = runstate_get();
|
||||
global_state_store();
|
||||
|
||||
ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
|
||||
trace_migration_completion_vm_stop(ret);
|
||||
if (ret >= 0) {
|
||||
ret = migration_maybe_pause(s, ¤t_active_state,
|
||||
MIGRATION_STATUS_DEVICE);
|
||||
}
|
||||
if (ret >= 0) {
|
||||
/*
|
||||
* Inactivate disks except in COLO, and track that we
|
||||
* have done so in order to remember to reactivate
|
||||
* them if migration fails or is cancelled.
|
||||
*/
|
||||
s->block_inactive = !migrate_colo();
|
||||
migration_rate_set(RATE_LIMIT_DISABLED);
|
||||
ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false,
|
||||
s->block_inactive);
|
||||
}
|
||||
|
||||
qemu_mutex_unlock_iothread();
|
||||
|
||||
if (ret < 0) {
|
||||
|
@ -2400,13 +2400,6 @@ static void bg_migration_completion(MigrationState *s)
|
|||
{
|
||||
int current_active_state = s->state;
|
||||
|
||||
/*
|
||||
* Stop tracking RAM writes - un-protect memory, un-register UFFD
|
||||
* memory ranges, flush kernel wait queues and wake up threads
|
||||
* waiting for write fault to be resolved.
|
||||
*/
|
||||
ram_write_tracking_stop();
|
||||
|
||||
if (s->state == MIGRATION_STATUS_ACTIVE) {
|
||||
/*
|
||||
* By this moment we have RAM content saved into the migration stream.
|
||||
|
@ -2761,18 +2754,18 @@ static void migration_iteration_finish(MigrationState *s)
|
|||
case MIGRATION_STATUS_COLO:
|
||||
assert(migrate_colo());
|
||||
migrate_start_colo_process(s);
|
||||
s->vm_was_running = true;
|
||||
s->vm_old_state = RUN_STATE_RUNNING;
|
||||
/* Fallthrough */
|
||||
case MIGRATION_STATUS_FAILED:
|
||||
case MIGRATION_STATUS_CANCELLED:
|
||||
case MIGRATION_STATUS_CANCELLING:
|
||||
if (s->vm_was_running) {
|
||||
if (s->vm_old_state == RUN_STATE_RUNNING) {
|
||||
if (!runstate_check(RUN_STATE_SHUTDOWN)) {
|
||||
vm_start();
|
||||
}
|
||||
} else {
|
||||
if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
|
||||
runstate_set(RUN_STATE_POSTMIGRATE);
|
||||
runstate_set(s->vm_old_state);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2788,6 +2781,13 @@ static void migration_iteration_finish(MigrationState *s)
|
|||
|
||||
static void bg_migration_iteration_finish(MigrationState *s)
|
||||
{
|
||||
/*
|
||||
* Stop tracking RAM writes - un-protect memory, un-register UFFD
|
||||
* memory ranges, flush kernel wait queues and wake up threads
|
||||
* waiting for write fault to be resolved.
|
||||
*/
|
||||
ram_write_tracking_stop();
|
||||
|
||||
qemu_mutex_lock_iothread();
|
||||
switch (s->state) {
|
||||
case MIGRATION_STATUS_COMPLETED:
|
||||
|
@ -3086,11 +3086,9 @@ static void *bg_migration_thread(void *opaque)
|
|||
* transition in vm_stop_force_state() we need to wakeup it up.
|
||||
*/
|
||||
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
|
||||
s->vm_was_running = runstate_is_running();
|
||||
s->vm_old_state = runstate_get();
|
||||
|
||||
if (global_state_store()) {
|
||||
goto fail;
|
||||
}
|
||||
global_state_store();
|
||||
/* Forcibly stop VM before saving state of vCPUs and devices */
|
||||
if (vm_stop_force_state(RUN_STATE_PAUSED)) {
|
||||
goto fail;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "net/announce.h"
|
||||
#include "qom/object.h"
|
||||
#include "postcopy-ram.h"
|
||||
#include "sysemu/runstate.h"
|
||||
|
||||
struct PostcopyBlocktimeContext;
|
||||
|
||||
|
@ -317,12 +318,14 @@ struct MigrationState {
|
|||
int64_t expected_downtime;
|
||||
bool capabilities[MIGRATION_CAPABILITY__MAX];
|
||||
int64_t setup_time;
|
||||
|
||||
/*
|
||||
* Whether guest was running when we enter the completion stage.
|
||||
* State before stopping the vm by vm_stop_force_state().
|
||||
* If migration is interrupted by any reason, we need to continue
|
||||
* running the guest on source.
|
||||
* running the guest on source if it was running or restore its stopped
|
||||
* state.
|
||||
*/
|
||||
bool vm_was_running;
|
||||
RunState vm_old_state;
|
||||
|
||||
/* Flag set once the migration has been asked to enter postcopy */
|
||||
bool start_postcopy;
|
||||
|
|
|
@ -2919,11 +2919,7 @@ bool save_snapshot(const char *name, bool overwrite, const char *vmstate,
|
|||
|
||||
saved_vm_running = runstate_is_running();
|
||||
|
||||
ret = global_state_store();
|
||||
if (ret) {
|
||||
error_setg(errp, "Error saving global state");
|
||||
return false;
|
||||
}
|
||||
global_state_store();
|
||||
vm_stop(RUN_STATE_SAVE_VM);
|
||||
|
||||
bdrv_drain_all_begin();
|
||||
|
|
|
@ -121,7 +121,13 @@ static const RunStateTransition runstate_transitions_def[] = {
|
|||
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED },
|
||||
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
|
||||
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_PRELAUNCH },
|
||||
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO},
|
||||
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO },
|
||||
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_INTERNAL_ERROR },
|
||||
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_IO_ERROR },
|
||||
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_SHUTDOWN },
|
||||
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_SUSPENDED },
|
||||
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_WATCHDOG },
|
||||
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_GUEST_PANICKED },
|
||||
|
||||
{ RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING },
|
||||
{ RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH },
|
||||
|
@ -175,18 +181,6 @@ bool runstate_check(RunState state)
|
|||
return current_run_state == state;
|
||||
}
|
||||
|
||||
bool runstate_store(char *str, size_t size)
|
||||
{
|
||||
const char *state = RunState_str(current_run_state);
|
||||
size_t len = strlen(state) + 1;
|
||||
|
||||
if (len > size) {
|
||||
return false;
|
||||
}
|
||||
memcpy(str, state, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void runstate_init(void)
|
||||
{
|
||||
const RunStateTransition *p;
|
||||
|
@ -221,6 +215,11 @@ void runstate_set(RunState new_state)
|
|||
current_run_state = new_state;
|
||||
}
|
||||
|
||||
RunState runstate_get(void)
|
||||
{
|
||||
return current_run_state;
|
||||
}
|
||||
|
||||
bool runstate_is_running(void)
|
||||
{
|
||||
return runstate_check(RUN_STATE_RUNNING);
|
||||
|
|
Loading…
Reference in New Issue