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.
> + 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