block/nbd: rename NBDConnectThread to NBDClientConnection
We are going to move the connection code to its own file, and want clear names and APIs first. The structure is shared between user and (possibly) several runs of connect-thread. So it's wrong to call it "thread". Let's rename to something more generic. Appropriately rename connect_thread and thr variables to conn. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Roman Kagan <rvkagan@yandex-team.ru> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20210610100802.5888-15-vsementsov@virtuozzo.com> Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
c3e7730485
commit
90ddc64fb2
134
block/nbd.c
134
block/nbd.c
@ -66,7 +66,7 @@ typedef enum NBDClientState {
|
||||
NBD_CLIENT_QUIT
|
||||
} NBDClientState;
|
||||
|
||||
typedef struct NBDConnectThread {
|
||||
typedef struct NBDClientConnection {
|
||||
/* Initialization constants */
|
||||
SocketAddress *saddr; /* address to connect to */
|
||||
|
||||
@ -91,7 +91,7 @@ typedef struct NBDConnectThread {
|
||||
* nbd_co_establish_connection() after yield()
|
||||
*/
|
||||
Coroutine *wait_co;
|
||||
} NBDConnectThread;
|
||||
} NBDClientConnection;
|
||||
|
||||
typedef struct BDRVNBDState {
|
||||
QIOChannelSocket *sioc; /* The master data channel */
|
||||
@ -124,36 +124,36 @@ typedef struct BDRVNBDState {
|
||||
char *x_dirty_bitmap;
|
||||
bool alloc_depth;
|
||||
|
||||
NBDConnectThread *connect_thread;
|
||||
NBDClientConnection *conn;
|
||||
} BDRVNBDState;
|
||||
|
||||
static void nbd_free_connect_thread(NBDConnectThread *thr);
|
||||
static void nbd_free_connect_thread(NBDClientConnection *conn);
|
||||
static int nbd_establish_connection(BlockDriverState *bs, SocketAddress *saddr,
|
||||
Error **errp);
|
||||
static coroutine_fn QIOChannelSocket *
|
||||
nbd_co_establish_connection(NBDConnectThread *thr, Error **errp);
|
||||
static void nbd_co_establish_connection_cancel(NBDConnectThread *thr);
|
||||
nbd_co_establish_connection(NBDClientConnection *conn, Error **errp);
|
||||
static void nbd_co_establish_connection_cancel(NBDClientConnection *conn);
|
||||
static int nbd_client_handshake(BlockDriverState *bs, Error **errp);
|
||||
static void nbd_yank(void *opaque);
|
||||
|
||||
static void nbd_clear_bdrvstate(BlockDriverState *bs)
|
||||
{
|
||||
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
|
||||
NBDConnectThread *thr = s->connect_thread;
|
||||
NBDClientConnection *conn = s->conn;
|
||||
bool do_free = false;
|
||||
|
||||
qemu_mutex_lock(&thr->mutex);
|
||||
assert(!thr->detached);
|
||||
if (thr->running) {
|
||||
thr->detached = true;
|
||||
qemu_mutex_lock(&conn->mutex);
|
||||
assert(!conn->detached);
|
||||
if (conn->running) {
|
||||
conn->detached = true;
|
||||
} else {
|
||||
do_free = true;
|
||||
}
|
||||
qemu_mutex_unlock(&thr->mutex);
|
||||
qemu_mutex_unlock(&conn->mutex);
|
||||
|
||||
/* the runaway thread will clean up itself */
|
||||
if (do_free) {
|
||||
nbd_free_connect_thread(thr);
|
||||
nbd_free_connect_thread(conn);
|
||||
}
|
||||
|
||||
yank_unregister_instance(BLOCKDEV_YANK_INSTANCE(bs->node_name));
|
||||
@ -295,7 +295,7 @@ static void coroutine_fn nbd_client_co_drain_begin(BlockDriverState *bs)
|
||||
s->drained = true;
|
||||
qemu_co_sleep_wake(&s->reconnect_sleep);
|
||||
|
||||
nbd_co_establish_connection_cancel(s->connect_thread);
|
||||
nbd_co_establish_connection_cancel(s->conn);
|
||||
|
||||
reconnect_delay_timer_del(s);
|
||||
|
||||
@ -333,7 +333,7 @@ static void nbd_teardown_connection(BlockDriverState *bs)
|
||||
s->state = NBD_CLIENT_QUIT;
|
||||
if (s->connection_co) {
|
||||
qemu_co_sleep_wake(&s->reconnect_sleep);
|
||||
nbd_co_establish_connection_cancel(s->connect_thread);
|
||||
nbd_co_establish_connection_cancel(s->conn);
|
||||
}
|
||||
if (qemu_in_coroutine()) {
|
||||
s->teardown_co = qemu_coroutine_self();
|
||||
@ -360,65 +360,65 @@ static bool nbd_client_connecting_wait(BDRVNBDState *s)
|
||||
|
||||
static void nbd_init_connect_thread(BDRVNBDState *s)
|
||||
{
|
||||
s->connect_thread = g_new(NBDConnectThread, 1);
|
||||
s->conn = g_new(NBDClientConnection, 1);
|
||||
|
||||
*s->connect_thread = (NBDConnectThread) {
|
||||
*s->conn = (NBDClientConnection) {
|
||||
.saddr = QAPI_CLONE(SocketAddress, s->saddr),
|
||||
};
|
||||
|
||||
qemu_mutex_init(&s->connect_thread->mutex);
|
||||
qemu_mutex_init(&s->conn->mutex);
|
||||
}
|
||||
|
||||
static void nbd_free_connect_thread(NBDConnectThread *thr)
|
||||
static void nbd_free_connect_thread(NBDClientConnection *conn)
|
||||
{
|
||||
if (thr->sioc) {
|
||||
qio_channel_close(QIO_CHANNEL(thr->sioc), NULL);
|
||||
object_unref(OBJECT(thr->sioc));
|
||||
if (conn->sioc) {
|
||||
qio_channel_close(QIO_CHANNEL(conn->sioc), NULL);
|
||||
object_unref(OBJECT(conn->sioc));
|
||||
}
|
||||
error_free(thr->err);
|
||||
qapi_free_SocketAddress(thr->saddr);
|
||||
g_free(thr);
|
||||
error_free(conn->err);
|
||||
qapi_free_SocketAddress(conn->saddr);
|
||||
g_free(conn);
|
||||
}
|
||||
|
||||
static void *connect_thread_func(void *opaque)
|
||||
{
|
||||
NBDConnectThread *thr = opaque;
|
||||
NBDClientConnection *conn = opaque;
|
||||
int ret;
|
||||
bool do_free;
|
||||
|
||||
thr->sioc = qio_channel_socket_new();
|
||||
conn->sioc = qio_channel_socket_new();
|
||||
|
||||
error_free(thr->err);
|
||||
thr->err = NULL;
|
||||
ret = qio_channel_socket_connect_sync(thr->sioc, thr->saddr, &thr->err);
|
||||
error_free(conn->err);
|
||||
conn->err = NULL;
|
||||
ret = qio_channel_socket_connect_sync(conn->sioc, conn->saddr, &conn->err);
|
||||
if (ret < 0) {
|
||||
object_unref(OBJECT(thr->sioc));
|
||||
thr->sioc = NULL;
|
||||
object_unref(OBJECT(conn->sioc));
|
||||
conn->sioc = NULL;
|
||||
}
|
||||
|
||||
qio_channel_set_delay(QIO_CHANNEL(thr->sioc), false);
|
||||
qio_channel_set_delay(QIO_CHANNEL(conn->sioc), false);
|
||||
|
||||
qemu_mutex_lock(&thr->mutex);
|
||||
qemu_mutex_lock(&conn->mutex);
|
||||
|
||||
assert(thr->running);
|
||||
thr->running = false;
|
||||
if (thr->wait_co) {
|
||||
aio_co_wake(thr->wait_co);
|
||||
thr->wait_co = NULL;
|
||||
assert(conn->running);
|
||||
conn->running = false;
|
||||
if (conn->wait_co) {
|
||||
aio_co_wake(conn->wait_co);
|
||||
conn->wait_co = NULL;
|
||||
}
|
||||
do_free = thr->detached;
|
||||
do_free = conn->detached;
|
||||
|
||||
qemu_mutex_unlock(&thr->mutex);
|
||||
qemu_mutex_unlock(&conn->mutex);
|
||||
|
||||
if (do_free) {
|
||||
nbd_free_connect_thread(thr);
|
||||
nbd_free_connect_thread(conn);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a new connection in context of @thr:
|
||||
* Get a new connection in context of @conn:
|
||||
* if the thread is running, wait for completion
|
||||
* if the thread already succeeded in the background, and user didn't get the
|
||||
* result, just return it now
|
||||
@ -426,38 +426,38 @@ static void *connect_thread_func(void *opaque)
|
||||
* completion
|
||||
*/
|
||||
static coroutine_fn QIOChannelSocket *
|
||||
nbd_co_establish_connection(NBDConnectThread *thr, Error **errp)
|
||||
nbd_co_establish_connection(NBDClientConnection *conn, Error **errp)
|
||||
{
|
||||
QIOChannelSocket *sioc = NULL;
|
||||
QemuThread thread;
|
||||
|
||||
qemu_mutex_lock(&thr->mutex);
|
||||
qemu_mutex_lock(&conn->mutex);
|
||||
|
||||
/*
|
||||
* Don't call nbd_co_establish_connection() in several coroutines in
|
||||
* parallel. Only one call at once is supported.
|
||||
*/
|
||||
assert(!thr->wait_co);
|
||||
assert(!conn->wait_co);
|
||||
|
||||
if (!thr->running) {
|
||||
if (thr->sioc) {
|
||||
if (!conn->running) {
|
||||
if (conn->sioc) {
|
||||
/* Previous attempt finally succeeded in background */
|
||||
sioc = g_steal_pointer(&thr->sioc);
|
||||
qemu_mutex_unlock(&thr->mutex);
|
||||
sioc = g_steal_pointer(&conn->sioc);
|
||||
qemu_mutex_unlock(&conn->mutex);
|
||||
|
||||
return sioc;
|
||||
}
|
||||
|
||||
thr->running = true;
|
||||
error_free(thr->err);
|
||||
thr->err = NULL;
|
||||
conn->running = true;
|
||||
error_free(conn->err);
|
||||
conn->err = NULL;
|
||||
qemu_thread_create(&thread, "nbd-connect",
|
||||
connect_thread_func, thr, QEMU_THREAD_DETACHED);
|
||||
connect_thread_func, conn, QEMU_THREAD_DETACHED);
|
||||
}
|
||||
|
||||
thr->wait_co = qemu_coroutine_self();
|
||||
conn->wait_co = qemu_coroutine_self();
|
||||
|
||||
qemu_mutex_unlock(&thr->mutex);
|
||||
qemu_mutex_unlock(&conn->mutex);
|
||||
|
||||
/*
|
||||
* We are going to wait for connect-thread finish, but
|
||||
@ -465,9 +465,9 @@ nbd_co_establish_connection(NBDConnectThread *thr, Error **errp)
|
||||
*/
|
||||
qemu_coroutine_yield();
|
||||
|
||||
qemu_mutex_lock(&thr->mutex);
|
||||
qemu_mutex_lock(&conn->mutex);
|
||||
|
||||
if (thr->running) {
|
||||
if (conn->running) {
|
||||
/*
|
||||
* The connection attempt was canceled and the coroutine resumed
|
||||
* before the connection thread finished its job. Report the
|
||||
@ -476,12 +476,12 @@ nbd_co_establish_connection(NBDConnectThread *thr, Error **errp)
|
||||
*/
|
||||
error_setg(errp, "Connection attempt cancelled by other operation");
|
||||
} else {
|
||||
error_propagate(errp, thr->err);
|
||||
thr->err = NULL;
|
||||
sioc = g_steal_pointer(&thr->sioc);
|
||||
error_propagate(errp, conn->err);
|
||||
conn->err = NULL;
|
||||
sioc = g_steal_pointer(&conn->sioc);
|
||||
}
|
||||
|
||||
qemu_mutex_unlock(&thr->mutex);
|
||||
qemu_mutex_unlock(&conn->mutex);
|
||||
|
||||
return sioc;
|
||||
}
|
||||
@ -494,15 +494,15 @@ nbd_co_establish_connection(NBDConnectThread *thr, Error **errp)
|
||||
* socket, but rather safely wakes nbd_co_establish_connection() which is
|
||||
* sleeping in yield()
|
||||
*/
|
||||
static void nbd_co_establish_connection_cancel(NBDConnectThread *thr)
|
||||
static void nbd_co_establish_connection_cancel(NBDClientConnection *conn)
|
||||
{
|
||||
Coroutine *wait_co;
|
||||
|
||||
qemu_mutex_lock(&thr->mutex);
|
||||
qemu_mutex_lock(&conn->mutex);
|
||||
|
||||
wait_co = g_steal_pointer(&thr->wait_co);
|
||||
wait_co = g_steal_pointer(&conn->wait_co);
|
||||
|
||||
qemu_mutex_unlock(&thr->mutex);
|
||||
qemu_mutex_unlock(&conn->mutex);
|
||||
|
||||
if (wait_co) {
|
||||
aio_co_wake(wait_co);
|
||||
@ -552,7 +552,7 @@ static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s)
|
||||
s->ioc = NULL;
|
||||
}
|
||||
|
||||
s->sioc = nbd_co_establish_connection(s->connect_thread, NULL);
|
||||
s->sioc = nbd_co_establish_connection(s->conn, NULL);
|
||||
if (!s->sioc) {
|
||||
ret = -ECONNREFUSED;
|
||||
goto out;
|
||||
|
Loading…
Reference in New Issue
Block a user