diff --git a/block/nbd-client.c b/block/nbd-client.c index 76e9ca3abe..fc5b7eda8e 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -992,10 +992,16 @@ int nbd_client_init(BlockDriverState *bs, logout("Failed to negotiate with the NBD server\n"); return ret; } + if (x_dirty_bitmap && !client->info.base_allocation) { + error_setg(errp, "requested x-dirty-bitmap %s not found", + x_dirty_bitmap); + ret = -EINVAL; + goto fail; + } if (client->info.flags & NBD_FLAG_READ_ONLY) { ret = bdrv_apply_auto_read_only(bs, "NBD export is read-only", errp); if (ret < 0) { - return ret; + goto fail; } } if (client->info.flags & NBD_FLAG_SEND_FUA) { @@ -1024,4 +1030,17 @@ int nbd_client_init(BlockDriverState *bs, logout("Established connection with NBD server\n"); return 0; + + fail: + /* + * We have connected, but must fail for other reasons. The + * connection is still blocking; send NBD_CMD_DISC as a courtesy + * to the server. + */ + { + NBDRequest request = { .type = NBD_CMD_DISC }; + + nbd_send_request(client->ioc ?: QIO_CHANNEL(sioc), &request); + return ret; + } } diff --git a/nbd/server.c b/nbd/server.c index dc04513de7..7af0ddffb2 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -978,6 +978,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client, if (client->opt == NBD_OPT_LIST_META_CONTEXT && !nb_queries) { /* enable all known contexts */ meta->base_allocation = true; + meta->bitmap = !!meta->exp->export_bitmap; } else { for (i = 0; i < nb_queries; ++i) { ret = nbd_negotiate_meta_query(client, meta, errp);