Move the code responsible for the various channels connection into channel.c. This is all executed before the migration_thread and process_incoming_migration_co are running, so it helps the reasoning to have them out of migration.c.
migration_ioc_process_incoming becomes migration_channel_identify which is more in line with what the function does. Signed-off-by: Fabiano Rosas <[email protected]> --- migration/channel.c | 99 ++++++++++++++++++++++++++++++++++++++++++- migration/channel.h | 12 ++++++ migration/migration.c | 98 ------------------------------------------ migration/migration.h | 5 +-- migration/rdma.c | 1 + 5 files changed, 113 insertions(+), 102 deletions(-) diff --git a/migration/channel.c b/migration/channel.c index c5bd89576a..a9ac3711b5 100644 --- a/migration/channel.c +++ b/migration/channel.c @@ -14,13 +14,110 @@ #include "channel.h" #include "tls.h" #include "migration.h" +#include "multifd.h" +#include "savevm.h" #include "trace.h" +#include "options.h" #include "qapi/error.h" #include "io/channel-tls.h" #include "io/channel-socket.h" #include "qemu/yank.h" #include "yank_functions.h" +bool migration_has_main_and_multifd_channels(void) +{ + MigrationIncomingState *mis = migration_incoming_get_current(); + if (!mis->from_src_file) { + /* main channel not established */ + return false; + } + + if (migrate_multifd() && !multifd_recv_all_channels_created()) { + return false; + } + + /* main and all multifd channels are established */ + return true; +} + +/** + * @migration_has_all_channels: We have received all channels that we need + * + * Returns true when we have got connections to all the channels that + * we need for migration. + */ +bool migration_has_all_channels(void) +{ + if (!migration_has_main_and_multifd_channels()) { + return false; + } + + MigrationIncomingState *mis = migration_incoming_get_current(); + if (migrate_postcopy_preempt() && !mis->postcopy_qemufile_dst) { + return false; + } + + return true; +} + +static int migration_channel_identify(MigrationIncomingState *mis, + QIOChannel *ioc, Error **errp) +{ + int channel = CH_NONE; + uint32_t channel_magic = 0; + int ret = 0; + + if (!migration_has_main_and_multifd_channels()) { + if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) { + /* + * With multiple channels, it is possible that we receive channels + * out of order on destination side, causing incorrect mapping of + * source channels on destination side. Check channel MAGIC to + * decide type of channel. Please note this is best effort, + * postcopy preempt channel does not send any magic number so + * avoid it for postcopy live migration. Also tls live migration + * already does tls handshake while initializing main channel so + * with tls this issue is not possible. + */ + ret = migration_channel_read_peek(ioc, (void *)&channel_magic, + sizeof(channel_magic), errp); + if (ret != 0) { + goto out; + } + + channel_magic = be32_to_cpu(channel_magic); + if (channel_magic == QEMU_VM_FILE_MAGIC) { + channel = CH_MAIN; + } else if (channel_magic == MULTIFD_MAGIC) { + assert(migrate_multifd()); + channel = CH_MULTIFD; + } else if (!mis->from_src_file && + mis->state == MIGRATION_STATUS_POSTCOPY_PAUSED) { + /* reconnect main channel for postcopy recovery */ + channel = CH_MAIN; + } else { + error_setg(errp, "unknown channel magic: %u", channel_magic); + } + } else if (mis->from_src_file && migrate_multifd()) { + /* + * Non-peekable channels like tls/file are processed as + * multifd channels when multifd is enabled. + */ + channel = CH_MULTIFD; + } else if (!mis->from_src_file) { + channel = CH_MAIN; + } else { + error_setg(errp, "non-peekable channel used without multifd"); + } + } else { + assert(migrate_postcopy_preempt()); + channel = CH_POSTCOPY; + } + +out: + return channel; +} + /** * @migration_channel_process_incoming - Create new incoming migration channel * @@ -42,7 +139,7 @@ void migration_channel_process_incoming(QIOChannel *ioc) migration_tls_channel_process_incoming(ioc, &local_err); } else { migration_ioc_register_yank(ioc); - ch = migration_ioc_process_incoming(ioc, &local_err); + ch = migration_channel_identify(mis, ioc, &local_err); if (!ch) { goto out; } diff --git a/migration/channel.h b/migration/channel.h index 7d3457271d..59d169e095 100644 --- a/migration/channel.h +++ b/migration/channel.h @@ -18,6 +18,14 @@ #include "io/channel.h" +/* Migration channel types */ +enum { + CH_NONE, + CH_MAIN, + CH_MULTIFD, + CH_POSTCOPY +}; + void migration_channel_process_incoming(QIOChannel *ioc); void migration_channel_connect_outgoing(MigrationState *s, QIOChannel *ioc); @@ -26,4 +34,8 @@ int migration_channel_read_peek(QIOChannel *ioc, const char *buf, const size_t buflen, Error **errp); + +bool migration_has_main_and_multifd_channels(void); +bool migration_has_all_channels(void); + #endif diff --git a/migration/migration.c b/migration/migration.c index 42adee5695..e0aee17317 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -91,9 +91,6 @@ enum mig_rp_message_type { MIG_RP_MSG_MAX }; -/* Migration channel types */ -enum { CH_NONE, CH_MAIN, CH_MULTIFD, CH_POSTCOPY }; - /* When we add fault tolerance, we could have several migrations at once. For now we don't need to add dynamic creation of migration */ @@ -934,8 +931,6 @@ out: migrate_incoming_unref_outgoing_state(); } -static bool migration_has_main_and_multifd_channels(void); - bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp) { MigrationIncomingState *mis = migration_incoming_get_current(); @@ -1021,99 +1016,6 @@ void migration_start_incoming(void) qemu_coroutine_enter(co); } -static bool migration_has_main_and_multifd_channels(void) -{ - MigrationIncomingState *mis = migration_incoming_get_current(); - if (!mis->from_src_file) { - /* main channel not established */ - return false; - } - - if (migrate_multifd() && !multifd_recv_all_channels_created()) { - return false; - } - - /* main and all multifd channels are established */ - return true; -} - -uint8_t migration_ioc_process_incoming(QIOChannel *ioc, Error **errp) -{ - MigrationIncomingState *mis = migration_incoming_get_current(); - uint8_t channel = CH_NONE; - uint32_t channel_magic = 0; - int ret = 0; - - if (!migration_has_main_and_multifd_channels()) { - if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) { - /* - * With multiple channels, it is possible that we receive channels - * out of order on destination side, causing incorrect mapping of - * source channels on destination side. Check channel MAGIC to - * decide type of channel. Please note this is best effort, - * postcopy preempt channel does not send any magic number so - * avoid it for postcopy live migration. Also tls live migration - * already does tls handshake while initializing main channel so - * with tls this issue is not possible. - */ - ret = migration_channel_read_peek(ioc, (void *)&channel_magic, - sizeof(channel_magic), errp); - if (ret != 0) { - goto out; - } - - channel_magic = be32_to_cpu(channel_magic); - if (channel_magic == QEMU_VM_FILE_MAGIC) { - channel = CH_MAIN; - } else if (channel_magic == MULTIFD_MAGIC) { - assert(migrate_multifd()); - channel = CH_MULTIFD; - } else if (!mis->from_src_file && - mis->state == MIGRATION_STATUS_POSTCOPY_PAUSED) { - /* reconnect main channel for postcopy recovery */ - channel = CH_MAIN; - } else { - error_setg(errp, "unknown channel magic: %u", channel_magic); - } - } else if (mis->from_src_file && migrate_multifd()) { - /* - * Non-peekable channels like tls/file are processed as - * multifd channels when multifd is enabled. - */ - channel = CH_MULTIFD; - } else if (!mis->from_src_file) { - channel = CH_MAIN; - } else { - error_setg(errp, "non-peekable channel used without multifd"); - } - } else { - assert(migrate_postcopy_preempt()); - channel = CH_POSTCOPY; - } -out: - return channel; -} - -/** - * @migration_has_all_channels: We have received all channels that we need - * - * Returns true when we have got connections to all the channels that - * we need for migration. - */ -bool migration_has_all_channels(void) -{ - if (!migration_has_main_and_multifd_channels()) { - return false; - } - - MigrationIncomingState *mis = migration_incoming_get_current(); - if (migrate_postcopy_preempt() && !mis->postcopy_qemufile_dst) { - return false; - } - - return true; -} - int migrate_send_rp_switchover_ack(MigrationIncomingState *mis) { return migrate_send_rp_message(mis, MIG_RP_MSG_SWITCHOVER_ACK, 0, NULL); diff --git a/migration/migration.h b/migration/migration.h index cbe90471c2..138831d7d9 100644 --- a/migration/migration.h +++ b/migration/migration.h @@ -529,13 +529,12 @@ void migrate_set_state(MigrationStatus *state, MigrationStatus old_state, void migration_outgoing_setup(QIOChannel *ioc); bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp); -bool migration_has_all_channels(void); - void migration_connect_error_propagate(MigrationState *s, Error *error); void migrate_error_propagate(MigrationState *s, Error *error); bool migrate_has_error(MigrationState *s); -void migration_start_outgoing(MigrationState *s, QEMUFile *file); +void migration_start_outgoing(MigrationState *s); +void migration_start_incoming(void); int migration_call_notifiers(MigrationState *s, MigrationEventType type, Error **errp); diff --git a/migration/rdma.c b/migration/rdma.c index 788120a0b1..6e9ca5f5f6 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -17,6 +17,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu/cutils.h" +#include "channel.h" #include "exec/target_page.h" #include "rdma.h" #include "migration.h" -- 2.51.0
