bdev/nvme: bdev_nvme_detach_controller now understands host parameters

You can now detach specific paths based on the host parameters. This is
useful for two paths to the same target that use different local NICs.

Change-Id: I4858bfda7d940052ca77ffb0bbe764a688fb315d
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9827
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
This commit is contained in:
Ben Walker 2021-10-11 13:35:39 -07:00 committed by Jim Harris
parent 8a154b2c0d
commit b098640f05
6 changed files with 64 additions and 2 deletions

View File

@ -2994,6 +2994,8 @@ traddr | Optional | string | NVMe-oF target address: ip or
adrfam | Optional | string | NVMe-oF target adrfam: ipv4, ipv6, ib, fc, intra_host
trsvcid | Optional | string | NVMe-oF target trsvcid: port number
subnqn | Optional | string | NVMe-oF target subnqn
hostaddr | Optional | string | NVMe-oF host address: ip
hostsvcid | Optional | string | NVMe-oF host svcid: port number
#### Example

View File

@ -2995,6 +2995,10 @@ nvme_ctrlr_create(struct spdk_nvme_ctrlr *ctrlr,
}
path_id->trid = *trid;
if (ctx != NULL) {
memcpy(path_id->hostid.hostaddr, ctx->opts.src_addr, sizeof(path_id->hostid.hostaddr));
memcpy(path_id->hostid.hostsvcid, ctx->opts.src_svcid, sizeof(path_id->hostid.hostsvcid));
}
nvme_ctrlr->active_path_id = path_id;
TAILQ_INSERT_HEAD(&nvme_ctrlr->trids, path_id, link);
@ -3604,6 +3608,18 @@ bdev_nvme_delete(const char *name, const struct nvme_path_id *path_id)
}
}
if (!spdk_mem_all_zero(path_id->hostid.hostaddr, sizeof(path_id->hostid.hostaddr))) {
if (strcmp(path_id->hostid.hostaddr, p->hostid.hostaddr) != 0) {
continue;
}
}
if (!spdk_mem_all_zero(path_id->hostid.hostsvcid, sizeof(path_id->hostid.hostsvcid))) {
if (strcmp(path_id->hostid.hostsvcid, p->hostid.hostsvcid) != 0) {
continue;
}
}
/* If we made it here, then this path is a match! Now we need to remove it. */
if (p == nvme_ctrlr->active_path_id) {
/* This is the active path in use right now. The active path is always the first in the list. */

View File

@ -84,6 +84,7 @@ struct nvme_bdev;
struct nvme_path_id {
struct spdk_nvme_transport_id trid;
struct spdk_nvme_host_id hostid;
TAILQ_ENTRY(nvme_path_id) link;
bool is_failed;
};

View File

@ -593,6 +593,8 @@ struct rpc_bdev_nvme_detach_controller {
char *traddr;
char *trsvcid;
char *subnqn;
char *hostaddr;
char *hostsvcid;
};
static void
@ -604,6 +606,8 @@ free_rpc_bdev_nvme_detach_controller(struct rpc_bdev_nvme_detach_controller *req
free(req->traddr);
free(req->trsvcid);
free(req->subnqn);
free(req->hostaddr);
free(req->hostsvcid);
}
static const struct spdk_json_object_decoder rpc_bdev_nvme_detach_controller_decoders[] = {
@ -613,6 +617,8 @@ static const struct spdk_json_object_decoder rpc_bdev_nvme_detach_controller_dec
{"adrfam", offsetof(struct rpc_bdev_nvme_detach_controller, adrfam), spdk_json_decode_string, true},
{"trsvcid", offsetof(struct rpc_bdev_nvme_detach_controller, trsvcid), spdk_json_decode_string, true},
{"subnqn", offsetof(struct rpc_bdev_nvme_detach_controller, subnqn), spdk_json_decode_string, true},
{"hostaddr", offsetof(struct rpc_bdev_nvme_detach_controller, hostaddr), spdk_json_decode_string, true},
{"hostsvcid", offsetof(struct rpc_bdev_nvme_detach_controller, hostsvcid), spdk_json_decode_string, true},
};
static void
@ -694,6 +700,28 @@ rpc_bdev_nvme_detach_controller(struct spdk_jsonrpc_request *request,
memcpy(path.trid.subnqn, req.subnqn, len + 1);
}
if (req.hostaddr) {
maxlen = sizeof(path.hostid.hostaddr);
len = strnlen(req.hostaddr, maxlen);
if (len == maxlen) {
spdk_jsonrpc_send_error_response_fmt(request, -EINVAL, "hostaddr too long: %s",
req.hostaddr);
goto cleanup;
}
snprintf(path.hostid.hostaddr, maxlen, "%s", req.hostaddr);
}
if (req.hostsvcid) {
maxlen = sizeof(path.hostid.hostsvcid);
len = strnlen(req.hostsvcid, maxlen);
if (len == maxlen) {
spdk_jsonrpc_send_error_response_fmt(request, -EINVAL, "hostsvcid too long: %s",
req.hostsvcid);
goto cleanup;
}
snprintf(path.hostid.hostsvcid, maxlen, "%s", req.hostsvcid);
}
rc = bdev_nvme_delete(req.name, &path);
if (rc != 0) {

View File

@ -577,7 +577,9 @@ if __name__ == "__main__":
traddr=args.traddr,
adrfam=args.adrfam,
trsvcid=args.trsvcid,
subnqn=args.subnqn)
subnqn=args.subnqn,
hostaddr=args.hostaddr,
hostsvcid=args.hostsvcid)
p = subparsers.add_parser('bdev_nvme_detach_controller', aliases=['delete_nvme_controller'],
help='Detach an NVMe controller and delete any associated bdevs')
@ -591,6 +593,10 @@ if __name__ == "__main__":
p.add_argument('-s', '--trsvcid',
help='NVMe-oF target trsvcid: e.g., a port number')
p.add_argument('-n', '--subnqn', help='NVMe-oF target subnqn')
p.add_argument('-i', '--hostaddr',
help='NVMe-oF host address: e.g., an ip address')
p.add_argument('-c', '--hostsvcid',
help='NVMe-oF host svcid: e.g., a port number')
p.set_defaults(func=bdev_nvme_detach_controller)
def bdev_nvme_reset_controller(args):

View File

@ -583,7 +583,8 @@ def bdev_nvme_attach_controller(client, name, trtype, traddr, adrfam=None, trsvc
@deprecated_alias('delete_nvme_controller')
def bdev_nvme_detach_controller(client, name, trtype=None, traddr=None,
adrfam=None, trsvcid=None, subnqn=None):
adrfam=None, trsvcid=None, subnqn=None,
hostaddr=None, hostsvcid=None):
"""Detach NVMe controller and delete any associated bdevs. Optionally,
If all of the transport ID options are specified, only remove that
transport path from the specified controller. If that is the only
@ -597,6 +598,8 @@ def bdev_nvme_detach_controller(client, name, trtype=None, traddr=None,
adrfam: address family ("IPv4", "IPv6", "IB", or "FC")
trsvcid: transport service ID (port number for IP-based addresses)
subnqn: subsystem NQN to connect to (optional)
hostaddr: Host address (IP address)
hostsvcid: transport service ID on host side (port number)
"""
params = {'name': name}
@ -616,6 +619,12 @@ def bdev_nvme_detach_controller(client, name, trtype=None, traddr=None,
if subnqn:
params['subnqn'] = subnqn
if hostaddr:
params['hostaddr'] = hostaddr
if hostsvcid:
params['hostsvcid'] = hostsvcid
return client.call('bdev_nvme_detach_controller', params)