All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Cc: qemu-devel@nongnu.org, peterx@redhat.com, qemu-block@nongnu.org,
	leiyang@redhat.com, marcandre.lureau@redhat.com,
	"Eric Blake" <eblake@redhat.com>, "Kevin Wolf" <kwolf@redhat.com>,
	"Hanna Reitz" <hreitz@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Elena Ufimtseva" <elena.ufimtseva@oracle.com>,
	"Jagannathan Raman" <jag.raman@oracle.com>,
	"John Levon" <john.levon@nutanix.com>,
	"Thanos Makatos" <thanos.makatos@nutanix.com>,
	"Cédric Le Goater" <clg@redhat.com>, "Fam Zheng" <fam@euphon.net>,
	"Zhao Liu" <zhao1.liu@intel.com>, "Coiby Xu" <Coiby.Xu@gmail.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"Stefano Garzarella" <sgarzare@redhat.com>
Subject: Re: [PATCH v5 04/13] handle result of qio_channel_set_blocking()
Date: Fri, 19 Sep 2025 11:22:28 +0100	[thread overview]
Message-ID: <aM0u5AXygVed6o9x@redhat.com> (raw)
In-Reply-To: <20250916131403.368343-5-vsementsov@yandex-team.ru>

On Tue, Sep 16, 2025 at 04:13:53PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> Currently, we just always pass NULL as errp argument. That doesn't
> look good.
> 
> Some realizations of interface may actually report errors.
> Channel-socket realization actually either ignore or crash on
> errors, but we are going to straighten it out to always reporting
> an errp in further commits.
> 
> So, convert all callers to either handle the error (where environment
> allows) or explicitly use &error_abort.
> 
> Take also a chance to change the return value to more convenient
> bool (keeping also in mind, that underlying realizations may
> return -1 on failure, not -errno).
> 
> Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
> ---
>  block/nbd.c                      |  4 +++-
>  chardev/char-socket.c            | 20 ++++++++++++++++----
>  hw/remote/proxy.c                |  6 +++++-
>  hw/remote/remote-obj.c           |  6 +++++-
>  hw/vfio-user/proxy.c             | 11 ++++++++---
>  include/io/channel.h             |  6 +++---
>  io/channel.c                     |  4 ++--

This needed to change channel-tls.c and channel-websock.c because
their impls of qio_channel_set_blocking callback in turn called
qio_channel_set_blocking, so had an int vs bool conversion mistake
introduced in this patch.

