|
@@ -81,7 +81,7 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
|
|
|
|
|
|
struct NBDClient {
|
|
|
int refcount;
|
|
|
- void (*close)(NBDClient *client);
|
|
|
+ void (*close_fn)(NBDClient *client, bool negotiated);
|
|
|
|
|
|
bool no_zeroes;
|
|
|
NBDExport *exp;
|
|
@@ -796,7 +796,7 @@ void nbd_client_put(NBDClient *client)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void client_close(NBDClient *client)
|
|
|
+static void client_close(NBDClient *client, bool negotiated)
|
|
|
{
|
|
|
if (client->closing) {
|
|
|
return;
|
|
@@ -811,8 +811,8 @@ static void client_close(NBDClient *client)
|
|
|
NULL);
|
|
|
|
|
|
/* Also tell the client, so that they release their reference. */
|
|
|
- if (client->close) {
|
|
|
- client->close(client);
|
|
|
+ if (client->close_fn) {
|
|
|
+ client->close_fn(client, negotiated);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -993,7 +993,7 @@ void nbd_export_close(NBDExport *exp)
|
|
|
|
|
|
nbd_export_get(exp);
|
|
|
QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
|
|
|
- client_close(client);
|
|
|
+ client_close(client, true);
|
|
|
}
|
|
|
nbd_export_set_name(exp, NULL);
|
|
|
nbd_export_set_description(exp, NULL);
|
|
@@ -1355,7 +1355,7 @@ done:
|
|
|
|
|
|
out:
|
|
|
nbd_request_put(req);
|
|
|
- client_close(client);
|
|
|
+ client_close(client, true);
|
|
|
nbd_client_put(client);
|
|
|
}
|
|
|
|
|
@@ -1381,7 +1381,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
|
|
|
qemu_co_mutex_init(&client->send_lock);
|
|
|
|
|
|
if (nbd_negotiate(data)) {
|
|
|
- client_close(client);
|
|
|
+ client_close(client, false);
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
@@ -1391,11 +1391,17 @@ out:
|
|
|
g_free(data);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Create a new client listener on the given export @exp, using the
|
|
|
+ * given channel @sioc. Begin servicing it in a coroutine. When the
|
|
|
+ * connection closes, call @close_fn with an indication of whether the
|
|
|
+ * client completed negotiation.
|
|
|
+ */
|
|
|
void nbd_client_new(NBDExport *exp,
|
|
|
QIOChannelSocket *sioc,
|
|
|
QCryptoTLSCreds *tlscreds,
|
|
|
const char *tlsaclname,
|
|
|
- void (*close_fn)(NBDClient *))
|
|
|
+ void (*close_fn)(NBDClient *, bool))
|
|
|
{
|
|
|
NBDClient *client;
|
|
|
NBDClientNewData *data = g_new(NBDClientNewData, 1);
|
|
@@ -1412,7 +1418,7 @@ void nbd_client_new(NBDExport *exp,
|
|
|
object_ref(OBJECT(client->sioc));
|
|
|
client->ioc = QIO_CHANNEL(sioc);
|
|
|
object_ref(OBJECT(client->ioc));
|
|
|
- client->close = close_fn;
|
|
|
+ client->close_fn = close_fn;
|
|
|
|
|
|
data->client = client;
|
|
|
data->co = qemu_coroutine_create(nbd_co_client_start, data);
|