|
@@ -2026,6 +2026,7 @@ static void nbd_export_delete(BlockExport *blk_exp)
|
|
|
const BlockExportDriver blk_exp_nbd = {
|
|
|
.type = BLOCK_EXPORT_TYPE_NBD,
|
|
|
.instance_size = sizeof(NBDExport),
|
|
|
+ .supports_inactive = true,
|
|
|
.create = nbd_export_create,
|
|
|
.delete = nbd_export_delete,
|
|
|
.request_shutdown = nbd_export_request_shutdown,
|
|
@@ -2920,6 +2921,22 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
|
|
|
NBDExport *exp = client->exp;
|
|
|
char *msg;
|
|
|
size_t i;
|
|
|
+ bool inactive;
|
|
|
+
|
|
|
+ WITH_GRAPH_RDLOCK_GUARD() {
|
|
|
+ inactive = bdrv_is_inactive(blk_bs(exp->common.blk));
|
|
|
+ if (inactive) {
|
|
|
+ switch (request->type) {
|
|
|
+ case NBD_CMD_READ:
|
|
|
+ /* These commands are allowed on inactive nodes */
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ /* Return an error for the rest */
|
|
|
+ return nbd_send_generic_reply(client, request, -EPERM,
|
|
|
+ "export is inactive", errp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
switch (request->type) {
|
|
|
case NBD_CMD_CACHE:
|