bdev/nvme: bdev_nvme_attach_controller now has a multipath parameter
This parameter may have the values "disable" or "failover". The default is failover to match existing behavior. In the future we expect to change the default behavior to disable. Further, we expect to add an "enable" option soon to do full multipath. Change-Id: Iebbdc9b95f23101f18d64e085933463498e627be Signed-off-by: Ben Walker <benjamin.walker@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9343 Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com> Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
parent
ed763cee62
commit
a24d549038
@ -2892,6 +2892,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.
|
||||
|
||||
#### Example
|
||||
|
||||
|
@ -180,6 +180,7 @@ struct rpc_bdev_nvme_attach_controller {
|
||||
bool prchk_reftag;
|
||||
bool prchk_guard;
|
||||
uint64_t fabrics_connect_timeout_us;
|
||||
char *multipath;
|
||||
struct spdk_nvme_ctrlr_opts opts;
|
||||
};
|
||||
|
||||
@ -196,6 +197,7 @@ free_rpc_bdev_nvme_attach_controller(struct rpc_bdev_nvme_attach_controller *req
|
||||
free(req->hostnqn);
|
||||
free(req->hostaddr);
|
||||
free(req->hostsvcid);
|
||||
free(req->multipath);
|
||||
}
|
||||
|
||||
static const struct spdk_json_object_decoder rpc_bdev_nvme_attach_controller_decoders[] = {
|
||||
@ -216,6 +218,7 @@ static const struct spdk_json_object_decoder rpc_bdev_nvme_attach_controller_dec
|
||||
{"hdgst", offsetof(struct rpc_bdev_nvme_attach_controller, opts.header_digest), spdk_json_decode_bool, true},
|
||||
{"ddgst", offsetof(struct rpc_bdev_nvme_attach_controller, opts.data_digest), spdk_json_decode_bool, true},
|
||||
{"fabrics_connect_timeout_us", offsetof(struct rpc_bdev_nvme_attach_controller, opts.fabrics_connect_timeout_us), spdk_json_decode_uint64, true},
|
||||
{"multipath", offsetof(struct rpc_bdev_nvme_attach_controller, multipath), spdk_json_decode_string, true},
|
||||
};
|
||||
|
||||
#define NVME_MAX_BDEVS_PER_RPC 128
|
||||
@ -387,8 +390,31 @@ rpc_bdev_nvme_attach_controller(struct spdk_jsonrpc_request *request,
|
||||
ctrlr = nvme_ctrlr_get_by_name(ctx->req.name);
|
||||
|
||||
if (ctrlr) {
|
||||
/* This controller already exists. Verify the parameters match sufficiently. */
|
||||
opts = spdk_nvme_ctrlr_get_opts(ctrlr->ctrlr);
|
||||
if (ctx->req.multipath == NULL) {
|
||||
/* For now, this means add a failover path. This maintains backward compatibility
|
||||
* with past behavior. In the future, this behavior will change to "disable". */
|
||||
SPDK_ERRLOG("The multipath parameter was not specified to bdev_nvme_attach_controller but "
|
||||
"it was used to add a failover path. This behavior will default to rejecting "
|
||||
"the request in the future. Specify the 'multipath' parameter to control the behavior");
|
||||
ctx->req.multipath = strdup("failover");
|
||||
}
|
||||
|
||||
/* This controller already exists. Check what the user wants to do. */
|
||||
if (strcasecmp(ctx->req.multipath, "disable") == 0) {
|
||||
/* The user does not want to do any form of multipathing. */
|
||||
spdk_jsonrpc_send_error_response_fmt(request, -EALREADY,
|
||||
"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 {
|
||||
/* Invalid multipath option */
|
||||
spdk_jsonrpc_send_error_response_fmt(request, -EINVAL,
|
||||
"Invalid multipath parameter: %s\n",
|
||||
ctx->req.multipath);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (strncmp(trid.subnqn,
|
||||
spdk_nvme_ctrlr_get_transport_id(ctrlr->ctrlr)->subnqn,
|
||||
@ -400,6 +426,8 @@ rpc_bdev_nvme_attach_controller(struct spdk_jsonrpc_request *request,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
opts = spdk_nvme_ctrlr_get_opts(ctrlr->ctrlr);
|
||||
|
||||
if (strncmp(ctx->req.opts.hostnqn, opts->hostnqn, SPDK_NVMF_NQN_MAX_LEN) != 0) {
|
||||
/* Different HOSTNQN is not allowed when specifying the same controller name. */
|
||||
spdk_jsonrpc_send_error_response_fmt(request, -EINVAL,
|
||||
|
@ -526,7 +526,8 @@ if __name__ == "__main__":
|
||||
prchk_guard=args.prchk_guard,
|
||||
hdgst=args.hdgst,
|
||||
ddgst=args.ddgst,
|
||||
fabrics_timeout=args.fabrics_timeout))
|
||||
fabrics_timeout=args.fabrics_timeout,
|
||||
multipath=args.multipath))
|
||||
|
||||
p = subparsers.add_parser('bdev_nvme_attach_controller', aliases=['construct_nvme_bdev'],
|
||||
help='Add bdevs with nvme backend')
|
||||
@ -556,6 +557,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.set_defaults(func=bdev_nvme_attach_controller)
|
||||
|
||||
def bdev_nvme_get_controllers(args):
|
||||
|
@ -511,7 +511,7 @@ def bdev_nvme_set_hotplug(client, enable, period_us=None):
|
||||
def bdev_nvme_attach_controller(client, name, trtype, traddr, adrfam=None, trsvcid=None,
|
||||
priority=None, subnqn=None, hostnqn=None, hostaddr=None,
|
||||
hostsvcid=None, prchk_reftag=None, prchk_guard=None,
|
||||
hdgst=None, ddgst=None, fabrics_timeout=None):
|
||||
hdgst=None, ddgst=None, fabrics_timeout=None, multipath=None):
|
||||
"""Construct block device for each NVMe namespace in the attached controller.
|
||||
|
||||
Args:
|
||||
@ -530,6 +530,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)
|
||||
|
||||
Returns:
|
||||
Names of created block devices.
|
||||
@ -574,6 +575,9 @@ def bdev_nvme_attach_controller(client, name, trtype, traddr, adrfam=None, trsvc
|
||||
if fabrics_timeout:
|
||||
params['fabrics_connect_timeout_us'] = fabrics_timeout
|
||||
|
||||
if multipath:
|
||||
params['multipath'] = multipath
|
||||
|
||||
return client.call('bdev_nvme_attach_controller', params)
|
||||
|
||||
|
||||
|
@ -64,6 +64,11 @@ NOT $rpc_py -s $bdevperf_rpc_sock bdev_nvme_attach_controller -b NVMe0 -t $TEST_
|
||||
NOT $rpc_py -s $bdevperf_rpc_sock bdev_nvme_attach_controller -b NVMe0 -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP \
|
||||
-s $NVMF_PORT -f ipv4 -n nqn.2016-06.io.spdk:cnode2 -i $NVMF_FIRST_TARGET_IP -c $NVMF_HOST_FIRST_PORT
|
||||
|
||||
# try to attach with the same controller name and multipathing disabled. Should fail
|
||||
NOT $rpc_py -s $bdevperf_rpc_sock bdev_nvme_attach_controller -b NVMe0 -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP \
|
||||
-s $NVMF_PORT -f ipv4 -n nqn.2016-06.io.spdk:cnode1 -i $NVMF_FIRST_TARGET_IP -c $NVMF_HOST_FIRST_PORT \
|
||||
-x disable
|
||||
|
||||
# Add a second path without specifying the host information. Should pass.
|
||||
$rpc_py -s $bdevperf_rpc_sock bdev_nvme_attach_controller -b NVMe0 -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP \
|
||||
-s $NVMF_SECOND_PORT -f ipv4 -n nqn.2016-06.io.spdk:cnode1
|
||||
|
Loading…
Reference in New Issue
Block a user