>  nbd/server.c                     |  4 +++-
>  scsi/qemu-pr-helper.c            |  9 ++++++---
>  tests/unit/io-channel-helpers.c  |  5 +++--
>  tests/unit/test-io-channel-tls.c |  4 ++--
>  tools/i386/qemu-vmsr-helper.c    |  6 ++++--
>  ui/vnc.c                         |  2 +-
>  util/vhost-user-server.c         |  7 ++++++-
>  14 files changed, 67 insertions(+), 27 deletions(-)
> 
> diff --git a/block/nbd.c b/block/nbd.c
> index d5a2b21c6d..5d231d5c4e 100644
> --- a/block/nbd.c
> +++ b/block/nbd.c
> @@ -351,7 +351,9 @@ int coroutine_fn nbd_co_do_establish_connection(BlockDriverState *bs,
>          return ret;
>      }
>  
> -    qio_channel_set_blocking(s->ioc, false, NULL);
> +    if (!qio_channel_set_blocking(s->ioc, false, errp)) {
> +        return -EINVAL;
> +    }
>      qio_channel_set_follow_coroutine_ctx(s->ioc, true);
>  
>      /* successfully connected */
> diff --git a/chardev/char-socket.c b/chardev/char-socket.c
> index 1be078dfc0..cb4ec78ebe 100644
> --- a/chardev/char-socket.c
> +++ b/chardev/char-socket.c
> @@ -530,16 +530,24 @@ static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
>      SocketChardev *s = SOCKET_CHARDEV(chr);
>      int size;
>      int saved_errno;
> +    Error *local_err = NULL;
>  
>      if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
>          return 0;
>      }
>  
> -    qio_channel_set_blocking(s->ioc, true, NULL);
> +    if (!qio_channel_set_blocking(s->ioc, true, &local_err)) {
> +        error_report_err(local_err);
> +        return -1;
> +    }
>      size = tcp_chr_recv(chr, (void *) buf, len);
>      saved_errno = errno;
>      if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) {
> -        qio_channel_set_blocking(s->ioc, false, NULL);
> +        if (!qio_channel_set_blocking(s->ioc, false, &local_err)) {
> +            error_report_err(local_err);
> +            /* failed to recover non-blocking state */
> +            tcp_chr_disconnect(chr);
> +        }
>      }
>      if (size == 0) {
>          /* connection closed */
> @@ -884,18 +892,22 @@ static void tcp_chr_set_client_ioc_name(Chardev *chr,
>  static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
>  {
>      SocketChardev *s = SOCKET_CHARDEV(chr);
> +    Error *local_err = NULL;
>  
>      if (s->state != TCP_CHARDEV_STATE_CONNECTING) {
>          return -1;
>      }
>  
> +    if (!qio_channel_set_blocking(QIO_CHANNEL(sioc), false, &local_err)) {
> +        error_report_err(local_err);
> +        return -1;
> +    }
> +
>      s->ioc = QIO_CHANNEL(sioc);
>      object_ref(OBJECT(sioc));
>      s->sioc = sioc;
>      object_ref(OBJECT(sioc));
>  
> -    qio_channel_set_blocking(s->ioc, false, NULL);
> -
>      if (s->do_nodelay) {
>          qio_channel_set_delay(s->ioc, false);
>      }
> diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c
> index b0165aa2a1..18e0f7a064 100644
> --- a/hw/remote/proxy.c
> +++ b/hw/remote/proxy.c
> @@ -112,8 +112,12 @@ static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
>          return;
>      }
>  
> +    if (!qio_channel_set_blocking(dev->ioc, true, errp)) {
> +        object_unref(dev->ioc);
> +        return;
> +    }
> +
>      qemu_mutex_init(&dev->io_mutex);
> -    qio_channel_set_blocking(dev->ioc, true, NULL);
>  
>      pci_conf[PCI_LATENCY_TIMER] = 0xff;
>      pci_conf[PCI_INTERRUPT_PIN] = 0x01;
> diff --git a/hw/remote/remote-obj.c b/hw/remote/remote-obj.c
> index 85882902d7..3402068ab9 100644
> --- a/hw/remote/remote-obj.c
> +++ b/hw/remote/remote-obj.c
> @@ -107,7 +107,11 @@ static void remote_object_machine_done(Notifier *notifier, void *data)
>          error_report_err(err);
>          return;
>      }
> -    qio_channel_set_blocking(ioc, false, NULL);
> +    if (!qio_channel_set_blocking(ioc, false, &err)) {
> +        error_report_err(err);
> +        object_unref(OBJECT(ioc));
> +        return;
> +    }
>  
>      o->dev = dev;
>  
> diff --git a/hw/vfio-user/proxy.c b/hw/vfio-user/proxy.c
> index 2c03d49f97..bbd7ec243d 100644
> --- a/hw/vfio-user/proxy.c
> +++ b/hw/vfio-user/proxy.c
> @@ -886,10 +886,11 @@ VFIOUserProxy *vfio_user_connect_dev(SocketAddress *addr, Error **errp)
>      sioc = qio_channel_socket_new();
>      ioc = QIO_CHANNEL(sioc);
>      if (qio_channel_socket_connect_sync(sioc, addr, errp) < 0) {
> -        object_unref(OBJECT(ioc));
> -        return NULL;
> +        goto fail;
> +    }
> +    if (!qio_channel_set_blocking(ioc, false, errp)) {
> +        goto fail;
>      }
> -    qio_channel_set_blocking(ioc, false, NULL);
>  
>      proxy = g_malloc0(sizeof(VFIOUserProxy));
>      proxy->sockname = g_strdup_printf("unix:%s", sockname);
> @@ -923,6 +924,10 @@ VFIOUserProxy *vfio_user_connect_dev(SocketAddress *addr, Error **errp)
>      QLIST_INSERT_HEAD(&vfio_user_sockets, proxy, next);
>  
>      return proxy;
> +
> +fail:
> +    object_unref(OBJECT(ioc));
> +    return NULL;
>  }
>  
>  void vfio_user_set_handler(VFIODevice *vbasedev,
> diff --git a/include/io/channel.h b/include/io/channel.h
> index c7f64506f7..999a8f5f23 100644
> --- a/include/io/channel.h
> +++ b/include/io/channel.h
> @@ -531,9 +531,9 @@ int coroutine_mixed_fn qio_channel_write_all(QIOChannel *ioc,
>   * return QIO_CHANNEL_ERR_BLOCK if they would otherwise
>   * block on I/O
>   */
> -int qio_channel_set_blocking(QIOChannel *ioc,
> -                             bool enabled,
> -                             Error **errp);
> +bool qio_channel_set_blocking(QIOChannel *ioc,
> +                              bool enabled,
> +                              Error **errp);
>  
>  /**
>   * qio_channel_set_follow_coroutine_ctx:
> diff --git a/io/channel.c b/io/channel.c
> index ebd9322765..852e684938 100644
> --- a/io/channel.c
> +++ b/io/channel.c
> @@ -359,12 +359,12 @@ int coroutine_mixed_fn qio_channel_write_all(QIOChannel *ioc,
>  }
>  
>  
> -int qio_channel_set_blocking(QIOChannel *ioc,
> +bool qio_channel_set_blocking(QIOChannel *ioc,
>                                bool enabled,
>                                Error **errp)
>  {
>      QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
> -    return klass->io_set_blocking(ioc, enabled, errp);
> +    return klass->io_set_blocking(ioc, enabled, errp) == 0;
>  }
>  
>  
> diff --git a/nbd/server.c b/nbd/server.c
> index d242be9811..acec0487a8 100644
> --- a/nbd/server.c
> +++ b/nbd/server.c
> @@ -1411,7 +1411,9 @@ static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp)
>          ....options sent, ending in NBD_OPT_EXPORT_NAME or NBD_OPT_GO....
>       */
>  
> -    qio_channel_set_blocking(client->ioc, false, NULL);
> +    if (!qio_channel_set_blocking(client->ioc, false, errp)) {
> +        return -EINVAL;
> +    }
>      qio_channel_set_follow_coroutine_ctx(client->ioc, true);
>  
>      trace_nbd_negotiate_begin();
> diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c
> index b69dd982d6..074b4db472 100644
> --- a/scsi/qemu-pr-helper.c
> +++ b/scsi/qemu-pr-helper.c
> @@ -733,8 +733,11 @@ static void coroutine_fn prh_co_entry(void *opaque)
>      uint32_t flags;
>      int r;
>  
> -    qio_channel_set_blocking(QIO_CHANNEL(client->ioc),
> -                             false, NULL);
> +    if (!qio_channel_set_blocking(QIO_CHANNEL(client->ioc),
> +                                  false, &local_err)) {
> +        goto out;
> +    }
> +
>      qio_channel_set_follow_coroutine_ctx(QIO_CHANNEL(client->ioc), true);
>  
>      /* A very simple negotiation for future extensibility.  No features
> @@ -786,6 +789,7 @@ static void coroutine_fn prh_co_entry(void *opaque)
>          }
>      }
>  
> +out:
>      if (local_err) {
>          if (verbose == 0) {
>              error_free(local_err);
> @@ -794,7 +798,6 @@ static void coroutine_fn prh_co_entry(void *opaque)
>          }
>      }
>  
> -out:
>      object_unref(OBJECT(client->ioc));
>      g_free(client);
>  }
> diff --git a/tests/unit/io-channel-helpers.c b/tests/unit/io-channel-helpers.c
> index c0799c21c2..22b42d14cd 100644
> --- a/tests/unit/io-channel-helpers.c
> +++ b/tests/unit/io-channel-helpers.c
> @@ -20,6 +20,7 @@
>  
>  #include "qemu/osdep.h"
>  #include "io-channel-helpers.h"
> +#include "qapi/error.h"
>  #include "qemu/iov.h"
>  
>  struct QIOChannelTest {
> @@ -109,8 +110,8 @@ void qio_channel_test_run_threads(QIOChannelTest *test,
>      test->src = src;
>      test->dst = dst;
>  
> -    qio_channel_set_blocking(test->dst, blocking, NULL);
> -    qio_channel_set_blocking(test->src, blocking, NULL);
> +    qio_channel_set_blocking(test->dst, blocking, &error_abort);
> +    qio_channel_set_blocking(test->src, blocking, &error_abort);
>  
>      reader = g_thread_new("reader",
>                            test_io_thread_reader,
> diff --git a/tests/unit/test-io-channel-tls.c b/tests/unit/test-io-channel-tls.c
> index e036ac5df4..6f282ad45d 100644
> --- a/tests/unit/test-io-channel-tls.c
> +++ b/tests/unit/test-io-channel-tls.c
> @@ -184,8 +184,8 @@ static void test_io_channel_tls(const void *opaque)
>       * thread, so we need these non-blocking to avoid deadlock
>       * of ourselves
>       */
> -    qio_channel_set_blocking(QIO_CHANNEL(clientChanSock), false, NULL);
> -    qio_channel_set_blocking(QIO_CHANNEL(serverChanSock), false, NULL);
> +    qio_channel_set_blocking(QIO_CHANNEL(clientChanSock), false, &error_abort);
> +    qio_channel_set_blocking(QIO_CHANNEL(serverChanSock), false, &error_abort);
>  
>      /* Now the real part of the test, setup the sessions */
>      clientChanTLS = qio_channel_tls_new_client(
> diff --git a/tools/i386/qemu-vmsr-helper.c b/tools/i386/qemu-vmsr-helper.c
> index 5f19a48cbd..6c0f4fe870 100644
> --- a/tools/i386/qemu-vmsr-helper.c
> +++ b/tools/i386/qemu-vmsr-helper.c
> @@ -213,8 +213,10 @@ static void coroutine_fn vh_co_entry(void *opaque)
>      uint64_t vmsr;
>      int r;
>  
> -    qio_channel_set_blocking(QIO_CHANNEL(client->ioc),
> -                             false, NULL);
> +    if (!qio_channel_set_blocking(QIO_CHANNEL(client->ioc),
> +                                  false, &local_err)) {
> +        goto out;
> +    }
>  
>      qio_channel_set_follow_coroutine_ctx(QIO_CHANNEL(client->ioc), true);
>  
> diff --git a/ui/vnc.c b/ui/vnc.c
> index 68ca4a68e7..8ca77b2971 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -3337,7 +3337,7 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
>  
>      VNC_DEBUG("New client on socket %p\n", vs->sioc);
>      update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
> -    qio_channel_set_blocking(vs->ioc, false, NULL);
> +    qio_channel_set_blocking(vs->ioc, false, &error_abort);
>      if (vs->ioc_tag) {
>          g_source_remove(vs->ioc_tag);
>      }
> diff --git a/util/vhost-user-server.c b/util/vhost-user-server.c
> index b19229074a..d805a92394 100644
> --- a/util/vhost-user-server.c
> +++ b/util/vhost-user-server.c
> @@ -336,6 +336,7 @@ static void vu_accept(QIONetListener *listener, QIOChannelSocket *sioc,
>                        gpointer opaque)
>  {
>      VuServer *server = opaque;
> +    Error *local_err = NULL;
>  
>      if (server->sioc) {
>          warn_report("Only one vhost-user client is allowed to "
> @@ -368,7 +369,11 @@ static void vu_accept(QIONetListener *listener, QIOChannelSocket *sioc,
>      object_ref(OBJECT(server->ioc));
>  
>      /* TODO vu_message_write() spins if non-blocking! */
> -    qio_channel_set_blocking(server->ioc, false, NULL);
> +    if (!qio_channel_set_blocking(server->ioc, false, &local_err)) {
> +        error_report_err(local_err);
> +        vu_deinit(&server->vu_dev);
> +        return;
> +    }
>  
>      qio_channel_set_follow_coroutine_ctx(server->ioc, true);
>  
> -- 
> 2.48.1
> 

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 :|



  parent reply	other threads:[~2025-09-19 10:24 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-16 13:13 [PATCH v5 00/13] io: deal with blocking/non-blocking fds Vladimir Sementsov-Ogievskiy
2025-09-16 13:13 ` [PATCH v5 01/13] char-socket: tcp_chr_recv(): drop extra _set_(block, cloexec) Vladimir Sementsov-Ogievskiy
2025-09-16 13:13 ` [PATCH v5 02/13] char-socket: tcp_chr_recv(): add comment Vladimir Sementsov-Ogievskiy
2025-09-16 13:13 ` [PATCH v5 03/13] util: add qemu_set_blocking() function Vladimir Sementsov-Ogievskiy
2025-09-16 13:13 ` [PATCH v5 04/13] handle result of qio_channel_set_blocking() Vladimir Sementsov-Ogievskiy
2025-09-16 13:57   ` Peter Xu
2025-09-16 14:18     ` Vladimir Sementsov-Ogievskiy
2025-09-19 10:22   ` Daniel P. Berrangé [this message]
2025-09-16 13:13 ` [PATCH v5 05/13] migration: qemu_file_set_blocking(): add errp parameter Vladimir Sementsov-Ogievskiy
2025-09-16 14:02   ` Peter Xu
2025-09-16 15:38   ` Daniel P. Berrangé
2025-09-16 15:43   ` Daniel P. Berrangé
2025-09-16 13:13 ` [PATCH v5 06/13] util: drop qemu_socket_set_nonblock() Vladimir Sementsov-Ogievskiy
2025-09-16 15:47   ` Daniel P. Berrangé
2025-09-16 13:13 ` [PATCH v5 07/13] util: drop qemu_socket_try_set_nonblock() Vladimir Sementsov-Ogievskiy
2025-09-16 13:13 ` [PATCH v5 08/13] io/channel-socket: rework qio_channel_socket_copy_fds() Vladimir Sementsov-Ogievskiy
2025-09-16 13:13 ` [PATCH v5 09/13] util: drop qemu_socket_set_block() Vladimir Sementsov-Ogievskiy
2025-09-16 13:13 ` [PATCH v5 10/13] use qemu_set_blocking instead of g_unix_set_fd_nonblocking Vladimir Sementsov-Ogievskiy
2025-09-19 10:24   ` Daniel P. Berrangé
2025-09-16 13:14 ` [PATCH v5 11/13] chardev: qemu_chr_open_fd(): add errp Vladimir Sementsov-Ogievskiy
2025-09-16 13:14 ` [PATCH v5 12/13] chardev: close an fd on failure path Vladimir Sementsov-Ogievskiy
2025-09-16 13:14 ` [PATCH v5 13/13] util/vhost-user-server: vu_message_read(): improve error handling Vladimir Sementsov-Ogievskiy
2025-09-16 15:50   ` Daniel P. Berrangé
2025-09-17 10:13     ` Vladimir Sementsov-Ogievskiy
2025-09-19 10:27       ` Daniel P. Berrangé
2025-09-19 10:44         ` Vladimir Sementsov-Ogievskiy
2025-09-16 13:15 ` [PATCH v5 00/13] io: deal with blocking/non-blocking fds Vladimir Sementsov-Ogievskiy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aM0u5AXygVed6o9x@redhat.com \
    --to=berrange@redhat.com \
    --cc=Coiby.Xu@gmail.com \
    --cc=clg@redhat.com \
    --cc=eblake@redhat.com \
    --cc=elena.ufimtseva@oracle.com \
    --cc=fam@euphon.net \
    --cc=hreitz@redhat.com \
    --cc=jag.raman@oracle.com \
    --cc=john.levon@nutanix.com \
    --cc=kwolf@redhat.com \
    --cc=leiyang@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=sgarzare@redhat.com \
    --cc=thanos.makatos@nutanix.com \
    --cc=vsementsov@yandex-team.ru \
    --cc=zhao1.liu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.