diff --git a/block/nbd.c b/block/nbd.c index 411435c155..8caeafc8d3 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -356,11 +356,50 @@ static int nbd_handle_updated_info(BlockDriverState *bs, Error **errp) return 0; } +static int coroutine_fn nbd_co_do_establish_connection(BlockDriverState *bs, + Error **errp) +{ + BDRVNBDState *s = (BDRVNBDState *)bs->opaque; + int ret; + + assert(!s->ioc); + + s->ioc = nbd_co_establish_connection(s->conn, &s->info, errp); + if (!s->ioc) { + return -ECONNREFUSED; + } + + ret = nbd_handle_updated_info(s->bs, NULL); + if (ret < 0) { + /* + * We have connected, but must fail for other reasons. + * Send NBD_CMD_DISC as a courtesy to the server. + */ + NBDRequest request = { .type = NBD_CMD_DISC }; + + nbd_send_request(s->ioc, &request); + + object_unref(OBJECT(s->ioc)); + s->ioc = NULL; + + return ret; + } + + qio_channel_set_blocking(s->ioc, false, NULL); + qio_channel_attach_aio_context(s->ioc, bdrv_get_aio_context(bs)); + + yank_register_function(BLOCKDEV_YANK_INSTANCE(s->bs->node_name), nbd_yank, + bs); + + /* successfully connected */ + s->state = NBD_CLIENT_CONNECTED; + qemu_co_queue_restart_all(&s->free_sema); + + return 0; +} + static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s) { - int ret; - AioContext *aio_context = bdrv_get_aio_context(s->bs); - if (!nbd_client_connecting(s)) { return; } @@ -398,42 +437,7 @@ static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s) s->ioc = NULL; } - s->ioc = nbd_co_establish_connection(s->conn, &s->info, NULL); - if (!s->ioc) { - ret = -ECONNREFUSED; - goto out; - } - - qio_channel_set_blocking(QIO_CHANNEL(s->ioc), false, NULL); - qio_channel_attach_aio_context(QIO_CHANNEL(s->ioc), aio_context); - - yank_register_function(BLOCKDEV_YANK_INSTANCE(s->bs->node_name), nbd_yank, - s->bs); - - ret = nbd_handle_updated_info(s->bs, NULL); - if (ret < 0) { - /* - * We have connected, but must fail for other reasons. - * Send NBD_CMD_DISC as a courtesy to the server. - */ - NBDRequest request = { .type = NBD_CMD_DISC }; - - nbd_send_request(s->ioc, &request); - - yank_unregister_function(BLOCKDEV_YANK_INSTANCE(s->bs->node_name), - nbd_yank, s->bs); - object_unref(OBJECT(s->ioc)); - s->ioc = NULL; - - return; - } - -out: - if (ret >= 0) { - /* successfully connected */ - s->state = NBD_CLIENT_CONNECTED; - qemu_co_queue_restart_all(&s->free_sema); - } + nbd_co_do_establish_connection(s->bs, NULL); } static coroutine_fn void nbd_co_reconnect_loop(BDRVNBDState *s)