From 6d716c47059129553317f0830911d38a050cbef8 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Wed, 25 Aug 2021 12:00:51 +0900 Subject: [PATCH] nvmf: Update only ANA state of specified ANA group by RPC Signed-off-by: Shuhei Matsumoto Change-Id: Iccf3f393d1f027d04a57324762e6aabaf9d5a0df Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9117 Community-CI: Mellanox Build Bot Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris Reviewed-by: Dong Yi --- CHANGELOG.md | 2 ++ doc/jsonrpc.md | 4 +++- lib/nvmf/nvmf_internal.h | 2 +- lib/nvmf/nvmf_rpc.c | 4 +++- lib/nvmf/subsystem.c | 19 ++++++++++++++++--- scripts/rpc.py | 4 +++- scripts/rpc/nvmf.py | 7 ++++++- 7 files changed, 34 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3695cb900..1e65aab4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ added in the `spdk_nvmf_ns_opts` structure. An new parameter `anagrpid` was added to the RPC `nvmf_subsystem_add_ns`. +An new parameter `anagrpid` was added to the RPC `nvmf_subsystem_listener_set_ana_state`. + ### bdev New API `spdk_bdev_get_memory_domains` has been added, it allows to get SPDK memory domains used by bdev. diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index f0210b502..04aa69eed 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -6278,7 +6278,8 @@ Example response: ### nvmf_subsystem_listener_set_ana_state method {#rpc_nvmf_subsystem_listener_set_ana_state} -Set ANA state of a listener for an NVMe-oF subsystem. +Set ANA state of a listener for an NVMe-oF subsystem. Only the ANA state of the specified ANA +group is updated, or ANA states of all ANA groups if ANA group is not specified. #### Parameters @@ -6288,6 +6289,7 @@ nqn | Required | string | Subsystem NQN tgt_name | Optional | string | Parent NVMe-oF target name. listen_address | Required | object | @ref rpc_nvmf_listen_address object ana_state | Required | string | ANA state to set ("optimized", "non_optimized", or "inaccessible") +anagrpid | Optional | number | ANA group ID #### Example diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index b34e2e089..2cbadf33d 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -391,7 +391,7 @@ struct spdk_nvmf_listener *nvmf_transport_find_listener( const struct spdk_nvme_transport_id *trid); void nvmf_subsystem_set_ana_state(struct spdk_nvmf_subsystem *subsystem, const struct spdk_nvme_transport_id *trid, - enum spdk_nvme_ana_state ana_state, + enum spdk_nvme_ana_state ana_state, uint32_t anagrpid, spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn, void *cb_arg); bool nvmf_subsystem_get_ana_reporting(struct spdk_nvmf_subsystem *subsystem); diff --git a/lib/nvmf/nvmf_rpc.c b/lib/nvmf/nvmf_rpc.c index 2d244c5a8..dba37aa09 100644 --- a/lib/nvmf/nvmf_rpc.c +++ b/lib/nvmf/nvmf_rpc.c @@ -615,6 +615,7 @@ struct nvmf_rpc_listener_ctx { struct rpc_listen_address address; char *ana_state_str; enum spdk_nvme_ana_state ana_state; + uint32_t anagrpid; struct spdk_jsonrpc_request *request; struct spdk_nvme_transport_id trid; @@ -757,7 +758,7 @@ nvmf_rpc_listen_paused(struct spdk_nvmf_subsystem *subsystem, "Invalid parameters"); ctx->response_sent = true; } else if (ctx->op == NVMF_RPC_LISTEN_SET_ANA_STATE) { - nvmf_subsystem_set_ana_state(subsystem, &ctx->trid, ctx->ana_state, + nvmf_subsystem_set_ana_state(subsystem, &ctx->trid, ctx->ana_state, ctx->anagrpid, nvmf_rpc_set_ana_state_done, ctx); return; } else { @@ -978,6 +979,7 @@ static const struct spdk_json_object_decoder nvmf_rpc_set_ana_state_decoder[] = {"listen_address", offsetof(struct nvmf_rpc_listener_ctx, address), decode_rpc_listen_address}, {"ana_state", offsetof(struct nvmf_rpc_listener_ctx, ana_state_str), spdk_json_decode_string}, {"tgt_name", offsetof(struct nvmf_rpc_listener_ctx, tgt_name), spdk_json_decode_string, true}, + {"anagrpid", offsetof(struct nvmf_rpc_listener_ctx, anagrpid), spdk_json_decode_uint32, true}, }; static int diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index ab07664b3..63226bfb1 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -3024,7 +3024,7 @@ subsystem_listener_update_on_pg(struct spdk_io_channel_iter *i) void nvmf_subsystem_set_ana_state(struct spdk_nvmf_subsystem *subsystem, const struct spdk_nvme_transport_id *trid, - enum spdk_nvme_ana_state ana_state, + enum spdk_nvme_ana_state ana_state, uint32_t anagrpid, spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn, void *cb_arg) { struct spdk_nvmf_subsystem_listener *listener; @@ -3052,6 +3052,12 @@ nvmf_subsystem_set_ana_state(struct spdk_nvmf_subsystem *subsystem, return; } + if (anagrpid > subsystem->max_nsid) { + SPDK_ERRLOG("ANA group ID %" PRIu32 " is more than maximum\n", anagrpid); + cb_fn(cb_arg, -EINVAL); + return; + } + listener = nvmf_subsystem_find_listener(subsystem, trid); if (!listener) { SPDK_ERRLOG("Unable to find listener.\n"); @@ -3059,6 +3065,11 @@ nvmf_subsystem_set_ana_state(struct spdk_nvmf_subsystem *subsystem, return; } + if (anagrpid != 0 && listener->ana_state[anagrpid - 1] == ana_state) { + cb_fn(cb_arg, 0); + return; + } + ctx = calloc(1, sizeof(*ctx)); if (!ctx) { SPDK_ERRLOG("Unable to allocate context\n"); @@ -3066,8 +3077,10 @@ nvmf_subsystem_set_ana_state(struct spdk_nvmf_subsystem *subsystem, return; } - for (i = 0; i < subsystem->max_nsid; i++) { - listener->ana_state[i] = ana_state; + for (i = 1; i <= subsystem->max_nsid; i++) { + if (anagrpid == 0 || i == anagrpid) { + listener->ana_state[i - 1] = ana_state; + } } listener->ana_state_change_count++; diff --git a/scripts/rpc.py b/scripts/rpc.py index b83156b60..1fe05d7d1 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -2035,7 +2035,8 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse traddr=args.traddr, tgt_name=args.tgt_name, adrfam=args.adrfam, - trsvcid=args.trsvcid) + trsvcid=args.trsvcid, + anagrpid=args.anagrpid) p = subparsers.add_parser('nvmf_subsystem_listener_set_ana_state', help='Set ANA state of a listener for an NVMe-oF subsystem') p.add_argument('nqn', help='NVMe-oF subsystem NQN') @@ -2045,6 +2046,7 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse p.add_argument('-p', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) p.add_argument('-f', '--adrfam', help='NVMe-oF transport adrfam: e.g., ipv4, ipv6, ib, fc, intra_host') p.add_argument('-s', '--trsvcid', help='NVMe-oF transport service id: e.g., a port number') + p.add_argument('-g', '--anagrpid', help='ANA group ID (optional)', type=int) p.set_defaults(func=nvmf_subsystem_listener_set_ana_state) def nvmf_subsystem_add_ns(args): diff --git a/scripts/rpc/nvmf.py b/scripts/rpc/nvmf.py index 1b0bd8099..a8bbf603c 100644 --- a/scripts/rpc/nvmf.py +++ b/scripts/rpc/nvmf.py @@ -300,7 +300,8 @@ def nvmf_subsystem_listener_set_ana_state( traddr, trsvcid, adrfam, - tgt_name=None): + tgt_name=None, + anagrpid=None): """Set ANA state of a listener for an NVMe-oF subsystem. Args: @@ -311,6 +312,7 @@ def nvmf_subsystem_listener_set_ana_state( trsvcid: Transport service ID. tgt_name: name of the parent NVMe-oF target (optional). adrfam: Address family ("IPv4", "IPv6", "IB", or "FC"). + anagrpid: ANA group ID (optional) Returns: True or False @@ -329,6 +331,9 @@ def nvmf_subsystem_listener_set_ana_state( if tgt_name: params['tgt_name'] = tgt_name + if anagrpid: + params['anagrpid'] = anagrpid + return client.call('nvmf_subsystem_listener_set_ana_state', params)