treewide: handle result of qio_channel_set_blocking()
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>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
[DB: fix return type mismatch in TLS/websocket channel
impls for qio_channel_set_blocking]
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
4149afca71
commit
1ed8903916
16 changed files with 69 additions and 30 deletions
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ static int qio_channel_tls_set_blocking(QIOChannel *ioc,
|
|||
{
|
||||
QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc);
|
||||
|
||||
return qio_channel_set_blocking(tioc->master, enabled, errp);
|
||||
return qio_channel_set_blocking(tioc->master, enabled, errp) ? 0 : -1;
|
||||
}
|
||||
|
||||
static void qio_channel_tls_set_delay(QIOChannel *ioc,
|
||||
|
|
|
|||
|
|
@ -1184,8 +1184,7 @@ static int qio_channel_websock_set_blocking(QIOChannel *ioc,
|
|||
{
|
||||
QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
|
||||
|
||||
qio_channel_set_blocking(wioc->master, enabled, errp);
|
||||
return 0;
|
||||
return qio_channel_set_blocking(wioc->master, enabled, errp) ? 0 : -1;
|
||||
}
|
||||
|
||||
static void qio_channel_websock_set_delay(QIOChannel *ioc,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
2
ui/vnc.c
2
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue