Modified 'migrate-incoming' QAPI design supports MigrateChannel parameters. This well-defined struct replaces uri string to prevent multiple encodings. (uri paramter is kept for backward compatibility).
socket_start_incoming_migration() has been deprecated and socket_start_incoming_migration_internal() name has been replaced with socket_outgoing_migration(). qemu_uri_parsing() has been used to populate the migration parameters in MigrateChannel struct. Suggested-by: Daniel P. Berrange <berra...@redhat.com> Suggested-by: Manish Mishra <manish.mis...@nutanix.com> Suggested-by: Aravind Retnakaran <aravind.retnaka...@nutanix.com> Signed-off-by: Het Gala <het.g...@nutanix.com> --- migration/exec.c | 7 +++--- migration/exec.h | 2 +- migration/migration.c | 51 +++++++++++++++++++++++++++++-------------- migration/rdma.c | 9 +++++--- migration/rdma.h | 2 +- migration/socket.c | 16 ++------------ migration/socket.h | 2 +- 7 files changed, 50 insertions(+), 39 deletions(-) diff --git a/migration/exec.c b/migration/exec.c index 4fa9819792..8506ad7f18 100644 --- a/migration/exec.c +++ b/migration/exec.c @@ -77,12 +77,13 @@ static gboolean exec_accept_incoming_migration(QIOChannel *ioc, return G_SOURCE_REMOVE; } -void exec_start_incoming_migration(const char *command, Error **errp) +void exec_start_incoming_migration(strList *command, Error **errp) { QIOChannel *ioc; - const char *argv[] = { "/bin/sh", "-c", command, NULL }; + const char *argv[4]; + init_exec_array(command, argv, errp); - trace_migration_exec_incoming(command); + trace_migration_exec_incoming(argv[2]); ioc = QIO_CHANNEL(qio_channel_command_new_spawn(argv, O_RDWR, errp)); diff --git a/migration/exec.h b/migration/exec.h index 5b39ba6cbb..5335f7c24a 100644 --- a/migration/exec.h +++ b/migration/exec.h @@ -21,7 +21,7 @@ #define QEMU_MIGRATION_EXEC_H void init_exec_array(strList *command, const char *argv[], Error **errp); -void exec_start_incoming_migration(const char *host_port, Error **errp); +void exec_start_incoming_migration(strList *host_port, Error **errp); void exec_start_outgoing_migration(MigrationState *s, strList *host_port, Error **errp); diff --git a/migration/migration.c b/migration/migration.c index e22ce2dd15..639d727393 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -528,27 +528,46 @@ static bool migrate_uri_parse(const char *uri, return true; } -static void qemu_start_incoming_migration(const char *uri, Error **errp) +static void qemu_start_incoming_migration(const char *uri, + MigrateChannel *channel, + Error **errp) { - const char *p = NULL; + MigrateAddress *addrs = g_new0(MigrateAddress, 1); + SocketAddress *saddr = g_new0(SocketAddress, 1); + + /* + * Having preliminary checks for uri and channel + */ + if (uri && channel) { + error_setg(errp, "uri and channels options should be used " + "mutually exclusive"); + return; + } else if (uri && !migrate_uri_parse(uri, &channel, errp)) { + error_setg(errp, "Error parsing uri"); + return; + } migrate_protocol_allow_multi_channels(false); /* reset it anyway */ + addrs = channel->addr; + saddr = QAPI_CLONE(SocketAddress, channel->addr->u.socket.socket_type); qapi_event_send_migration(MIGRATION_STATUS_SETUP); - if (strstart(uri, "tcp:", &p) || - strstart(uri, "unix:", NULL) || - strstart(uri, "vsock:", NULL)) { - migrate_protocol_allow_multi_channels(true); - socket_start_incoming_migration(p ? p : uri, errp); + if (addrs->transport == MIGRATE_TRANSPORT_SOCKET) { + if (saddr->type == SOCKET_ADDRESS_TYPE_INET || + saddr->type == SOCKET_ADDRESS_TYPE_UNIX || + saddr->type == SOCKET_ADDRESS_TYPE_VSOCK) { + migrate_protocol_allow_multi_channels(true); + socket_start_incoming_migration(saddr, errp); + } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) { + fd_start_incoming_migration(saddr->u.fd.str, errp); + } #ifdef CONFIG_RDMA - } else if (strstart(uri, "rdma:", &p)) { - rdma_start_incoming_migration(p, errp); + } else if (addrs->transport == MIGRATE_TRANSPORT_RDMA) { + rdma_start_incoming_migration(addrs->u.rdma.data, errp); #endif - } else if (strstart(uri, "exec:", &p)) { - exec_start_incoming_migration(p, errp); - } else if (strstart(uri, "fd:", &p)) { - fd_start_incoming_migration(p, errp); + } else if (addrs->transport == MIGRATE_TRANSPORT_EXEC) { + exec_start_incoming_migration(addrs->u.exec.data, errp); } else { - error_setg(errp, "unknown migration protocol: %s", uri); + error_setg(errp, "unknown migration protocol: %i", addrs->transport); } } @@ -2333,7 +2352,7 @@ void qmp_migrate_incoming(const char *uri, MigrateChannel *channel, return; } - qemu_start_incoming_migration(uri, &local_err); + qemu_start_incoming_migration(uri, channel, &local_err); if (local_err) { yank_unregister_instance(MIGRATION_YANK_INSTANCE); @@ -2369,7 +2388,7 @@ void qmp_migrate_recover(const char *uri, Error **errp) * only re-setup the migration stream and poke existing migration * to continue using that newly established channel. */ - qemu_start_incoming_migration(uri, errp); + qemu_start_incoming_migration(uri, NULL, errp); } void qmp_migrate_pause(Error **errp) diff --git a/migration/rdma.c b/migration/rdma.c index 48f49add6f..0225bbaf3c 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -3356,12 +3356,15 @@ static int qemu_rdma_accept(RDMAContext *rdma) goto err_rdma_dest_wait; } + isock->host = rdma->host; + isock->port = (char *)(intptr_t)rdma->port; + /* * initialize the RDMAContext for return path for postcopy after first * connection request reached. */ if (migrate_postcopy() && !rdma->is_return_path) { - rdma_return_path = qemu_rdma_data_init(rdma->host_port, NULL); + rdma_return_path = qemu_rdma_data_init(isock, NULL); if (rdma_return_path == NULL) { rdma_ack_cm_event(cm_event); goto err_rdma_dest_wait; @@ -4093,7 +4096,7 @@ static void rdma_accept_incoming_migration(void *opaque) } } -void rdma_start_incoming_migration(const char *host_port, Error **errp) +void rdma_start_incoming_migration(InetSocketAddress *addr, Error **errp) { int ret; RDMAContext *rdma, *rdma_return_path = NULL; @@ -4107,7 +4110,7 @@ void rdma_start_incoming_migration(const char *host_port, Error **errp) return; } - rdma = qemu_rdma_data_init(host_port, &local_err); + rdma = qemu_rdma_data_init(addr, &local_err); if (rdma == NULL) { goto err; } diff --git a/migration/rdma.h b/migration/rdma.h index 8d9978e1a9..40673287a7 100644 --- a/migration/rdma.h +++ b/migration/rdma.h @@ -21,6 +21,6 @@ void rdma_start_outgoing_migration(void *opaque, InetSocketAddress *addr, Error **errp); -void rdma_start_incoming_migration(const char *host_port, Error **errp); +void rdma_start_incoming_migration(InetSocketAddress *addr, Error **errp); #endif diff --git a/migration/socket.c b/migration/socket.c index c751e0bfc1..6469d615d6 100644 --- a/migration/socket.c +++ b/migration/socket.c @@ -162,9 +162,8 @@ socket_incoming_migration_end(void *opaque) object_unref(OBJECT(listener)); } -static void -socket_start_incoming_migration_internal(SocketAddress *saddr, - Error **errp) +void socket_start_incoming_migration(SocketAddress *saddr, + Error **errp) { QIONetListener *listener = qio_net_listener_new(); MigrationIncomingState *mis = migration_incoming_get_current(); @@ -202,14 +201,3 @@ socket_start_incoming_migration_internal(SocketAddress *saddr, qapi_free_SocketAddress(address); } } - -void socket_start_incoming_migration(const char *str, Error **errp) -{ - Error *err = NULL; - SocketAddress *saddr = socket_parse(str, &err); - if (!err) { - socket_start_incoming_migration_internal(saddr, &err); - } - qapi_free_SocketAddress(saddr); - error_propagate(errp, err); -} diff --git a/migration/socket.h b/migration/socket.h index 95c9c166ec..4769a2bdf9 100644 --- a/migration/socket.h +++ b/migration/socket.h @@ -25,7 +25,7 @@ void socket_send_channel_create(QIOTaskFunc f, void *data); QIOChannel *socket_send_channel_create_sync(Error **errp); int socket_send_channel_destroy(QIOChannel *send); -void socket_start_incoming_migration(const char *str, Error **errp); +void socket_start_incoming_migration(SocketAddress *saddr, Error **errp); void socket_start_outgoing_migration(MigrationState *s, SocketAddress *saddr, Error **errp); -- 2.22.3