diff --git a/lib/nbd/nbd_rpc.c b/lib/nbd/nbd_rpc.c index 1487b1b96..f24dda673 100644 --- a/lib/nbd/nbd_rpc.c +++ b/lib/nbd/nbd_rpc.c @@ -39,6 +39,71 @@ #include "nbd_internal.h" #include "spdk_internal/log.h" +struct rpc_start_nbd_disk { + char *bdev_name; + char *nbd_device; +}; + +static void +free_rpc_start_nbd_disk(struct rpc_start_nbd_disk *req) +{ + free(req->bdev_name); + free(req->nbd_device); +} + +static const struct spdk_json_object_decoder rpc_start_nbd_disk_decoders[] = { + {"bdev_name", offsetof(struct rpc_start_nbd_disk, bdev_name), spdk_json_decode_string}, + {"nbd_device", offsetof(struct rpc_start_nbd_disk, nbd_device), spdk_json_decode_string}, +}; + +static void +spdk_rpc_start_nbd_disk(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_start_nbd_disk req = {}; + struct spdk_json_write_ctx *w; + struct spdk_nbd_disk *nbd; + + if (spdk_json_decode_object(params, rpc_start_nbd_disk_decoders, + SPDK_COUNTOF(rpc_start_nbd_disk_decoders), + &req)) { + SPDK_ERRLOG("spdk_json_decode_object failed\n"); + goto invalid; + } + + if (req.nbd_device == NULL || req.bdev_name == NULL) { + goto invalid; + } + + /* make sure nbd_device is not registered */ + nbd = spdk_nbd_disk_find_by_nbd_path(req.nbd_device); + if (nbd) { + goto invalid; + } + + nbd = spdk_nbd_start(req.bdev_name, req.nbd_device); + if (!nbd) { + goto invalid; + } + + free_rpc_start_nbd_disk(&req); + + w = spdk_jsonrpc_begin_result(request); + if (w == NULL) { + return; + } + + spdk_json_write_bool(w, true); + spdk_jsonrpc_end_result(request, w); + return; + +invalid: + free_rpc_start_nbd_disk(&req); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); +} + +SPDK_RPC_REGISTER("start_nbd_disk", spdk_rpc_start_nbd_disk) + struct rpc_stop_nbd_disk { char *nbd_device; }; diff --git a/scripts/rpc.py b/scripts/rpc.py index 01d4f07c7..ae80a7597 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -604,6 +604,18 @@ p = subparsers.add_parser('delete_bdev', help='Delete a blockdev') p.add_argument('bdev_name', help='Blockdev name to be deleted. Example: Malloc0.') p.set_defaults(func=delete_bdev) +def start_nbd_disk(args): + params = { + 'bdev_name': args.bdev_name, + 'nbd_device': args.nbd_device + } + jsonrpc_call('start_nbd_disk', params) + +p = subparsers.add_parser('start_nbd_disk', help='Export a bdev as a nbd disk') +p.add_argument('bdev_name', help='Blockdev name to be exported. Example: Malloc0.') +p.add_argument('nbd_device', help='Nbd device name to be assigned. Example: /dev/nbd0.') +p.set_defaults(func=start_nbd_disk) + def stop_nbd_disk(args): params = {'nbd_device': args.nbd_device} jsonrpc_call('stop_nbd_disk', params)