diff options
Diffstat (limited to 'migration')
| -rw-r--r-- | migration/channel.c | 1 | ||||
| -rw-r--r-- | migration/migration.c | 66 | ||||
| -rw-r--r-- | migration/migration.h | 4 | ||||
| -rw-r--r-- | migration/multifd.c | 29 | ||||
| -rw-r--r-- | migration/multifd.h | 4 | ||||
| -rw-r--r-- | migration/ram.c | 10 | ||||
| -rw-r--r-- | migration/ram.h | 1 | ||||
| -rw-r--r-- | migration/savevm.c | 3 | ||||
| -rw-r--r-- | migration/tls.c | 4 |
9 files changed, 55 insertions, 67 deletions
diff --git a/migration/channel.c b/migration/channel.c index c4fc000a1a..c6a8dcf1d7 100644 --- a/migration/channel.c +++ b/migration/channel.c @@ -96,6 +96,5 @@ void migration_channel_connect(MigrationState *s, } } migrate_fd_connect(s, error); - g_free(s->hostname); error_free(error); } diff --git a/migration/migration.c b/migration/migration.c index 4dcb511bb6..5a31b23bd6 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -180,6 +180,18 @@ static int migration_maybe_pause(MigrationState *s, int new_state); static void migrate_fd_cancel(MigrationState *s); +static bool migrate_allow_multi_channels = true; + +void migrate_protocol_allow_multi_channels(bool allow) +{ + migrate_allow_multi_channels = allow; +} + +bool migrate_multi_channels_is_allowed(void) +{ + return migrate_allow_multi_channels; +} + static gint page_request_addr_cmp(gconstpointer ap, gconstpointer bp) { uintptr_t a = (uintptr_t) ap, b = (uintptr_t) bp; @@ -469,12 +481,12 @@ static void qemu_start_incoming_migration(const char *uri, Error **errp) { const char *p = NULL; - migrate_protocol_allow_multifd(false); /* reset it anyway */ + migrate_protocol_allow_multi_channels(false); /* reset it anyway */ qapi_event_send_migration(MIGRATION_STATUS_SETUP); if (strstart(uri, "tcp:", &p) || strstart(uri, "unix:", NULL) || strstart(uri, "vsock:", NULL)) { - migrate_protocol_allow_multifd(true); + migrate_protocol_allow_multi_channels(true); socket_start_incoming_migration(p ? p : uri, errp); #ifdef CONFIG_RDMA } else if (strstart(uri, "rdma:", &p)) { @@ -659,19 +671,20 @@ void migration_incoming_process(void) } /* Returns true if recovered from a paused migration, otherwise false */ -static bool postcopy_try_recover(QEMUFile *f) +static bool postcopy_try_recover(void) { MigrationIncomingState *mis = migration_incoming_get_current(); if (mis->state == MIGRATION_STATUS_POSTCOPY_PAUSED) { /* Resumed from a paused postcopy migration */ - mis->from_src_file = f; + /* This should be set already in migration_incoming_setup() */ + assert(mis->from_src_file); /* Postcopy has standalone thread to do vm load */ - qemu_file_set_blocking(f, true); + qemu_file_set_blocking(mis->from_src_file, true); /* Re-configure the return path */ - mis->to_src_file = qemu_file_get_return_path(f); + mis->to_src_file = qemu_file_get_return_path(mis->from_src_file); migrate_set_state(&mis->state, MIGRATION_STATUS_POSTCOPY_PAUSED, MIGRATION_STATUS_POSTCOPY_RECOVER); @@ -692,11 +705,10 @@ static bool postcopy_try_recover(QEMUFile *f) void migration_fd_process_incoming(QEMUFile *f, Error **errp) { - if (postcopy_try_recover(f)) { + if (!migration_incoming_setup(f, errp)) { return; } - - if (!migration_incoming_setup(f, errp)) { + if (postcopy_try_recover()) { return; } migration_incoming_process(); @@ -712,11 +724,6 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp) /* The first connection (multifd may have multiple) */ QEMUFile *f = qemu_fopen_channel_input(ioc); - /* If it's a recovery, we're done */ - if (postcopy_try_recover(f)) { - return; - } - if (!migration_incoming_setup(f, errp)) { return; } @@ -737,6 +744,10 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp) } if (start_migration) { + /* If it's a recovery, we're done */ + if (postcopy_try_recover()) { + return; + } migration_incoming_process(); } } @@ -1073,6 +1084,7 @@ static void populate_disk_info(MigrationInfo *info) static void fill_source_migration_info(MigrationInfo *info) { MigrationState *s = migrate_get_current(); + int state = qatomic_read(&s->state); GSList *cur_blocker = migration_blockers; info->blocked_reasons = NULL; @@ -1092,7 +1104,7 @@ static void fill_source_migration_info(MigrationInfo *info) } info->has_blocked_reasons = info->blocked_reasons != NULL; - switch (s->state) { + switch (state) { case MIGRATION_STATUS_NONE: /* no migration has happened ever */ /* do not overwrite destination migration status */ @@ -1137,7 +1149,7 @@ static void fill_source_migration_info(MigrationInfo *info) info->has_status = true; break; } - info->status = s->state; + info->status = state; } typedef enum WriteTrackingSupport { @@ -1261,7 +1273,7 @@ static bool migrate_caps_check(bool *cap_list, /* incoming side only */ if (runstate_check(RUN_STATE_INMIGRATE) && - !migrate_multifd_is_allowed() && + !migrate_multi_channels_is_allowed() && cap_list[MIGRATION_CAPABILITY_MULTIFD]) { error_setg(errp, "multifd is not supported by current protocol"); return false; @@ -1809,6 +1821,9 @@ static void migrate_fd_cleanup(MigrationState *s) qemu_bh_delete(s->cleanup_bh); s->cleanup_bh = NULL; + g_free(s->hostname); + s->hostname = NULL; + qemu_savevm_state_cleanup(); if (s->to_dst_file) { @@ -2148,11 +2163,8 @@ void qmp_migrate_recover(const char *uri, Error **errp) return; } - if (qatomic_cmpxchg(&mis->postcopy_recover_triggered, - false, true) == true) { - error_setg(errp, "Migrate recovery is triggered already"); - return; - } + /* If there's an existing transport, release it */ + migration_incoming_transport_cleanup(mis); /* * Note that this call will never start a real migration; it will @@ -2160,12 +2172,6 @@ void qmp_migrate_recover(const char *uri, Error **errp) * to continue using that newly established channel. */ qemu_start_incoming_migration(uri, errp); - - /* Safe to dereference with the assert above */ - if (*errp) { - /* Reset the flag so user could still retry */ - qatomic_set(&mis->postcopy_recover_triggered, false); - } } void qmp_migrate_pause(Error **errp) @@ -2319,11 +2325,11 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, } } - migrate_protocol_allow_multifd(false); + migrate_protocol_allow_multi_channels(false); if (strstart(uri, "tcp:", &p) || strstart(uri, "unix:", NULL) || strstart(uri, "vsock:", NULL)) { - migrate_protocol_allow_multifd(true); + migrate_protocol_allow_multi_channels(true); socket_start_outgoing_migration(s, p ? p : uri, &local_err); #ifdef CONFIG_RDMA } else if (strstart(uri, "rdma:", &p)) { diff --git a/migration/migration.h b/migration/migration.h index 2de861df01..a863032b71 100644 --- a/migration/migration.h +++ b/migration/migration.h @@ -139,7 +139,6 @@ struct MigrationIncomingState { struct PostcopyBlocktimeContext *blocktime_ctx; /* notify PAUSED postcopy incoming migrations to try to continue */ - bool postcopy_recover_triggered; QemuSemaphore postcopy_pause_sem_dst; QemuSemaphore postcopy_pause_sem_fault; @@ -430,4 +429,7 @@ void migration_cancel(const Error *error); void populate_vfio_info(MigrationInfo *info); void postcopy_temp_page_reset(PostcopyTmpPage *tmp_page); +bool migrate_multi_channels_is_allowed(void); +void migrate_protocol_allow_multi_channels(bool allow); + #endif diff --git a/migration/multifd.c b/migration/multifd.c index 76b57a7177..9ea4f581e2 100644 --- a/migration/multifd.c +++ b/migration/multifd.c @@ -517,7 +517,7 @@ void multifd_save_cleanup(void) { int i; - if (!migrate_use_multifd() || !migrate_multifd_is_allowed()) { + if (!migrate_use_multifd() || !migrate_multi_channels_is_allowed()) { return; } multifd_send_terminate_threads(NULL); @@ -542,8 +542,6 @@ void multifd_save_cleanup(void) qemu_sem_destroy(&p->sem_sync); g_free(p->name); p->name = NULL; - g_free(p->tls_hostname); - p->tls_hostname = NULL; multifd_pages_clear(p->pages); p->pages = NULL; p->packet_len = 0; @@ -763,7 +761,7 @@ static void multifd_tls_channel_connect(MultiFDSendParams *p, Error **errp) { MigrationState *s = migrate_get_current(); - const char *hostname = p->tls_hostname; + const char *hostname = s->hostname; QIOChannelTLS *tioc; tioc = migration_tls_client_create(s, ioc, hostname, errp); @@ -787,7 +785,8 @@ static bool multifd_channel_connect(MultiFDSendParams *p, MigrationState *s = migrate_get_current(); trace_multifd_set_outgoing_channel( - ioc, object_get_typename(OBJECT(ioc)), p->tls_hostname, error); + ioc, object_get_typename(OBJECT(ioc)), + migrate_get_current()->hostname, error); if (!error) { if (s->parameters.tls_creds && @@ -858,33 +857,20 @@ cleanup: multifd_new_send_channel_cleanup(p, sioc, local_err); } -static bool migrate_allow_multifd = true; -void migrate_protocol_allow_multifd(bool allow) -{ - migrate_allow_multifd = allow; -} - -bool migrate_multifd_is_allowed(void) -{ - return migrate_allow_multifd; -} - int multifd_save_setup(Error **errp) { int thread_count; uint32_t page_count = MULTIFD_PACKET_SIZE / qemu_target_page_size(); uint8_t i; - MigrationState *s; if (!migrate_use_multifd()) { return 0; } - if (!migrate_multifd_is_allowed()) { + if (!migrate_multi_channels_is_allowed()) { error_setg(errp, "multifd is not supported by current protocol"); return -1; } - s = migrate_get_current(); thread_count = migrate_multifd_channels(); multifd_send_state = g_malloc0(sizeof(*multifd_send_state)); multifd_send_state->params = g_new0(MultiFDSendParams, thread_count); @@ -909,7 +895,6 @@ int multifd_save_setup(Error **errp) p->packet->magic = cpu_to_be32(MULTIFD_MAGIC); p->packet->version = cpu_to_be32(MULTIFD_VERSION); p->name = g_strdup_printf("multifdsend_%d", i); - p->tls_hostname = g_strdup(s->hostname); /* We need one extra place for the packet header */ p->iov = g_new0(struct iovec, page_count + 1); p->normal = g_new0(ram_addr_t, page_count); @@ -980,7 +965,7 @@ int multifd_load_cleanup(Error **errp) { int i; - if (!migrate_use_multifd() || !migrate_multifd_is_allowed()) { + if (!migrate_use_multifd() || !migrate_multi_channels_is_allowed()) { return 0; } multifd_recv_terminate_threads(NULL); @@ -1129,7 +1114,7 @@ int multifd_load_setup(Error **errp) if (!migrate_use_multifd()) { return 0; } - if (!migrate_multifd_is_allowed()) { + if (!migrate_multi_channels_is_allowed()) { error_setg(errp, "multifd is not supported by current protocol"); return -1; } diff --git a/migration/multifd.h b/migration/multifd.h index 4dda900a0b..7d0effcb03 100644 --- a/migration/multifd.h +++ b/migration/multifd.h @@ -13,8 +13,6 @@ #ifndef QEMU_MIGRATION_MULTIFD_H #define QEMU_MIGRATION_MULTIFD_H -bool migrate_multifd_is_allowed(void); -void migrate_protocol_allow_multifd(bool allow); int multifd_save_setup(Error **errp); void multifd_save_cleanup(void); int multifd_load_setup(Error **errp); @@ -72,8 +70,6 @@ typedef struct { uint8_t id; /* channel thread name */ char *name; - /* tls hostname */ - char *tls_hostname; /* channel thread id */ QemuThread thread; /* communication channel */ diff --git a/migration/ram.c b/migration/ram.c index 3532f64ecb..a2489a2699 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -414,6 +414,8 @@ struct PageSearchStatus { unsigned long page; /* Set once we wrap around */ bool complete_round; + /* Whether current page is explicitly requested by postcopy */ + bool postcopy_requested; }; typedef struct PageSearchStatus PageSearchStatus; @@ -1289,7 +1291,7 @@ static int save_normal_page(RAMState *rs, RAMBlock *block, ram_addr_t offset, offset | RAM_SAVE_FLAG_PAGE)); if (async) { qemu_put_buffer_async(rs->f, buf, TARGET_PAGE_SIZE, - migrate_release_ram() & + migrate_release_ram() && migration_in_postcopy()); } else { qemu_put_buffer(rs->f, buf, TARGET_PAGE_SIZE); @@ -1487,6 +1489,9 @@ retry: */ static bool find_dirty_block(RAMState *rs, PageSearchStatus *pss, bool *again) { + /* This is not a postcopy requested page */ + pss->postcopy_requested = false; + pss->page = migration_bitmap_find_dirty(rs, pss->block, pss->page); if (pss->complete_round && pss->block == rs->last_seen_block && pss->page >= rs->last_page) { @@ -1981,6 +1986,7 @@ static bool get_queued_page(RAMState *rs, PageSearchStatus *pss) * really rare. */ pss->complete_round = false; + pss->postcopy_requested = true; } return !!block; @@ -3639,7 +3645,7 @@ int ram_postcopy_incoming_init(MigrationIncomingState *mis) * * @f: QEMUFile where to send the data */ -static int ram_load_postcopy(QEMUFile *f) +int ram_load_postcopy(QEMUFile *f) { int flags = 0, ret = 0; bool place_needed = false; diff --git a/migration/ram.h b/migration/ram.h index 2c6dc3675d..ded0a3a086 100644 --- a/migration/ram.h +++ b/migration/ram.h @@ -61,6 +61,7 @@ void ram_postcopy_send_discard_bitmap(MigrationState *ms); /* For incoming postcopy discard */ int ram_discard_range(const char *block_name, uint64_t start, size_t length); int ram_postcopy_incoming_init(MigrationIncomingState *mis); +int ram_load_postcopy(QEMUFile *f); void ram_handle_compressed(void *host, uint8_t ch, uint64_t size); diff --git a/migration/savevm.c b/migration/savevm.c index 02ed94c180..d9076897b8 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2589,9 +2589,6 @@ static bool postcopy_pause_incoming(MigrationIncomingState *mis) assert(migrate_postcopy_ram()); - /* Clear the triggered bit to allow one recovery */ - mis->postcopy_recover_triggered = false; - /* * Unregister yank with either from/to src would work, since ioc behind it * is the same diff --git a/migration/tls.c b/migration/tls.c index ca1ea3bbdd..32c384a8b6 100644 --- a/migration/tls.c +++ b/migration/tls.c @@ -137,10 +137,6 @@ QIOChannelTLS *migration_tls_client_create(MigrationState *s, if (s->parameters.tls_hostname && *s->parameters.tls_hostname) { hostname = s->parameters.tls_hostname; } - if (!hostname) { - error_setg(errp, "No hostname available for TLS"); - return NULL; - } tioc = qio_channel_tls_new_client( ioc, creds, hostname, errp); |