Skip to content

Commit

Permalink
block/nbd: rename NBDConnectThread to NBDClientConnection
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Vladimir Sementsov-Ogievskiy authored and ebblake committed Jun 15, 2021
1 parent 257b357 commit 3df4ed5
Showing 1 changed file with 67 additions and 67 deletions.
134 changes: 67 additions & 67 deletions block/nbd.c
Expand Up @@ -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 */

Expand All @@ -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 */
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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();
Expand All @@ -360,114 +360,114 @@ 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
* otherwise the thread is not running, so start a thread and wait for
* 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
* nbd_co_establish_connection_cancel() can interrupt.
*/
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
Expand All @@ -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;
}
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 3df4ed5

Please sign in to comment.