On Wed, Nov 23, 2022 at 03:05:27PM +0000, manish.mishra wrote: > Current logic assumes that channel connections on the destination side are > always established in the same order as the source and the first one will > always be the main channel followed by the multifid or post-copy > preemption channel. This may not be always true, as even if a channel has a > connection established on the source side it can be in the pending state on > the destination side and a newer connection can be established first. > Basically causing out of order mapping of channels on the destination side. > Currently, all channels except post-copy preempt send a magic number, this > patch uses that magic number to decide the type of channel. This logic is > applicable only for precopy(multifd) live migration, as mentioned, the > post-copy preempt channel does not send any magic number. Also, tls live > migrations already does tls handshake before creating other channels, so > this issue is not possible with tls, hence this logic is avoided for tls > live migrations. This patch uses read peek to check the magic number of > channels so that current data/control stream management remains > un-effected. > > Reviewed-by: Peter Xu <pet...@redhat.com> > Reviewed-by: Daniel P. Berrangé <berra...@redhat.co > Suggested-by: Daniel P. Berrangé <berra...@redhat.com > Signed-off-by: manish.mishra <manish.mis...@nutanix.com> > --- > migration/channel.c | 46 ++++++++++++++++++++++++++++++++++++++++ > migration/channel.h | 5 +++++ > migration/migration.c | 45 ++++++++++++++++++++++++++++----------- > migration/multifd.c | 12 ++++------- > migration/multifd.h | 2 +- > migration/postcopy-ram.c | 5 +---- > migration/postcopy-ram.h | 2 +- > 7 files changed, 91 insertions(+), 26 deletions(-) > > diff --git a/migration/channel.c b/migration/channel.c > index 1b0815039f..a4600f52c5 100644 > --- a/migration/channel.c > +++ b/migration/channel.c > @@ -92,3 +92,49 @@ void migration_channel_connect(MigrationState *s, > migrate_fd_connect(s, error); > error_free(error); > } > + > + > +/** > + * @migration_channel_read_peek - Read from the peek of migration channel, > + * without actually removing it from channel buffer. > + * > + * @ioc: the channel object > + * @buf: the memory region to read data into > + * @buflen: the number of bytes to read in @buf > + * @errp: pointer to a NULL-initialized error object > + * > + * Returns 0 if successful, returns -1 and sets @errp if fails. > + */ > +int migration_channel_read_peek(QIOChannel *ioc, > + const char *buf, > + const size_t buflen, > + Error **errp) > +{ > + ssize_t len = 0; > + struct iovec iov = { .iov_base = (char *)buf, .iov_len = buflen }; > + > + while (len < buflen) { > + len = qio_channel_readv_full(ioc, &iov, 1, NULL, > + NULL, QIO_CHANNEL_READ_FLAG_MSG_PEEK, > errp); > + > + if (len == QIO_CHANNEL_ERR_BLOCK) { > + if (qemu_in_coroutine()) { > + /* 1ms sleep. */ > + qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000); > + } else { > + qio_channel_wait(ioc, G_IO_IN); > + } > + continue; > + } > + if (len == 0) { > + error_setg(errp, > + "Unexpected end-of-file on channel"); > + return -1; > + } > + if (len < 0) { > + return -1; > + } > + }
This busy waits when len > 0 and < buflen With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|