diff mbox series

[RFC,02/26] migration: Add migration channel header send/receive

Message ID 636cec92eb801f13ba893de79d4872f5d8342097.1713269378.git.maciej.szmigiero@oracle.com (mailing list archive)
State New
Headers show
Series Multifd | expand

Commit Message

Maciej S. Szmigiero April 16, 2024, 2:42 p.m. UTC
From: Avihai Horon <avihaih@nvidia.com>

Add functions to send and receive migration channel header.

Signed-off-by: Avihai Horon <avihaih@nvidia.com>
[MSS: Mark MigChannelHeader as packed, remove device id from it]
Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
---
 migration/channel.c    | 59 ++++++++++++++++++++++++++++++++++++++++++
 migration/channel.h    | 14 ++++++++++
 migration/trace-events |  2 ++
 3 files changed, 75 insertions(+)
diff mbox series

Patch

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) ""