If a record has this set to anything other than the default value of 1, performing a login with this record will ensure that at least that number of sessions are present for that recordr: The code counts the number of sessions currently active for this record, and will perform multiple logins if the count is less than nr_sessions.
Copyright (c) 2011 Dell Inc. Signed-off-by: Jim Ramsay <jim_ram...@dell.com> --- etc/iscsid.conf | 5 ++++ usr/config.h | 1 + usr/idbm.c | 3 ++ usr/idbm_fields.h | 1 + usr/iscsi_util.c | 11 ++++++++++ usr/iscsi_util.h | 1 + usr/session_mgmt.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++-- 7 files changed, 74 insertions(+), 3 deletions(-) diff --git a/etc/iscsid.conf b/etc/iscsid.conf index e8087c8..4e8c08d 100644 --- a/etc/iscsid.conf +++ b/etc/iscsid.conf @@ -278,6 +278,11 @@ discovery.sendtargets.iscsi.MaxRecvDataSegmentLength = 32768 # The default is to never use DataDigests or HeaderDigests. # +# For multipath configurations, you may want more than one session to be +# created on each iface record. If node.session.nr_sessions is greater +# than 1, performing a 'login' for that node will ensure that the +# appropriate number of sessions is created. +node.session.nr_sessions = 1 #************ # Workarounds diff --git a/usr/config.h b/usr/config.h index 245e933..1b35d97 100644 --- a/usr/config.h +++ b/usr/config.h @@ -189,6 +189,7 @@ typedef struct session_rec { int cmds_max; int queue_depth; int initial_login_retry_max; + int nr_sessions; struct iscsi_auth_config auth; struct iscsi_session_timeout_config timeo; struct iscsi_error_timeout_config err_timeo; diff --git a/usr/idbm.c b/usr/idbm.c index 99b7308..bc49793 100644 --- a/usr/idbm.c +++ b/usr/idbm.c @@ -248,6 +248,8 @@ idbm_recinfo_node(node_rec_t *r, recinfo_t *ri) session.cmds_max, IDBM_SHOW, num, 1); __recinfo_int(SESSION_QDEPTH, ri, r, session.queue_depth, IDBM_SHOW, num, 1); + __recinfo_int(SESSION_NR_SESSIONS, ri, r, + session.nr_sessions, IDBM_SHOW, num, 1); __recinfo_int_o2(SESSION_AUTH_METHOD, ri, r, session.auth.authmethod, IDBM_SHOW, "None", "CHAP", num, 1); __recinfo_str(SESSION_USERNAME, ri, r, @@ -2425,6 +2427,7 @@ void idbm_node_setup_defaults(node_rec_t *rec) rec->session.xmit_thread_priority = XMIT_THREAD_PRIORITY; rec->session.initial_cmdsn = 0; rec->session.queue_depth = QUEUE_DEPTH; + rec->session.nr_sessions = 1; rec->session.initial_login_retry_max = DEF_INITIAL_LOGIN_RETRIES_MAX; rec->session.reopen_max = 32; rec->session.auth.authmethod = 0; diff --git a/usr/idbm_fields.h b/usr/idbm_fields.h index eaa55d1..824a7a9 100644 --- a/usr/idbm_fields.h +++ b/usr/idbm_fields.h @@ -21,6 +21,7 @@ #define SESSION_CMDS_MAX "node.session.cmds_max" #define SESSION_XMIT_THREAD_PRIORITY "node.session.xmit_thread_priority" #define SESSION_QDEPTH "node.session.queue_depth" +#define SESSION_NR_SESSIONS "node.session.nr_sessions" #define SESSION_AUTH_METHOD "node.session.auth.authmethod" #define SESSION_USERNAME "node.session.auth.username" #define SESSION_PASSWORD "node.session.auth.password" diff --git a/usr/iscsi_util.c b/usr/iscsi_util.c index d7e97f0..6ce6cf3 100644 --- a/usr/iscsi_util.c +++ b/usr/iscsi_util.c @@ -331,3 +331,14 @@ int iscsi_match_session(void *data, struct session_info *info) info->persistent_port, &info->iface, info->sid); } + +int iscsi_match_session_count(void *data, struct session_info *info) +{ + // iscsi_sysfs_for_each_session expects: + // 0==match -1==nomatch >0==error + // but iscsi_match_session returns: + // 1==match 0==nomatch + if (iscsi_match_session(data, info)) + return 0; + return -1; +} diff --git a/usr/iscsi_util.h b/usr/iscsi_util.h index 9428867..13a5eb2 100644 --- a/usr/iscsi_util.h +++ b/usr/iscsi_util.h @@ -14,6 +14,7 @@ extern int increase_max_files(void); extern char *str_to_ipport(char *str, int *port, int *tgpt); extern int iscsi_match_session(void *data, struct session_info *info); +extern int iscsi_match_session_count(void *data, struct session_info *info); extern int __iscsi_match_session(struct node_rec *rec, char *targetname, char *address, int port, struct iface_rec *iface, diff --git a/usr/session_mgmt.c b/usr/session_mgmt.c index afdd077..3546b8e 100644 --- a/usr/session_mgmt.c +++ b/usr/session_mgmt.c @@ -93,18 +93,18 @@ static int iscsid_login_reqs_wait(struct list_head *list) } /** - * iscsi_login_portal - request iscsid to login to portal + * __iscsi_login_portal - request iscsid to login to portal * @data: If set, copies the session.multiple value to the portal record * so it is propagated to iscsid. * @list: If async, list to add session to * @rec: portal rec to log into */ -int iscsi_login_portal(void *data, struct list_head *list, struct node_rec *rec) +static int __iscsi_login_portal(void *data, struct list_head *list, struct node_rec *rec) { struct iscsid_async_req *async_req = NULL; int rc = 0, fd; - if (data) { + if (data && !rec->session.multiple) { struct node_rec *pattern_rec = data; rec->session.multiple = pattern_rec->session.multiple; } @@ -147,6 +147,55 @@ int iscsi_login_portal(void *data, struct list_head *list, struct node_rec *rec) } /** + * iscsi_login_portal - request iscsid to login to portal multiple + * times, based on the session.nr_sessions in the portal record. + * @data: If set, session.multiple will cause an additional session to + * be created regardless of the value of session.nr_sessions + * @list: If async, list to add session to + * @rec: portal rec to log into + */ +int iscsi_login_portal(void *data, struct list_head *list, struct node_rec *rec) +{ + struct node_rec *pattern_rec = data; + int alloc_pattern_rec = 0, rc = 0, session_count = 0, i; + + // If pattern_rec->session.multiple is set, just add a single new + // session by passing things along to __iscsi_login_portal + if (pattern_rec && pattern_rec->session.multiple) { + return __iscsi_login_portal(data, list, rec); + } + + // Count the current number of sessions, and only create those + // that are missing. + rc = iscsi_sysfs_for_each_session(rec, &session_count, iscsi_match_session_count); + if (rc) { + log_error("Could not count current number of sessions"); + goto done; + } + if (session_count >= rec->session.nr_sessions) { + log_debug(1, "%s: %d session%s requested, but %d already present.", + rec->iface.name, + rec->session.nr_sessions, + rec->session.nr_sessions == 1 ? "" : "s", session_count); + rc = 0; + goto done; + } + + // Ensure the record's 'multiple' flag is set so + // __iscsi_login_portal will allow multiple logins. + rec->session.multiple = 1; + for (i = session_count; i < rec->session.nr_sessions; ++i) { + log_debug(1, "%s: Creating session %d/%d", rec->iface.name, i + 1, rec->session.nr_sessions); + int err = __iscsi_login_portal(pattern_rec, list, rec); + if (err && !rc) + rc = err; + } + +done: + return rc; +} + +/** * iscsi_login_portal_nowait - request iscsid to login to portal * @rec: portal rec to log into * -- 1.7.5.3 -- You received this message because you are subscribed to the Google Groups "open-iscsi" group. To post to this group, send email to open-iscsi@googlegroups.com. To unsubscribe from this group, send email to open-iscsi+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/open-iscsi?hl=en.