migration/block-dirty-bitmap: refactor state global variables
Move all state variables into one global struct. Reduce global variable usage, utilizing opaque pointer where possible. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> Message-Id: <20200727194236.19551-12-vsementsov@virtuozzo.com> Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
d0cccbd118
commit
3b52726ec0
@ -128,6 +128,12 @@ typedef struct DBMSaveState {
|
|||||||
BdrvDirtyBitmap *prev_bitmap;
|
BdrvDirtyBitmap *prev_bitmap;
|
||||||
} DBMSaveState;
|
} DBMSaveState;
|
||||||
|
|
||||||
|
typedef struct LoadBitmapState {
|
||||||
|
BlockDriverState *bs;
|
||||||
|
BdrvDirtyBitmap *bitmap;
|
||||||
|
bool migrated;
|
||||||
|
} LoadBitmapState;
|
||||||
|
|
||||||
/* State of the dirty bitmap migration (DBM) during load process */
|
/* State of the dirty bitmap migration (DBM) during load process */
|
||||||
typedef struct DBMLoadState {
|
typedef struct DBMLoadState {
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
@ -135,18 +141,17 @@ typedef struct DBMLoadState {
|
|||||||
char bitmap_name[256];
|
char bitmap_name[256];
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
BdrvDirtyBitmap *bitmap;
|
BdrvDirtyBitmap *bitmap;
|
||||||
|
|
||||||
|
GSList *enabled_bitmaps;
|
||||||
|
QemuMutex finish_lock;
|
||||||
} DBMLoadState;
|
} DBMLoadState;
|
||||||
|
|
||||||
static DBMSaveState dirty_bitmap_mig_state;
|
typedef struct DBMState {
|
||||||
|
DBMSaveState save;
|
||||||
|
DBMLoadState load;
|
||||||
|
} DBMState;
|
||||||
|
|
||||||
/* State of one bitmap during load process */
|
static DBMState dbm_state;
|
||||||
typedef struct LoadBitmapState {
|
|
||||||
BlockDriverState *bs;
|
|
||||||
BdrvDirtyBitmap *bitmap;
|
|
||||||
bool migrated;
|
|
||||||
} LoadBitmapState;
|
|
||||||
static GSList *enabled_bitmaps;
|
|
||||||
QemuMutex finish_lock;
|
|
||||||
|
|
||||||
static uint32_t qemu_get_bitmap_flags(QEMUFile *f)
|
static uint32_t qemu_get_bitmap_flags(QEMUFile *f)
|
||||||
{
|
{
|
||||||
@ -169,21 +174,21 @@ static void qemu_put_bitmap_flags(QEMUFile *f, uint32_t flags)
|
|||||||
qemu_put_byte(f, flags);
|
qemu_put_byte(f, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_bitmap_header(QEMUFile *f, SaveBitmapState *dbms,
|
static void send_bitmap_header(QEMUFile *f, DBMSaveState *s,
|
||||||
uint32_t additional_flags)
|
SaveBitmapState *dbms, uint32_t additional_flags)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs = dbms->bs;
|
BlockDriverState *bs = dbms->bs;
|
||||||
BdrvDirtyBitmap *bitmap = dbms->bitmap;
|
BdrvDirtyBitmap *bitmap = dbms->bitmap;
|
||||||
uint32_t flags = additional_flags;
|
uint32_t flags = additional_flags;
|
||||||
trace_send_bitmap_header_enter();
|
trace_send_bitmap_header_enter();
|
||||||
|
|
||||||
if (bs != dirty_bitmap_mig_state.prev_bs) {
|
if (bs != s->prev_bs) {
|
||||||
dirty_bitmap_mig_state.prev_bs = bs;
|
s->prev_bs = bs;
|
||||||
flags |= DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME;
|
flags |= DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitmap != dirty_bitmap_mig_state.prev_bitmap) {
|
if (bitmap != s->prev_bitmap) {
|
||||||
dirty_bitmap_mig_state.prev_bitmap = bitmap;
|
s->prev_bitmap = bitmap;
|
||||||
flags |= DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME;
|
flags |= DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,19 +203,22 @@ static void send_bitmap_header(QEMUFile *f, SaveBitmapState *dbms,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_bitmap_start(QEMUFile *f, SaveBitmapState *dbms)
|
static void send_bitmap_start(QEMUFile *f, DBMSaveState *s,
|
||||||
|
SaveBitmapState *dbms)
|
||||||
{
|
{
|
||||||
send_bitmap_header(f, dbms, DIRTY_BITMAP_MIG_FLAG_START);
|
send_bitmap_header(f, s, dbms, DIRTY_BITMAP_MIG_FLAG_START);
|
||||||
qemu_put_be32(f, bdrv_dirty_bitmap_granularity(dbms->bitmap));
|
qemu_put_be32(f, bdrv_dirty_bitmap_granularity(dbms->bitmap));
|
||||||
qemu_put_byte(f, dbms->flags);
|
qemu_put_byte(f, dbms->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_bitmap_complete(QEMUFile *f, SaveBitmapState *dbms)
|
static void send_bitmap_complete(QEMUFile *f, DBMSaveState *s,
|
||||||
|
SaveBitmapState *dbms)
|
||||||
{
|
{
|
||||||
send_bitmap_header(f, dbms, DIRTY_BITMAP_MIG_FLAG_COMPLETE);
|
send_bitmap_header(f, s, dbms, DIRTY_BITMAP_MIG_FLAG_COMPLETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_bitmap_bits(QEMUFile *f, SaveBitmapState *dbms,
|
static void send_bitmap_bits(QEMUFile *f, DBMSaveState *s,
|
||||||
|
SaveBitmapState *dbms,
|
||||||
uint64_t start_sector, uint32_t nr_sectors)
|
uint64_t start_sector, uint32_t nr_sectors)
|
||||||
{
|
{
|
||||||
/* align for buffer_is_zero() */
|
/* align for buffer_is_zero() */
|
||||||
@ -235,7 +243,7 @@ static void send_bitmap_bits(QEMUFile *f, SaveBitmapState *dbms,
|
|||||||
|
|
||||||
trace_send_bitmap_bits(flags, start_sector, nr_sectors, buf_size);
|
trace_send_bitmap_bits(flags, start_sector, nr_sectors, buf_size);
|
||||||
|
|
||||||
send_bitmap_header(f, dbms, flags);
|
send_bitmap_header(f, s, dbms, flags);
|
||||||
|
|
||||||
qemu_put_be64(f, start_sector);
|
qemu_put_be64(f, start_sector);
|
||||||
qemu_put_be32(f, nr_sectors);
|
qemu_put_be32(f, nr_sectors);
|
||||||
@ -254,12 +262,12 @@ static void send_bitmap_bits(QEMUFile *f, SaveBitmapState *dbms,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Called with iothread lock taken. */
|
/* Called with iothread lock taken. */
|
||||||
static void dirty_bitmap_do_save_cleanup(void)
|
static void dirty_bitmap_do_save_cleanup(DBMSaveState *s)
|
||||||
{
|
{
|
||||||
SaveBitmapState *dbms;
|
SaveBitmapState *dbms;
|
||||||
|
|
||||||
while ((dbms = QSIMPLEQ_FIRST(&dirty_bitmap_mig_state.dbms_list)) != NULL) {
|
while ((dbms = QSIMPLEQ_FIRST(&s->dbms_list)) != NULL) {
|
||||||
QSIMPLEQ_REMOVE_HEAD(&dirty_bitmap_mig_state.dbms_list, entry);
|
QSIMPLEQ_REMOVE_HEAD(&s->dbms_list, entry);
|
||||||
bdrv_dirty_bitmap_set_busy(dbms->bitmap, false);
|
bdrv_dirty_bitmap_set_busy(dbms->bitmap, false);
|
||||||
bdrv_unref(dbms->bs);
|
bdrv_unref(dbms->bs);
|
||||||
g_free(dbms);
|
g_free(dbms);
|
||||||
@ -267,7 +275,8 @@ static void dirty_bitmap_do_save_cleanup(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Called with iothread lock taken. */
|
/* Called with iothread lock taken. */
|
||||||
static int add_bitmaps_to_list(BlockDriverState *bs, const char *bs_name)
|
static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
|
||||||
|
const char *bs_name)
|
||||||
{
|
{
|
||||||
BdrvDirtyBitmap *bitmap;
|
BdrvDirtyBitmap *bitmap;
|
||||||
SaveBitmapState *dbms;
|
SaveBitmapState *dbms;
|
||||||
@ -322,25 +331,24 @@ static int add_bitmaps_to_list(BlockDriverState *bs, const char *bs_name)
|
|||||||
dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT;
|
dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSIMPLEQ_INSERT_TAIL(&dirty_bitmap_mig_state.dbms_list,
|
QSIMPLEQ_INSERT_TAIL(&s->dbms_list, dbms, entry);
|
||||||
dbms, entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called with iothread lock taken. */
|
/* Called with iothread lock taken. */
|
||||||
static int init_dirty_bitmap_migration(void)
|
static int init_dirty_bitmap_migration(DBMSaveState *s)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
SaveBitmapState *dbms;
|
SaveBitmapState *dbms;
|
||||||
GHashTable *handled_by_blk = g_hash_table_new(NULL, NULL);
|
GHashTable *handled_by_blk = g_hash_table_new(NULL, NULL);
|
||||||
BlockBackend *blk;
|
BlockBackend *blk;
|
||||||
|
|
||||||
dirty_bitmap_mig_state.bulk_completed = false;
|
s->bulk_completed = false;
|
||||||
dirty_bitmap_mig_state.prev_bs = NULL;
|
s->prev_bs = NULL;
|
||||||
dirty_bitmap_mig_state.prev_bitmap = NULL;
|
s->prev_bitmap = NULL;
|
||||||
dirty_bitmap_mig_state.no_bitmaps = false;
|
s->no_bitmaps = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use blockdevice name for direct (or filtered) children of named block
|
* Use blockdevice name for direct (or filtered) children of named block
|
||||||
@ -369,7 +377,7 @@ static int init_dirty_bitmap_migration(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bs && bs->drv && !bs->drv->is_filter) {
|
if (bs && bs->drv && !bs->drv->is_filter) {
|
||||||
if (add_bitmaps_to_list(bs, name)) {
|
if (add_bitmaps_to_list(s, bs, name)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
g_hash_table_add(handled_by_blk, bs);
|
g_hash_table_add(handled_by_blk, bs);
|
||||||
@ -381,18 +389,18 @@ static int init_dirty_bitmap_migration(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add_bitmaps_to_list(bs, bdrv_get_node_name(bs))) {
|
if (add_bitmaps_to_list(s, bs, bdrv_get_node_name(bs))) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unset migration flags here, to not roll back it */
|
/* unset migration flags here, to not roll back it */
|
||||||
QSIMPLEQ_FOREACH(dbms, &dirty_bitmap_mig_state.dbms_list, entry) {
|
QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) {
|
||||||
bdrv_dirty_bitmap_skip_store(dbms->bitmap, true);
|
bdrv_dirty_bitmap_skip_store(dbms->bitmap, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QSIMPLEQ_EMPTY(&dirty_bitmap_mig_state.dbms_list)) {
|
if (QSIMPLEQ_EMPTY(&s->dbms_list)) {
|
||||||
dirty_bitmap_mig_state.no_bitmaps = true;
|
s->no_bitmaps = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_destroy(handled_by_blk);
|
g_hash_table_destroy(handled_by_blk);
|
||||||
@ -401,18 +409,19 @@ static int init_dirty_bitmap_migration(void)
|
|||||||
|
|
||||||
fail:
|
fail:
|
||||||
g_hash_table_destroy(handled_by_blk);
|
g_hash_table_destroy(handled_by_blk);
|
||||||
dirty_bitmap_do_save_cleanup();
|
dirty_bitmap_do_save_cleanup(s);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called with no lock taken. */
|
/* Called with no lock taken. */
|
||||||
static void bulk_phase_send_chunk(QEMUFile *f, SaveBitmapState *dbms)
|
static void bulk_phase_send_chunk(QEMUFile *f, DBMSaveState *s,
|
||||||
|
SaveBitmapState *dbms)
|
||||||
{
|
{
|
||||||
uint32_t nr_sectors = MIN(dbms->total_sectors - dbms->cur_sector,
|
uint32_t nr_sectors = MIN(dbms->total_sectors - dbms->cur_sector,
|
||||||
dbms->sectors_per_chunk);
|
dbms->sectors_per_chunk);
|
||||||
|
|
||||||
send_bitmap_bits(f, dbms, dbms->cur_sector, nr_sectors);
|
send_bitmap_bits(f, s, dbms, dbms->cur_sector, nr_sectors);
|
||||||
|
|
||||||
dbms->cur_sector += nr_sectors;
|
dbms->cur_sector += nr_sectors;
|
||||||
if (dbms->cur_sector >= dbms->total_sectors) {
|
if (dbms->cur_sector >= dbms->total_sectors) {
|
||||||
@ -421,61 +430,66 @@ static void bulk_phase_send_chunk(QEMUFile *f, SaveBitmapState *dbms)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Called with no lock taken. */
|
/* Called with no lock taken. */
|
||||||
static void bulk_phase(QEMUFile *f, bool limit)
|
static void bulk_phase(QEMUFile *f, DBMSaveState *s, bool limit)
|
||||||
{
|
{
|
||||||
SaveBitmapState *dbms;
|
SaveBitmapState *dbms;
|
||||||
|
|
||||||
QSIMPLEQ_FOREACH(dbms, &dirty_bitmap_mig_state.dbms_list, entry) {
|
QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) {
|
||||||
while (!dbms->bulk_completed) {
|
while (!dbms->bulk_completed) {
|
||||||
bulk_phase_send_chunk(f, dbms);
|
bulk_phase_send_chunk(f, s, dbms);
|
||||||
if (limit && qemu_file_rate_limit(f)) {
|
if (limit && qemu_file_rate_limit(f)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dirty_bitmap_mig_state.bulk_completed = true;
|
s->bulk_completed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for SaveVMHandlers */
|
/* for SaveVMHandlers */
|
||||||
static void dirty_bitmap_save_cleanup(void *opaque)
|
static void dirty_bitmap_save_cleanup(void *opaque)
|
||||||
{
|
{
|
||||||
dirty_bitmap_do_save_cleanup();
|
DBMSaveState *s = &((DBMState *)opaque)->save;
|
||||||
|
|
||||||
|
dirty_bitmap_do_save_cleanup(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dirty_bitmap_save_iterate(QEMUFile *f, void *opaque)
|
static int dirty_bitmap_save_iterate(QEMUFile *f, void *opaque)
|
||||||
{
|
{
|
||||||
|
DBMSaveState *s = &((DBMState *)opaque)->save;
|
||||||
|
|
||||||
trace_dirty_bitmap_save_iterate(migration_in_postcopy());
|
trace_dirty_bitmap_save_iterate(migration_in_postcopy());
|
||||||
|
|
||||||
if (migration_in_postcopy() && !dirty_bitmap_mig_state.bulk_completed) {
|
if (migration_in_postcopy() && !s->bulk_completed) {
|
||||||
bulk_phase(f, true);
|
bulk_phase(f, s, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS);
|
qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS);
|
||||||
|
|
||||||
return dirty_bitmap_mig_state.bulk_completed;
|
return s->bulk_completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called with iothread lock taken. */
|
/* Called with iothread lock taken. */
|
||||||
|
|
||||||
static int dirty_bitmap_save_complete(QEMUFile *f, void *opaque)
|
static int dirty_bitmap_save_complete(QEMUFile *f, void *opaque)
|
||||||
{
|
{
|
||||||
|
DBMSaveState *s = &((DBMState *)opaque)->save;
|
||||||
SaveBitmapState *dbms;
|
SaveBitmapState *dbms;
|
||||||
trace_dirty_bitmap_save_complete_enter();
|
trace_dirty_bitmap_save_complete_enter();
|
||||||
|
|
||||||
if (!dirty_bitmap_mig_state.bulk_completed) {
|
if (!s->bulk_completed) {
|
||||||
bulk_phase(f, false);
|
bulk_phase(f, s, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSIMPLEQ_FOREACH(dbms, &dirty_bitmap_mig_state.dbms_list, entry) {
|
QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) {
|
||||||
send_bitmap_complete(f, dbms);
|
send_bitmap_complete(f, s, dbms);
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS);
|
qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS);
|
||||||
|
|
||||||
trace_dirty_bitmap_save_complete_finish();
|
trace_dirty_bitmap_save_complete_finish();
|
||||||
|
|
||||||
dirty_bitmap_do_save_cleanup();
|
dirty_bitmap_save_cleanup(opaque);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,12 +499,13 @@ static void dirty_bitmap_save_pending(QEMUFile *f, void *opaque,
|
|||||||
uint64_t *res_compatible,
|
uint64_t *res_compatible,
|
||||||
uint64_t *res_postcopy_only)
|
uint64_t *res_postcopy_only)
|
||||||
{
|
{
|
||||||
|
DBMSaveState *s = &((DBMState *)opaque)->save;
|
||||||
SaveBitmapState *dbms;
|
SaveBitmapState *dbms;
|
||||||
uint64_t pending = 0;
|
uint64_t pending = 0;
|
||||||
|
|
||||||
qemu_mutex_lock_iothread();
|
qemu_mutex_lock_iothread();
|
||||||
|
|
||||||
QSIMPLEQ_FOREACH(dbms, &dirty_bitmap_mig_state.dbms_list, entry) {
|
QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) {
|
||||||
uint64_t gran = bdrv_dirty_bitmap_granularity(dbms->bitmap);
|
uint64_t gran = bdrv_dirty_bitmap_granularity(dbms->bitmap);
|
||||||
uint64_t sectors = dbms->bulk_completed ? 0 :
|
uint64_t sectors = dbms->bulk_completed ? 0 :
|
||||||
dbms->total_sectors - dbms->cur_sector;
|
dbms->total_sectors - dbms->cur_sector;
|
||||||
@ -549,7 +564,7 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s)
|
|||||||
b->bs = s->bs;
|
b->bs = s->bs;
|
||||||
b->bitmap = s->bitmap;
|
b->bitmap = s->bitmap;
|
||||||
b->migrated = false;
|
b->migrated = false;
|
||||||
enabled_bitmaps = g_slist_prepend(enabled_bitmaps, b);
|
s->enabled_bitmaps = g_slist_prepend(s->enabled_bitmaps, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -557,11 +572,12 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s)
|
|||||||
|
|
||||||
void dirty_bitmap_mig_before_vm_start(void)
|
void dirty_bitmap_mig_before_vm_start(void)
|
||||||
{
|
{
|
||||||
|
DBMLoadState *s = &dbm_state.load;
|
||||||
GSList *item;
|
GSList *item;
|
||||||
|
|
||||||
qemu_mutex_lock(&finish_lock);
|
qemu_mutex_lock(&s->finish_lock);
|
||||||
|
|
||||||
for (item = enabled_bitmaps; item; item = g_slist_next(item)) {
|
for (item = s->enabled_bitmaps; item; item = g_slist_next(item)) {
|
||||||
LoadBitmapState *b = item->data;
|
LoadBitmapState *b = item->data;
|
||||||
|
|
||||||
if (b->migrated) {
|
if (b->migrated) {
|
||||||
@ -573,10 +589,10 @@ void dirty_bitmap_mig_before_vm_start(void)
|
|||||||
g_free(b);
|
g_free(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_free(enabled_bitmaps);
|
g_slist_free(s->enabled_bitmaps);
|
||||||
enabled_bitmaps = NULL;
|
s->enabled_bitmaps = NULL;
|
||||||
|
|
||||||
qemu_mutex_unlock(&finish_lock);
|
qemu_mutex_unlock(&s->finish_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dirty_bitmap_load_complete(QEMUFile *f, DBMLoadState *s)
|
static void dirty_bitmap_load_complete(QEMUFile *f, DBMLoadState *s)
|
||||||
@ -585,9 +601,9 @@ static void dirty_bitmap_load_complete(QEMUFile *f, DBMLoadState *s)
|
|||||||
trace_dirty_bitmap_load_complete();
|
trace_dirty_bitmap_load_complete();
|
||||||
bdrv_dirty_bitmap_deserialize_finish(s->bitmap);
|
bdrv_dirty_bitmap_deserialize_finish(s->bitmap);
|
||||||
|
|
||||||
qemu_mutex_lock(&finish_lock);
|
qemu_mutex_lock(&s->finish_lock);
|
||||||
|
|
||||||
for (item = enabled_bitmaps; item; item = g_slist_next(item)) {
|
for (item = s->enabled_bitmaps; item; item = g_slist_next(item)) {
|
||||||
LoadBitmapState *b = item->data;
|
LoadBitmapState *b = item->data;
|
||||||
|
|
||||||
if (b->bitmap == s->bitmap) {
|
if (b->bitmap == s->bitmap) {
|
||||||
@ -598,7 +614,7 @@ static void dirty_bitmap_load_complete(QEMUFile *f, DBMLoadState *s)
|
|||||||
|
|
||||||
if (bdrv_dirty_bitmap_has_successor(s->bitmap)) {
|
if (bdrv_dirty_bitmap_has_successor(s->bitmap)) {
|
||||||
bdrv_dirty_bitmap_lock(s->bitmap);
|
bdrv_dirty_bitmap_lock(s->bitmap);
|
||||||
if (enabled_bitmaps == NULL) {
|
if (s->enabled_bitmaps == NULL) {
|
||||||
/* in postcopy */
|
/* in postcopy */
|
||||||
bdrv_reclaim_dirty_bitmap_locked(s->bitmap, &error_abort);
|
bdrv_reclaim_dirty_bitmap_locked(s->bitmap, &error_abort);
|
||||||
bdrv_enable_dirty_bitmap_locked(s->bitmap);
|
bdrv_enable_dirty_bitmap_locked(s->bitmap);
|
||||||
@ -617,7 +633,7 @@ static void dirty_bitmap_load_complete(QEMUFile *f, DBMLoadState *s)
|
|||||||
bdrv_dirty_bitmap_unlock(s->bitmap);
|
bdrv_dirty_bitmap_unlock(s->bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_mutex_unlock(&finish_lock);
|
qemu_mutex_unlock(&s->finish_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dirty_bitmap_load_bits(QEMUFile *f, DBMLoadState *s)
|
static int dirty_bitmap_load_bits(QEMUFile *f, DBMLoadState *s)
|
||||||
@ -714,7 +730,7 @@ static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s)
|
|||||||
|
|
||||||
static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id)
|
static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id)
|
||||||
{
|
{
|
||||||
static DBMLoadState s;
|
DBMLoadState *s = &((DBMState *)opaque)->load;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
trace_dirty_bitmap_load_enter();
|
trace_dirty_bitmap_load_enter();
|
||||||
@ -724,17 +740,17 @@ static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = dirty_bitmap_load_header(f, &s);
|
ret = dirty_bitmap_load_header(f, s);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s.flags & DIRTY_BITMAP_MIG_FLAG_START) {
|
if (s->flags & DIRTY_BITMAP_MIG_FLAG_START) {
|
||||||
ret = dirty_bitmap_load_start(f, &s);
|
ret = dirty_bitmap_load_start(f, s);
|
||||||
} else if (s.flags & DIRTY_BITMAP_MIG_FLAG_COMPLETE) {
|
} else if (s->flags & DIRTY_BITMAP_MIG_FLAG_COMPLETE) {
|
||||||
dirty_bitmap_load_complete(f, &s);
|
dirty_bitmap_load_complete(f, s);
|
||||||
} else if (s.flags & DIRTY_BITMAP_MIG_FLAG_BITS) {
|
} else if (s->flags & DIRTY_BITMAP_MIG_FLAG_BITS) {
|
||||||
ret = dirty_bitmap_load_bits(f, &s);
|
ret = dirty_bitmap_load_bits(f, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
@ -744,7 +760,7 @@ static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} while (!(s.flags & DIRTY_BITMAP_MIG_FLAG_EOS));
|
} while (!(s->flags & DIRTY_BITMAP_MIG_FLAG_EOS));
|
||||||
|
|
||||||
trace_dirty_bitmap_load_success();
|
trace_dirty_bitmap_load_success();
|
||||||
return 0;
|
return 0;
|
||||||
@ -752,13 +768,14 @@ static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
|
|
||||||
static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque)
|
static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque)
|
||||||
{
|
{
|
||||||
|
DBMSaveState *s = &((DBMState *)opaque)->save;
|
||||||
SaveBitmapState *dbms = NULL;
|
SaveBitmapState *dbms = NULL;
|
||||||
if (init_dirty_bitmap_migration() < 0) {
|
if (init_dirty_bitmap_migration(s) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSIMPLEQ_FOREACH(dbms, &dirty_bitmap_mig_state.dbms_list, entry) {
|
QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) {
|
||||||
send_bitmap_start(f, dbms);
|
send_bitmap_start(f, s, dbms);
|
||||||
}
|
}
|
||||||
qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS);
|
qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS);
|
||||||
|
|
||||||
@ -767,7 +784,9 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque)
|
|||||||
|
|
||||||
static bool dirty_bitmap_is_active(void *opaque)
|
static bool dirty_bitmap_is_active(void *opaque)
|
||||||
{
|
{
|
||||||
return migrate_dirty_bitmaps() && !dirty_bitmap_mig_state.no_bitmaps;
|
DBMSaveState *s = &((DBMState *)opaque)->save;
|
||||||
|
|
||||||
|
return migrate_dirty_bitmaps() && !s->no_bitmaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dirty_bitmap_is_active_iterate(void *opaque)
|
static bool dirty_bitmap_is_active_iterate(void *opaque)
|
||||||
@ -795,10 +814,10 @@ static SaveVMHandlers savevm_dirty_bitmap_handlers = {
|
|||||||
|
|
||||||
void dirty_bitmap_mig_init(void)
|
void dirty_bitmap_mig_init(void)
|
||||||
{
|
{
|
||||||
QSIMPLEQ_INIT(&dirty_bitmap_mig_state.dbms_list);
|
QSIMPLEQ_INIT(&dbm_state.save.dbms_list);
|
||||||
qemu_mutex_init(&finish_lock);
|
qemu_mutex_init(&dbm_state.load.finish_lock);
|
||||||
|
|
||||||
register_savevm_live("dirty-bitmap", 0, 1,
|
register_savevm_live("dirty-bitmap", 0, 1,
|
||||||
&savevm_dirty_bitmap_handlers,
|
&savevm_dirty_bitmap_handlers,
|
||||||
&dirty_bitmap_mig_state);
|
&dbm_state);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user