Introduced both runstates: RUN_STATE_MIGRATE and RUN_STATE_DUMP_BITMAP to both migration and bitmap dump process.
I want the bitmap dump process to get canceled so whenever the state changes from RUN_STATE_BITMAP to something else. But, this does not happen when I stop the guest via stop qmp interface as the current_run_state variable is not updated. Any thoughts on that? Do I need to make the changes there as well or is there any simple way to do it? Signed-off-by: Sanidhya Kashyap <sanidhya.ii...@gmail.com> --- migration.c | 7 +++++++ savevm.c | 26 +++++++++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/migration.c b/migration.c index 3fc03d6..d91dd4c 100644 --- a/migration.c +++ b/migration.c @@ -436,6 +436,13 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, return; } + if (runstate_check(RUN_STATE_DUMP_BITMAP)) { + error_setg(errp, "bitmap dump in progress"); + return; + } + + runstate_set(RUN_STATE_MIGRATE); + s = migrate_init(¶ms); if (strstart(uri, "tcp:", &p)) { diff --git a/savevm.c b/savevm.c index 525b388..675c8e5 100644 --- a/savevm.c +++ b/savevm.c @@ -1163,7 +1163,8 @@ static void *bitmap_logging_thread(void *opaque) * using the FILE pointer f. */ while (epoch_count < total_epochs) { - if (!runstate_is_running() || b->state != LOG_BITMAP_STATE_ACTIVE) { + if (!runstate_check(RUN_STATE_DUMP_BITMAP) || + b->state != LOG_BITMAP_STATE_ACTIVE) { goto log_thread_end; } bitmap_zero(logging_bitmap, ram_bitmap_pages); @@ -1193,6 +1194,7 @@ static void *bitmap_logging_thread(void *opaque) logging_state_set_status(b, LOG_BITMAP_STATE_ERROR, LOG_BITMAP_STATE_COMPLETED); } + runstate_set(RUN_STATE_RUNNING); return NULL; } @@ -1203,18 +1205,26 @@ void qmp_log_dirty_bitmap(const char *filename, bool has_epochs, int fd = -1; BitmapLogState *b = logging_current_state(); Error *local_err = NULL; - if (b->state == LOG_BITMAP_STATE_ACTIVE || - b->state == LOG_BITMAP_STATE_SETUP || - b->state == LOG_BITMAP_STATE_CANCELING) { + + if (runstate_check(RUN_STATE_DUMP_BITMAP) || + b->state == LOG_BITMAP_STATE_ACTIVE || + b->state == LOG_BITMAP_STATE_SETUP || + b->state == LOG_BITMAP_STATE_CANCELING) { b = NULL; error_setg(errp, "dirty bitmap dump in progress"); return; } - if (b->state == LOG_BITMAP_STATE_COMPLETED) { - b->state = LOG_BITMAP_STATE_NONE; + if (!runstate_is_running()) { + b = NULL; + error_setg(errp, "Guest is not in a running state"); + return; } + runstate_set(RUN_STATE_DUMP_BITMAP); + + b->state = LOG_BITMAP_STATE_NONE; + if (!has_epochs) { epochs = MIN_EPOCH_VALUE; } @@ -1227,14 +1237,16 @@ void qmp_log_dirty_bitmap(const char *filename, bool has_epochs, if (local_err) { b = NULL; error_propagate(errp, local_err); + runstate_set(RUN_STATE_RUNNING); return; } } fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR); if (fd < 0) { - error_setg_file_open(errp, errno, filename); b = NULL; + error_setg_file_open(errp, errno, filename); + runstate_set(RUN_STATE_RUNNING); return; } -- 1.8.3.1