* Juan Quintela (quint...@redhat.com) wrote: > We still don't put anything there. > > Signed-off-by: Juan Quintela <quint...@redhat.com> > --- > migration/ram.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 136 insertions(+), 1 deletion(-) > > diff --git a/migration/ram.c b/migration/ram.c > index b19300992e..804c83ed89 100644 > --- a/migration/ram.c > +++ b/migration/ram.c > @@ -412,6 +412,17 @@ typedef struct { > uint8_t id; > } __attribute__((packed)) MultiFDInit_t; > > +typedef struct { > + uint32_t magic; > + uint32_t version; > + uint32_t flags; > + uint32_t size; > + uint32_t used; > + uint32_t seq; > + char ramblock[256]; > + uint64_t offset[]; > +} __attribute__((packed)) MultiFDPacket_t; > + > typedef struct { > /* number of used pages */ > uint32_t used; > @@ -446,6 +457,14 @@ typedef struct { > bool quit; > /* array of pages to sent */ > MultiFDPages_t *pages; > + /* packet allocated len */ > + uint32_t packet_len; > + /* pointer to the packet */ > + MultiFDPacket_t *packet; > + /* multifd flags for each packet */ > + uint32_t flags; > + /* global number of generated multifd packets */ > + uint32_t seq; > } MultiFDSendParams; > > typedef struct { > @@ -468,6 +487,14 @@ typedef struct { > bool quit; > /* array of pages to receive */ > MultiFDPages_t *pages; > + /* packet allocated len */ > + uint32_t packet_len; > + /* pointer to the packet */ > + MultiFDPacket_t *packet; > + /* multifd flags for each packet */ > + uint32_t flags; > + /* global number of generated multifd packets */ > + uint32_t seq; > } MultiFDRecvParams; > > static int multifd_send_initial_packet(MultiFDSendParams *p, Error **errp) > @@ -552,6 +579,91 @@ static void multifd_pages_clear(MultiFDPages_t *pages) > g_free(pages); > } > > +static void multifd_send_fill_packet(MultiFDSendParams *p) > +{ > + MultiFDPacket_t *packet = p->packet; > + int i; > + > + packet->magic = cpu_to_be32(MULTIFD_MAGIC); > + packet->version = cpu_to_be32(MULTIFD_VERSION); > + packet->flags = cpu_to_be32(p->flags); > + packet->size = cpu_to_be32(migrate_multifd_page_count()); > + packet->used = cpu_to_be32(p->pages->used); > + packet->seq = cpu_to_be32(p->seq); > + > + if (p->pages->block) { > + strncpy(packet->ramblock, p->pages->block->idstr, 256); > + } > + > + for (i = 0; i < p->pages->used; i++) { > + packet->offset[i] = cpu_to_be64(p->pages->offset[i]); > + } > +} > + > +static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp) > +{ > + MultiFDPacket_t *packet = p->packet; > + RAMBlock *block; > + int i; > + > + /* ToDo: We can't use it until we haven't received a message */ > + return 0; > + > + be32_to_cpus(&packet->magic); > + if (packet->magic != MULTIFD_MAGIC) { > + error_setg(errp, "multifd: received packet " > + "version %d and expected version %d", > + packet->magic, MULTIFD_VERSION);
That's mixing magic and version. (Magic's as %x please) > + return -1; > + } > + > + be32_to_cpus(&packet->version); > + if (packet->version != MULTIFD_VERSION) { > + error_setg(errp, "multifd: received packet " > + "version %d and expected version %d", > + packet->version, MULTIFD_VERSION); > + return -1; > + } > + > + p->flags = be32_to_cpu(packet->flags); > + > + be32_to_cpus(&packet->size); > + if (packet->size > migrate_multifd_page_count()) { > + error_setg(errp, "multifd: received packet " > + "with size %d and expected maximum size %d", > + packet->size, migrate_multifd_page_count()) ; > + return -1; > + } > + > + p->pages->used = be32_to_cpu(packet->used); > + if (p->pages->used > packet->size) { > + error_setg(errp, "multifd: received packet " > + "with size %d and expected maximum size %d", > + p->pages->used, packet->size) ; > + return -1; > + } > + > + p->seq = be32_to_cpu(packet->seq); > + > + if (p->pages->used) { > + block = qemu_ram_block_by_name(packet->ramblock); Do you need to ensure that packet->ramblock is a terminated string first? > + if (!block) { > + error_setg(errp, "multifd: unknown ram block %s", > + packet->ramblock); > + return -1; > + } > + } > + > + for (i = 0; i < p->pages->used; i++) { > + ram_addr_t offset = be64_to_cpu(packet->offset[i]); > + > + p->pages->iov[i].iov_base = block->host + offset; I think that needs validating to ensure that the source didn't send us junk and cause us to overwrite after the end of block->host > + p->pages->iov[i].iov_len = TARGET_PAGE_SIZE; > + } > + > + return 0; > +} > + > struct { > MultiFDSendParams *params; > /* number of created threads */ > @@ -607,6 +719,9 @@ int multifd_save_cleanup(Error **errp) > p->name = NULL; > multifd_pages_clear(p->pages); > p->pages = NULL; > + p->packet_len = 0; > + g_free(p->packet); > + p->packet = NULL; > } > g_free(multifd_send_state->params); > multifd_send_state->params = NULL; > @@ -628,6 +743,7 @@ static void *multifd_send_thread(void *opaque) > > while (true) { > qemu_mutex_lock(&p->mutex); > + multifd_send_fill_packet(p); > if (p->quit) { > qemu_mutex_unlock(&p->mutex); > break; > @@ -692,6 +808,9 @@ int multifd_save_setup(void) > p->quit = false; > p->id = i; > multifd_pages_init(&p->pages, page_count); > + p->packet_len = sizeof(MultiFDPacket_t) > + + sizeof(ram_addr_t) * page_count; > + p->packet = g_malloc0(p->packet_len); > p->name = g_strdup_printf("multifdsend_%d", i); > socket_send_channel_create(multifd_new_send_channel_async, p); > } > @@ -751,6 +870,9 @@ int multifd_load_cleanup(Error **errp) > p->name = NULL; > multifd_pages_clear(p->pages); > p->pages = NULL; > + p->packet_len = 0; > + g_free(p->packet); > + p->packet = NULL; > } > g_free(multifd_recv_state->params); > multifd_recv_state->params = NULL; > @@ -763,10 +885,20 @@ int multifd_load_cleanup(Error **errp) > static void *multifd_recv_thread(void *opaque) > { > MultiFDRecvParams *p = opaque; > + Error *local_err = NULL; > + int ret; > > while (true) { > qemu_mutex_lock(&p->mutex); > - if (p->quit) { > + if (false) { > + /* ToDo: Packet reception goes here */ > + > + ret = multifd_recv_unfill_packet(p, &local_err); > + qemu_mutex_unlock(&p->mutex); > + if (ret) { > + break; > + } > + } else if (p->quit) { > qemu_mutex_unlock(&p->mutex); > break; > } > @@ -803,6 +935,9 @@ int multifd_load_setup(void) > p->quit = false; > p->id = i; > multifd_pages_init(&p->pages, page_count); > + p->packet_len = sizeof(MultiFDPacket_t) > + + sizeof(ram_addr_t) * page_count; > + p->packet = g_malloc0(p->packet_len); > p->name = g_strdup_printf("multifdrecv_%d", i); > } > return 0; > -- > 2.17.0 > -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK