Re: [PATCH v2 4/5] migration: Fix rare hang of migration_channel_read_peek()
Peter Xu <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
On Tue, Jul 28, 2026 at 05:29:35PM -0400, Peter Xu wrote: > On Tue, Jul 28, 2026 at 05:04:16PM -0400, Peter Xu wrote: > > In an unlikely case, when a migration stream is attached to the destination > > QEMU and only send <4 bytes to the channel as magic, it's possible that > > migration_channel_read_peek() may spin forever. > > > > Fix it by adding a manual sleep for partial read. > > > > Since the path isn't attached to a coroutine, it means when partial read > > happens, there's yet not much we can do but hang the main thread, it will > > happen even for len==0 case. It means monitors can hang due to this, > > either partial read or no data arrived (but connection established). > > > > Leave this for later, the hope is this is extremely rare in production. > > > > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3889 > > Reported-by: Feifan Qian <[email protected]> > > Cc: Daniel P. Berrangé <[email protected]> > > Signed-off-by: Peter Xu <[email protected]> > > --- > > migration/channel.c | 11 +++++++++-- > > 1 file changed, 9 insertions(+), 2 deletions(-) > > > > diff --git a/migration/channel.c b/migration/channel.c > > index 1e2935f926..f446561b59 100644 > > --- a/migration/channel.c > > +++ b/migration/channel.c > > @@ -296,9 +296,16 @@ int migration_channel_read_peek(QIOChannel *ioc, > > > > if (len == buflen) { > > break; > > + } else if (len == 0) { > > I think this should be QIO_CHANNEL_ERR_BLOCK, not 0.. I'll fix it when I > post v3, and I'll do some more tests. I just found that I cannot really hit this path.. because essentially migration_channel_read_peek() is too early, and we haven't set iochannel to be in non-blocking (QEMU only does it for the main channel; for the rest channels they're always in blocking mode). But still, instead of asserting it, I plan to keep this line so this code is generic to blocking mode too in the future. > > > + qio_channel_wait_cond(ioc, G_IO_IN); > > + } else { > > + /* > > + * When partially ready, we can't use qio_channel_wait_cond() > > + * because it will return immediately. Apply a manual wait. > > + */ > > + assert(!qemu_in_coroutine()); > > + g_usleep(1000); > > } > > - > > - qio_channel_wait_cond(ioc, G_IO_IN); > > } > > > > return 0; > > -- > > 2.54.0 > > > > -- > Peter Xu -- Peter Xu