subsystem/iscsi: Add set_iscsi_options RPC to set global params
An new RPC set_iscsi_options allocates and set options dynamically. Initialization of iSCSI subsystem skips initialization of options if it is already allocated. To use and test this RPC easily, add python script too. Change-Id: I71e252da6495a194ae9a1a9e3aaae4feb543487a Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/403624 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
cfbae9c23b
commit
59b3479bfd
@ -35,7 +35,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../..)
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||
|
||||
CFLAGS += -I$(SPDK_ROOT_DIR)/lib
|
||||
C_SRCS = iscsi.c
|
||||
C_SRCS = iscsi.c iscsi_rpc.c
|
||||
LIBNAME = event_iscsi
|
||||
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.lib.mk
|
||||
|
113
lib/event/subsystems/iscsi/iscsi_rpc.c
Normal file
113
lib/event/subsystems/iscsi/iscsi_rpc.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (c) Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "iscsi/iscsi.h"
|
||||
#include "iscsi/conn.h"
|
||||
|
||||
#include "spdk/rpc.h"
|
||||
#include "spdk/util.h"
|
||||
#include "spdk/event.h"
|
||||
|
||||
#include "spdk_internal/log.h"
|
||||
|
||||
static const struct spdk_json_object_decoder rpc_set_iscsi_opts_decoders[] = {
|
||||
{"auth_file", offsetof(struct spdk_iscsi_opts, authfile), spdk_json_decode_string, true},
|
||||
{"node_base", offsetof(struct spdk_iscsi_opts, nodebase), spdk_json_decode_string, true},
|
||||
{"timeout", offsetof(struct spdk_iscsi_opts, timeout), spdk_json_decode_int32, true},
|
||||
{"nop_in_interval", offsetof(struct spdk_iscsi_opts, nopininterval), spdk_json_decode_int32, true},
|
||||
{"no_discovery_auth", offsetof(struct spdk_iscsi_opts, no_discovery_auth), spdk_json_decode_bool, true},
|
||||
{"req_discovery_auth", offsetof(struct spdk_iscsi_opts, req_discovery_auth), spdk_json_decode_bool, true},
|
||||
{"req_discovery_auth_mutual", offsetof(struct spdk_iscsi_opts, req_discovery_auth_mutual), spdk_json_decode_bool, true},
|
||||
{"discovery_auth_group", offsetof(struct spdk_iscsi_opts, discovery_auth_group), spdk_json_decode_int32, true},
|
||||
{"max_sessions", offsetof(struct spdk_iscsi_opts, MaxSessions), spdk_json_decode_uint32, true},
|
||||
{"max_queue_depth", offsetof(struct spdk_iscsi_opts, MaxQueueDepth), spdk_json_decode_uint32, true},
|
||||
{"max_connections_per_session", offsetof(struct spdk_iscsi_opts, MaxConnectionsPerSession), spdk_json_decode_uint32, true},
|
||||
{"default_time2wait", offsetof(struct spdk_iscsi_opts, DefaultTime2Wait), spdk_json_decode_uint32, true},
|
||||
{"default_time2retain", offsetof(struct spdk_iscsi_opts, DefaultTime2Retain), spdk_json_decode_uint32, true},
|
||||
{"immediate_data", offsetof(struct spdk_iscsi_opts, ImmediateData), spdk_json_decode_bool, true},
|
||||
{"error_recovery_level", offsetof(struct spdk_iscsi_opts, ErrorRecoveryLevel), spdk_json_decode_uint32, true},
|
||||
{"allow_duplicated_isid", offsetof(struct spdk_iscsi_opts, AllowDuplicateIsid), spdk_json_decode_bool, true},
|
||||
{"min_connections_per_core", offsetof(struct spdk_iscsi_opts, min_connections_per_core), spdk_json_decode_uint32, true},
|
||||
};
|
||||
|
||||
static void
|
||||
spdk_rpc_iscsi_set_opts(struct spdk_jsonrpc_request *request,
|
||||
const struct spdk_json_val *params)
|
||||
{
|
||||
struct spdk_iscsi_opts *opts;
|
||||
struct spdk_json_write_ctx *w;
|
||||
|
||||
if (g_spdk_iscsi_opts != NULL) {
|
||||
SPDK_ERRLOG("this RPC must not be called more than once.\n");
|
||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||
"Must not call more than once");
|
||||
return;
|
||||
}
|
||||
|
||||
opts = spdk_iscsi_opts_alloc();
|
||||
if (opts == NULL) {
|
||||
SPDK_ERRLOG("spdk_iscsi_opts_alloc() failed.\n");
|
||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||
"Out of memory");
|
||||
return;
|
||||
}
|
||||
|
||||
if (params != NULL) {
|
||||
if (spdk_json_decode_object(params, rpc_set_iscsi_opts_decoders,
|
||||
SPDK_COUNTOF(rpc_set_iscsi_opts_decoders), opts)) {
|
||||
SPDK_ERRLOG("spdk_json_decode_object() failed\n");
|
||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
||||
"Invalid parameters");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_spdk_iscsi_opts = spdk_iscsi_opts_copy(opts);
|
||||
spdk_iscsi_opts_free(opts);
|
||||
|
||||
if (g_spdk_iscsi_opts == NULL) {
|
||||
SPDK_ERRLOG("spdk_iscsi_opts_copy() failed\n");
|
||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||
"Out of memory");
|
||||
return;
|
||||
}
|
||||
|
||||
w = spdk_jsonrpc_begin_result(request);
|
||||
if (w == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
spdk_json_write_bool(w, true);
|
||||
spdk_jsonrpc_end_result(request, w);
|
||||
}
|
||||
SPDK_RPC_REGISTER("set_iscsi_options", spdk_rpc_iscsi_set_opts, SPDK_RPC_STARTUP)
|
@ -346,6 +346,7 @@ enum spdk_error_codes {
|
||||
#define xstrdup(s) (s ? strdup(s) : (char *)NULL)
|
||||
|
||||
extern struct spdk_iscsi_globals g_spdk_iscsi;
|
||||
extern struct spdk_iscsi_opts *g_spdk_iscsi_opts;
|
||||
|
||||
struct spdk_iscsi_task;
|
||||
struct spdk_json_write_ctx;
|
||||
@ -359,6 +360,10 @@ void spdk_shutdown_iscsi_conns_done(void);
|
||||
void spdk_iscsi_config_text(FILE *fp);
|
||||
void spdk_iscsi_config_json(struct spdk_json_write_ctx *w);
|
||||
|
||||
struct spdk_iscsi_opts *spdk_iscsi_opts_alloc(void);
|
||||
void spdk_iscsi_opts_free(struct spdk_iscsi_opts *opts);
|
||||
struct spdk_iscsi_opts *spdk_iscsi_opts_copy(struct spdk_iscsi_opts *src);
|
||||
|
||||
void spdk_iscsi_send_nopin(struct spdk_iscsi_conn *conn);
|
||||
void spdk_iscsi_task_response(struct spdk_iscsi_conn *conn,
|
||||
struct spdk_iscsi_task *task);
|
||||
|
@ -47,6 +47,8 @@
|
||||
#include "spdk_internal/event.h"
|
||||
#include "spdk_internal/log.h"
|
||||
|
||||
struct spdk_iscsi_opts *g_spdk_iscsi_opts = NULL;
|
||||
|
||||
static spdk_iscsi_init_cb g_init_cb_fn = NULL;
|
||||
static void *g_init_cb_arg = NULL;
|
||||
|
||||
@ -397,11 +399,78 @@ spdk_iscsi_opts_init(struct spdk_iscsi_opts *opts)
|
||||
opts->min_connections_per_core = DEFAULT_CONNECTIONS_PER_LCORE;
|
||||
}
|
||||
|
||||
static void
|
||||
struct spdk_iscsi_opts *
|
||||
spdk_iscsi_opts_alloc(void)
|
||||
{
|
||||
struct spdk_iscsi_opts *opts;
|
||||
|
||||
opts = calloc(1, sizeof(*opts));
|
||||
if (!opts) {
|
||||
SPDK_ERRLOG("calloc() failed for iscsi options\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spdk_iscsi_opts_init(opts);
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
void
|
||||
spdk_iscsi_opts_free(struct spdk_iscsi_opts *opts)
|
||||
{
|
||||
free(opts->authfile);
|
||||
free(opts->nodebase);
|
||||
free(opts);
|
||||
}
|
||||
|
||||
/* Deep copy of spdk_iscsi_opts */
|
||||
struct spdk_iscsi_opts *
|
||||
spdk_iscsi_opts_copy(struct spdk_iscsi_opts *src)
|
||||
{
|
||||
struct spdk_iscsi_opts *dst;
|
||||
|
||||
dst = calloc(1, sizeof(*dst));
|
||||
if (!dst) {
|
||||
SPDK_ERRLOG("calloc() failed for iscsi options\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (src->authfile) {
|
||||
dst->authfile = strdup(src->authfile);
|
||||
if (!dst->authfile) {
|
||||
free(dst);
|
||||
SPDK_ERRLOG("failed to strdup for auth file %s\n", src->authfile);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (src->nodebase) {
|
||||
dst->nodebase = strdup(src->nodebase);
|
||||
if (!dst->nodebase) {
|
||||
free(dst->authfile);
|
||||
free(dst);
|
||||
SPDK_ERRLOG("failed to strdup for nodebase %s\n", src->nodebase);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dst->MaxSessions = src->MaxSessions;
|
||||
dst->MaxConnectionsPerSession = src->MaxConnectionsPerSession;
|
||||
dst->MaxQueueDepth = src->MaxQueueDepth;
|
||||
dst->DefaultTime2Wait = src->DefaultTime2Wait;
|
||||
dst->DefaultTime2Retain = src->DefaultTime2Retain;
|
||||
dst->ImmediateData = src->ImmediateData;
|
||||
dst->AllowDuplicateIsid = src->AllowDuplicateIsid;
|
||||
dst->ErrorRecoveryLevel = src->ErrorRecoveryLevel;
|
||||
dst->timeout = src->timeout;
|
||||
dst->nopininterval = src->nopininterval;
|
||||
dst->no_discovery_auth = src->no_discovery_auth;
|
||||
dst->req_discovery_auth = src->req_discovery_auth;
|
||||
dst->req_discovery_auth_mutual = src->req_discovery_auth;
|
||||
dst->discovery_auth_group = src->discovery_auth_group;
|
||||
dst->min_connections_per_core = src->min_connections_per_core;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -611,6 +680,36 @@ spdk_iscsi_opts_verify(struct spdk_iscsi_opts *opts)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_iscsi_parse_options(struct spdk_iscsi_opts **popts)
|
||||
{
|
||||
struct spdk_iscsi_opts *opts;
|
||||
struct spdk_conf_section *sp;
|
||||
int rc;
|
||||
|
||||
opts = spdk_iscsi_opts_alloc();
|
||||
if (!opts) {
|
||||
SPDK_ERRLOG("spdk_iscsi_opts_alloc_failed() failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Process parameters */
|
||||
SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "spdk_iscsi_read_config_file_parmas\n");
|
||||
sp = spdk_conf_find_section(NULL, "iSCSI");
|
||||
if (sp != NULL) {
|
||||
rc = spdk_iscsi_read_config_file_params(sp, opts);
|
||||
if (rc != 0) {
|
||||
free(opts);
|
||||
SPDK_ERRLOG("spdk_iscsi_read_config_file_params() failed\n");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
*popts = opts;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_iscsi_set_global_params(struct spdk_iscsi_opts *opts)
|
||||
{
|
||||
@ -659,29 +758,24 @@ spdk_iscsi_set_global_params(struct spdk_iscsi_opts *opts)
|
||||
static int
|
||||
spdk_iscsi_initialize_global_params(void)
|
||||
{
|
||||
struct spdk_conf_section *sp;
|
||||
struct spdk_iscsi_opts opts;
|
||||
int rc;
|
||||
|
||||
spdk_iscsi_opts_init(&opts);
|
||||
|
||||
/* Process parameters */
|
||||
SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "spdk_iscsi_read_config_file_parmas\n");
|
||||
sp = spdk_conf_find_section(NULL, "iSCSI");
|
||||
if (sp != NULL) {
|
||||
rc = spdk_iscsi_read_config_file_params(sp, &opts);
|
||||
if (!g_spdk_iscsi_opts) {
|
||||
rc = spdk_iscsi_parse_options(&g_spdk_iscsi_opts);
|
||||
if (rc != 0) {
|
||||
SPDK_ERRLOG("spdk_iscsi_read_config_file_params() failed\n");
|
||||
SPDK_ERRLOG("spdk_iscsi_parse_options() failed\n");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
rc = spdk_iscsi_set_global_params(&opts);
|
||||
spdk_iscsi_opts_free(&opts);
|
||||
rc = spdk_iscsi_set_global_params(g_spdk_iscsi_opts);
|
||||
if (rc != 0) {
|
||||
SPDK_ERRLOG("spdk_iscsi_set_global_params() failed\n");
|
||||
}
|
||||
|
||||
spdk_iscsi_opts_free(g_spdk_iscsi_opts);
|
||||
g_spdk_iscsi_opts = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -313,6 +313,31 @@ if __name__ == "__main__":
|
||||
p.set_defaults(func=apply_firmware)
|
||||
|
||||
# iSCSI
|
||||
def set_iscsi_options(args):
|
||||
rpc.iscsi.set_iscsi_options(args.client, args)
|
||||
|
||||
p = subparsers.add_parser('set_iscsi_options', help="""Set options of iSCSI subsystem""")
|
||||
p.add_argument('-f', '--auth-file', help='Path to CHAP shared secret file for discovery session')
|
||||
p.add_argument('-b', '--node-base', help='Prefix of the name of iSCSI target node')
|
||||
p.add_argument('-o', '--nop-timeout', help='Timeout in seconds to nop-in request to the initiator', type=int)
|
||||
p.add_argument('-n', '--nop-in-interval', help='Time interval in secs between nop-in requests by the target', type=int)
|
||||
p.add_argument('-d', '--no-discovery-auth', help="""CHAP for discovery session should be disabled.
|
||||
*** Mutually exclusive with --req-discovery-auth""", action='store_true')
|
||||
p.add_argument('-r', '--req-discovery-auth', help="""CHAP for discovery session should be required.
|
||||
*** Mutually exclusive with --no-discovery-auth""", action='store_true')
|
||||
p.add_argument('-m', '--req-discovery-auth-mutual', help='CHAP for discovery session should be mutual', action='store_true')
|
||||
p.add_argument('-g', '--discovery-auth-group', help="""Authentication group ID for discovery session.
|
||||
*** Authentication group must be precreated ***""", type=int)
|
||||
p.add_argument('-a', '--max-sessions', help='Maximum number of sessions in the host.', type=int)
|
||||
p.add_argument('-c', '--max-connections-per-session', help='Negotiated parameter, MaxConnections.', type=int)
|
||||
p.add_argument('-w', '--default-time2wait', help='Negotiated parameter, DefaultTime2Wait.', type=int)
|
||||
p.add_argument('-v', '--default-time2retain', help='Negotiated parameter, DefaultTime2Retain.', type=int)
|
||||
p.add_argument('-i', '--immediate-data', help='Negotiated parameter, ImmediateData.', action='store_true')
|
||||
p.add_argument('-l', '--error-recovery-level', help='Negotiated parameter, ErrorRecoveryLevel', type=int)
|
||||
p.add_argument('-p', '--allow-duplicated-isid', help='Allow duplicated initiator session ID.', action='store_true')
|
||||
p.add_argument('-u', '--min-connections-per-session', help='Allocation unit of connections per core', type=int)
|
||||
p.set_defaults(func=set_iscsi_options)
|
||||
|
||||
@call_cmd
|
||||
def get_portal_groups(args):
|
||||
print_dict(rpc.iscsi.get_portal_groups(args.client, args))
|
||||
|
@ -1,3 +1,41 @@
|
||||
def set_iscsi_options(client, args):
|
||||
params = {}
|
||||
|
||||
if args.auth_file:
|
||||
params['auth_file'] = args.auth_file
|
||||
if args.node_base:
|
||||
params['node_base'] = args.node_base
|
||||
if args.nop_timeout:
|
||||
params['nop_timeout'] = args.nop_timeout
|
||||
if args.nop_in_interval:
|
||||
params['nop_in_interval'] = args.nop_in_interval
|
||||
if args.no_discovery_auth:
|
||||
params['no_discovery_auth'] = args.no_discovery_auth
|
||||
if args.req_discovery_auth:
|
||||
params['req_discovery_auth'] = args.req_discovery_auth
|
||||
if args.req_discovery_auth_mutual:
|
||||
params['req_discovery_auth_mutual'] = args.req_discovery_auth_mutual
|
||||
if args.discovery_auth_group:
|
||||
params['discovery_auth_group'] = args.discovery_auth_group
|
||||
if args.max_sessions:
|
||||
params['max_sessions'] = args.max_sessions
|
||||
if args.max_connections_per_session:
|
||||
params['max_connections_per_session'] = args.max_connections_per_session
|
||||
if args.default_time2wait:
|
||||
params['default_time2wait'] = args.default_time2wait
|
||||
if args.default_time2retain:
|
||||
params['default_time2retain'] = args.default_time2retain
|
||||
if args.immediate_data:
|
||||
params['immediate_data'] = args.immediate_data
|
||||
if args.error_recovery_level:
|
||||
params['error_recovery_level'] = args.error_recovery_level
|
||||
if args.allow_duplicated_isid:
|
||||
params['allow_duplicated_isid'] = args.allow_duplicated_isid
|
||||
if args.min_connections_per_session:
|
||||
params['min_connections_per_session'] = args.min_connections_per_session
|
||||
return client.call('set_iscsi_options', params)
|
||||
|
||||
|
||||
def get_portal_groups(client, args):
|
||||
return client.call('get_portal_groups')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user