Currently the global state header is included in the list of data sections to send for migration. This makes for an asymmetry between the source and target sides: for the source, the header is sent after the 'pre' handlers along with all the rest of the data. For the target side, the header must be read first (before the 'pre' handlers), so that we know the version which determines what all the rest of the data will be. Change this so that the header is handled explicitly on both the source and target side. This will make some future changes simpler as well. Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- migrate.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/migrate.c b/migrate.c index 2d9f77ef..025f3b71 100644 --- a/migrate.c +++ b/migrate.c @@ -50,7 +50,6 @@ static union migrate_header header = { /* Data sections for version 1 */ static struct iovec sections_v1[] = { - { &header, sizeof(header) }, { &flow_first_free, sizeof(flow_first_free) }, { flowtab, sizeof(flowtab) }, { flow_hashtab, sizeof(flow_hashtab) }, @@ -172,6 +171,12 @@ static int migrate_source(struct ctx *c, int fd) struct migrate_meta m; int rc; + rc = write_all_buf(fd, &header, sizeof(header)); + if (rc) { + err("Failed to send migration header: %s, abort", strerror_(rc)); + return rc; + } + if ((rc = migrate_source_pre(c, &m))) { err("Source pre-migration failed: %s, abort", strerror_(rc)); return rc; @@ -279,10 +284,10 @@ static int migrate_target_state(int fd, const struct migrate_meta *m) 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; d->sections[cnt].iov_len; cnt++); debug("Reading %u migration sections", cnt); - rc = read_remainder(fd, d->sections + 1, cnt, 0); + rc = read_remainder(fd, d->sections, cnt, 0); if (rc < 0) return errno; -- 2.48.1