diff options
-rw-r--r-- | block.c | 34 | ||||
-rw-r--r-- | include/block/block.h | 1 | ||||
-rw-r--r-- | include/block/block_int.h | 1 | ||||
-rw-r--r-- | migration/migration.c | 7 | ||||
-rw-r--r-- | qmp.c | 12 |
5 files changed, 55 insertions, 0 deletions
@@ -3303,6 +3303,40 @@ void bdrv_invalidate_cache_all(Error **errp) } } +static int bdrv_inactivate(BlockDriverState *bs) +{ + int ret; + + if (bs->drv->bdrv_inactivate) { + ret = bs->drv->bdrv_inactivate(bs); + if (ret < 0) { + return ret; + } + } + + bs->open_flags |= BDRV_O_INACTIVE; + return 0; +} + +int bdrv_inactivate_all(void) +{ + BlockDriverState *bs; + int ret; + + QTAILQ_FOREACH(bs, &bdrv_states, device_list) { + AioContext *aio_context = bdrv_get_aio_context(bs); + + aio_context_acquire(aio_context); + ret = bdrv_inactivate(bs); + aio_context_release(aio_context); + if (ret < 0) { + return ret; + } + } + + return 0; +} + /**************************************************************/ /* removable device support */ diff --git a/include/block/block.h b/include/block/block.h index 2b7d33c..25f36dc 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -369,6 +369,7 @@ BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, /* Invalidate any cached metadata used by image formats */ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp); void bdrv_invalidate_cache_all(Error **errp); +int bdrv_inactivate_all(void); /* Ensure contents are flushed to disk. */ int bdrv_flush(BlockDriverState *bs); diff --git a/include/block/block_int.h b/include/block/block_int.h index 256609d..428fa33 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -172,6 +172,7 @@ struct BlockDriver { * Invalidate any cached meta-data. */ void (*bdrv_invalidate_cache)(BlockDriverState *bs, Error **errp); + int (*bdrv_inactivate)(BlockDriverState *bs); /* * Flushes all data that was already written to the OS all the way down to diff --git a/migration/migration.c b/migration/migration.c index bc611e4..aaca451 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1422,7 +1422,11 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running) *old_vm_running = runstate_is_running(); global_state_store(); ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); + if (ret < 0) { + goto fail; + } + ret = bdrv_inactivate_all(); if (ret < 0) { goto fail; } @@ -1542,6 +1546,9 @@ static void migration_completion(MigrationState *s, int current_active_state, if (!ret) { ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); if (ret >= 0) { + ret = bdrv_inactivate_all(); + } + if (ret >= 0) { qemu_file_set_rate_limit(s->file, INT64_MAX); qemu_savevm_state_complete_precopy(s->file, false); } @@ -192,6 +192,18 @@ void qmp_cont(Error **errp) } } + /* Continuing after completed migration. Images have been inactivated to + * allow the destination to take control. Need to get control back now. */ + if (runstate_check(RUN_STATE_FINISH_MIGRATE) || + runstate_check(RUN_STATE_POSTMIGRATE)) + { + bdrv_invalidate_cache_all(&local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + } + if (runstate_check(RUN_STATE_INMIGRATE)) { autostart = 1; } else { |