module/bdev_rpc: modify detach_ctrlr rpc to accept trid.

This will allow us to use this RPC to detach only specific
paths from controllers.

Signed-off-by: Seth Howell <seth.howell@intel.com>
Change-Id: Ib52e38aa7d4ea096418a6dc0328481c2e8db6c54
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3070
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Seth Howell 2020-06-25 12:23:30 -07:00 committed by Tomasz Zawadzki
parent ca8c9be341
commit 8bff48f63c
4 changed files with 133 additions and 5 deletions

View File

@ -1877,13 +1877,25 @@ Example response:
## bdev_nvme_detach_controller {#rpc_bdev_nvme_detach_controller}
Detach NVMe controller and delete any associated bdevs.
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
available path for the controller, this will also result in the
controller being detached and the associated bdevs being deleted.
returns true if the controller and bdevs were successfully destroyed
or the address was properly removed, false otherwise.
### Parameters
Name | Optional | Type | Description
----------------------- | -------- | ----------- | -----------
name | Required | string | Controller name
trtype | Optional | string | NVMe-oF target trtype: rdma or tcp
traddr | Optional | string | NVMe-oF target address: ip or BDF
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
### Example

View File

@ -489,16 +489,31 @@ SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_nvme_get_controllers, get_nvme_controlle
struct rpc_bdev_nvme_detach_controller {
char *name;
char *trtype;
char *adrfam;
char *traddr;
char *trsvcid;
char *subnqn;
};
static void
free_rpc_bdev_nvme_detach_controller(struct rpc_bdev_nvme_detach_controller *req)
{
free(req->name);
free(req->trtype);
free(req->adrfam);
free(req->traddr);
free(req->trsvcid);
free(req->subnqn);
}
static const struct spdk_json_object_decoder rpc_bdev_nvme_detach_controller_decoders[] = {
{"name", offsetof(struct rpc_bdev_nvme_detach_controller, name), spdk_json_decode_string},
{"trtype", offsetof(struct rpc_bdev_nvme_detach_controller, trtype), spdk_json_decode_string, true},
{"traddr", offsetof(struct rpc_bdev_nvme_detach_controller, traddr), spdk_json_decode_string, true},
{"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},
};
static void
@ -506,8 +521,11 @@ rpc_bdev_nvme_detach_controller(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_bdev_nvme_detach_controller req = {NULL};
struct spdk_nvme_transport_id trid = {};
struct spdk_json_write_ctx *w;
size_t len, maxlen;
int rc = 0;
bool all_trid_entries, one_trid_entry;
if (spdk_json_decode_object(params, rpc_bdev_nvme_detach_controller_decoders,
SPDK_COUNTOF(rpc_bdev_nvme_detach_controller_decoders),
@ -517,7 +535,65 @@ rpc_bdev_nvme_detach_controller(struct spdk_jsonrpc_request *request,
goto cleanup;
}
rc = bdev_nvme_delete(req.name);
all_trid_entries = req.trtype && req.traddr && req.adrfam && req.trsvcid && req.subnqn;
one_trid_entry = req.trtype || req.traddr || req.adrfam || req.trsvcid || req.subnqn;
if (all_trid_entries ^ one_trid_entry) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"trtype, traddr, adrfam, trsvcid, subnqn must all be provided together or not at all.");
goto cleanup;
}
if (all_trid_entries) {
/* Parse trtype */
rc = spdk_nvme_transport_id_parse_trtype(&trid.trtype, req.trtype);
if (rc < 0) {
SPDK_ERRLOG("Failed to parse trtype: %s\n", req.trtype);
spdk_jsonrpc_send_error_response_fmt(request, -EINVAL, "Failed to parse trtype: %s",
req.trtype);
goto cleanup;
}
/* Parse traddr */
maxlen = sizeof(trid.traddr);
len = strnlen(req.traddr, maxlen);
if (len == maxlen) {
spdk_jsonrpc_send_error_response_fmt(request, -EINVAL, "traddr too long: %s",
req.traddr);
goto cleanup;
}
memcpy(trid.traddr, req.traddr, len + 1);
rc = spdk_nvme_transport_id_parse_adrfam(&trid.adrfam, req.adrfam);
if (rc < 0) {
SPDK_ERRLOG("Failed to parse adrfam: %s\n", req.adrfam);
spdk_jsonrpc_send_error_response_fmt(request, -EINVAL, "Failed to parse adrfam: %s",
req.adrfam);
goto cleanup;
}
maxlen = sizeof(trid.trsvcid);
len = strnlen(req.trsvcid, maxlen);
if (len == maxlen) {
spdk_jsonrpc_send_error_response_fmt(request, -EINVAL, "trsvcid too long: %s",
req.trsvcid);
goto cleanup;
}
memcpy(trid.trsvcid, req.trsvcid, len + 1);
maxlen = sizeof(trid.subnqn);
len = strnlen(req.subnqn, maxlen);
if (len == maxlen) {
spdk_jsonrpc_send_error_response_fmt(request, -EINVAL, "subnqn too long: %s",
req.subnqn);
goto cleanup;
}
memcpy(trid.subnqn, req.subnqn, len + 1);
rc = bdev_nvme_remove_trid(req.name, &trid);
} else {
rc = bdev_nvme_delete(req.name);
}
if (rc != 0) {
spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
goto cleanup;

View File

@ -484,11 +484,25 @@ if __name__ == "__main__":
def bdev_nvme_detach_controller(args):
rpc.bdev.bdev_nvme_detach_controller(args.client,
name=args.name)
name=args.name,
trtype=args.trtype,
traddr=args.traddr,
adrfam=args.adrfam,
trsvcid=args.trsvcid,
subnqn=args.subnqn)
p = subparsers.add_parser('bdev_nvme_detach_controller', aliases=['delete_nvme_controller'],
help='Detach an NVMe controller and delete any associated bdevs')
p.add_argument('name', help="Name of the controller")
p.add_argument('-t', '--trtype',
help='NVMe-oF target trtype: e.g., rdma, pcie')
p.add_argument('-a', '--traddr',
help='NVMe-oF target address: e.g., an ip address or BDF')
p.add_argument('-f', '--adrfam',
help='NVMe-oF target adrfam: e.g., ipv4, ipv6, ib, fc, intra_host')
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.set_defaults(func=bdev_nvme_detach_controller)
def bdev_nvme_cuse_register(args):

View File

@ -492,14 +492,40 @@ def bdev_nvme_attach_controller(client, name, trtype, traddr, adrfam=None, trsvc
@deprecated_alias('delete_nvme_controller')
def bdev_nvme_detach_controller(client, name):
"""Detach NVMe controller and delete any associated bdevs.
def bdev_nvme_detach_controller(client, name, trtype=None, traddr=None,
adrfam=None, trsvcid=None, subnqn=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
available path for the controller, this will also result in the
controller being detached and the associated bdevs being deleted.
Args:
name: controller name
trtype: transport type ("PCIe", "RDMA")
traddr: transport address (PCI BDF or IP address)
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)
"""
params = {'name': name}
if trtype:
params['trtype'] = trtype
if traddr:
params['traddr'] = traddr
if adrfam:
params['adrfam'] = adrfam
if trsvcid:
params['trsvcid'] = trsvcid
if subnqn:
params['subnqn'] = subnqn
return client.call('bdev_nvme_detach_controller', params)