iscsi/rpc: Set processor affinity of connection through JSON-RPC

Currently setting cpumask to portal is possible only through
iSCSI.conf. This patch makes possible for any user to set cpumask
through JSON-RPC too.

The following are done in this patch:
- To keep compatibility, cpumask parameter handled as optional.
- Python test code is added.
- Current python script for JSON-RPC does not work correctly for
  IPv6 and the issue is fixed.

Change-Id: I42ef397ce95040a36db4430417a35e9e97527477
Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/391728
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Shuhei Matsumoto 2018-01-22 08:04:19 +09:00 committed by Jim Harris
parent 7bae25dfcd
commit 632f0ced75
3 changed files with 26 additions and 9 deletions

View File

@ -732,6 +732,8 @@ spdk_rpc_get_portal_groups(struct spdk_jsonrpc_request *request,
spdk_json_write_string(w, portal->host);
spdk_json_write_name(w, "port");
spdk_json_write_string(w, portal->port);
spdk_json_write_name(w, "cpumask");
spdk_json_write_string_fmt(w, "%#" PRIx64, portal->cpumask);
spdk_json_write_object_end(w);
}
spdk_json_write_array_end(w);
@ -751,6 +753,7 @@ SPDK_RPC_REGISTER("get_portal_groups", spdk_rpc_get_portal_groups)
struct rpc_portal {
char *host;
char *port;
char *cpumask;
};
struct rpc_portal_list {
@ -767,9 +770,8 @@ static void
free_rpc_portal(struct rpc_portal *portal)
{
free(portal->host);
portal->host = NULL;
free(portal->port);
portal->port = NULL;
free(portal->cpumask);
}
static void
@ -792,6 +794,7 @@ free_rpc_portal_group(struct rpc_portal_group *pg)
static const struct spdk_json_object_decoder rpc_portal_decoders[] = {
{"host", offsetof(struct rpc_portal, host), spdk_json_decode_string},
{"port", offsetof(struct rpc_portal, port), spdk_json_decode_string},
{"cpumask", offsetof(struct rpc_portal, cpumask), spdk_json_decode_string, true},
};
static int
@ -838,7 +841,8 @@ spdk_rpc_add_portal_group(struct spdk_jsonrpc_request *request,
for (i = 0; i < req.portal_list.num_portals; i++) {
portal_list[i] = spdk_iscsi_portal_create(req.portal_list.portals[i].host,
req.portal_list.portals[i].port, NULL);
req.portal_list.portals[i].port,
req.portal_list.portals[i].cpumask);
if (portal_list[i] == NULL) {
SPDK_ERRLOG("portal_list allocation failed\n");
goto out;

View File

@ -488,16 +488,24 @@ def add_portal_group(args):
# parse out portal list host1:port1 host2:port2
portals = []
for p in args.portal_list:
host_port = p.split(':')
portals.append({'host': host_port[0], 'port': host_port[1]})
ip, separator, port_cpumask = p.rpartition(':')
split_port_cpumask = port_cpumask.split('@')
if len(split_port_cpumask) == 1:
port = port_cpumask
portals.append({'host': ip, 'port': port})
else:
port = split_port_cpumask[0]
cpumask = split_port_cpumask[1]
portals.append({'host': ip, 'port': port, 'cpumask': cpumask})
params = {'tag': args.tag, 'portals': portals}
jsonrpc_call('add_portal_group', params)
p = subparsers.add_parser('add_portal_group', help='Add a portal group')
p.add_argument('tag', help='Portal group tag (unique, integer > 0)', type=int)
p.add_argument('portal_list', nargs=argparse.REMAINDER, help="""List of portals in 'host:port' format, separated by whitespace
Example: '192.168.100.100:3260' '192.168.100.100:3261'""")
p.add_argument('portal_list', nargs=argparse.REMAINDER, help="""List of portals in 'host:port@cpumask' format, separated by whitespace
(cpumask is optional and can be skipped)
Example: '192.168.100.100:3260' '192.168.100.100:3261' '192.168.100.100:3262@0x1""")
p.set_defaults(func=add_portal_group)

View File

@ -28,7 +28,8 @@ rpc_param = {
'chap_auth_group': 0,
'header_digest': 0,
'data_digest': 0,
'trace_flag': 'rpc'
'trace_flag': 'rpc',
'cpumask': 0x1
}
@ -187,7 +188,7 @@ def verify_portal_groups_rpc_methods(rpc_py, rpc_param):
for idx, value in enumerate(lo_ip):
# The portal group tag must start at 1
tag = idx + 1
rpc.add_portal_group(tag, "{}:{}".format(value, rpc_param['port']))
rpc.add_portal_group(tag, "{}:{}@{}".format(value, rpc_param['port'], rpc_param['cpumask']))
output = rpc.get_portal_groups()
jsonvalues = json.loads(output)
verify(len(jsonvalues) == tag, 1,
@ -199,6 +200,8 @@ def verify_portal_groups_rpc_methods(rpc_py, rpc_param):
"host value is {}, expected {}".format(value['portals'][0]['host'], rpc_param['target_ip']))
verify(value['portals'][0]['port'] == str(rpc_param['port']), 1,
"port value is {}, expected {}".format(value['portals'][0]['port'], str(rpc_param['port'])))
verify(value['portals'][0]['cpumask'] == format(rpc_param['cpumask'], '#x'), 1,
"cpumask value is {}, expected {}".format(value['portals'][0]['cpumask'], format(rpc_param['cpumask'], '#x')))
tag_list.append(value['tag'])
verify(value['tag'] == idx + 1, 1,
"tag value is {}, expected {}".format(value['tag'], idx + 1))
@ -217,6 +220,8 @@ def verify_portal_groups_rpc_methods(rpc_py, rpc_param):
"host value is {}, expected {}".format(jvalue['portals'][0]['host'], lo_ip[idx + jidx + 1]))
verify(jvalue['portals'][0]['port'] == str(rpc_param['port']), 1,
"port value is {}, expected {}".format(jvalue['portals'][0]['port'], str(rpc_param['port'])))
verify(jvalue['portals'][0]['cpumask'] == format(rpc_param['cpumask'], '#x'), 1,
"cpumask value is {}, expected {}".format(jvalue['portals'][0]['cpumask'], format(rpc_param['cpumask'], '#x')))
verify(jvalue['tag'] != value or jvalue['tag'] == tag_list[idx + jidx + 1], 1,
"tag value is {}, expected {} and not {}".format(jvalue['tag'], tag_list[idx + jidx + 1], value))