[Patch v2 4/4] Add new node.session.nr_sessions config parameter

2011-06-28 Thread Jim Ramsay
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 
---
 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_configauth;
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)
 }
 

[Patch v2 3/4] Add multiple sessions per iface commandline syntax

2011-06-28 Thread Jim Ramsay
This accepts the syntax '-m session -r  -o new' and creates a new
session based on the session selected via the '-r' option, by setting
the 'multiple' flag in the session_rec_t.

Example:

  # iscsiadm -m session
  tcp: [4]  
  # iscsiadm -m session -r 4 -o new
  Logging in to [iface: iface0, target: , portal: ] (multiple)
  Login to [iface: iface0, target: , portal: ] successful.
  # iscsiadm -m session
  tcp: [4]  
  tcp: [5]  

Copyright (c) 2011 Dell Inc.
Signed-off-by: Jim Ramsay 
---
 doc/iscsiadm.8 |5 +++--
 usr/iscsiadm.c |   13 +
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/doc/iscsiadm.8 b/doc/iscsiadm.8
index 53900a9..b41281a 100644
--- a/doc/iscsiadm.8
+++ b/doc/iscsiadm.8
@@ -10,7 +10,7 @@ iscsiadm \- open-iscsi administration utility
 \fBiscsiadm\fR \-m node [ \-hV ] [ \-d debug_level ] [ \-P printlevel ] [ \-L 
all,manual,automatic ] [ \-U all,manual,automatic ] [ \-S ] [ [ \-T targetname 
\-p ip:port \-I iface ] [ \-l | \-u | \-R | \-s] ]
 [ [ \-o operation ]  [ \-n name ] [ \-v value ] [ \-p ip:port ] ]
 
-\fBiscsiadm\fR \-m session [ \-hV ] [ \-d debug_level ] [ \-P printlevel ] [ 
\-r sessionid | sysfsdir [ \-R ] [ \-u | \-s ] ]
+\fBiscsiadm\fR \-m session [ \-hV ] [ \-d debug_level ] [ \-P printlevel ] [ 
\-r sessionid | sysfsdir [ \-R ] [ \-u | \-s | \-o new ] ]
 
 \fBiscsiadm\fR \-m iface [ \-hV ] [ \-d debug_level ] [ \-P printlevel ] [ \-I 
ifacename ] [ [ \-o  operation  ] [ \-n name ] [ \-v value ] ]
 
@@ -154,7 +154,8 @@ record.
 \fIrecid\fR is the target name and portal (IP:port). In iface mode, the 
\fIrecid\fR
 is the iface name. In discovery mode, the \fIrecid\fR is the portal and
 discovery type.
-
+.IP
+In session mode, the \fInew\fR operation logs in a new session using the same 
node database and iface information as the specified session.
 .IP
 In discovery mode, if the \fIrecid\fR and new operation is passed in, but the 
\fI--discover\fR argument is not, then iscsiadm will only create a discovery 
record (it will not perform discovery). If the \fI--discover\fR argument is 
passed in with the portal and discovery type, then iscsiadm will create the 
discovery record if needed, and it will create records for portals returned by 
the target that do not yet have a node DB record.
 .IP
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index 45b4c00..916042f 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -2154,6 +2154,14 @@ main(int argc, char **argv)
rec->session.info = info;
rec->session.sid = sid;
 
