diff --git a/CHANGELOG.md b/CHANGELOG.md index 2384ee23e..1f236776d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,14 @@ be notified of any discovery log changes. A new API `spdk_jsonrpc_send_bool_response` was added to allow sending response for writing json bool results into one function. +### rpc + +An new optional parameter `wait` was added to the RPC `iscsi_create_portal_group`, +and an new RPC `iscsi_start_portal_group` was added. They will be used not to start +listening on portals for a portal group until all associated target nodes are created +at startup, otherwise some iSCSI initiators may fail to re-login when SPDK iSCSI +target application restarts. + ## v20.10: ### accel diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index 3815a77f3..e50ebb193 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -4433,6 +4433,7 @@ Name | Optional | Type | Description tag | Required | number | Portal group tag portals | Required | array | Not empty array of portals private | Optional | boolean | When true, portals in this group are not returned by a discovery session. Used for login redirection. (default: `false`) +wait | Optional | boolean | When true, do not listen on portals until it is started explicitly. (default: `false`) Portal object diff --git a/lib/iscsi/iscsi_rpc.c b/lib/iscsi/iscsi_rpc.c index 04ef5b685..20b4fa57e 100644 --- a/lib/iscsi/iscsi_rpc.c +++ b/lib/iscsi/iscsi_rpc.c @@ -706,6 +706,7 @@ struct rpc_portal_group { int32_t tag; struct rpc_portal_list portal_list; bool is_private; + bool wait; }; static void @@ -760,6 +761,7 @@ static const struct spdk_json_object_decoder rpc_portal_group_decoders[] = { {"tag", offsetof(struct rpc_portal_group, tag), spdk_json_decode_int32}, {"portals", offsetof(struct rpc_portal_group, portal_list), decode_rpc_portal_list}, {"private", offsetof(struct rpc_portal_group, is_private), spdk_json_decode_bool, true}, + {"wait", offsetof(struct rpc_portal_group, wait), spdk_json_decode_bool, true}, }; static void @@ -794,7 +796,7 @@ rpc_iscsi_create_portal_group(struct spdk_jsonrpc_request *request, iscsi_portal_grp_add_portal(pg, portal); } - rc = iscsi_portal_grp_open(pg, false); + rc = iscsi_portal_grp_open(pg, req.wait); if (rc != 0) { SPDK_ERRLOG("portal_grp_open failed\n"); goto out; diff --git a/scripts/rpc.py b/scripts/rpc.py index b9e50a94f..4bc804c85 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -1183,7 +1183,8 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse args.client, portals=portals, tag=args.tag, - private=args.private) + private=args.private, + wait=args.wait) p = subparsers.add_parser('iscsi_create_portal_group', aliases=['add_portal_group'], help='Add a portal group') @@ -1195,6 +1196,9 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse Private portal groups do not have their portals returned by a discovery session. A public portal group may optionally specify a redirect portal for non-discovery logins. This redirect portal must be from a private portal group.""", action='store_true') + p.add_argument('-w', '--wait', help="""Do not listening on portals until it is started explicitly. + One major iSCSI initiator may not retry login once it failed. Hence for such initiator, listening + on portals should be allowed after all associated target nodes are created.""", action='store_true') p.set_defaults(func=iscsi_create_portal_group) def iscsi_start_portal_group(args): diff --git a/scripts/rpc/iscsi.py b/scripts/rpc/iscsi.py index c4631133e..e98126f57 100644 --- a/scripts/rpc/iscsi.py +++ b/scripts/rpc/iscsi.py @@ -424,13 +424,14 @@ def iscsi_target_node_request_logout(client, name, pg_tag): @deprecated_alias('add_portal_group') -def iscsi_create_portal_group(client, portals, tag, private): +def iscsi_create_portal_group(client, portals, tag, private, wait): """Add a portal group. Args: portals: List of portals, e.g. [{'host': ip, 'port': port}] tag: Initiator group tag (unique, integer > 0) private: Public (false) or private (true) portal group for login redirection. + wait: Do not listen on portals until it is allowed explictly. Returns: True or False @@ -439,6 +440,8 @@ def iscsi_create_portal_group(client, portals, tag, private): if private: params['private'] = private + if wait: + params['wait'] = wait return client.call('iscsi_create_portal_group', params) diff --git a/scripts/spdkcli/ui_node_iscsi.py b/scripts/spdkcli/ui_node_iscsi.py index 6852670b3..cb7cbee19 100644 --- a/scripts/spdkcli/ui_node_iscsi.py +++ b/scripts/spdkcli/ui_node_iscsi.py @@ -315,7 +315,7 @@ class UIPortalGroups(UINode): if cpumask: print("WARNING: Specifying a CPU mask for portal groups is no longer supported. Ignoring.") tag = self.ui_eval_param(tag, "number", None) - self.get_root().construct_portal_group(tag=tag, portals=portals, private=None) + self.get_root().construct_portal_group(tag=tag, portals=portals, private=None, wait=None) def ui_command_delete(self, tag): """Delete a portal group with given tag (unique, integer > 0))"""