[{"id":3629505,"web_url":"http://patchwork.ozlabs.org/comment/3629505/","msgid":"<aVLRsm5dukbnVZtb@x1.local>","list_archive_url":null,"date":"2025-12-29T19:08:34","subject":"Re: [RFC PATCH 13/25] migration: Handle error in the early async\n paths","submitter":{"id":67717,"url":"http://patchwork.ozlabs.org/api/people/67717/","name":"Peter Xu","email":"peterx@redhat.com"},"content":"On Fri, Dec 26, 2025 at 06:19:15PM -0300, Fabiano Rosas wrote:\n> Simplify migration_channel_connect() and migration_connect() to not\n> take an error as input. Move the error handling into the paths that\n> generate the error.\n> \n> To achive this, call migration_connect_error_propagate() from socket.c\n> and tls.c, which are the async paths.\n> \n> For the sync paths, the handling is done as normal by returning all\n> the way to qmp_migrate_finish(), except that now the sync paths don't\n> pass the error forward into migration_connect() anymore.\n> \n> Signed-off-by: Fabiano Rosas <farosas@suse.de>\n\nYeah this looks better in general, feel free to take:\n\nReviewed-by: Peter Xu <peterx@redhat.com>\n\nOne thing to mention:\n\nStrictly speaking, migration_tls_channel_connect() doesn't fall into the\n\"async op\" category - it was invoked from migration core, so logically it\ncan still keep its errp, then the migration core should also be able to\nprocess the error in migration_channel_connect().  It's not like the other\ntwo \"async ops\" where migration context was lost.\n\nIOW, I can kind of see why we used to pass an Error into the current\nmigration_channel_connect(), and it still makes some sense.  OTOH, it\ndoesn't really make sense to me to keep passing it to migration_connect()..\n\nBut since that's the only user of migration_tls_channel_connect(), I assume\nit's not a huge deal, anyway.\n\n> ---\n>  migration/channel.c    | 46 +++++++++++++++++-------------------------\n>  migration/channel.h    |  4 +---\n>  migration/exec.c       |  2 +-\n>  migration/fd.c         |  2 +-\n>  migration/file.c       |  2 +-\n>  migration/migration.c  | 11 ++--------\n>  migration/migration.h  |  3 ++-\n>  migration/rdma.c       |  2 +-\n>  migration/socket.c     | 17 ++++++++--------\n>  migration/tls.c        | 19 ++++++++---------\n>  migration/tls.h        |  4 +---\n>  migration/trace-events |  2 +-\n>  12 files changed, 49 insertions(+), 65 deletions(-)\n> \n> diff --git a/migration/channel.c b/migration/channel.c\n> index ba14f66d85..7243b99108 100644\n> --- a/migration/channel.c\n> +++ b/migration/channel.c\n> @@ -60,38 +60,30 @@ void migration_channel_process_incoming(QIOChannel *ioc)\n>   *\n>   * @s: Current migration state\n>   * @ioc: Channel to which we are connecting\n> - * @error: Error indicating failure to connect, free'd here\n>   */\n> -void migration_channel_connect(MigrationState *s,\n> -                               QIOChannel *ioc,\n> -                               Error *error)\n> +void migration_channel_connect(MigrationState *s, QIOChannel *ioc)\n>  {\n> -    trace_migration_set_outgoing_channel(\n> -        ioc, object_get_typename(OBJECT(ioc)), error);\n> +    trace_migration_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc)));\n>  \n> -    if (!error) {\n> -        if (migrate_channel_requires_tls_upgrade(ioc)) {\n> -            migration_tls_channel_connect(s, ioc, &error);\n> +    if (migrate_channel_requires_tls_upgrade(ioc)) {\n> +        migration_tls_channel_connect(s, ioc);\n>  \n> -            if (!error) {\n> -                /* tls_channel_connect will call back to this\n> -                 * function after the TLS handshake,\n> -                 * so we mustn't call migration_connect until then\n> -                 */\n> -\n> -                return;\n> -            }\n> -        } else {\n> -            QEMUFile *f = qemu_file_new_output(ioc);\n> -\n> -            migration_ioc_register_yank(ioc);\n> -\n> -            qemu_mutex_lock(&s->qemu_file_lock);\n> -            s->to_dst_file = f;\n> -            qemu_mutex_unlock(&s->qemu_file_lock);\n> -        }\n> +        /*\n> +         * async: the above will call back to this function after\n> +         * the TLS handshake is successfully completed.\n> +         */\n> +        return;\n>      }\n> -    migration_connect(s, error);\n> +\n> +    QEMUFile *f = qemu_file_new_output(ioc);\n> +\n> +    migration_ioc_register_yank(ioc);\n> +\n> +    qemu_mutex_lock(&s->qemu_file_lock);\n> +    s->to_dst_file = f;\n> +    qemu_mutex_unlock(&s->qemu_file_lock);\n> +\n> +    migration_connect(s);\n>  }\n>  \n>  \n> diff --git a/migration/channel.h b/migration/channel.h\n> index 2215091323..ccfeaaef18 100644\n> --- a/migration/channel.h\n> +++ b/migration/channel.h\n> @@ -20,9 +20,7 @@\n>  \n>  void migration_channel_process_incoming(QIOChannel *ioc);\n>  \n> -void migration_channel_connect(MigrationState *s,\n> -                               QIOChannel *ioc,\n> -                               Error *error_in);\n> +void migration_channel_connect(MigrationState *s, QIOChannel *ioc);\n>  \n>  int migration_channel_read_peek(QIOChannel *ioc,\n>                                  const char *buf,\n> diff --git a/migration/exec.c b/migration/exec.c\n> index 78fe0fff13..d83a07435a 100644\n> --- a/migration/exec.c\n> +++ b/migration/exec.c\n> @@ -55,7 +55,7 @@ void exec_start_outgoing_migration(MigrationState *s, strList *command,\n>      }\n>  \n>      qio_channel_set_name(ioc, \"migration-exec-outgoing\");\n> -    migration_channel_connect(s, ioc, NULL);\n> +    migration_channel_connect(s, ioc);\n>      object_unref(OBJECT(ioc));\n>  }\n>  \n> diff --git a/migration/fd.c b/migration/fd.c\n> index c956b260a4..0144a70742 100644\n> --- a/migration/fd.c\n> +++ b/migration/fd.c\n> @@ -70,7 +70,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **\n>      }\n>  \n>      qio_channel_set_name(ioc, \"migration-fd-outgoing\");\n> -    migration_channel_connect(s, ioc, NULL);\n> +    migration_channel_connect(s, ioc);\n>      object_unref(OBJECT(ioc));\n>  }\n>  \n> diff --git a/migration/file.c b/migration/file.c\n> index c490f2b219..7bb9c1c79f 100644\n> --- a/migration/file.c\n> +++ b/migration/file.c\n> @@ -122,7 +122,7 @@ void file_start_outgoing_migration(MigrationState *s,\n>          return;\n>      }\n>      qio_channel_set_name(ioc, \"migration-file-outgoing\");\n> -    migration_channel_connect(s, ioc, NULL);\n> +    migration_channel_connect(s, ioc);\n>  }\n>  \n>  static gboolean file_accept_incoming_migration(QIOChannel *ioc,\n> diff --git a/migration/migration.c b/migration/migration.c\n> index a66b2d7aaf..5c6c76f110 100644\n> --- a/migration/migration.c\n> +++ b/migration/migration.c\n> @@ -1572,7 +1572,7 @@ static void migrate_error_free(MigrationState *s)\n>      }\n>  }\n>  \n> -static void migration_connect_error_propagate(MigrationState *s, Error *error)\n> +void migration_connect_error_propagate(MigrationState *s, Error *error)\n>  {\n>      MigrationStatus current = s->state;\n>      MigrationStatus next = MIGRATION_STATUS_NONE;\n> @@ -4033,7 +4033,7 @@ fail_setup:\n>      return NULL;\n>  }\n>  \n> -void migration_connect(MigrationState *s, Error *error_in)\n> +void migration_connect(MigrationState *s)\n>  {\n>      Error *local_err = NULL;\n>      uint64_t rate_limit;\n> @@ -4041,13 +4041,6 @@ void migration_connect(MigrationState *s, Error *error_in)\n>      int ret;\n>  \n>      s->expected_downtime = migrate_downtime_limit();\n> -    if (error_in) {\n> -        migration_connect_error_propagate(s, error_in);\n> -        if (s->error) {\n> -            error_report_err(error_copy(s->error));\n> -        }\n> -        return;\n> -    }\n>  \n>      if (resume) {\n>          /* This is a resumed migration */\n> diff --git a/migration/migration.h b/migration/migration.h\n> index 4d42e8f9a7..f340cd518d 100644\n> --- a/migration/migration.h\n> +++ b/migration/migration.h\n> @@ -532,10 +532,11 @@ void migration_incoming_process(void);\n>  \n>  bool  migration_has_all_channels(void);\n>  \n> +void migration_connect_error_propagate(MigrationState *s, Error *error);\n>  void migrate_error_propagate(MigrationState *s, Error *error);\n>  bool migrate_has_error(MigrationState *s);\n>  \n> -void migration_connect(MigrationState *s, Error *error_in);\n> +void migration_connect(MigrationState *s);\n>  \n>  int migration_call_notifiers(MigrationState *s, MigrationEventType type,\n>                               Error **errp);\n> diff --git a/migration/rdma.c b/migration/rdma.c\n> index 337b415889..596a1aba0b 100644\n> --- a/migration/rdma.c\n> +++ b/migration/rdma.c\n> @@ -3997,7 +3997,7 @@ void rdma_start_outgoing_migration(void *opaque,\n>  \n>      s->to_dst_file = rdma_new_output(rdma);\n>      s->rdma_migration = true;\n> -    migration_connect(s, NULL);\n> +    migration_connect(s);\n>      return;\n>  return_path_err:\n>      qemu_rdma_cleanup(rdma);\n> diff --git a/migration/socket.c b/migration/socket.c\n> index 426f363b99..298bac30cc 100644\n> --- a/migration/socket.c\n> +++ b/migration/socket.c\n> @@ -59,24 +59,25 @@ static void socket_outgoing_migration(QIOTask *task,\n>                                        gpointer opaque)\n>  {\n>      struct SocketConnectData *data = opaque;\n> -    QIOChannel *sioc = QIO_CHANNEL(qio_task_get_source(task));\n> +    g_autoptr(QIOChannel) sioc = QIO_CHANNEL(qio_task_get_source(task));\n>      Error *err = NULL;\n>  \n>      if (qio_task_propagate_error(task, &err)) {\n> -        trace_migration_socket_outgoing_error(error_get_pretty(err));\n> -           goto out;\n> +        goto err;\n>      }\n>  \n> -    trace_migration_socket_outgoing_connected();\n> -\n>      if (migrate_zero_copy_send() &&\n>          !qio_channel_has_feature(sioc, QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY)) {\n>          error_setg(&err, \"Zero copy send feature not detected in host kernel\");\n> +        goto err;\n>      }\n>  \n> -out:\n> -    migration_channel_connect(data->s, sioc, err);\n> -    object_unref(OBJECT(sioc));\n> +    trace_migration_socket_outgoing_connected();\n> +    migration_channel_connect(data->s, sioc);\n> +    return;\n> +err:\n> +    trace_migration_socket_outgoing_error(error_get_pretty(err));\n> +    migration_connect_error_propagate(data->s, err);\n>  }\n>  \n>  void socket_start_outgoing_migration(MigrationState *s,\n> diff --git a/migration/tls.c b/migration/tls.c\n> index 82f58cbc78..a54e8e6e14 100644\n> --- a/migration/tls.c\n> +++ b/migration/tls.c\n> @@ -104,16 +104,17 @@ static void migration_tls_outgoing_handshake(QIOTask *task,\n>                                               gpointer opaque)\n>  {\n>      MigrationState *s = opaque;\n> -    QIOChannel *ioc = QIO_CHANNEL(qio_task_get_source(task));\n> +    g_autoptr(QIOChannel) ioc = QIO_CHANNEL(qio_task_get_source(task));\n>      Error *err = NULL;\n>  \n>      if (qio_task_propagate_error(task, &err)) {\n>          trace_migration_tls_outgoing_handshake_error(error_get_pretty(err));\n> -    } else {\n> -        trace_migration_tls_outgoing_handshake_complete();\n> +        migration_connect_error_propagate(s, err);\n> +        return;\n>      }\n> -    migration_channel_connect(s, ioc, err);\n> -    object_unref(OBJECT(ioc));\n> +\n> +    trace_migration_tls_outgoing_handshake_complete();\n> +    migration_channel_connect(s, ioc);\n>  }\n>  \n>  QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,\n> @@ -129,14 +130,14 @@ QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,\n>      return qio_channel_tls_new_client(ioc, creds, migrate_tls_hostname(), errp);\n>  }\n>  \n> -void migration_tls_channel_connect(MigrationState *s,\n> -                                   QIOChannel *ioc,\n> -                                   Error **errp)\n> +void migration_tls_channel_connect(MigrationState *s, QIOChannel *ioc)\n>  {\n>      QIOChannelTLS *tioc;\n> +    Error *local_err = NULL;\n>  \n> -    tioc = migration_tls_client_create(ioc, errp);\n> +    tioc = migration_tls_client_create(ioc, &local_err);\n>      if (!tioc) {\n> +        migration_connect_error_propagate(s, local_err);\n>          return;\n>      }\n>  \n> diff --git a/migration/tls.h b/migration/tls.h\n> index 7cd9c76013..7399c42edf 100644\n> --- a/migration/tls.h\n> +++ b/migration/tls.h\n> @@ -29,9 +29,7 @@ void migration_tls_channel_process_incoming(QIOChannel *ioc, Error **errp);\n>  QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,\n>                                             Error **errp);\n>  \n> -void migration_tls_channel_connect(MigrationState *s,\n> -                                   QIOChannel *ioc,\n> -                                   Error **errp);\n> +void migration_tls_channel_connect(MigrationState *s, QIOChannel *ioc);\n>  void migration_tls_channel_end(QIOChannel *ioc, Error **errp);\n>  /* Whether the QIO channel requires further TLS handshake? */\n>  bool migrate_channel_requires_tls_upgrade(QIOChannel *ioc);\n> diff --git a/migration/trace-events b/migration/trace-events\n> index da8f909cac..cbf10d0b63 100644\n> --- a/migration/trace-events\n> +++ b/migration/trace-events\n> @@ -204,7 +204,7 @@ migration_transferred_bytes(uint64_t qemu_file, uint64_t multifd, uint64_t rdma)\n>  \n>  # channel.c\n>  migration_set_incoming_channel(void *ioc, const char *ioctype) \"ioc=%p ioctype=%s\"\n> -migration_set_outgoing_channel(void *ioc, const char *ioctype, void *err)  \"ioc=%p ioctype=%s err=%p\"\n> +migration_set_outgoing_channel(void *ioc, const char *ioctype) \"ioc=%p ioctype=%s\"\n>  \n>  # global_state.c\n>  migrate_state_too_big(void) \"\"\n> -- \n> 2.51.0\n>","headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=Lf3qN8De;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=google header.b=M5aKZh8B;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4dg5P22Tvfz1xpZ\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 30 Dec 2025 06:09:10 +1100 (AEDT)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1vaIbx-000136-Ah; Mon, 29 Dec 2025 14:08:57 -0500","from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <peterx@redhat.com>) id 1vaIbo-00011W-Kf\n for qemu-devel@nongnu.org; Mon, 29 Dec 2025 14:08:51 -0500","from us-smtp-delivery-124.mimecast.com ([170.10.133.124])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <peterx@redhat.com>) id 1vaIbk-00025Z-Pu\n for qemu-devel@nongnu.org; Mon, 29 Dec 2025 14:08:47 -0500","from mail-qv1-f70.google.com (mail-qv1-f70.google.com\n [209.85.219.70]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-260-pchcfwr3PlSdy8eboJQs1A-1; Mon, 29 Dec 2025 14:08:38 -0500","by mail-qv1-f70.google.com with SMTP id\n 6a1803df08f44-88888397482so286868306d6.1\n for <qemu-devel@nongnu.org>; Mon, 29 Dec 2025 11:08:37 -0800 (PST)","from x1.local ([142.188.210.156]) by smtp.gmail.com with ESMTPSA id\n 6a1803df08f44-88d925f935asm234042246d6.0.2025.12.29.11.08.35\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Mon, 29 Dec 2025 11:08:35 -0800 (PST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1767035323;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n in-reply-to:in-reply-to:references:references;\n bh=lMsvNNKL2RM2lr4MWFkdcQUtSeuFt6thqaMnG/RbcPI=;\n b=Lf3qN8DerGx2bMO8TLMSwT9YJPLpaUeboivEQc/eepjZkAGfYh0YZqif/8T7Fz4SRDeUQC\n fwYblijzgo7vDXAdtoXSwNqvAtB50+E2xT0pMapMnw4kgo7DHpBB25rIUhN1Qto9tw6lc7\n jHZl069aeo/VjrqzLx8NCjuPUDaofVk=","v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=redhat.com; s=google; t=1767035317; x=1767640117; darn=nongnu.org;\n h=in-reply-to:content-disposition:mime-version:references:message-id\n :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to;\n bh=lMsvNNKL2RM2lr4MWFkdcQUtSeuFt6thqaMnG/RbcPI=;\n b=M5aKZh8B/WmF3cK2ulHxDLv1NMU+ACK09rNN/4d2CvpZRKSSWnVYq6a8ZfIFPHkQ2e\n SeQdZk8yoMebmopBPLQhEUSNggTk+0eBkltnk4DukXKf7EBikWWVwdCY0GVmUXgS5zjc\n XdpdWsWUlxt0iNoWAeuegMzh6+E1XJTIWWAfd1qP+zihaUBTUYJc8pZJ9OFZ90bkeDX+\n 384pjPjyuxolgihOG6g9OAePLNVICjo3UjcHEgrt/3tgNIf4T1u2UGpPovEE6bbhJKEe\n UNXTnbay0FjA3XmXqVz2iebBb1HG8vPxux0+9wMV/zwLL3J8pS3j6hngemi3P+4hygrC\n o4Dg=="],"X-MC-Unique":"pchcfwr3PlSdy8eboJQs1A-1","X-Mimecast-MFC-AGG-ID":"pchcfwr3PlSdy8eboJQs1A_1767035317","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1767035317; x=1767640117;\n h=in-reply-to:content-disposition:mime-version:references:message-id\n :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc\n :subject:date:message-id:reply-to;\n bh=lMsvNNKL2RM2lr4MWFkdcQUtSeuFt6thqaMnG/RbcPI=;\n b=dBQiXffaZFX/YItYrt0jhSlnGKCU7PY5AN5qyQaPukMzOFcbyu48nueU8jZKe0+Wc1\n AVZlI2hsi4OPXM8SQ5N8y9+wHO8REZAplBJkkvlPCJhgj8X4nUh1QdDLHhFz8FKJKK4n\n TI3LMIq9qI1rmmqR4ZIdAGi2pwDWO725oYTiG7G5dKBWfbRYopRxJzKiYJWZ3cGEq3tb\n aAw0muKozt6fClKPF9eklz39uZ4ke+rgDsrTXVhjJMBc1oO+oQPoO6HrLCpdcJ6lMmN/\n 1+jUfxJpNwqCFPWlcMsb6aKk6dXt4vR1gRb3ILClIi8jZYUbiwWeuu69WpXIHEM5i0a/\n 3qlw==","X-Gm-Message-State":"AOJu0YwHT9SCm7SXr1FHp3mn41/Ne8cHjXev2ToQ+nefmOfO/up8GddD\n VccUBUVSvmqyzL2gQbBpyOOPxh5StQwZT5ezSxcVnGEP8mLQ5KTj9ChKokSsvyZRef5yiFl/Vs0\n HTFUZ/qnZho2f1GTHiarW2i6w8xxVNBnDqeQBfQdKcpXfp1hpwNtYLw54","X-Gm-Gg":"AY/fxX653AKntBgeBcMJ6weEsnq4UwQRGZzQxrmTXxM5SLEkOAvvgw0kLXUSzYe4B2V\n o+hkc1Dz8pe671IXde5EeOxQZDmVAWJWQGS2IF4Tpe/+icuqH9RQ2+1q0iYcsRVT+bxjj54+g39\n tQCcy0ijjorC4y3imV0dAcXrsaR8bwUDZekMYBfOGGzWoEiQnPqCf5B+lZRaeNwr11oGlH6dtWG\n neyHY5AVowoF+w+0ND263M3qFK51DXUBvow6GCt/Kvjb253Q5HM5V5gqwgfx5wEbRXnSvn3ozqU\n V6RNGn8hGPxaohI38mmifN7dBT4SZkaLEkWdfQfyySkzEQrxuWmdw6fBCefUHamXOfaLYwJAacf\n sCrs=","X-Received":["by 2002:a05:6214:5711:b0:88a:57db:8e12 with SMTP id\n 6a1803df08f44-88d83792ef9mr471502456d6.32.1767035316803;\n Mon, 29 Dec 2025 11:08:36 -0800 (PST)","by 2002:a05:6214:5711:b0:88a:57db:8e12 with SMTP id\n 6a1803df08f44-88d83792ef9mr471501886d6.32.1767035316182;\n Mon, 29 Dec 2025 11:08:36 -0800 (PST)"],"X-Google-Smtp-Source":"\n AGHT+IHnTDyv4+uBifOq89eayC/HGsrkydkOHLiGOy3QIjw5k6hAWwKBwJvEj5yqjfBsYbRS9CPtkw==","Date":"Mon, 29 Dec 2025 14:08:34 -0500","From":"Peter Xu <peterx@redhat.com>","To":"Fabiano Rosas <farosas@suse.de>","Cc":"qemu-devel@nongnu.org, Li Zhijian <lizhijian@fujitsu.com>","Subject":"Re: [RFC PATCH 13/25] migration: Handle error in the early async\n paths","Message-ID":"<aVLRsm5dukbnVZtb@x1.local>","References":"<20251226211930.27565-1-farosas@suse.de>\n <20251226211930.27565-14-farosas@suse.de>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20251226211930.27565-14-farosas@suse.de>","Received-SPF":"pass client-ip=170.10.133.124; envelope-from=peterx@redhat.com;\n helo=us-smtp-delivery-124.mimecast.com","X-Spam_score_int":"-20","X-Spam_score":"-2.1","X-Spam_bar":"--","X-Spam_report":"(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,\n SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no","X-Spam_action":"no action","X-BeenThere":"qemu-devel@nongnu.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"}},{"id":3629514,"web_url":"http://patchwork.ozlabs.org/comment/3629514/","msgid":"<87fr8t84jt.fsf@suse.de>","list_archive_url":null,"date":"2025-12-29T19:35:18","subject":"Re: [RFC PATCH 13/25] migration: Handle error in the early async\n paths","submitter":{"id":85343,"url":"http://patchwork.ozlabs.org/api/people/85343/","name":"Fabiano Rosas","email":"farosas@suse.de"},"content":"Peter Xu <peterx@redhat.com> writes:\n\n> On Fri, Dec 26, 2025 at 06:19:15PM -0300, Fabiano Rosas wrote:\n>> Simplify migration_channel_connect() and migration_connect() to not\n>> take an error as input. Move the error handling into the paths that\n>> generate the error.\n>> \n>> To achive this, call migration_connect_error_propagate() from socket.c\n>> and tls.c, which are the async paths.\n>> \n>> For the sync paths, the handling is done as normal by returning all\n>> the way to qmp_migrate_finish(), except that now the sync paths don't\n>> pass the error forward into migration_connect() anymore.\n>> \n>> Signed-off-by: Fabiano Rosas <farosas@suse.de>\n>\n> Yeah this looks better in general, feel free to take:\n>\n> Reviewed-by: Peter Xu <peterx@redhat.com>\n>\n> One thing to mention:\n>\n> Strictly speaking, migration_tls_channel_connect() doesn't fall into the\n> \"async op\" category - it was invoked from migration core, so logically it\n> can still keep its errp, then the migration core should also be able to\n> process the error in migration_channel_connect().  It's not like the other\n> two \"async ops\" where migration context was lost.\n>\n\nI actually had it return the error in a previous version. Let me check\nif it still makes sense to do that.\n\n> IOW, I can kind of see why we used to pass an Error into the current\n> migration_channel_connect(), and it still makes some sense.\n\nYes, it was definitely not incorrect. I just think it's become a\nsurprising thing to do given how the code has evolved.\n\n> OTOH, it doesn't really make sense to me to keep passing it to\n> migration_connect()..\n>\n> But since that's the only user of migration_tls_channel_connect(), I assume\n> it's not a huge deal, anyway.\n>\n>> ---\n>>  migration/channel.c    | 46 +++++++++++++++++-------------------------\n>>  migration/channel.h    |  4 +---\n>>  migration/exec.c       |  2 +-\n>>  migration/fd.c         |  2 +-\n>>  migration/file.c       |  2 +-\n>>  migration/migration.c  | 11 ++--------\n>>  migration/migration.h  |  3 ++-\n>>  migration/rdma.c       |  2 +-\n>>  migration/socket.c     | 17 ++++++++--------\n>>  migration/tls.c        | 19 ++++++++---------\n>>  migration/tls.h        |  4 +---\n>>  migration/trace-events |  2 +-\n>>  12 files changed, 49 insertions(+), 65 deletions(-)\n>> \n>> diff --git a/migration/channel.c b/migration/channel.c\n>> index ba14f66d85..7243b99108 100644\n>> --- a/migration/channel.c\n>> +++ b/migration/channel.c\n>> @@ -60,38 +60,30 @@ void migration_channel_process_incoming(QIOChannel *ioc)\n>>   *\n>>   * @s: Current migration state\n>>   * @ioc: Channel to which we are connecting\n>> - * @error: Error indicating failure to connect, free'd here\n>>   */\n>> -void migration_channel_connect(MigrationState *s,\n>> -                               QIOChannel *ioc,\n>> -                               Error *error)\n>> +void migration_channel_connect(MigrationState *s, QIOChannel *ioc)\n>>  {\n>> -    trace_migration_set_outgoing_channel(\n>> -        ioc, object_get_typename(OBJECT(ioc)), error);\n>> +    trace_migration_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc)));\n>>  \n>> -    if (!error) {\n>> -        if (migrate_channel_requires_tls_upgrade(ioc)) {\n>> -            migration_tls_channel_connect(s, ioc, &error);\n>> +    if (migrate_channel_requires_tls_upgrade(ioc)) {\n>> +        migration_tls_channel_connect(s, ioc);\n>>  \n>> -            if (!error) {\n>> -                /* tls_channel_connect will call back to this\n>> -                 * function after the TLS handshake,\n>> -                 * so we mustn't call migration_connect until then\n>> -                 */\n>> -\n>> -                return;\n>> -            }\n>> -        } else {\n>> -            QEMUFile *f = qemu_file_new_output(ioc);\n>> -\n>> -            migration_ioc_register_yank(ioc);\n>> -\n>> -            qemu_mutex_lock(&s->qemu_file_lock);\n>> -            s->to_dst_file = f;\n>> -            qemu_mutex_unlock(&s->qemu_file_lock);\n>> -        }\n>> +        /*\n>> +         * async: the above will call back to this function after\n>> +         * the TLS handshake is successfully completed.\n>> +         */\n>> +        return;\n>>      }\n>> -    migration_connect(s, error);\n>> +\n>> +    QEMUFile *f = qemu_file_new_output(ioc);\n>> +\n>> +    migration_ioc_register_yank(ioc);\n>> +\n>> +    qemu_mutex_lock(&s->qemu_file_lock);\n>> +    s->to_dst_file = f;\n>> +    qemu_mutex_unlock(&s->qemu_file_lock);\n>> +\n>> +    migration_connect(s);\n>>  }\n>>  \n>>  \n>> diff --git a/migration/channel.h b/migration/channel.h\n>> index 2215091323..ccfeaaef18 100644\n>> --- a/migration/channel.h\n>> +++ b/migration/channel.h\n>> @@ -20,9 +20,7 @@\n>>  \n>>  void migration_channel_process_incoming(QIOChannel *ioc);\n>>  \n>> -void migration_channel_connect(MigrationState *s,\n>> -                               QIOChannel *ioc,\n>> -                               Error *error_in);\n>> +void migration_channel_connect(MigrationState *s, QIOChannel *ioc);\n>>  \n>>  int migration_channel_read_peek(QIOChannel *ioc,\n>>                                  const char *buf,\n>> diff --git a/migration/exec.c b/migration/exec.c\n>> index 78fe0fff13..d83a07435a 100644\n>> --- a/migration/exec.c\n>> +++ b/migration/exec.c\n>> @@ -55,7 +55,7 @@ void exec_start_outgoing_migration(MigrationState *s, strList *command,\n>>      }\n>>  \n>>      qio_channel_set_name(ioc, \"migration-exec-outgoing\");\n>> -    migration_channel_connect(s, ioc, NULL);\n>> +    migration_channel_connect(s, ioc);\n>>      object_unref(OBJECT(ioc));\n>>  }\n>>  \n>> diff --git a/migration/fd.c b/migration/fd.c\n>> index c956b260a4..0144a70742 100644\n>> --- a/migration/fd.c\n>> +++ b/migration/fd.c\n>> @@ -70,7 +70,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **\n>>      }\n>>  \n>>      qio_channel_set_name(ioc, \"migration-fd-outgoing\");\n>> -    migration_channel_connect(s, ioc, NULL);\n>> +    migration_channel_connect(s, ioc);\n>>      object_unref(OBJECT(ioc));\n>>  }\n>>  \n>> diff --git a/migration/file.c b/migration/file.c\n>> index c490f2b219..7bb9c1c79f 100644\n>> --- a/migration/file.c\n>> +++ b/migration/file.c\n>> @@ -122,7 +122,7 @@ void file_start_outgoing_migration(MigrationState *s,\n>>          return;\n>>      }\n>>      qio_channel_set_name(ioc, \"migration-file-outgoing\");\n>> -    migration_channel_connect(s, ioc, NULL);\n>> +    migration_channel_connect(s, ioc);\n>>  }\n>>  \n>>  static gboolean file_accept_incoming_migration(QIOChannel *ioc,\n>> diff --git a/migration/migration.c b/migration/migration.c\n>> index a66b2d7aaf..5c6c76f110 100644\n>> --- a/migration/migration.c\n>> +++ b/migration/migration.c\n>> @@ -1572,7 +1572,7 @@ static void migrate_error_free(MigrationState *s)\n>>      }\n>>  }\n>>  \n>> -static void migration_connect_error_propagate(MigrationState *s, Error *error)\n>> +void migration_connect_error_propagate(MigrationState *s, Error *error)\n>>  {\n>>      MigrationStatus current = s->state;\n>>      MigrationStatus next = MIGRATION_STATUS_NONE;\n>> @@ -4033,7 +4033,7 @@ fail_setup:\n>>      return NULL;\n>>  }\n>>  \n>> -void migration_connect(MigrationState *s, Error *error_in)\n>> +void migration_connect(MigrationState *s)\n>>  {\n>>      Error *local_err = NULL;\n>>      uint64_t rate_limit;\n>> @@ -4041,13 +4041,6 @@ void migration_connect(MigrationState *s, Error *error_in)\n>>      int ret;\n>>  \n>>      s->expected_downtime = migrate_downtime_limit();\n>> -    if (error_in) {\n>> -        migration_connect_error_propagate(s, error_in);\n>> -        if (s->error) {\n>> -            error_report_err(error_copy(s->error));\n>> -        }\n>> -        return;\n>> -    }\n>>  \n>>      if (resume) {\n>>          /* This is a resumed migration */\n>> diff --git a/migration/migration.h b/migration/migration.h\n>> index 4d42e8f9a7..f340cd518d 100644\n>> --- a/migration/migration.h\n>> +++ b/migration/migration.h\n>> @@ -532,10 +532,11 @@ void migration_incoming_process(void);\n>>  \n>>  bool  migration_has_all_channels(void);\n>>  \n>> +void migration_connect_error_propagate(MigrationState *s, Error *error);\n>>  void migrate_error_propagate(MigrationState *s, Error *error);\n>>  bool migrate_has_error(MigrationState *s);\n>>  \n>> -void migration_connect(MigrationState *s, Error *error_in);\n>> +void migration_connect(MigrationState *s);\n>>  \n>>  int migration_call_notifiers(MigrationState *s, MigrationEventType type,\n>>                               Error **errp);\n>> diff --git a/migration/rdma.c b/migration/rdma.c\n>> index 337b415889..596a1aba0b 100644\n>> --- a/migration/rdma.c\n>> +++ b/migration/rdma.c\n>> @@ -3997,7 +3997,7 @@ void rdma_start_outgoing_migration(void *opaque,\n>>  \n>>      s->to_dst_file = rdma_new_output(rdma);\n>>      s->rdma_migration = true;\n>> -    migration_connect(s, NULL);\n>> +    migration_connect(s);\n>>      return;\n>>  return_path_err:\n>>      qemu_rdma_cleanup(rdma);\n>> diff --git a/migration/socket.c b/migration/socket.c\n>> index 426f363b99..298bac30cc 100644\n>> --- a/migration/socket.c\n>> +++ b/migration/socket.c\n>> @@ -59,24 +59,25 @@ static void socket_outgoing_migration(QIOTask *task,\n>>                                        gpointer opaque)\n>>  {\n>>      struct SocketConnectData *data = opaque;\n>> -    QIOChannel *sioc = QIO_CHANNEL(qio_task_get_source(task));\n>> +    g_autoptr(QIOChannel) sioc = QIO_CHANNEL(qio_task_get_source(task));\n>>      Error *err = NULL;\n>>  \n>>      if (qio_task_propagate_error(task, &err)) {\n>> -        trace_migration_socket_outgoing_error(error_get_pretty(err));\n>> -           goto out;\n>> +        goto err;\n>>      }\n>>  \n>> -    trace_migration_socket_outgoing_connected();\n>> -\n>>      if (migrate_zero_copy_send() &&\n>>          !qio_channel_has_feature(sioc, QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY)) {\n>>          error_setg(&err, \"Zero copy send feature not detected in host kernel\");\n>> +        goto err;\n>>      }\n>>  \n>> -out:\n>> -    migration_channel_connect(data->s, sioc, err);\n>> -    object_unref(OBJECT(sioc));\n>> +    trace_migration_socket_outgoing_connected();\n>> +    migration_channel_connect(data->s, sioc);\n>> +    return;\n>> +err:\n>> +    trace_migration_socket_outgoing_error(error_get_pretty(err));\n>> +    migration_connect_error_propagate(data->s, err);\n>>  }\n>>  \n>>  void socket_start_outgoing_migration(MigrationState *s,\n>> diff --git a/migration/tls.c b/migration/tls.c\n>> index 82f58cbc78..a54e8e6e14 100644\n>> --- a/migration/tls.c\n>> +++ b/migration/tls.c\n>> @@ -104,16 +104,17 @@ static void migration_tls_outgoing_handshake(QIOTask *task,\n>>                                               gpointer opaque)\n>>  {\n>>      MigrationState *s = opaque;\n>> -    QIOChannel *ioc = QIO_CHANNEL(qio_task_get_source(task));\n>> +    g_autoptr(QIOChannel) ioc = QIO_CHANNEL(qio_task_get_source(task));\n>>      Error *err = NULL;\n>>  \n>>      if (qio_task_propagate_error(task, &err)) {\n>>          trace_migration_tls_outgoing_handshake_error(error_get_pretty(err));\n>> -    } else {\n>> -        trace_migration_tls_outgoing_handshake_complete();\n>> +        migration_connect_error_propagate(s, err);\n>> +        return;\n>>      }\n>> -    migration_channel_connect(s, ioc, err);\n>> -    object_unref(OBJECT(ioc));\n>> +\n>> +    trace_migration_tls_outgoing_handshake_complete();\n>> +    migration_channel_connect(s, ioc);\n>>  }\n>>  \n>>  QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,\n>> @@ -129,14 +130,14 @@ QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,\n>>      return qio_channel_tls_new_client(ioc, creds, migrate_tls_hostname(), errp);\n>>  }\n>>  \n>> -void migration_tls_channel_connect(MigrationState *s,\n>> -                                   QIOChannel *ioc,\n>> -                                   Error **errp)\n>> +void migration_tls_channel_connect(MigrationState *s, QIOChannel *ioc)\n>>  {\n>>      QIOChannelTLS *tioc;\n>> +    Error *local_err = NULL;\n>>  \n>> -    tioc = migration_tls_client_create(ioc, errp);\n>> +    tioc = migration_tls_client_create(ioc, &local_err);\n>>      if (!tioc) {\n>> +        migration_connect_error_propagate(s, local_err);\n>>          return;\n>>      }\n>>  \n>> diff --git a/migration/tls.h b/migration/tls.h\n>> index 7cd9c76013..7399c42edf 100644\n>> --- a/migration/tls.h\n>> +++ b/migration/tls.h\n>> @@ -29,9 +29,7 @@ void migration_tls_channel_process_incoming(QIOChannel *ioc, Error **errp);\n>>  QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,\n>>                                             Error **errp);\n>>  \n>> -void migration_tls_channel_connect(MigrationState *s,\n>> -                                   QIOChannel *ioc,\n>> -                                   Error **errp);\n>> +void migration_tls_channel_connect(MigrationState *s, QIOChannel *ioc);\n>>  void migration_tls_channel_end(QIOChannel *ioc, Error **errp);\n>>  /* Whether the QIO channel requires further TLS handshake? */\n>>  bool migrate_channel_requires_tls_upgrade(QIOChannel *ioc);\n>> diff --git a/migration/trace-events b/migration/trace-events\n>> index da8f909cac..cbf10d0b63 100644\n>> --- a/migration/trace-events\n>> +++ b/migration/trace-events\n>> @@ -204,7 +204,7 @@ migration_transferred_bytes(uint64_t qemu_file, uint64_t multifd, uint64_t rdma)\n>>  \n>>  # channel.c\n>>  migration_set_incoming_channel(void *ioc, const char *ioctype) \"ioc=%p ioctype=%s\"\n>> -migration_set_outgoing_channel(void *ioc, const char *ioctype, void *err)  \"ioc=%p ioctype=%s err=%p\"\n>> +migration_set_outgoing_channel(void *ioc, const char *ioctype) \"ioc=%p ioctype=%s\"\n>>  \n>>  # global_state.c\n>>  migrate_state_too_big(void) \"\"\n>> -- \n>> 2.51.0\n>>","headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256\n header.s=susede2_rsa header.b=NNYGtVou;\n\tdkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256\n header.s=susede2_ed25519 header.b=647B6icB;\n\tdkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de\n header.a=rsa-sha256 header.s=susede2_rsa header.b=FMyqsswe;\n\tdkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256\n header.s=susede2_ed25519 header.b=DsZriVsO;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)","smtp-out1.suse.de;\n\tnone"],"Received":["from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4dg5zx4hggz1xpZ\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 30 Dec 2025 06:35:56 +1100 (AEDT)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1vaJ1h-00011e-L2; Mon, 29 Dec 2025 14:35:33 -0500","from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <farosas@suse.de>) id 1vaJ1c-0000xw-G9\n for qemu-devel@nongnu.org; Mon, 29 Dec 2025 14:35:29 -0500","from smtp-out1.suse.de ([195.135.223.130])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <farosas@suse.de>) id 1vaJ1a-0008D1-3Y\n for qemu-devel@nongnu.org; Mon, 29 Dec 2025 14:35:28 -0500","from imap1.dmz-prg2.suse.org (unknown [10.150.64.97])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n (No client certificate requested)\n by smtp-out1.suse.de (Postfix) with ESMTPS id B6161336BA;\n Mon, 29 Dec 2025 19:35:21 +0000 (UTC)","from imap1.dmz-prg2.suse.org (localhost [127.0.0.1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n (No client certificate requested)\n by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id 31FB8137C3;\n Mon, 29 Dec 2025 19:35:20 +0000 (UTC)","from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167])\n by imap1.dmz-prg2.suse.org with ESMTPSA id 9poiOfjXUmlIVgAAD6G6ig\n (envelope-from <farosas@suse.de>); Mon, 29 Dec 2025 19:35:20 +0000"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_rsa;\n t=1767036922;\n h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc:\n mime-version:mime-version:content-type:content-type:\n in-reply-to:in-reply-to:references:references;\n bh=EZDrq1EN9UYHWklRiflBzSW/afKV6QONVnfiH/tw0LU=;\n b=NNYGtVouIJVH4/8Hi9Y200X0cMOqifZYsHGDQ4j0JVn1LndQeqvpuN5GyI0ANDLWoVYXyn\n epL7liA7UxlVoZZ9X/ikVWP9S2K8AEHyxe4Yi1H+R6ppfNBPkp27IYlBsAGz5r2eRMpEly\n KQSWzENW5D96/2eBGPtKOHQIcooBhGI=","v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_ed25519; t=1767036922;\n h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc:\n mime-version:mime-version:content-type:content-type:\n in-reply-to:in-reply-to:references:references;\n bh=EZDrq1EN9UYHWklRiflBzSW/afKV6QONVnfiH/tw0LU=;\n b=647B6icBK4mhHerZgnq1sEhOxxhFA5hoxYNa4g2qFiGCmK3fibReVRXbtN6FlLFXi4ZSnq\n ZL7kvuRoBMxyRbDQ==","v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_rsa;\n t=1767036921;\n h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc:\n mime-version:mime-version:content-type:content-type:\n in-reply-to:in-reply-to:references:references;\n bh=EZDrq1EN9UYHWklRiflBzSW/afKV6QONVnfiH/tw0LU=;\n b=FMyqsswe4DDTvvUKsTKrFSSg2CblbieiNlPS1tNfuQnn5AlOnRkXZ0AOip0QkRhfw9TEDL\n /LJ3AjsOQP/aRgegTrZW6gCdv0QRW7YIJwDDkqUbu56U7Do6CR17jD4SIauLELkdbxL5bz\n NKeJ4HZkmcNaivFXxcjRxkyooENMJ6U=","v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_ed25519; t=1767036921;\n h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc:\n mime-version:mime-version:content-type:content-type:\n in-reply-to:in-reply-to:references:references;\n bh=EZDrq1EN9UYHWklRiflBzSW/afKV6QONVnfiH/tw0LU=;\n b=DsZriVsO9c/Mwp0GQNYZ2v0WI2nn5y7B9HqluMQ+wGQYxz/sMt99ry74aQrXgIKFf0KObf\n NJIbq3dInQST6gAQ=="],"From":"Fabiano Rosas <farosas@suse.de>","To":"Peter Xu <peterx@redhat.com>","Cc":"qemu-devel@nongnu.org, Li Zhijian <lizhijian@fujitsu.com>","Subject":"Re: [RFC PATCH 13/25] migration: Handle error in the early async\n paths","In-Reply-To":"<aVLRsm5dukbnVZtb@x1.local>","References":"<20251226211930.27565-1-farosas@suse.de>\n <20251226211930.27565-14-farosas@suse.de> <aVLRsm5dukbnVZtb@x1.local>","Date":"Mon, 29 Dec 2025 16:35:18 -0300","Message-ID":"<87fr8t84jt.fsf@suse.de>","MIME-Version":"1.0","Content-Type":"text/plain","X-Spam-Score":"-4.30","X-Spamd-Result":"default: False [-4.30 / 50.00]; BAYES_HAM(-3.00)[100.00%];\n NEURAL_HAM_LONG(-1.00)[-1.000];\n NEURAL_HAM_SHORT(-0.20)[-0.992]; MIME_GOOD(-0.10)[text/plain];\n ARC_NA(0.00)[]; MISSING_XM_UA(0.00)[]; RCVD_TLS_ALL(0.00)[];\n MIME_TRACE(0.00)[0:+]; RCVD_VIA_SMTP_AUTH(0.00)[];\n TO_DN_SOME(0.00)[]; FUZZY_RATELIMITED(0.00)[rspamd.com];\n MID_RHS_MATCH_FROM(0.00)[];\n DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519];\n FROM_HAS_DN(0.00)[]; RCPT_COUNT_THREE(0.00)[3];\n FROM_EQ_ENVFROM(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[];\n RCVD_COUNT_TWO(0.00)[2];\n DBL_BLOCKED_OPENRESOLVER(0.00)[imap1.dmz-prg2.suse.org:helo, suse.de:email,\n suse.de:mid]","Received-SPF":"pass client-ip=195.135.223.130; envelope-from=farosas@suse.de;\n helo=smtp-out1.suse.de","X-Spam_score_int":"-43","X-Spam_score":"-4.4","X-Spam_bar":"----","X-Spam_report":"(-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001,\n RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no","X-Spam_action":"no action","X-BeenThere":"qemu-devel@nongnu.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"}}]