diff options
author | Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | 2021-06-10 13:07:51 +0300 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2021-06-18 10:59:53 -0500 |
commit | f58b2dfe3e815d0c8491b33c36622824e8a08e40 (patch) | |
tree | c467b6ca4ea66fbaffe056092b79daac8ed621bf /nbd | |
parent | e0e67cbe58f42500e3451c46b3caba572f2a965f (diff) | |
download | qemu-f58b2dfe3e815d0c8491b33c36622824e8a08e40.zip qemu-f58b2dfe3e815d0c8491b33c36622824e8a08e40.tar.gz qemu-f58b2dfe3e815d0c8491b33c36622824e8a08e40.tar.bz2 |
nbd/client-connection: shutdown connection on release
Now, when a thread can do negotiation and retry, it may run relatively
long. We need a mechanism to stop it, when the user is not interested
in a result any more. So, on nbd_client_connection_release() let's
shutdown the socket, and do not retry connection if thread is detached.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20210610100802.5888-22-vsementsov@virtuozzo.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Diffstat (limited to 'nbd')
-rw-r--r-- | nbd/client-connection.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/nbd/client-connection.c b/nbd/client-connection.c index 032b38e..883f9cf 100644 --- a/nbd/client-connection.c +++ b/nbd/client-connection.c @@ -168,9 +168,13 @@ static void *connect_thread_func(void *opaque) uint64_t timeout = 1; uint64_t max_timeout = 16; - while (true) { + qemu_mutex_lock(&conn->mutex); + while (!conn->detached) { + assert(!conn->sioc); conn->sioc = qio_channel_socket_new(); + qemu_mutex_unlock(&conn->mutex); + error_free(conn->err); conn->err = NULL; conn->updated_info = conn->initial_info; @@ -188,14 +192,20 @@ static void *connect_thread_func(void *opaque) conn->updated_info.x_dirty_bitmap = NULL; conn->updated_info.name = NULL; + qemu_mutex_lock(&conn->mutex); + if (ret < 0) { object_unref(OBJECT(conn->sioc)); conn->sioc = NULL; - if (conn->do_retry) { + if (conn->do_retry && !conn->detached) { + qemu_mutex_unlock(&conn->mutex); + sleep(timeout); if (timeout < max_timeout) { timeout *= 2; } + + qemu_mutex_lock(&conn->mutex); continue; } } @@ -203,7 +213,7 @@ static void *connect_thread_func(void *opaque) break; } - qemu_mutex_lock(&conn->mutex); + /* mutex is locked */ assert(conn->running); conn->running = false; @@ -237,6 +247,10 @@ void nbd_client_connection_release(NBDClientConnection *conn) } else { do_free = true; } + if (conn->sioc) { + qio_channel_shutdown(QIO_CHANNEL(conn->sioc), + QIO_CHANNEL_SHUTDOWN_BOTH, NULL); + } } if (do_free) { |