+   // a "new" session means to login a multiple of the
+   // currently-detected session.
+   if (op == OP_NEW) {
+   op = OP_NOOP;
+   do_login = 1;
+   rec->session.multiple = 1;
+   }
+
/* drop down to node ops */
rc = exec_node_op(op, do_login, do_logout, do_show,
  do_rescan, do_stats, info_level,
@@ -2162,6 +2170,11 @@ free_info:
free(info);
goto out;
} else {
+   if (op == OP_NEW) {
+   log_error("session mode: Operation 'new' only 
allowed with specific session IDs");
+   rc = ISCSI_ERR_INVAL;
+   goto out;
+   }
if (do_logout || do_rescan || do_stats) {
rc = exec_node_op(op, do_login, do_logout,
 do_show, do_rescan, do_stats,
-- 
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.



[Patch v2 1/4] Add specific session information to session_rec_t

2011-06-28 Thread Jim Ramsay
This is populated by iscsiadm in 'session' mode when the '-r' options is
given, and passed along in the session_rec_t.  It limits the operation
of exec_node_op to only the specific session specified by the user.

This is a prerequisite for "multiple sessions per iface recond".

Copyright (c) 2011 Dell Inc.
Signed-off-by: Jim Ramsay 
---
 usr/config.h |2 ++
 usr/idbm.c   |5 -
 usr/initiator.c  |3 ++-
 usr/iscsi_util.c |   18 --
 usr/iscsi_util.h |5 -
 usr/iscsiadm.c   |   19 ++-
 6 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/usr/config.h b/usr/config.h
index 5cb4d56..579c8ec 100644
--- a/usr/config.h
+++ b/usr/config.h
@@ -193,6 +193,8 @@ typedef struct session_rec {
struct iscsi_session_timeout_config timeo;
struct iscsi_error_timeout_config   err_timeo;
struct iscsi_session_operational_config iscsi;
+   struct session_info*info;
+   unsignedsid;
 } session_rec_t;
 
 #define ISCSI_TRANSPORT_NAME_MAXLEN 16
diff --git a/usr/idbm.c b/usr/idbm.c
index 2cb346d..7e10929 100644
--- a/usr/idbm.c
+++ b/usr/idbm.c
@@ -2435,6 +2435,8 @@ void idbm_node_setup_defaults(node_rec_t *rec)
rec->session.err_timeo.tgt_reset_timeout = DEF_TGT_RESET_TIMEO;
rec->session.err_timeo.host_reset_timeout = DEF_HOST_RESET_TIMEO;
rec->session.timeo.replacement_timeout = DEF_REPLACEMENT_TIMEO;
+   rec->session.info = NULL;
+   rec->session.sid = 0;
idbm_setup_session_defaults(&rec->session.iscsi);
 
for (i=0; inrec.name,
 session->nrec.conn[0].address,
 session->nrec.conn[0].port,
-&session->nrec.iface))
+&session->nrec.iface,
+MATCH_ANY_SID))
return session;
}
}
diff --git a/usr/iscsi_util.c b/usr/iscsi_util.c
index 4481294..d7e97f0 100644
--- a/usr/iscsi_util.c
+++ b/usr/iscsi_util.c
@@ -33,6 +33,7 @@
 #include "iscsi_settings.h"
 #include "iface.h"
 #include "session_info.h"
+#include "iscsi_util.h"
 
 void daemon_init(void)
 {
@@ -285,24 +286,28 @@ free_res1:
 }
 
 int __iscsi_match_session(node_rec_t *rec, char *targetname,
- char *address, int port, struct iface_rec *iface)
+ char *address, int port, struct iface_rec *iface,
+ unsigned sid)
 {
if (!rec) {
log_debug(6, "no rec info to match\n");
return 1;
}
 
-   log_debug(6, "match session [%s,%s,%d][%s %s,%s,%s]",
+   log_debug(6, "match session [%s,%s,%d][%s %s,%s,%s]:%u",
  rec->name, rec->conn[0].address, rec->conn[0].port,
  rec->iface.name, rec->iface.transport_name,
- rec->iface.hwaddress, rec->iface.ipaddress);
+ rec->iface.hwaddress, rec->iface.ipaddress,
+ rec->session.sid);
 
if (iface)
-   log_debug(6, "to [%s,%s,%d][%s %s,%s,%s]",
+   log_debug(6, "to [%s,%s,%d][%s %s,%s,%s]:%u",
  targetname, address, port, iface->name,
  iface->transport_name, iface->hwaddress,
- iface->ipaddress);
+ iface->ipaddress, sid);
 
+   if (rec->session.sid && sid && rec->session.sid != sid)
+   return 0;
 
if (strlen(rec->name) && strcmp(rec->name, targetname))
return 0;
@@ -323,5 +328,6 @@ int iscsi_match_session(void *data, struct session_info 
*info)
 {
return __iscsi_match_session(data, info->targetname,
 info->persistent_address,
-info->persistent_port, &info->iface);
+info->persistent_port, &info->iface,
+info->sid);
 }
