mirror of https://github.com/xemu-project/xemu.git
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
|
NBD_CLIENT_QUIT
|
||||||
} NBDClientState;
|
} NBDClientState;
|
||||||
|
|
||||||
typedef struct NBDConnectThread {
|
typedef struct NBDClientConnection {
|
||||||
/* Initialization constants */
|
/* Initialization constants */
|
||||||
SocketAddress *saddr; /* address to connect to */
|
SocketAddress *saddr; /* address to connect to */
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ typedef struct NBDConnectThread {
|
||||||
* nbd_co_establish_connection() after yield()
|
* nbd_co_establish_connection() after yield()
|
||||||
*/
|
*/
|
||||||
Coroutine *wait_co;
|
Coroutine *wait_co;
|
||||||
} NBDConnectThread;
|
} NBDClientConnection;
|
||||||
|
|
||||||
typedef struct BDRVNBDState {
|
typedef struct BDRVNBDState {
|
||||||
QIOChannelSocket *sioc; /* The master data channel */
|
QIOChannelSocket *sioc; /* The master data channel */
|
||||||
|
@ -124,36 +124,36 @@ typedef struct BDRVNBDState {
|
||||||
char *x_dirty_bitmap;
|
char *x_dirty_bitmap;
|
||||||
bool alloc_depth;
|
bool alloc_depth;
|
||||||
|
|
||||||
NBDConnectThread *connect_thread;
|
NBDClientConnection *conn;
|
||||||
} BDRVNBDState;
|
} 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,
|
static int nbd_establish_connection(BlockDriverState *bs, SocketAddress *saddr,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
static coroutine_fn QIOChannelSocket *
|
static coroutine_fn QIOChannelSocket *
|
||||||
nbd_co_establish_connection(NBDConnectThread *thr, Error **errp);
|
nbd_co_establish_connection(NBDClientConnection *conn, Error **errp);
|
||||||
static void nbd_co_establish_connection_cancel(NBDConnectThread *thr);
|
static void nbd_co_establish_connection_cancel(NBDClientConnection *conn);
|
||||||
static int nbd_client_handshake(BlockDriverState *bs, Error **errp);
|
static int nbd_client_handshake(BlockDriverState *bs, Error **errp);
|
||||||
static void nbd_yank(void *opaque);
|
static void nbd_yank(void *opaque);
|
||||||
|
|
||||||
static void nbd_clear_bdrvstate(BlockDriverState *bs)
|
static void nbd_clear_bdrvstate(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
|
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
|
||||||
NBDConnectThread *thr = s->connect_thread;
|
NBDClientConnection *conn = s->conn;
|
||||||
bool do_free = false;
|
bool do_free = false;
|
||||||
|
|
||||||
qemu_mutex_lock(&thr->mutex);
|
qemu_mutex_lock(&conn->mutex);
|
||||||
assert(!thr->detached);
|
assert(!conn->detached);
|
||||||
if (thr->running) {
|
if (conn->running) {
|
||||||
thr->detached = true;
|
conn->detached = true;
|
||||||
} else {
|
} else {
|
||||||
do_free = true;
|
do_free = true;
|
||||||
}
|
}
|
||||||
qemu_mutex_unlock(&thr->mutex);
|
qemu_mutex_unlock(&conn->mutex);
|
||||||
|
|
||||||
/* the runaway thread will clean up itself */
|
/* the runaway thread will clean up itself */
|
||||||
if (do_free) {
|
if (do_free) {
|
||||||
nbd_free_connect_thread(thr);
|
nbd_free_connect_thread(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
yank_unregister_instance(BLOCKDEV_YANK_INSTANCE(bs->node_name));
|
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;
|
s->drained = true;
|
||||||
qemu_co_sleep_wake(&s->reconnect_sleep);
|
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);
|
reconnect_delay_timer_del(s);
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ static void nbd_teardown_connection(BlockDriverState *bs)
|
||||||
s->state = NBD_CLIENT_QUIT;
|
s->state = NBD_CLIENT_QUIT;
|
||||||
if (s->connection_co) {
|
if (s->connection_co) {
|
||||||
qemu_co_sleep_wake(&s->reconnect_sleep);
|
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()) {
|
if (qemu_in_coroutine()) {
|
||||||
s->teardown_co = qemu_coroutine_self();
|
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)
|
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),
|
.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) {
|
if (conn->sioc) {
|
||||||
qio_channel_close(QIO_CHANNEL(thr->sioc), NULL);
|
qio_channel_close(QIO_CHANNEL(conn->sioc), NULL);
|
||||||
object_unref(OBJECT(thr->sioc));
|
object_unref(OBJECT(conn->sioc));
|
||||||
}
|
}
|
||||||
error_free(thr->err);
|
error_free(conn->err);
|
||||||
qapi_free_SocketAddress(thr->saddr);
|
qapi_free_SocketAddress(conn->saddr);
|
||||||
g_free(thr);
|
g_free(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *connect_thread_func(void *opaque)
|
static void *connect_thread_func(void *opaque)
|
||||||
{
|
{
|
||||||
NBDConnectThread *thr = opaque;
|
NBDClientConnection *conn = opaque;
|
||||||
int ret;
|
int ret;
|
||||||
bool do_free;
|
bool do_free;
|
||||||
|
|
||||||
thr->sioc = qio_channel_socket_new();
|
conn->sioc = qio_channel_socket_new();
|
||||||
|
|
||||||
error_free(thr->err);
|
error_free(conn->err);
|
||||||
thr->err = NULL;
|
conn->err = NULL;
|
||||||
ret = qio_channel_socket_connect_sync(thr->sioc, thr->saddr, &thr->err);
|
ret = qio_channel_socket_connect_sync(conn->sioc, conn->saddr, &conn->err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
object_unref(OBJECT(thr->sioc));
|
object_unref(OBJECT(conn->sioc));
|
||||||
thr->sioc = NULL;
|
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);
|
assert(conn->running);
|
||||||
thr->running = false;
|
conn->running = false;
|
||||||
if (thr->wait_co) {
|
if (conn->wait_co) {
|
||||||
aio_co_wake(thr->wait_co);
|
aio_co_wake(conn->wait_co);
|
||||||
thr->wait_co = NULL;
|
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) {
|
if (do_free) {
|
||||||
nbd_free_connect_thread(thr);
|
nbd_free_connect_thread(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
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 is running, wait for completion
|
||||||
* if the thread already succeeded in the background, and user didn't get the
|
* if the thread already succeeded in the background, and user didn't get the
|
||||||
* result, just return it now
|
* result, just return it now
|
||||||
|
@ -426,38 +426,38 @@ static void *connect_thread_func(void *opaque)
|
||||||
* completion
|
* completion
|
||||||
*/
|
*/
|
||||||
static coroutine_fn QIOChannelSocket *
|
static coroutine_fn QIOChannelSocket *
|
||||||
nbd_co_establish_connection(NBDConnectThread *thr, Error **errp)
|
nbd_co_establish_connection(NBDClientConnection *conn, Error **errp)
|
||||||
{
|
{
|
||||||
QIOChannelSocket *sioc = NULL;
|
QIOChannelSocket *sioc = NULL;
|
||||||
QemuThread thread;
|
QemuThread thread;
|
||||||
|
|
||||||
qemu_mutex_lock(&thr->mutex);
|
qemu_mutex_lock(&conn->mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't call nbd_co_establish_connection() in several coroutines in
|
* Don't call nbd_co_establish_connection() in several coroutines in
|
||||||
* parallel. Only one call at once is supported.
|
* parallel. Only one call at once is supported.
|
||||||
*/
|
*/
|
||||||
assert(!thr->wait_co);
|
assert(!conn->wait_co);
|
||||||
|
|
||||||
if (!thr->running) {
|
if (!conn->running) {
|
||||||
if (thr->sioc) {
|
if (conn->sioc) {
|
||||||
/* Previous attempt finally succeeded in background */
|
/* Previous attempt finally succeeded in background */
|
||||||
sioc = g_steal_pointer(&thr->sioc);
|
sioc = g_steal_pointer(&conn->sioc);
|
||||||
qemu_mutex_unlock(&thr->mutex);
|
qemu_mutex_unlock(&conn->mutex);
|
||||||
|
|
||||||
return sioc;
|
return sioc;
|
||||||
}
|
}
|
||||||
|
|
||||||
thr->running = true;
|
conn->running = true;
|
||||||
error_free(thr->err);
|
error_free(conn->err);
|
||||||
thr->err = NULL;
|
conn->err = NULL;
|
||||||
qemu_thread_create(&thread, "nbd-connect",
|
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
|
* 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_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
|
* The connection attempt was canceled and the coroutine resumed
|
||||||
* before the connection thread finished its job. Report the
|
* 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");
|
error_setg(errp, "Connection attempt cancelled by other operation");
|
||||||
} else {
|
} else {
|
||||||
error_propagate(errp, thr->err);
|
error_propagate(errp, conn->err);
|
||||||
thr->err = NULL;
|
conn->err = NULL;
|
||||||
sioc = g_steal_pointer(&thr->sioc);
|
sioc = g_steal_pointer(&conn->sioc);
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_mutex_unlock(&thr->mutex);
|
qemu_mutex_unlock(&conn->mutex);
|
||||||
|
|
||||||
return sioc;
|
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
|
* socket, but rather safely wakes nbd_co_establish_connection() which is
|
||||||
* sleeping in yield()
|
* sleeping in yield()
|
||||||
*/
|
*/
|
||||||
static void nbd_co_establish_connection_cancel(NBDConnectThread *thr)
|
static void nbd_co_establish_connection_cancel(NBDClientConnection *conn)
|
||||||
{
|
{
|
||||||
Coroutine *wait_co;
|
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) {
|
if (wait_co) {
|
||||||
aio_co_wake(wait_co);
|
aio_co_wake(wait_co);
|
||||||
|
@ -552,7 +552,7 @@ static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s)
|
||||||
s->ioc = NULL;
|
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) {
|
if (!s->sioc) {
|
||||||
ret = -ECONNREFUSED;
|
ret = -ECONNREFUSED;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
Loading…
Reference in New Issue