diff options
Diffstat (limited to 'migration')
| -rw-r--r-- | migration/block-dirty-bitmap.c | 23 | ||||
| -rw-r--r-- | migration/colo.c | 57 | ||||
| -rw-r--r-- | migration/migration.c | 81 | ||||
| -rw-r--r-- | migration/migration.h | 4 | ||||
| -rw-r--r-- | migration/ram.c | 84 | ||||
| -rw-r--r-- | migration/rdma.c | 6 | ||||
| -rw-r--r-- | migration/savevm.c | 2 | ||||
| -rw-r--r-- | migration/socket.c | 1 | ||||
| -rw-r--r-- | migration/tls.c | 2 | ||||
| -rw-r--r-- | migration/trace-events | 74 |
10 files changed, 194 insertions, 140 deletions
diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index 6426151e4f..d1bb863cb6 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -261,7 +261,7 @@ static void dirty_bitmap_mig_cleanup(void) while ((dbms = QSIMPLEQ_FIRST(&dirty_bitmap_mig_state.dbms_list)) != NULL) { QSIMPLEQ_REMOVE_HEAD(&dirty_bitmap_mig_state.dbms_list, entry); - bdrv_dirty_bitmap_set_qmp_locked(dbms->bitmap, false); + bdrv_dirty_bitmap_set_busy(dbms->bitmap, false); bdrv_unref(dbms->bs); g_free(dbms); } @@ -274,6 +274,7 @@ static int init_dirty_bitmap_migration(void) BdrvDirtyBitmap *bitmap; DirtyBitmapMigBitmapState *dbms; BdrvNextIterator it; + Error *local_err = NULL; dirty_bitmap_mig_state.bulk_completed = false; dirty_bitmap_mig_state.prev_bs = NULL; @@ -301,20 +302,14 @@ static int init_dirty_bitmap_migration(void) goto fail; } - if (bdrv_dirty_bitmap_user_locked(bitmap)) { - error_report("Can't migrate a bitmap that is in use by another operation: '%s'", - bdrv_dirty_bitmap_name(bitmap)); - goto fail; - } - - if (bdrv_dirty_bitmap_readonly(bitmap)) { - error_report("Can't migrate read-only dirty bitmap: '%s", - bdrv_dirty_bitmap_name(bitmap)); + if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, + &local_err)) { + error_report_err(local_err); goto fail; } bdrv_ref(bs); - bdrv_dirty_bitmap_set_qmp_locked(bitmap, true); + bdrv_dirty_bitmap_set_busy(bitmap, true); dbms = g_new0(DirtyBitmapMigBitmapState, 1); dbms->bs = bs; @@ -326,7 +321,7 @@ static int init_dirty_bitmap_migration(void) if (bdrv_dirty_bitmap_enabled(bitmap)) { dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_ENABLED; } - if (bdrv_dirty_bitmap_get_persistance(bitmap)) { + if (bdrv_dirty_bitmap_get_persistence(bitmap)) { dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT; } @@ -478,7 +473,7 @@ static int dirty_bitmap_load_start(QEMUFile *f, DirtyBitmapLoadState *s) } if (flags & DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT) { - bdrv_dirty_bitmap_set_persistance(s->bitmap, true); + bdrv_dirty_bitmap_set_persistence(s->bitmap, true); } bdrv_disable_dirty_bitmap(s->bitmap); @@ -542,7 +537,7 @@ static void dirty_bitmap_load_complete(QEMUFile *f, DirtyBitmapLoadState *s) } } - if (bdrv_dirty_bitmap_frozen(s->bitmap)) { + if (bdrv_dirty_bitmap_has_successor(s->bitmap)) { bdrv_dirty_bitmap_lock(s->bitmap); if (enabled_bitmaps == NULL) { /* in postcopy */ diff --git a/migration/colo.c b/migration/colo.c index 5ba610dc01..238a6d62c7 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -38,6 +38,9 @@ static bool vmstate_loading; static Notifier packets_compare_notifier; +/* User need to know colo mode after COLO failover */ +static COLOMode last_colo_mode; + #define COLO_BUFFER_BASE_SIZE (4 * 1024 * 1024) bool migration_in_colo_state(void) @@ -121,6 +124,7 @@ static void secondary_vm_do_failover(void) } /* Notify COLO incoming thread that failover work is finished */ qemu_sem_post(&mis->colo_incoming_sem); + /* For Secondary VM, jump to incoming co */ if (mis->migration_incoming_co) { qemu_coroutine_enter(mis->migration_incoming_co); @@ -196,10 +200,16 @@ void colo_do_failover(MigrationState *s) vm_stop_force_state(RUN_STATE_COLO); } - if (get_colo_mode() == COLO_MODE_PRIMARY) { + switch (get_colo_mode()) { + case COLO_MODE_PRIMARY: primary_vm_do_failover(); - } else { + break; + case COLO_MODE_SECONDARY: secondary_vm_do_failover(); + break; + default: + error_report("colo_do_failover failed because the colo mode" + " could not be obtained"); } } @@ -257,16 +267,21 @@ COLOStatus *qmp_query_colo_status(Error **errp) COLOStatus *s = g_new0(COLOStatus, 1); s->mode = get_colo_mode(); + s->last_mode = last_colo_mode; switch (failover_get_state()) { case FAILOVER_STATUS_NONE: s->reason = COLO_EXIT_REASON_NONE; break; - case FAILOVER_STATUS_REQUIRE: + case FAILOVER_STATUS_COMPLETED: s->reason = COLO_EXIT_REASON_REQUEST; break; default: - s->reason = COLO_EXIT_REASON_ERROR; + if (migration_in_colo_state()) { + s->reason = COLO_EXIT_REASON_PROCESSING; + } else { + s->reason = COLO_EXIT_REASON_ERROR; + } } return s; @@ -504,6 +519,12 @@ static void colo_process_checkpoint(MigrationState *s) Error *local_err = NULL; int ret; + last_colo_mode = get_colo_mode(); + if (last_colo_mode != COLO_MODE_PRIMARY) { + error_report("COLO mode must be COLO_MODE_PRIMARY"); + return; + } + failover_init_state(); s->rp_state.from_dst_file = qemu_file_get_return_path(s->to_dst_file); @@ -578,16 +599,13 @@ out: * or the user triggered failover. */ switch (failover_get_state()) { - case FAILOVER_STATUS_NONE: - qapi_event_send_colo_exit(COLO_MODE_PRIMARY, - COLO_EXIT_REASON_ERROR); - break; - case FAILOVER_STATUS_REQUIRE: + case FAILOVER_STATUS_COMPLETED: qapi_event_send_colo_exit(COLO_MODE_PRIMARY, COLO_EXIT_REASON_REQUEST); break; default: - abort(); + qapi_event_send_colo_exit(COLO_MODE_PRIMARY, + COLO_EXIT_REASON_ERROR); } /* Hope this not to be too long to wait here */ @@ -680,6 +698,12 @@ void *colo_process_incoming_thread(void *opaque) migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE, MIGRATION_STATUS_COLO); + last_colo_mode = get_colo_mode(); + if (last_colo_mode != COLO_MODE_SECONDARY) { + error_report("COLO mode must be COLO_MODE_SECONDARY"); + return NULL; + } + failover_init_state(); mis->to_src_file = qemu_file_get_return_path(mis->from_src_file); @@ -849,17 +873,18 @@ out: error_report_err(local_err); } + /* + * There are only two reasons we can get here, some error happened + * or the user triggered failover. + */ switch (failover_get_state()) { - case FAILOVER_STATUS_NONE: - qapi_event_send_colo_exit(COLO_MODE_SECONDARY, - COLO_EXIT_REASON_ERROR); - break; - case FAILOVER_STATUS_REQUIRE: + case FAILOVER_STATUS_COMPLETED: qapi_event_send_colo_exit(COLO_MODE_SECONDARY, COLO_EXIT_REASON_REQUEST); break; default: - abort(); + qapi_event_send_colo_exit(COLO_MODE_SECONDARY, + COLO_EXIT_REASON_ERROR); } if (fb) { diff --git a/migration/migration.c b/migration/migration.c index df6fd8e0e5..609e0df5d0 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -82,7 +82,6 @@ /* The delay time (in ms) between two COLO checkpoints */ #define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100) #define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2 -#define DEFAULT_MIGRATE_MULTIFD_PAGE_COUNT 16 /* Background transfer rate for postcopy, 0 means unlimited, note * that page requests can still exceed this limit. @@ -758,6 +757,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) params->tls_creds = g_strdup(s->parameters.tls_creds); params->has_tls_hostname = true; params->tls_hostname = g_strdup(s->parameters.tls_hostname); + params->has_tls_authz = true; + params->tls_authz = g_strdup(s->parameters.tls_authz); params->has_max_bandwidth = true; params->max_bandwidth = s->parameters.max_bandwidth; params->has_downtime_limit = true; @@ -766,10 +767,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) params->x_checkpoint_delay = s->parameters.x_checkpoint_delay; params->has_block_incremental = true; params->block_incremental = s->parameters.block_incremental; - params->has_x_multifd_channels = true; - params->x_multifd_channels = s->parameters.x_multifd_channels; - params->has_x_multifd_page_count = true; - params->x_multifd_page_count = s->parameters.x_multifd_page_count; + params->has_multifd_channels = true; + params->multifd_channels = s->parameters.multifd_channels; params->has_xbzrle_cache_size = true; params->xbzrle_cache_size = s->parameters.xbzrle_cache_size; params->has_max_postcopy_bandwidth = true; @@ -1152,20 +1151,12 @@ static bool migrate_params_check(MigrationParameters *params, Error **errp) /* x_checkpoint_delay is now always positive */ - if (params->has_x_multifd_channels && (params->x_multifd_channels < 1)) { + if (params->has_multifd_channels && (params->multifd_channels < 1)) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_channels", "is invalid, it should be in the range of 1 to 255"); return false; } - if (params->has_x_multifd_page_count && - (params->x_multifd_page_count < 1 || - params->x_multifd_page_count > 10000)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - "multifd_page_count", - "is invalid, it should be in the range of 1 to 10000"); - return false; - } if (params->has_xbzrle_cache_size && (params->xbzrle_cache_size < qemu_target_page_size() || @@ -1274,11 +1265,8 @@ static void migrate_params_test_apply(MigrateSetParameters *params, if (params->has_block_incremental) { dest->block_incremental = params->block_incremental; } - if (params->has_x_multifd_channels) { - dest->x_multifd_channels = params->x_multifd_channels; - } - if (params->has_x_multifd_page_count) { - dest->x_multifd_page_count = params->x_multifd_page_count; + if (params->has_multifd_channels) { + dest->multifd_channels = params->multifd_channels; } if (params->has_xbzrle_cache_size) { dest->xbzrle_cache_size = params->xbzrle_cache_size; @@ -1345,9 +1333,15 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp) s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s); } + if (params->has_tls_authz) { + g_free(s->parameters.tls_authz); + assert(params->tls_authz->type == QTYPE_QSTRING); + s->parameters.tls_authz = g_strdup(params->tls_authz->u.s); + } + if (params->has_max_bandwidth) { s->parameters.max_bandwidth = params->max_bandwidth; - if (s->to_dst_file) { + if (s->to_dst_file && !migration_in_postcopy()) { qemu_file_set_rate_limit(s->to_dst_file, s->parameters.max_bandwidth / XFER_LIMIT_RATIO); } @@ -1367,11 +1361,8 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp) if (params->has_block_incremental) { s->parameters.block_incremental = params->block_incremental; } - if (params->has_x_multifd_channels) { - s->parameters.x_multifd_channels = params->x_multifd_channels; - } - if (params->has_x_multifd_page_count) { - s->parameters.x_multifd_page_count = params->x_multifd_page_count; + if (params->has_multifd_channels) { + s->parameters.multifd_channels = params->multifd_channels; } if (params->has_xbzrle_cache_size) { s->parameters.xbzrle_cache_size = params->xbzrle_cache_size; @@ -1379,6 +1370,10 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp) } if (params->has_max_postcopy_bandwidth) { s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth; + if (s->to_dst_file && migration_in_postcopy()) { + qemu_file_set_rate_limit(s->to_dst_file, + s->parameters.max_postcopy_bandwidth / XFER_LIMIT_RATIO); + } } if (params->has_max_cpu_throttle) { s->parameters.max_cpu_throttle = params->max_cpu_throttle; @@ -1651,7 +1646,11 @@ bool migration_in_postcopy_after_devices(MigrationState *s) bool migration_is_idle(void) { - MigrationState *s = migrate_get_current(); + MigrationState *s = current_migration; + + if (!s) { + return true; + } switch (s->state) { case MIGRATION_STATUS_NONE: @@ -1712,7 +1711,7 @@ static GSList *migration_blockers; int migrate_add_blocker(Error *reason, Error **errp) { - if (migrate_get_current()->only_migratable) { + if (only_migratable) { error_propagate_prepend(errp, error_copy(reason), "disallowing migration blocker " "(--only_migratable) for: "); @@ -2130,7 +2129,7 @@ bool migrate_use_multifd(void) s = migrate_get_current(); - return s->enabled_capabilities[MIGRATION_CAPABILITY_X_MULTIFD]; + return s->enabled_capabilities[MIGRATION_CAPABILITY_MULTIFD]; } bool migrate_pause_before_switchover(void) @@ -2149,16 +2148,7 @@ int migrate_multifd_channels(void) s = migrate_get_current(); - return s->parameters.x_multifd_channels; -} - -int migrate_multifd_page_count(void) -{ - MigrationState *s; - - s = migrate_get_current(); - - return s->parameters.x_multifd_page_count; + return s->parameters.multifd_channels; } int migrate_use_xbzrle(void) @@ -3351,7 +3341,7 @@ void migration_global_dump(Monitor *mon) monitor_printf(mon, "store-global-state: %s\n", ms->store_global_state ? "on" : "off"); monitor_printf(mon, "only-migratable: %s\n", - ms->only_migratable ? "on" : "off"); + only_migratable ? "on" : "off"); monitor_printf(mon, "send-configuration: %s\n", ms->send_configuration ? "on" : "off"); monitor_printf(mon, "send-section-footer: %s\n", @@ -3366,7 +3356,6 @@ void migration_global_dump(Monitor *mon) static Property migration_properties[] = { DEFINE_PROP_BOOL("store-global-state", MigrationState, store_global_state, true), - DEFINE_PROP_BOOL("only-migratable", MigrationState, only_migratable, false), DEFINE_PROP_BOOL("send-configuration", MigrationState, send_configuration, true), DEFINE_PROP_BOOL("send-section-footer", MigrationState, @@ -3400,12 +3389,9 @@ static Property migration_properties[] = { DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState, parameters.x_checkpoint_delay, DEFAULT_MIGRATE_X_CHECKPOINT_DELAY), - DEFINE_PROP_UINT8("x-multifd-channels", MigrationState, - parameters.x_multifd_channels, + DEFINE_PROP_UINT8("multifd-channels", MigrationState, + parameters.multifd_channels, DEFAULT_MIGRATE_MULTIFD_CHANNELS), - DEFINE_PROP_UINT32("x-multifd-page-count", MigrationState, - parameters.x_multifd_page_count, - DEFAULT_MIGRATE_MULTIFD_PAGE_COUNT), DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState, parameters.xbzrle_cache_size, DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE), @@ -3440,7 +3426,7 @@ static Property migration_properties[] = { DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM), DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK), DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH), - DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_X_MULTIFD), + DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD), DEFINE_PROP_END_OF_LIST(), }; @@ -3494,8 +3480,7 @@ static void migration_instance_init(Object *obj) params->has_downtime_limit = true; params->has_x_checkpoint_delay = true; params->has_block_incremental = true; - params->has_x_multifd_channels = true; - params->has_x_multifd_page_count = true; + params->has_multifd_channels = true; params->has_xbzrle_cache_size = true; params->has_max_postcopy_bandwidth = true; params->has_max_cpu_throttle = true; diff --git a/migration/migration.h b/migration/migration.h index 99e99e56bd..438f17edad 100644 --- a/migration/migration.h +++ b/migration/migration.h @@ -219,9 +219,6 @@ struct MigrationState */ bool store_global_state; - /* Whether the VM is only allowing for migratable devices */ - bool only_migratable; - /* Whether we send QEMU_VM_CONFIGURATION during migration */ bool send_configuration; /* Whether we send section footer during migration */ @@ -274,7 +271,6 @@ bool migrate_auto_converge(void); bool migrate_use_multifd(void); bool migrate_pause_before_switchover(void); int migrate_multifd_channels(void); -int migrate_multifd_page_count(void); int migrate_use_xbzrle(void); int64_t migrate_xbzrle_cache_size(void); diff --git a/migration/ram.c b/migration/ram.c index 35bd6213e9..1ca9ba77b6 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -583,20 +583,29 @@ exit: #define MULTIFD_FLAG_SYNC (1 << 0) +/* This value needs to be a multiple of qemu_target_page_size() */ +#define MULTIFD_PACKET_SIZE (512 * 1024) + typedef struct { uint32_t magic; uint32_t version; unsigned char uuid[16]; /* QemuUUID */ uint8_t id; + uint8_t unused1[7]; /* Reserved for future use */ + uint64_t unused2[4]; /* Reserved for future use */ } __attribute__((packed)) MultiFDInit_t; typedef struct { uint32_t magic; uint32_t version; uint32_t flags; - uint32_t size; - uint32_t used; + /* maximum number of allocated pages */ + uint32_t pages_alloc; + uint32_t pages_used; + /* size of the next packet that contains pages */ + uint32_t next_packet_size; uint64_t packet_num; + uint64_t unused[4]; /* Reserved for future use */ char ramblock[256]; uint64_t offset[]; } __attribute__((packed)) MultiFDPacket_t; @@ -643,6 +652,8 @@ typedef struct { MultiFDPacket_t *packet; /* multifd flags for each packet */ uint32_t flags; + /* size of the next packet that contains pages */ + uint32_t next_packet_size; /* global number of generated multifd packets */ uint64_t packet_num; /* thread local variables */ @@ -679,6 +690,8 @@ typedef struct { /* global number of generated multifd packets */ uint64_t packet_num; /* thread local variables */ + /* size of the next packet that contains pages */ + uint32_t next_packet_size; /* packets sent through this channel */ uint64_t num_packets; /* pages sent through this channel */ @@ -776,13 +789,15 @@ static void multifd_pages_clear(MultiFDPages_t *pages) static void multifd_send_fill_packet(MultiFDSendParams *p) { MultiFDPacket_t *packet = p->packet; + uint32_t page_max = MULTIFD_PACKET_SIZE / qemu_target_page_size(); int i; packet->magic = cpu_to_be32(MULTIFD_MAGIC); packet->version = cpu_to_be32(MULTIFD_VERSION); packet->flags = cpu_to_be32(p->flags); - packet->size = cpu_to_be32(migrate_multifd_page_count()); - packet->used = cpu_to_be32(p->pages->used); + packet->pages_alloc = cpu_to_be32(page_max); + packet->pages_used = cpu_to_be32(p->pages->used); + packet->next_packet_size = cpu_to_be32(p->next_packet_size); packet->packet_num = cpu_to_be64(p->packet_num); if (p->pages->block) { @@ -797,6 +812,7 @@ static void multifd_send_fill_packet(MultiFDSendParams *p) static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp) { MultiFDPacket_t *packet = p->packet; + uint32_t pages_max = MULTIFD_PACKET_SIZE / qemu_target_page_size(); RAMBlock *block; int i; @@ -818,22 +834,35 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp) p->flags = be32_to_cpu(packet->flags); - packet->size = be32_to_cpu(packet->size); - if (packet->size > migrate_multifd_page_count()) { + packet->pages_alloc = be32_to_cpu(packet->pages_alloc); + /* + * If we recevied a packet that is 100 times bigger than expected + * just stop migration. It is a magic number. + */ + if (packet->pages_alloc > pages_max * 100) { error_setg(errp, "multifd: received packet " - "with size %d and expected maximum size %d", - packet->size, migrate_multifd_page_count()) ; + "with size %d and expected a maximum size of %d", + packet->pages_alloc, pages_max * 100) ; return -1; } + /* + * We received a packet that is bigger than expected but inside + * reasonable limits (see previous comment). Just reallocate. + */ + if (packet->pages_alloc > p->pages->allocated) { + multifd_pages_clear(p->pages); + p->pages = multifd_pages_init(packet->pages_alloc); + } - p->pages->used = be32_to_cpu(packet->used); - if (p->pages->used > packet->size) { + p->pages->used = be32_to_cpu(packet->pages_used); + if (p->pages->used > packet->pages_alloc) { error_setg(errp, "multifd: received packet " - "with size %d and expected maximum size %d", - p->pages->used, packet->size) ; + "with %d pages and expected maximum pages are %d", + p->pages->used, packet->pages_alloc) ; return -1; } + p->next_packet_size = be32_to_cpu(packet->next_packet_size); p->packet_num = be64_to_cpu(packet->packet_num); if (p->pages->used) { @@ -1073,6 +1102,7 @@ static void *multifd_send_thread(void *opaque) uint64_t packet_num = p->packet_num; uint32_t flags = p->flags; + p->next_packet_size = used * qemu_target_page_size(); multifd_send_fill_packet(p); p->flags = 0; p->num_packets++; @@ -1080,7 +1110,8 @@ static void *multifd_send_thread(void *opaque) p->pages->used = 0; qemu_mutex_unlock(&p->mutex); - trace_multifd_send(p->id, packet_num, used, flags); + trace_multifd_send(p->id, packet_num, used, flags, + p->next_packet_size); ret = qio_channel_write_all(p->c, (void *)p->packet, p->packet_len, &local_err); @@ -1088,9 +1119,12 @@ static void *multifd_send_thread(void *opaque) break; } - ret = qio_channel_writev_all(p->c, p->pages->iov, used, &local_err); - if (ret != 0) { - break; + if (used) { + ret = qio_channel_writev_all(p->c, p->pages->iov, + used, &local_err); + if (ret != 0) { + break; + } } qemu_mutex_lock(&p->mutex); @@ -1148,7 +1182,7 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque) int multifd_save_setup(void) { int thread_count; - uint32_t page_count = migrate_multifd_page_count(); + uint32_t page_count = MULTIFD_PACKET_SIZE / qemu_target_page_size(); uint8_t i; if (!migrate_use_multifd()) { @@ -1312,14 +1346,18 @@ static void *multifd_recv_thread(void *opaque) used = p->pages->used; flags = p->flags; - trace_multifd_recv(p->id, p->packet_num, used, flags); + trace_multifd_recv(p->id, p->packet_num, used, flags, + p->next_packet_size); p->num_packets++; p->num_pages += used; qemu_mutex_unlock(&p->mutex); - ret = qio_channel_readv_all(p->c, p->pages->iov, used, &local_err); - if (ret != 0) { - break; + if (used) { + ret = qio_channel_readv_all(p->c, p->pages->iov, + used, &local_err); + if (ret != 0) { + break; + } } if (flags & MULTIFD_FLAG_SYNC) { @@ -1344,7 +1382,7 @@ static void *multifd_recv_thread(void *opaque) int multifd_load_setup(void) { int thread_count; - uint32_t page_count = migrate_multifd_page_count(); + uint32_t page_count = MULTIFD_PACKET_SIZE / qemu_target_page_size(); uint8_t i; if (!migrate_use_multifd()) { @@ -3880,6 +3918,7 @@ int colo_init_ram_cache(void) } ram_state = g_new0(RAMState, 1); ram_state->migration_dirty_pages = 0; + qemu_mutex_init(&ram_state->bitmap_mutex); memory_global_dirty_log_start(); return 0; @@ -3918,6 +3957,7 @@ void colo_release_ram_cache(void) } rcu_read_unlock(); + qemu_mutex_destroy(&ram_state->bitmap_mutex); g_free(ram_state); ram_state = NULL; } diff --git a/migration/rdma.c b/migration/rdma.c index 63c118af09..c1bcece53b 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -641,10 +641,14 @@ static int qemu_rdma_init_one_block(RAMBlock *rb, void *opaque) static int qemu_rdma_init_ram_blocks(RDMAContext *rdma) { RDMALocalBlocks *local = &rdma->local_ram_blocks; + int ret; assert(rdma->blockmap == NULL); memset(local, 0, sizeof *local); - foreach_not_ignored_block(qemu_rdma_init_one_block, rdma); + ret = foreach_not_ignored_block(qemu_rdma_init_one_block, rdma); + if (ret) { + return ret; + } trace_qemu_rdma_init_ram_blocks(local->nb_blocks); rdma->dest_blocks = g_new0(RDMADestBlock, rdma->local_ram_blocks.nb_blocks); diff --git a/migration/savevm.c b/migration/savevm.c index 1415001d1c..34bcad3807 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2844,7 +2844,7 @@ void vmstate_register_ram_global(MemoryRegion *mr) bool vmstate_check_only_migratable(const VMStateDescription *vmsd) { /* check needed if --only-migratable is specified */ - if (!migrate_get_current()->only_migratable) { + if (!only_migratable) { return true; } diff --git a/migration/socket.c b/migration/socket.c index 239527fb1f..49bacf78fd 100644 --- a/migration/socket.c +++ b/migration/socket.c @@ -199,6 +199,7 @@ static void socket_start_incoming_migration(SocketAddress *saddr, return; } migrate_add_address(address); + qapi_free_SocketAddress(address); } } diff --git a/migration/tls.c b/migration/tls.c index 3b9e8c9263..5171afc6c4 100644 --- a/migration/tls.c +++ b/migration/tls.c @@ -94,7 +94,7 @@ void migration_tls_channel_process_incoming(MigrationState *s, tioc = qio_channel_tls_new_server( ioc, creds, - NULL, /* XXX pass ACL name */ + s->parameters.tls_authz, errp); if (!tioc) { return; diff --git a/migration/trace-events b/migration/trace-events index 72e3fcb885..de2e136e57 100644 --- a/migration/trace-events +++ b/migration/trace-events @@ -1,6 +1,6 @@ # See docs/devel/tracing.txt for syntax documentation. -# migration/savevm.c +# savevm.c qemu_loadvm_state_section(unsigned int section_type) "%d" qemu_loadvm_state_section_command(int ret) "%d" qemu_loadvm_state_section_partend(uint32_t section_id) "%u" @@ -46,14 +46,11 @@ savevm_state_iterate(void) "" savevm_state_cleanup(void) "" savevm_state_complete_precopy(void) "" vmstate_save(const char *idstr, const char *vmsd_name) "%s, %s" -vmstate_save_state_pre_save_res(const char *name, int res) "%s/%d" -vmstate_save_state_loop(const char *name, const char *field, int n_elems) "%s/%s[%d]" -vmstate_save_state_top(const char *idstr) "%s" -vmstate_subsection_save_loop(const char *name, const char *sub) "%s/%s" -vmstate_subsection_save_top(const char *idstr) "%s" vmstate_load(const char *idstr, const char *vmsd_name) "%s, %s" +postcopy_pause_incoming(void) "" +postcopy_pause_incoming_continued(void) "" -# migration/vmstate.c +# vmstate.c vmstate_load_field_error(const char *field, int ret) "field \"%s\" load failed, ret = %d" vmstate_load_state(const char *name, int version_id) "%s v%d" vmstate_load_state_end(const char *name, const char *reason, int val) "%s %s/%d" @@ -62,27 +59,34 @@ vmstate_n_elems(const char *name, int n_elems) "%s: %d" vmstate_subsection_load(const char *parent) "%s" vmstate_subsection_load_bad(const char *parent, const char *sub, const char *sub2) "%s: %s/%s" vmstate_subsection_load_good(const char *parent) "%s" +vmstate_save_state_pre_save_res(const char *name, int res) "%s/%d" +vmstate_save_state_loop(const char *name, const char *field, int n_elems) "%s/%s[%d]" +vmstate_save_state_top(const char *idstr) "%s" +vmstate_subsection_save_loop(const char *name, const char *sub) "%s/%s" +vmstate_subsection_save_top(const char *idstr) "%s" + +# vmstate-types.c get_qtailq(const char *name, int version_id) "%s v%d" get_qtailq_end(const char *name, const char *reason, int val) "%s %s/%d" put_qtailq(const char *name, int version_id) "%s v%d" put_qtailq_end(const char *name, const char *reason) "%s %s" -# migration/qemu-file.c +# qemu-file.c qemu_file_fclose(void) "" -# migration/ram.c +# ram.c get_queued_page(const char *block_name, uint64_t tmp_offset, unsigned long page_abs) "%s/0x%" PRIx64 " page_abs=0x%lx" get_queued_page_not_dirty(const char *block_name, uint64_t tmp_offset, unsigned long page_abs, int sent) "%s/0x%" PRIx64 " page_abs=0x%lx (sent=%d)" migration_bitmap_sync_start(void) "" migration_bitmap_sync_end(uint64_t dirty_pages) "dirty_pages %" PRIu64 migration_throttle(void) "" -multifd_recv(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags) "channel %d packet number %" PRIu64 " pages %d flags 0x%x" +multifd_recv(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags, uint32_t next_packet_size) "channel %d packet number %" PRIu64 " pages %d flags 0x%x next packet size %d" multifd_recv_sync_main(long packet_num) "packet num %ld" multifd_recv_sync_main_signal(uint8_t id) "channel %d" multifd_recv_sync_main_wait(uint8_t id) "channel %d" multifd_recv_thread_end(uint8_t id, uint64_t packets, uint64_t pages) "channel %d packets %" PRIu64 " pages %" PRIu64 multifd_recv_thread_start(uint8_t id) "%d" -multifd_send(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags) "channel %d packet_num %" PRIu64 " pages %d flags 0x%x" +multifd_send(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags, uint32_t next_packet_size) "channel %d packet_num %" PRIu64 " pages %d flags 0x%x next packet size %d" multifd_send_sync_main(long packet_num) "packet num %ld" multifd_send_sync_main_signal(uint8_t id) "channel %d" multifd_send_sync_main_wait(uint8_t id) "channel %d" @@ -103,8 +107,12 @@ ram_dirty_bitmap_sync_complete(void) "" ram_state_resume_prepare(uint64_t v) "%" PRId64 colo_flush_ram_cache_begin(uint64_t dirty_pages) "dirty_pages %" PRIu64 colo_flush_ram_cache_end(void) "" +save_xbzrle_page_skipping(void) "" +save_xbzrle_page_overflow(void) "" +ram_save_iterate_big_wait(uint64_t milliconds, int iterations) "big wait: %" PRIu64 " milliseconds, %d iterations" +ram_load_complete(int ret, uint64_t seq_iter) "exit_code %d seq iteration %" PRIu64 -# migration/migration.c +# migration.c await_return_path_close_on_source_close(void) "" await_return_path_close_on_source_joining(void) "" migrate_set_state(const char *new_state) "new state %s" @@ -130,11 +138,7 @@ open_return_path_on_source_continue(void) "" postcopy_start(void) "" postcopy_pause_return_path(void) "" postcopy_pause_return_path_continued(void) "" -postcopy_pause_fault_thread(void) "" -postcopy_pause_fault_thread_continued(void) "" postcopy_pause_continued(void) "" -postcopy_pause_incoming(void) "" -postcopy_pause_incoming_continued(void) "" postcopy_start_set_run(void) "" source_return_path_thread_bad_end(void) "" source_return_path_thread_end(void) "" @@ -143,19 +147,21 @@ source_return_path_thread_loop_top(void) "" source_return_path_thread_pong(uint32_t val) "0x%x" source_return_path_thread_shut(uint32_t val) "0x%x" source_return_path_thread_resume_ack(uint32_t v) "%"PRIu32 -migrate_global_state_post_load(const char *state) "loaded state: %s" -migrate_global_state_pre_save(const char *state) "saved state: %s" migration_thread_low_pending(uint64_t pending) "%" PRIu64 -migrate_state_too_big(void) "" migrate_transferred(uint64_t tranferred, uint64_t time_spent, uint64_t bandwidth, uint64_t size) "transferred %" PRIu64 " time_spent %" PRIu64 " bandwidth %" PRIu64 " max_size %" PRId64 process_incoming_migration_co_end(int ret, int ps) "ret=%d postcopy-state=%d" process_incoming_migration_co_postcopy_end_main(void) "" + +# channel.c migration_set_incoming_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s" migration_set_outgoing_channel(void *ioc, const char *ioctype, const char *hostname, void *err) "ioc=%p ioctype=%s hostname=%s err=%p" -mark_postcopy_blocktime_begin(uint64_t addr, void *dd, uint32_t time, int cpu, int received) "addr: 0x%" PRIx64 ", dd: %p, time: %u, cpu: %d, already_received: %d" -mark_postcopy_blocktime_end(uint64_t addr, void *dd, uint32_t time, int affected_cpu) "addr: 0x%" PRIx64 ", dd: %p, time: %u, affected_cpu: %d" -# migration/rdma.c +# global_state.c +migrate_state_too_big(void) "" +migrate_global_state_post_load(const char *state) "loaded state: %s" +migrate_global_state_pre_save(const char *state) "saved state: %s" + +# rdma.c qemu_rdma_accept_incoming_migration(void) "" qemu_rdma_accept_incoming_migration_accepted(void) "" qemu_rdma_accept_pin_state(bool pin) "%d" @@ -217,7 +223,7 @@ rdma_start_incoming_migration_after_rdma_listen(void) "" rdma_start_outgoing_migration_after_rdma_connect(void) "" rdma_start_outgoing_migration_after_rdma_source_init(void) "" -# migration/postcopy-ram.c +# postcopy-ram.c postcopy_discard_send_finish(const char *ramblock, int nwords, int ncmds) "%s mask words sent=%d in %d commands" postcopy_discard_send_range(const char *ramblock, unsigned long start, unsigned long length) "%s:%lx/%lx" postcopy_cleanup_range(const char *ramblock, void *host_addr, size_t offset, size_t length) "%s: %p offset=0x%zx length=0x%zx" @@ -226,6 +232,10 @@ postcopy_nhp_range(const char *ramblock, void *host_addr, size_t offset, size_t postcopy_place_page(void *host_addr) "host=%p" postcopy_place_page_zero(void *host_addr) "host=%p" postcopy_ram_enable_notify(void) "" +mark_postcopy_blocktime_begin(uint64_t addr, void *dd, uint32_t time, int cpu, int received) "addr: 0x%" PRIx64 ", dd: %p, time: %u, cpu: %d, already_received: %d" +mark_postcopy_blocktime_end(uint64_t addr, void *dd, uint32_t time, int affected_cpu) "addr: 0x%" PRIx64 ", dd: %p, time: %u, affected_cpu: %d" +postcopy_pause_fault_thread(void) "" +postcopy_pause_fault_thread_continued(void) "" postcopy_ram_fault_thread_entry(void) "" postcopy_ram_fault_thread_exit(void) "" postcopy_ram_fault_thread_fds_core(int baseufd, int quitfd) "ufd: %d quitfd: %d" @@ -241,26 +251,22 @@ postcopy_request_shared_page(const char *sharer, const char *rb, uint64_t rb_off postcopy_request_shared_page_present(const char *sharer, const char *rb, uint64_t rb_offset) "%s already %s offset 0x%"PRIx64 postcopy_wake_shared(uint64_t client_addr, const char *rb) "at 0x%"PRIx64" in %s" -save_xbzrle_page_skipping(void) "" -save_xbzrle_page_overflow(void) "" -ram_save_iterate_big_wait(uint64_t milliconds, int iterations) "big wait: %" PRIu64 " milliseconds, %d iterations" -ram_load_complete(int ret, uint64_t seq_iter) "exit_code %d seq iteration %" PRIu64 get_mem_fault_cpu_index(int cpu, uint32_t pid) "cpu: %d, pid: %u" -# migration/exec.c +# exec.c migration_exec_outgoing(const char *cmd) "cmd=%s" migration_exec_incoming(const char *cmd) "cmd=%s" -# migration/fd.c +# fd.c migration_fd_outgoing(int fd) "fd=%d" migration_fd_incoming(int fd) "fd=%d" -# migration/socket.c +# socket.c migration_socket_incoming_accepted(void) "" migration_socket_outgoing_connected(const char *hostname) "hostname=%s" migration_socket_outgoing_error(const char *err) "error=%s" -# migration/tls.c +# tls.c migration_tls_outgoing_handshake_start(const char *hostname) "hostname=%s" migration_tls_outgoing_handshake_error(const char *err) "err=%s" migration_tls_outgoing_handshake_complete(void) "" @@ -268,13 +274,15 @@ migration_tls_incoming_handshake_start(void) "" migration_tls_incoming_handshake_error(const char *err) "err=%s" migration_tls_incoming_handshake_complete(void) "" -# migration/colo.c +# colo.c colo_vm_state_change(const char *old, const char *new) "Change '%s' => '%s'" colo_send_message(const char *msg) "Send '%s' message" colo_receive_message(const char *msg) "Receive '%s' message" + +# colo-failover.c colo_failover_set_state(const char *new_state) "new state %s" -# migration/block-dirty-bitmap.c +# block-dirty-bitmap.c send_bitmap_header_enter(void) "" send_bitmap_bits(uint32_t flags, uint64_t start_sector, uint32_t nr_sectors, uint64_t data_size) "flags: 0x%x, start_sector: %" PRIu64 ", nr_sectors: %" PRIu32 ", data_size: %" PRIu64 dirty_bitmap_save_iterate(int in_postcopy) "in postcopy: %d" |