diff --git a/usr/iscsi_util.h b/usr/iscsi_util.h
index 87b2bb2..9428867 100644
--- a/usr/iscsi_util.h
+++ b/usr/iscsi_util.h
@@ -16,7 +16,10 @@ 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(struct node_rec *rec, char *targetname,
 char *address, int port,
-struct iface_rec *iface);
+struct iface_rec *iface,
+unsigned sid);
+
+#define MATCH_ANY_SID 0
 
 extern char *strstrip(char *s);
 extern char *cfg_get_string_param(char *pathname, const char *key);
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index e3a6b81..937b99e 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -292,7 +292,12 @@ for_each_session(struct node_rec *rec, 
iscsi_

[Patch v2 2/4] Add support for multiple sessions per iface to iscsid

2011-06-28 Thread Jim Ramsay
This introduces a new 'multiple' flag to the session_rec_t, which if set
instructs iscsid to bypass the check which would normally prevent
multiple sessions from a single iface record, allowing multiple sessions
to be created.

The commandline syntax to actually set this flag will be introduced in a
later commit.

Copyright (c) 2011 Dell Inc.
Signed-off-by: Jim Ramsay 
---
 usr/config.h   |3 +++
 usr/idbm.c |1 +
 usr/initiator.c|8 ++--
 usr/iscsiadm.c |2 +-
 usr/session_mgmt.c |   13 ++---
 5 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/usr/config.h b/usr/config.h
index 579c8ec..245e933 100644
--- a/usr/config.h
+++ b/usr/config.h
@@ -195,6 +195,9 @@ typedef struct session_rec {
struct iscsi_session_operational_config iscsi;
struct session_info*info;
unsignedsid;
+   /* This is a flag passed to iscsid.  If set, multiple sessions are
+* allowed to be initiated on this record */
+   unsigned char   multiple;
 } session_rec_t;
 
 #define ISCSI_TRANSPORT_NAME_MAXLEN 16
diff --git a/usr/idbm.c b/usr/idbm.c
index 7e10929..99b7308 100644
--- a/usr/idbm.c
+++ b/usr/idbm.c
@@ -2437,6 +2437,7 @@ void idbm_node_setup_defaults(node_rec_t *rec)
rec->session.timeo.replacement_timeout = DEF_REPLACEMENT_TIMEO;
rec->session.info = NULL;
rec->session.sid = 0;
+   rec->session.multiple = 0;
idbm_setup_session_defaults(&rec->session.iscsi);
 
for (i=0; isession.multiple)
+   log_debug(2, "Adding a new multiple of an existing 
session");
+   else
+   return ISCSI_ERR_SESS_EXISTS;
+   }
 
t = iscsi_sysfs_get_transport_by_name(rec->iface.transport_name);
if (!t)
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index 937b99e..45b4c00 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -522,7 +522,7 @@ static int login_portals(struct node_rec *pattern_rec)
rc = err;
/* if there is an err but some recs then try to login to what we have */
 
-   err = iscsi_login_portals(NULL, &nr_found, 1, &rec_list,
+   err = iscsi_login_portals(pattern_rec, &nr_found, 1, &rec_list,
  iscsi_login_portal);
if (err)
log_error("Could not log into all portals");
diff --git a/usr/session_mgmt.c b/usr/session_mgmt.c
index 0bfa205..afdd077 100644
--- a/usr/session_mgmt.c
+++ b/usr/session_mgmt.c
@@ -94,7 +94,8 @@ static int iscsid_login_reqs_wait(struct list_head *list)
 
 /**
  * iscsi_login_portal - request iscsid to login to portal
- * @data: Unused. Only needed so this can be used in iscsi_login_portals
+ * @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
  */
@@ -103,9 +104,15 @@ 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;
 
-   log_info("Logging in to [iface: %s, target: %s, portal: %s,%d]",
+   if (data) {
+   struct node_rec *pattern_rec = data;
+   rec->session.multiple = pattern_rec->session.multiple;
+   }
+
+   log_info("Logging in to [iface: %s, target: %s, portal: %s,%d]%s",
 rec->iface.name, rec->name, rec->conn[0].address,
-rec->conn[0].port);
+rec->conn[0].port,
+(rec->session.multiple ? " (multiple)" : ""));
 
if (list) {
async_req = calloc(1, sizeof(*async_req));
-- 
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.



Re: Multiple sessions per iface record

2011-06-28 Thread Jim Ramsay
On Mon, Jun 27, 2011 at 10:31:06PM -0500, Mike Christie wrote:
> On 06/27/2011 02:19 PM, Jim Ramsay wrote:
> > This patchset introduces a new commandline syntax that takes an existing 
> > iSCSI
> > session and creates a new session, using exactly the same node, portal, and
> > iface record as the specified session.  This uses the 'new' operation in the
> > 'session' mode, a syntax which was previously allowed but had no real 
> > purpose.
> > 
> > Example:
> >  # iscsiadm -m session
> >  tcp: [4]  
> >  # iscsiadm -m session -r 4 -o new
> >  Logging in to [iface: iface0, target: , portal: ] 
> > (multiple)
> >  Login to [iface: iface0, target: , portal: ] successful.
> >  # iscsiadm -m session
> >  tcp: [4]  
> >  tcp: [5]  
> > 
> 
> Thanks for your work on this. I think this is a good feature to add. One
> question I have is how will this work for distros and on reboots? Users
> do not want to have to run the iscsiadm -m session ... -o new command
> every reboot, and users do not want to have to add in their own script
> to run during boot. It should be nicely integrated by the distros I mean.
> 
> I think we could add a iscsid.conf/db setting for this. We can add a new
> setting:
> 
> node.session.nr_sessions = N
> 
> where N is int and 1 by default.
> 
> When the iscsiadm login command is run then it will read this value that
> is stored in the:
> 
> /etc/iscsi/nodes/iqn.2001-08.com.sometarget/20.15.0.23,3260,1/ifaceX
> 
> file with the other settings and then create that number of sessions.
> 
> User can then set that value in iscsid.conf or for specific
> iface,target,portal recs like other settings.

An excellent suggestion.  I am sending v2 of my patchset which now
contains this 'node.sessions.nr_sessions' feature as well, implemented as you
suggested.

This v2 patchset also rebases the changes to the current git HEAD, and fixes a
segfault I found in my first set of changes.

-- 
Jim Ramsay

-- 
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.