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


Reply via email to