void nbd_client_close(BlockDriverState *bs) { NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_DISC, .from = 0, .len = 0 }; if (client->sock == -1) { return; } nbd_send_request(client->sock, &request); nbd_teardown_connection(bs); } int nbd_client_init(BlockDriverState *bs, int sock, const char *export, Error **errp) { NbdClientSession *client = nbd_get_client_session(bs); int ret; /* NBD handshake */ logout("session init %s\n", export); qemu_set_block(sock); ret = nbd_receive_negotiate(sock, export, &client->nbdflags, &client->size, &client->blocksize, errp); if (ret < 0) { logout("Failed to negotiate with the NBD server\n"); closesocket(sock); return ret; } qemu_co_mutex_init(&client->send_mutex); qemu_co_mutex_init(&client->free_sema); client->sock = sock; /* Now that we're connected, set the socket to be non-blocking and * kick the reply mechanism. */ qemu_set_nonblock(sock); nbd_client_attach_aio_context(bs, bdrv_get_aio_context(bs)); logout("Established connection with NBD server\n"); return 0; }
void nbd_client_close(BlockDriverState *bs) { NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_DISC, .from = 0, .len = 0 }; if (client->ioc == NULL) { return; } nbd_send_request(client->ioc, &request); nbd_teardown_connection(bs); } int nbd_client_init(BlockDriverState *bs, QIOChannelSocket *sioc, const char *export, QCryptoTLSCreds *tlscreds, const char *hostname, Error **errp) { NbdClientSession *client = nbd_get_client_session(bs); int ret; /* NBD handshake */ logout("session init %s\n", export); qio_channel_set_blocking(QIO_CHANNEL(sioc), true, NULL); ret = nbd_receive_negotiate(QIO_CHANNEL(sioc), export, &client->nbdflags, tlscreds, hostname, &client->ioc, &client->size, errp); if (ret < 0) { logout("Failed to negotiate with the NBD server\n"); return ret; } qemu_co_mutex_init(&client->send_mutex); qemu_co_mutex_init(&client->free_sema); client->sioc = sioc; object_ref(OBJECT(client->sioc)); if (!client->ioc) { client->ioc = QIO_CHANNEL(sioc); object_ref(OBJECT(client->ioc)); } /* Now that we're connected, set the socket to be non-blocking and * kick the reply mechanism. */ qio_channel_set_blocking(QIO_CHANNEL(sioc), false, NULL); nbd_client_attach_aio_context(bs, bdrv_get_aio_context(bs)); logout("Established connection with NBD server\n"); return 0; }