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.

Reply via email to