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 <farosas@suse.de>
---
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