From: David Gibson <david@gibson.dropbear.id.au>
To: passt-dev@passt.top, Stefano Brivio <sbrivio@redhat.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH 1/2] migrate: Merge protocol version information into one table
Date: Fri, 31 Jan 2025 15:52:14 +1100 [thread overview]
Message-ID: <20250131045215.1368543-2-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20250131045215.1368543-1-david@gibson.dropbear.id.au>
Currently information on protocol version specific things is split between
struct migrate_data, which lists the memory blocks to save and restore and
struct migrate_target_handlers which gives the per-version (target) pre and
post handlers to run.
In addition, despite having already looked up the version in the
migrate_data table at the top-level, we look it up again in
migrate_target_state() and do a similar lookup in target_handlers in
migrate_target_{pre,post}().
Combine the per-version information into a single struct migrate_version,
look it up once at the top level, then pass that through to the other
functions within migrate_meta.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
migrate.c | 68 ++++++++++++++++++++-----------------------------------
migrate.h | 55 +++++++++++++++++++++-----------------------
2 files changed, 51 insertions(+), 72 deletions(-)
diff --git a/migrate.c b/migrate.c
index 4279d1f8..f9e967cf 100644
--- a/migrate.c
+++ b/migrate.c
@@ -42,19 +42,6 @@ static union migrate_header header = {
.voidp_size = htonl_constant(sizeof(void *)),
};
-/* Data sections for version 1 */
-static struct iovec sections_v1[] = {
- { &header, sizeof(header) },
-};
-
-/* Set of data versions */
-static struct migrate_data data_versions[] = {
- {
- 1, sections_v1,
- },
- { 0 },
-};
-
/* Handlers to call in source before sending data */
struct migrate_handler handlers_source_pre[] = {
{ flow_migrate_source_pre },
@@ -76,12 +63,18 @@ struct migrate_handler handlers_target_post_v1[] = {
{ 0 },
};
-/* Versioned sets of migration handlers */
-struct migrate_target_handlers target_handlers[] = {
+/* Data sections for version 1 */
+static struct iovec sections_v1[] = {
+ { &header, sizeof(header) },
+};
+
+/* Supported protocol versions */
+static const struct migrate_version versions[] = {
{
- 1,
- handlers_target_pre_v1,
- handlers_target_post_v1,
+ .v = 1,
+ .pre = handlers_target_pre_v1,
+ .sections = sections_v1,
+ .post = handlers_target_post_v1,
},
{ 0 },
};
@@ -116,17 +109,12 @@ static int migrate_source_pre(struct ctx *c, struct migrate_meta *m)
*/
static int migrate_source_state(int fd, const struct migrate_meta *m)
{
- static struct migrate_data *d;
int count, rc;
- (void)m;
-
- for (d = data_versions; d->v != MIGRATE_VERSION; d++);
-
- for (count = 0; d->sections[count].iov_len; count++);
+ for (count = 0; m->v->sections[count].iov_len; count++);
debug("Writing %u migration sections", count - 1 /* minus header */);
- rc = write_remainder(fd, d->sections, count, 0);
+ rc = write_remainder(fd, m->v->sections, count, 0);
if (rc < 0)
return errno;
@@ -160,6 +148,9 @@ static int migrate_source(struct ctx *c, int fd)
struct migrate_meta m;
int rc;
+ m.version = MIGRATE_VERSION;
+ for (m.v = versions; m.v->v != m.version; m.v++);
+
if ((rc = migrate_source_pre(c, &m))) {
err("Source pre-migration failed: %s, abort", strerror_(rc));
return rc;
@@ -185,19 +176,19 @@ static int migrate_source(struct ctx *c, int fd)
*/
static int migrate_target_read_header(int fd, struct migrate_meta *m)
{
- static struct migrate_data *d;
union migrate_header h;
if (read_all_buf(fd, &h, sizeof(h)))
return errno;
+ m->version = ntohl(h.version);
+
debug("Source magic: 0x%016" PRIx64 ", sizeof(void *): %u, version: %u",
- h.magic, ntohl(h.voidp_size), ntohl(h.version));
+ h.magic, ntohl(h.voidp_size), m->version);
- for (d = data_versions; d->v != ntohl(h.version) && d->v; d++);
- if (!d->v)
+ for (m->v = versions; m->v->v != m->version; m->v++);
+ if (!m->v->v)
return ENOTSUP;
- m->v = d->v;
if (h.magic == MIGRATE_MAGIC)
m->bswap = false;
@@ -235,12 +226,9 @@ static int migrate_target_read_header(int fd, struct migrate_meta *m)
*/
static int migrate_target_pre(struct ctx *c, struct migrate_meta *m)
{
- struct migrate_target_handlers *th;
struct migrate_handler *h;
- for (th = target_handlers; th->v != m->v && th->v; th++);
-
- for (h = th->pre; h->fn; h++) {
+ for (h = m->v->pre; h->fn; h++) {
int rc;
if ((rc = h->fn(c, m)))
@@ -261,16 +249,13 @@ static int migrate_target_pre(struct ctx *c, struct migrate_meta *m)
*/
static int migrate_target_state(int fd, const struct migrate_meta *m)
{
- static struct migrate_data *d;
unsigned cnt;
int rc;
- for (d = data_versions; d->v != m->v && d->v; d++);
-
- for (cnt = 0; d->sections[cnt + 1 /* skip header */].iov_len; cnt++);
+ for (cnt = 0; m->v->sections[cnt + 1 /* skip header */].iov_len; cnt++);
debug("Reading %u migration sections", cnt);
- rc = read_remainder(fd, d->sections + 1, cnt, 0);
+ rc = read_remainder(fd, m->v->sections + 1, cnt, 0);
if (rc < 0)
return errno;
@@ -284,12 +269,9 @@ static int migrate_target_state(int fd, const struct migrate_meta *m)
*/
static void migrate_target_post(struct ctx *c, struct migrate_meta *m)
{
- struct migrate_target_handlers *th;
struct migrate_handler *h;
- for (th = target_handlers; th->v != m->v && th->v; th++);
-
- for (h = th->post; h->fn; h++)
+ for (h = m->v->post; h->fn; h++)
h->fn(c, m);
}
diff --git a/migrate.h b/migrate.h
index 3432940d..b532bde0 100644
--- a/migrate.h
+++ b/migrate.h
@@ -6,24 +6,6 @@
#ifndef MIGRATE_H
#define MIGRATE_H
-/**
- * struct migrate_meta - Migration metadata
- * @v: Chosen migration data version, host order
- * @bswap: Source has opposite endianness
- * @peer_64b: Source uses 64-bit void *
- * @time_64b: Source uses 64-bit time_t
- * @flow_size: Size of union flow in source
- * @flow_sidx_size: Size of struct flow_sidx in source
- */
-struct migrate_meta {
- uint32_t v;
- bool bswap;
- bool source_64b;
- bool time_64b;
- size_t flow_size;
- size_t flow_sidx_size;
-};
-
/**
* union migrate_header - Migration header from source
* @magic: 0xB1BB1D1B0BB1D1B0, host order
@@ -46,15 +28,7 @@ union migrate_header {
uint8_t unused[65536];
};
-/**
- * struct migrate_data - Data sections for given source version
- * @v: Source version this applies to, host order
- * @sections: Array of data sections, NULL-terminated
- */
-struct migrate_data {
- uint32_t v;
- struct iovec *sections;
-};
+struct migrate_meta;
/**
* struct migrate_handler - Function to handle a specific data section
@@ -65,17 +39,40 @@ struct migrate_handler {
};
/**
- * struct migrate_target_handlers - Versioned sets of migration target handlers
+ * struct migrate_version - Handlers and data sections for a protocol version
* @v: Source version this applies to, host order
* @pre: Set of functions to execute in target before data copy
+ * @sections: Array of data sections, NULL-terminated
* @post: Set of functions to execute in target after data copy
*/
-struct migrate_target_handlers {
+struct migrate_version {
uint32_t v;
struct migrate_handler *pre;
+ struct iovec *sections;
struct migrate_handler *post;
};
+/**
+ * struct migrate_meta - Migration metadata
+ * @version: Version number, host order
+ * @v: Version information
+ * @bswap: Source has opposite endianness
+ * @peer_64b: Source uses 64-bit void *
+ * @time_64b: Source uses 64-bit time_t
+ * @flow_size: Size of union flow in source
+ * @flow_sidx_size: Size of struct flow_sidx in source
+ */
+struct migrate_meta {
+ uint32_t version;
+ const struct migrate_version *v;
+ bool bswap;
+ bool source_64b;
+ bool time_64b;
+ size_t flow_size;
+ size_t flow_sidx_size;
+};
+
+
void migrate_init(struct ctx *c);
void migrate_close(struct ctx *c);
void migrate_request(struct ctx *c, int fd, bool target);
--
@@ -6,24 +6,6 @@
#ifndef MIGRATE_H
#define MIGRATE_H
-/**
- * struct migrate_meta - Migration metadata
- * @v: Chosen migration data version, host order
- * @bswap: Source has opposite endianness
- * @peer_64b: Source uses 64-bit void *
- * @time_64b: Source uses 64-bit time_t
- * @flow_size: Size of union flow in source
- * @flow_sidx_size: Size of struct flow_sidx in source
- */
-struct migrate_meta {
- uint32_t v;
- bool bswap;
- bool source_64b;
- bool time_64b;
- size_t flow_size;
- size_t flow_sidx_size;
-};
-
/**
* union migrate_header - Migration header from source
* @magic: 0xB1BB1D1B0BB1D1B0, host order
@@ -46,15 +28,7 @@ union migrate_header {
uint8_t unused[65536];
};
-/**
- * struct migrate_data - Data sections for given source version
- * @v: Source version this applies to, host order
- * @sections: Array of data sections, NULL-terminated
- */
-struct migrate_data {
- uint32_t v;
- struct iovec *sections;
-};
+struct migrate_meta;
/**
* struct migrate_handler - Function to handle a specific data section
@@ -65,17 +39,40 @@ struct migrate_handler {
};
/**
- * struct migrate_target_handlers - Versioned sets of migration target handlers
+ * struct migrate_version - Handlers and data sections for a protocol version
* @v: Source version this applies to, host order
* @pre: Set of functions to execute in target before data copy
+ * @sections: Array of data sections, NULL-terminated
* @post: Set of functions to execute in target after data copy
*/
-struct migrate_target_handlers {
+struct migrate_version {
uint32_t v;
struct migrate_handler *pre;
+ struct iovec *sections;
struct migrate_handler *post;
};
+/**
+ * struct migrate_meta - Migration metadata
+ * @version: Version number, host order
+ * @v: Version information
+ * @bswap: Source has opposite endianness
+ * @peer_64b: Source uses 64-bit void *
+ * @time_64b: Source uses 64-bit time_t
+ * @flow_size: Size of union flow in source
+ * @flow_sidx_size: Size of struct flow_sidx in source
+ */
+struct migrate_meta {
+ uint32_t version;
+ const struct migrate_version *v;
+ bool bswap;
+ bool source_64b;
+ bool time_64b;
+ size_t flow_size;
+ size_t flow_sidx_size;
+};
+
+
void migrate_init(struct ctx *c);
void migrate_close(struct ctx *c);
void migrate_request(struct ctx *c, int fd, bool target);
--
2.48.1
next prev parent reply other threads:[~2025-01-31 4:52 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-31 4:52 [PATCH 0/2] Fancier version handling for migration David Gibson
2025-01-31 4:52 ` David Gibson [this message]
2025-01-31 5:53 ` [PATCH 1/2] migrate: Merge protocol version information into one table Stefano Brivio
2025-01-31 6:17 ` David Gibson
2025-01-31 4:52 ` [PATCH 2/2] migrate: More sophisticated versioning David Gibson
2025-01-31 5:53 ` Stefano Brivio
2025-01-31 6:21 ` David Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250131045215.1368543-2-david@gibson.dropbear.id.au \
--to=david@gibson.dropbear.id.au \
--cc=passt-dev@passt.top \
--cc=sbrivio@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).