diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index 4da4ddf8d..7c30f17f4 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -2894,7 +2894,7 @@ prchk_guard | Optional | bool | Enable checking of PI guar hdgst | Optional | bool | Enable TCP header digest ddgst | Optional | bool | Enable TCP data digest fabrics_connect_timeout_us | Optional | bool | Timeout for fabrics connect (in microseconds) -multipath | Optional | string | Multipathing behavior: disable, failover. Default is failover. +multipath | Optional | string | Multipathing behavior: disable, failover, multipath. Default is failover. #### Example diff --git a/module/bdev/nvme/bdev_nvme_rpc.c b/module/bdev/nvme/bdev_nvme_rpc.c index 6837bcd83..b47a6e69f 100644 --- a/module/bdev/nvme/bdev_nvme_rpc.c +++ b/module/bdev/nvme/bdev_nvme_rpc.c @@ -281,6 +281,7 @@ rpc_bdev_nvme_attach_controller(struct spdk_jsonrpc_request *request, uint32_t prchk_flags = 0; struct nvme_ctrlr *ctrlr = NULL; size_t len, maxlen; + bool multipath = false; int rc; ctx = calloc(1, sizeof(*ctx)); @@ -416,8 +417,9 @@ rpc_bdev_nvme_attach_controller(struct spdk_jsonrpc_request *request, "A controller named %s already exists and multipath is disabled\n", ctx->req.name); goto cleanup; - } else if (strcasecmp(ctx->req.multipath, "failover") == 0) { - /* The user wants to add this as a failover path. */ + } else if (strcasecmp(ctx->req.multipath, "failover") == 0 || + strcasecmp(ctx->req.multipath, "multipath") == 0) { + /* The user wants to add this as a failover path or add this to create multipath. */ if (strncmp(trid.traddr, ctrlr_trid->traddr, sizeof(trid.traddr)) == 0 && strncmp(trid.trsvcid, ctrlr_trid->trsvcid, sizeof(trid.trsvcid)) == 0 && @@ -473,11 +475,15 @@ rpc_bdev_nvme_attach_controller(struct spdk_jsonrpc_request *request, prchk_flags |= SPDK_NVME_IO_FLAGS_PRCHK_GUARD; } + if (ctx->req.multipath != NULL && strcasecmp(ctx->req.multipath, "multipath") == 0) { + multipath = true; + } + ctx->request = request; ctx->count = NVME_MAX_BDEVS_PER_RPC; rc = bdev_nvme_create(&trid, ctx->req.name, ctx->names, ctx->count, prchk_flags, rpc_bdev_nvme_attach_controller_done, ctx, &ctx->req.opts, - false); + multipath); if (rc) { spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); goto cleanup; diff --git a/scripts/rpc.py b/scripts/rpc.py index f9ed8a80d..caabe85e2 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -564,7 +564,7 @@ if __name__ == "__main__": p.add_argument('-d', '--ddgst', help='Enable TCP data digest.', action='store_true') p.add_argument('--fabrics-timeout', type=int, help='Fabrics connect timeout in microseconds') - p.add_argument('-x', '--multipath', help='Set multipath behavior (disable, failover)') + p.add_argument('-x', '--multipath', help='Set multipath behavior (disable, failover, multipath)') p.set_defaults(func=bdev_nvme_attach_controller) def bdev_nvme_get_controllers(args): diff --git a/scripts/rpc/bdev.py b/scripts/rpc/bdev.py index d325b25ba..9e53ad68b 100644 --- a/scripts/rpc/bdev.py +++ b/scripts/rpc/bdev.py @@ -539,7 +539,7 @@ def bdev_nvme_attach_controller(client, name, trtype, traddr, adrfam=None, trsvc hdgst: Enable TCP header digest (optional) ddgst: Enable TCP data digest (optional) fabrics_timeout: Fabrics connect timeout in us (optional) - multipath: The behavior when multiple paths are created ("disable", "failover"; failover if not specified) + multipath: The behavior when multiple paths are created ("disable", "failover", or "multipath"; failover if not specified) Returns: Names of created block devices.