From: Avihai Horon <avih...@nvidia.com> Add functions to send and receive migration channel header.
Signed-off-by: Avihai Horon <avih...@nvidia.com> [MSS: Mark MigChannelHeader as packed, remove device id from it] Signed-off-by: Maciej S. Szmigiero <maciej.szmigi...@oracle.com> --- migration/channel.c | 59 ++++++++++++++++++++++++++++++++++++++++++ migration/channel.h | 14 ++++++++++ migration/trace-events | 2 ++ 3 files changed, 75 insertions(+) diff --git a/migration/channel.c b/migration/channel.c index f9de064f3b13..a72e85f5791c 100644 --- a/migration/channel.c +++ b/migration/channel.c @@ -21,6 +21,7 @@ #include "io/channel-socket.h" #include "qemu/yank.h" #include "yank_functions.h" +#include "options.h" /** * @migration_channel_process_incoming - Create new incoming migration channel @@ -93,6 +94,64 @@ void migration_channel_connect(MigrationState *s, error_free(error); } +int migration_channel_header_recv(QIOChannel *ioc, MigChannelHeader *header, + Error **errp) +{ + uint64_t header_size; + int ret; + + ret = qio_channel_read_all_eof(ioc, (char *)&header_size, + sizeof(header_size), errp); + if (ret == 0 || ret == -1) { + return -1; + } + + header_size = be64_to_cpu(header_size); + if (header_size > sizeof(*header)) { + error_setg(errp, + "Received header of size %lu bytes which is greater than " + "max header size of %lu bytes", + header_size, sizeof(*header)); + return -EINVAL; + } + + ret = qio_channel_read_all_eof(ioc, (char *)header, header_size, errp); + if (ret == 0 || ret == -1) { + return -1; + } + + header->channel_type = be32_to_cpu(header->channel_type); + + trace_migration_channel_header_recv(header->channel_type, + header_size); + + return 0; +} + +int migration_channel_header_send(QIOChannel *ioc, MigChannelHeader *header, + Error **errp) +{ + uint64_t header_size = sizeof(*header); + int ret; + + if (!migrate_channel_header()) { + return 0; + } + + trace_migration_channel_header_send(header->channel_type, + header_size); + + header_size = cpu_to_be64(header_size); + ret = qio_channel_write_all(ioc, (char *)&header_size, sizeof(header_size), + errp); + if (ret) { + return ret; + } + + header->channel_type = cpu_to_be32(header->channel_type); + + return qio_channel_write_all(ioc, (char *)header, sizeof(*header), errp); +} /** * @migration_channel_read_peek - Peek at migration channel, without diff --git a/migration/channel.h b/migration/channel.h index 5bdb8208a744..95d281828aaa 100644 --- a/migration/channel.h +++ b/migration/channel.h @@ -29,4 +29,18 @@ int migration_channel_read_peek(QIOChannel *ioc, const char *buf, const size_t buflen, Error **errp); +typedef enum { + MIG_CHANNEL_TYPE_MAIN, +} MigChannelTypes; + +typedef struct QEMU_PACKED { + uint32_t channel_type; +} MigChannelHeader; + +int migration_channel_header_send(QIOChannel *ioc, MigChannelHeader *header, + Error **errp); + +int migration_channel_header_recv(QIOChannel *ioc, MigChannelHeader *header, + Error **errp); + #endif diff --git a/migration/trace-events b/migration/trace-events index f0e1cb80c75b..e48607d5a6a2 100644 --- a/migration/trace-events +++ b/migration/trace-events @@ -198,6 +198,8 @@ migration_transferred_bytes(uint64_t qemu_file, uint64_t multifd, uint64_t rdma) # 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" +migration_channel_header_send(uint32_t channel_type, uint64_t header_size) "Migration channel header send: channel_type=%u, header_size=%lu" +migration_channel_header_recv(uint32_t channel_type, uint64_t header_size) "Migration channel header recv: channel_type=%u, header_size=%lu" # global_state.c migrate_state_too_big(void) ""