Coroutines are not supposed to block. Instead, they should yield. Fixes: f95910f ("nbd: implement TLS support in the protocol negotiation") Signed-off-by: Zhu Yangyang <zhuyangyan...@huawei.com> --- nbd/client.c | 7 ++++--- nbd/common.c | 19 ++++++++++++++++--- nbd/nbd-internal.h | 6 +++--- nbd/server.c | 10 +++++----- 4 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/nbd/client.c b/nbd/client.c index 29ffc609a4..1ab91ed205 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -619,18 +619,19 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, return NULL; } qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-client-tls"); - data.loop = g_main_loop_new(g_main_context_default(), FALSE); trace_nbd_receive_starttls_tls_handshake(); qio_channel_tls_handshake(tioc, - nbd_tls_handshake, + nbd_client_tls_handshake, &data, NULL, NULL); if (!data.complete) { + data.loop = g_main_loop_new(g_main_context_default(), FALSE); g_main_loop_run(data.loop); + g_main_loop_unref(data.loop); } - g_main_loop_unref(data.loop); + if (data.error) { error_propagate(errp, data.error); object_unref(OBJECT(tioc)); diff --git a/nbd/common.c b/nbd/common.c index 3247c1d618..01ca30a5c4 100644 --- a/nbd/common.c +++ b/nbd/common.c @@ -47,14 +47,27 @@ int nbd_drop(QIOChannel *ioc, size_t size, Error **errp) } -void nbd_tls_handshake(QIOTask *task, - void *opaque) +void nbd_client_tls_handshake(QIOTask *task, void *opaque) { struct NBDTLSHandshakeData *data = opaque; qio_task_propagate_error(task, &data->error); data->complete = true; - g_main_loop_quit(data->loop); + if (data->loop) { + g_main_loop_quit(data->loop); + } +} + + +void nbd_server_tls_handshake(QIOTask *task, void *opaque) +{ + struct NBDTLSHandshakeData *data = opaque; + + qio_task_propagate_error(task, &data->error); + data->complete = true; + if (!qemu_coroutine_entered(data->co)) { + aio_co_wake(data->co); + } } diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h index dfa02f77ee..99cca9382c 100644 --- a/nbd/nbd-internal.h +++ b/nbd/nbd-internal.h @@ -74,13 +74,13 @@ static inline int nbd_write(QIOChannel *ioc, const void *buffer, size_t size, struct NBDTLSHandshakeData { GMainLoop *loop; + Coroutine *co; bool complete; Error *error; }; - -void nbd_tls_handshake(QIOTask *task, - void *opaque); +void nbd_server_tls_handshake(QIOTask *task, void *opaque); +void nbd_client_tls_handshake(QIOTask *task, void *opaque); int nbd_drop(QIOChannel *ioc, size_t size, Error **errp); diff --git a/nbd/server.c b/nbd/server.c index c3484cc1eb..b218512ced 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -777,17 +777,17 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-server-tls"); trace_nbd_negotiate_handle_starttls_handshake(); - data.loop = g_main_loop_new(g_main_context_default(), FALSE); + data.co = qemu_coroutine_self(); qio_channel_tls_handshake(tioc, - nbd_tls_handshake, + nbd_server_tls_handshake, &data, NULL, NULL); - if (!data.complete) { - g_main_loop_run(data.loop); + while (!data.complete) { + qemu_coroutine_yield(); } - g_main_loop_unref(data.loop); + if (data.error) { object_unref(OBJECT(tioc)); error_propagate(errp, data.error); -- 2.33.0