Divide node parameters into 3 categories:
  a. Immutable - properties that are not allowed to change at all.
  b. Immediate - properties that are allowed to change and take effect 
immediately.
  c. Deferred  - properties that are allowed to be changed only while
                 session is not active (or when using -f flag).
                 The change will take effect only next session.

Add -f flag (force) to iscsiadm when changing node parameters
that are defined as ATTR_DEFERRED.

When using this flag, changing of ATTR_DEFERRED parameter
while in active session is allowed.
The change itself will take effect only in the next session.
A warning message will be displayed.

Signed-off-by: Doron Shoham <[EMAIL PROTECTED]>
---
 README         |   12 +++--
 doc/iscsiadm.8 |   10 +++-
 usr/idbm.c     |  166 ++++++++++++++++++++++++++++++--------------------------
 usr/idbm.h     |   21 +++++--
 usr/iscsiadm.c |   47 +++++++++++-----
 5 files changed, 152 insertions(+), 104 deletions(-)

diff --git a/README b/README
index 21f961a..386d711 100644
--- a/README
+++ b/README
@@ -277,13 +277,14 @@ Usage: iscsiadm [OPTION]
                          Nodes marked as ONBOOT are skipped.
   -m session              display all active sessions and connections
   -m session --sid=[sid] [ --print=level | --rescan | --logout ]
-                               --op=[op] [--name=[name] --value=[value]]
+                               --op=[op] [--name=[name] --value=[value] 
--force]
                           perform operation for specific session with
                           session id sid. If no sid is given the operation
                          will be performed on all running sessions if possible.
                          --logout and --op work like they do in node mode,
                          but in session mode targetname and portal info is
-                         is not passed in.
+                         is not passed in. --force allows changing node 
deferred
+                         parameters while session is active.
 
                          Print level can be 0 to 2.
                          1 = Print basic session info like node we are
@@ -292,10 +293,11 @@ Usage: iscsiadm [OPTION]
                          3 = Print SCSI info like LUNs, device state.
                          If no sid and no operation is given print out the
                          running sessions.
-  -m iface --interface=iscsi_ifacename --op=[op] [--name=[name] 
--value=[value]]
+  -m iface --interface=iscsi_ifacename --op=[op] [--name=[name] 
--value=[value] --force ]
                                --print=level
-                         perform operation on fiven interface with name
-                         iscsi_ifacename.
+                         perform operation on given interface with name
+                         iscsi_ifacename. --force allows changing node deferred
+                         parameters while session is active.
 
                          See below for examples.
   -d, --debug debuglevel  print debugging information
diff --git a/doc/iscsiadm.8 b/doc/iscsiadm.8
index 11f49e2..e8ea94b 100644
--- a/doc/iscsiadm.8
+++ b/doc/iscsiadm.8
@@ -6,11 +6,11 @@ iscsiadm \- open-iscsi administration utility
 [ -o operation ] [ -n name ] [ -v value ]
 
 \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 ] ]
+[ [ -o operation ]  [ -n name ] [ -v value ] [ -p ip:port ] [ -f ] ]
 
 \fBiscsiadm\fR -m session [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -r 
sessionid | sysfsdir [ -R ] [ -u | -s ] ]
 
-\fBiscsiadm\fR -m iface [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -I 
ifacename ] [ [ -o  operation  ] [ -n name ] [ -v value ] ]
+\fBiscsiadm\fR -m iface [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -I 
ifacename ] [ [ -o  operation  ] [ -n name ] [ -v value ] [ -f ] ]
 
 \fBiscsiadm\fR -m fw [-l]
 
@@ -41,6 +41,12 @@ daemon (iscsid) be running.
 print debugging information. Valid values for debug_level are 0 to 8.
 
 .TP
+\fB\-f\fR, \fB\-\-force\fR
+Force update operation, allows changing node deferred parameters while session 
is active. 
+For use with the \fIupdate\fR operator.
+.IP
+
+.TP
 \fB\-h\fR, \fB\-\-help\fR
 display help text and exit
 
diff --git a/usr/idbm.c b/usr/idbm.c
index c76bed6..7e078e8 100644
--- a/usr/idbm.c
+++ b/usr/idbm.c
@@ -205,47 +205,47 @@ idbm_recinfo_discovery(discovery_rec_t *r, recinfo_t *ri)
        int num = 0;
 
        __recinfo_int_o2("discovery.startup", ri, r, startup, IDBM_SHOW,
-                       "manual", "automatic", num, 1);
+                       "manual", "automatic", num, ATTR_DEFERRED);
        __recinfo_int_o6("discovery.type", ri, r, type, IDBM_SHOW,
                        "sendtargets", "offload_send_targets", "slp", "isns",
-                       "static", "fw", num, 0);
+                       "static", "fw", num, ATTR_IMMUTABLE);
        if (r->type == DISCOVERY_TYPE_SENDTARGETS) {
                __recinfo_str("discovery.sendtargets.address", ri, r,
-                       address, IDBM_SHOW, num, 0);
+                       address, IDBM_SHOW, num, ATTR_IMMUTABLE);
                __recinfo_int("discovery.sendtargets.port", ri, r,
-                       port, IDBM_SHOW, num, 0);
+                       port, IDBM_SHOW, num, ATTR_IMMUTABLE);
                __recinfo_int_o2("discovery.sendtargets.auth.authmethod", ri, r,
                        u.sendtargets.auth.authmethod,
-                       IDBM_SHOW, "None", "CHAP", num, 1);
+                       IDBM_SHOW, "None", "CHAP", num, ATTR_DEFERRED);
                __recinfo_str("discovery.sendtargets.auth.username", ri, r,
-                       u.sendtargets.auth.username, IDBM_SHOW, num, 1);
+                       u.sendtargets.auth.username, IDBM_SHOW, num, 
ATTR_DEFERRED);
                __recinfo_str("discovery.sendtargets.auth.password", ri, r,
-                       u.sendtargets.auth.password, IDBM_MASKED, num, 1);
+                       u.sendtargets.auth.password, IDBM_MASKED, num, 
ATTR_DEFERRED);
                __recinfo_int("discovery.sendtargets.auth.password_length",
                        ri, r, u.sendtargets.auth.password_length,
-                       IDBM_HIDE, num, 1);
+                       IDBM_HIDE, num, ATTR_DEFERRED);
                __recinfo_str("discovery.sendtargets.auth.username_in", ri, r,
-                       u.sendtargets.auth.username_in, IDBM_SHOW, num, 1);
+                       u.sendtargets.auth.username_in, IDBM_SHOW, num, 
ATTR_DEFERRED);
                __recinfo_str("discovery.sendtargets.auth.password_in", ri, r,
-                       u.sendtargets.auth.password_in, IDBM_MASKED, num, 1);
+                       u.sendtargets.auth.password_in, IDBM_MASKED, num, 
ATTR_DEFERRED);
                __recinfo_int("discovery.sendtargets.auth.password_in_length",
                        ri, r, u.sendtargets.auth.password_in_length,
-                       IDBM_HIDE, num, 1);
+                       IDBM_HIDE, num, ATTR_DEFERRED);
                __recinfo_int("discovery.sendtargets.timeo.login_timeout",ri, r,
                        u.sendtargets.conn_timeo.login_timeout,
-                       IDBM_SHOW, num, 1);
+                       IDBM_SHOW, num, ATTR_IMMEDIATE);
                __recinfo_int("discovery.sendtargets.reopen_max",ri, r,
                        u.sendtargets.reopen_max,
-                       IDBM_SHOW, num, 1);
+                       IDBM_SHOW, num, ATTR_DEFERRED);
                __recinfo_int("discovery.sendtargets.timeo.auth_timeout", ri, r,
                        u.sendtargets.conn_timeo.auth_timeout,
-                       IDBM_SHOW, num, 1);
+                       IDBM_SHOW, num, ATTR_IMMEDIATE);
                __recinfo_int("discovery.sendtargets.timeo.active_timeout",ri,r,
                              u.sendtargets.conn_timeo.active_timeout,
-                             IDBM_SHOW, num, 1);
+                             IDBM_SHOW, num, ATTR_IMMEDIATE);
                
__recinfo_int("discovery.sendtargets.iscsi.MaxRecvDataSegmentLength",
                        ri, r, u.sendtargets.iscsi.MaxRecvDataSegmentLength,
-                       IDBM_SHOW, num, 1);
+                       IDBM_SHOW, num, ATTR_DEFERRED);
        }
 }
 
@@ -254,10 +254,10 @@ idbm_recinfo_node(node_rec_t *r, recinfo_t *ri)
 {
        int num = 0, i;
 
-       __recinfo_str("node.name", ri, r, name, IDBM_SHOW, num, 0);
-       __recinfo_int("node.tpgt", ri, r, tpgt, IDBM_SHOW, num, 0);
+       __recinfo_str("node.name", ri, r, name, IDBM_SHOW, num, ATTR_IMMUTABLE);
+       __recinfo_int("node.tpgt", ri, r, tpgt, IDBM_SHOW, num, ATTR_IMMUTABLE);
        __recinfo_int_o3("node.startup", ri, r, startup,
-                       IDBM_SHOW, "manual", "automatic", "onboot", num, 1);
+                       IDBM_SHOW, "manual", "automatic", "onboot", num, 
ATTR_DEFERRED);
        /*
         * Note: because we do not add the iface.iscsi_ifacename to
         * sysfs iscsiadm does some weird matching. We can change the iface
@@ -270,135 +270,135 @@ idbm_recinfo_node(node_rec_t *r, recinfo_t *ri)
         * needs some locking).
         */
        __recinfo_str("iface.hwaddress", ri, r, iface.hwaddress, IDBM_SHOW,
-                     num, 1);
+                     num, ATTR_DEFERRED);
 //     __recinfo_str("iface.ipaddress", ri, r, iface.ipaddress,
 //                  IDBM_SHOW, num);
        __recinfo_str("iface.iscsi_ifacename", ri, r, iface.name, IDBM_SHOW,
-                     num, 1);
+                     num, ATTR_DEFERRED);
        __recinfo_str("iface.net_ifacename", ri, r, iface.netdev, IDBM_SHOW,
-                     num, 1);
+                     num, ATTR_DEFERRED);
        /*
         * svn 780 compat: older versions used node.transport_name and
         * rec->transport_name
         */
        __recinfo_str("iface.transport_name", ri, r, iface.transport_name,
-                     IDBM_SHOW, num, 1);
+                     IDBM_SHOW, num, ATTR_DEFERRED);
        __recinfo_str("node.discovery_address", ri, r, disc_address, IDBM_SHOW,
-                     num, 0);
+                     num, ATTR_IMMUTABLE);
        __recinfo_int("node.discovery_port", ri, r, disc_port, IDBM_SHOW,
-                     num, 0);
+                     num, ATTR_IMMUTABLE);
        __recinfo_int_o6("node.discovery_type", ri, r, disc_type,
                         IDBM_SHOW, "send_targets", "offload_send_targets",
-                        "slp", "isns", "static", "fw", num, 0);
+                        "slp", "isns", "static", "fw", num, ATTR_IMMUTABLE);
        __recinfo_int("node.session.initial_cmdsn", ri, r,
-                     session.initial_cmdsn, IDBM_SHOW, num, 1);
+                     session.initial_cmdsn, IDBM_SHOW, num, ATTR_DEFERRED);
        __recinfo_int("node.session.initial_login_retry_max", ri, r,
-                     session.initial_login_retry_max, IDBM_SHOW, num, 1);
+                     session.initial_login_retry_max, IDBM_SHOW, num, 
ATTR_DEFERRED);
        __recinfo_int("node.session.cmds_max", ri, r,
-                     session.cmds_max, IDBM_SHOW, num, 1);
+                     session.cmds_max, IDBM_SHOW, num, ATTR_DEFERRED);
        __recinfo_int("node.session.queue_depth", ri, r,
-                      session.queue_depth, IDBM_SHOW, num, 1);
+                      session.queue_depth, IDBM_SHOW, num, ATTR_DEFERRED);
        __recinfo_int_o2("node.session.auth.authmethod", ri, r,
-               session.auth.authmethod, IDBM_SHOW, "None", "CHAP", num, 1);
+               session.auth.authmethod, IDBM_SHOW, "None", "CHAP", num, 
ATTR_DEFERRED);
        __recinfo_str("node.session.auth.username", ri, r,
-                     session.auth.username, IDBM_SHOW, num, 1);
+                     session.auth.username, IDBM_SHOW, num, ATTR_DEFERRED);
        __recinfo_str("node.session.auth.password", ri, r,
-                     session.auth.password, IDBM_MASKED, num, 1);
+                     session.auth.password, IDBM_MASKED, num, ATTR_DEFERRED);
        __recinfo_int("node.session.auth.password_length", ri, r,
-                     session.auth.password_length, IDBM_HIDE, num, 1);
+                     session.auth.password_length, IDBM_HIDE, num, 
ATTR_DEFERRED);
        __recinfo_str("node.session.auth.username_in", ri, r,
-                     session.auth.username_in, IDBM_SHOW, num, 1);
+                     session.auth.username_in, IDBM_SHOW, num, ATTR_DEFERRED);
        __recinfo_str("node.session.auth.password_in", ri, r,
-                     session.auth.password_in, IDBM_MASKED, num, 1);
+                     session.auth.password_in, IDBM_MASKED, num, 
ATTR_DEFERRED);
        __recinfo_int("node.session.auth.password_in_length", ri, r,
-                     session.auth.password_in_length, IDBM_HIDE, num, 1);
+                     session.auth.password_in_length, IDBM_HIDE, num, 
ATTR_DEFERRED);
        __recinfo_int("node.session.timeo.replacement_timeout", ri, r,
                      session.timeo.replacement_timeout,
-                     IDBM_SHOW, num, 1);
+                     IDBM_SHOW, num, ATTR_IMMEDIATE);
        __recinfo_int("node.session.err_timeo.abort_timeout", ri, r,
                      session.err_timeo.abort_timeout,
-                     IDBM_SHOW, num, 1);
+                     IDBM_SHOW, num, ATTR_IMMEDIATE);
        __recinfo_int("node.session.err_timeo.lu_reset_timeout", ri, r,
                      session.err_timeo.lu_reset_timeout,
-                     IDBM_SHOW, num, 1);
+                     IDBM_SHOW, num, ATTR_IMMEDIATE);
        __recinfo_int("node.session.err_timeo.host_reset_timeout", ri, r,
                      session.err_timeo.host_reset_timeout,
-                     IDBM_SHOW, num, 1);
+                     IDBM_SHOW, num, ATTR_IMMEDIATE);
        __recinfo_int_o2("node.session.iscsi.FastAbort", ri, r,
                         session.iscsi.FastAbort, IDBM_SHOW, "No", "Yes",
-                        num, 1);
+                        num, ATTR_DEFERRED);
        __recinfo_int_o2("node.session.iscsi.InitialR2T", ri, r,
                         session.iscsi.InitialR2T, IDBM_SHOW,
-                       "No", "Yes", num, 1);
+                       "No", "Yes", num, ATTR_DEFERRED);
        __recinfo_int_o2("node.session.iscsi.ImmediateData",
                         ri, r, session.iscsi.ImmediateData, IDBM_SHOW,
-                       "No", "Yes", num, 1);
+                       "No", "Yes", num, ATTR_DEFERRED);
        __recinfo_int("node.session.iscsi.FirstBurstLength", ri, r,
-                     session.iscsi.FirstBurstLength, IDBM_SHOW, num, 1);
+                     session.iscsi.FirstBurstLength, IDBM_SHOW, num, 
ATTR_DEFERRED);
        __recinfo_int("node.session.iscsi.MaxBurstLength", ri, r,
-                     session.iscsi.MaxBurstLength, IDBM_SHOW, num, 1);
+                     session.iscsi.MaxBurstLength, IDBM_SHOW, num, 
ATTR_DEFERRED);
        __recinfo_int("node.session.iscsi.DefaultTime2Retain", ri, r,
-                     session.iscsi.DefaultTime2Retain, IDBM_SHOW, num, 1);
+                     session.iscsi.DefaultTime2Retain, IDBM_SHOW, num, 
ATTR_DEFERRED);
        __recinfo_int("node.session.iscsi.DefaultTime2Wait", ri, r,
-                     session.iscsi.DefaultTime2Wait, IDBM_SHOW, num, 1);
+                     session.iscsi.DefaultTime2Wait, IDBM_SHOW, num, 
ATTR_DEFERRED);
        __recinfo_int("node.session.iscsi.MaxConnections", ri, r,
-                     session.iscsi.MaxConnections, IDBM_SHOW, num, 1);
+                     session.iscsi.MaxConnections, IDBM_SHOW, num, 
ATTR_DEFERRED);
        __recinfo_int("node.session.iscsi.MaxOutstandingR2T", ri, r,
-                     session.iscsi.MaxOutstandingR2T, IDBM_SHOW, num, 1);
+                     session.iscsi.MaxOutstandingR2T, IDBM_SHOW, num, 
ATTR_DEFERRED);
        __recinfo_int("node.session.iscsi.ERL", ri, r,
-                     session.iscsi.ERL, IDBM_SHOW, num, 1);
+                     session.iscsi.ERL, IDBM_SHOW, num, ATTR_DEFERRED);
 
        for (i = 0; i < ISCSI_CONN_MAX; i++) {
                char key[NAME_MAXVAL];
 
                sprintf(key, "node.conn[%d].address", i);
-               __recinfo_str(key, ri, r, conn[i].address, IDBM_SHOW, num, 0);
+               __recinfo_str(key, ri, r, conn[i].address, IDBM_SHOW, num, 
ATTR_IMMUTABLE);
                sprintf(key, "node.conn[%d].port", i);
-               __recinfo_int(key, ri, r, conn[i].port, IDBM_SHOW, num, 0);
+               __recinfo_int(key, ri, r, conn[i].port, IDBM_SHOW, num, 
ATTR_IMMUTABLE);
                sprintf(key, "node.conn[%d].startup", i);
                __recinfo_int_o3(key, ri, r, conn[i].startup, IDBM_SHOW,
-                                "manual", "automatic", "onboot", num, 1);
+                                "manual", "automatic", "onboot", num, 
ATTR_DEFERRED);
                sprintf(key, "node.conn[%d].tcp.window_size", i);
                __recinfo_int(key, ri, r, conn[i].tcp.window_size,
-                             IDBM_SHOW, num, 1);
+                             IDBM_SHOW, num, ATTR_DEFERRED);
                sprintf(key, "node.conn[%d].tcp.type_of_service", i);
                __recinfo_int(key, ri, r, conn[i].tcp.type_of_service,
-                               IDBM_SHOW, num, 1);
+                               IDBM_SHOW, num, ATTR_DEFERRED);
                sprintf(key, "node.conn[%d].timeo.logout_timeout", i);
                __recinfo_int(key, ri, r, conn[i].timeo.logout_timeout,
-                               IDBM_SHOW, num, 1);
+                               IDBM_SHOW, num, ATTR_IMMEDIATE);
                sprintf(key, "node.conn[%d].timeo.login_timeout", i);
                __recinfo_int(key, ri, r, conn[i].timeo.login_timeout,
-                               IDBM_SHOW, num, 1);
+                               IDBM_SHOW, num, ATTR_IMMEDIATE);
                sprintf(key, "node.conn[%d].timeo.auth_timeout", i);
                __recinfo_int(key, ri, r, conn[i].timeo.auth_timeout,
-                               IDBM_SHOW, num, 1);
+                               IDBM_SHOW, num, ATTR_IMMEDIATE);
 
                sprintf(key, "node.conn[%d].timeo.noop_out_interval", i);
                __recinfo_int(key, ri, r, conn[i].timeo.noop_out_interval,
-                               IDBM_SHOW, num, 1);
+                               IDBM_SHOW, num, ATTR_IMMEDIATE);
                sprintf(key, "node.conn[%d].timeo.noop_out_timeout", i);
                __recinfo_int(key, ri, r, conn[i].timeo.noop_out_timeout,
-                               IDBM_SHOW, num, 1);
+                               IDBM_SHOW, num, ATTR_IMMEDIATE);
 
                sprintf(key, "node.conn[%d].iscsi.MaxRecvDataSegmentLength", i);
                __recinfo_int(key, ri, r,
                        conn[i].iscsi.MaxRecvDataSegmentLength, IDBM_SHOW,
-                       num, 1);
+                       num, ATTR_DEFERRED);
                sprintf(key, "node.conn[%d].iscsi.HeaderDigest", i);
                __recinfo_int_o4(key, ri, r, conn[i].iscsi.HeaderDigest,
                                 IDBM_SHOW, "None", "CRC32C", "CRC32C,None",
-                                "None,CRC32C", num, 1);
+                                "None,CRC32C", num, ATTR_DEFERRED);
                sprintf(key, "node.conn[%d].iscsi.DataDigest", i);
                __recinfo_int_o4(key, ri, r, conn[i].iscsi.DataDigest, 
IDBM_SHOW,
                                 "None", "CRC32C", "CRC32C,None",
-                                "None,CRC32C", num, 1);
+                                "None,CRC32C", num, ATTR_DEFERRED);
                sprintf(key, "node.conn[%d].iscsi.IFMarker", i);
                __recinfo_int_o2(key, ri, r, conn[i].iscsi.IFMarker, IDBM_SHOW,
-                               "No", "Yes", num, 1);
+                               "No", "Yes", num, ATTR_DEFERRED);
                sprintf(key, "node.conn[%d].iscsi.OFMarker", i);
                __recinfo_int_o2(key, ri, r, conn[i].iscsi.OFMarker, IDBM_SHOW,
-                               "No", "Yes", num, 1);
+                               "No", "Yes", num, ATTR_DEFERRED);
        }
 }
 
@@ -407,12 +407,12 @@ idbm_recinfo_iface(iface_rec_t *r, recinfo_t *ri)
 {
        int num = 0;
 
-       __recinfo_str("iface.iscsi_ifacename", ri, r, name, IDBM_SHOW, num, 0);
-       __recinfo_str("iface.net_ifacename", ri, r, netdev, IDBM_SHOW, num, 1);
+       __recinfo_str("iface.iscsi_ifacename", ri, r, name, IDBM_SHOW, num, 
ATTR_IMMUTABLE);
+       __recinfo_str("iface.net_ifacename", ri, r, netdev, IDBM_SHOW, num, 
ATTR_DEFERRED);
 //     __recinfo_str("iface.ipaddress", ri, r, ipaddress, IDBM_SHOW, num, 1);
-       __recinfo_str("iface.hwaddress", ri, r, hwaddress, IDBM_SHOW, num, 1);
+       __recinfo_str("iface.hwaddress", ri, r, hwaddress, IDBM_SHOW, num, 
ATTR_DEFERRED);
        __recinfo_str("iface.transport_name", ri, r, transport_name,
-                     IDBM_SHOW, num, 1);
+                     IDBM_SHOW, num, ATTR_DEFERRED);
 }
 
 static recinfo_t*
@@ -579,7 +579,7 @@ updated:
 /*
  * TODO: we can also check for valid values here.
  */
-static int idbm_verify_param(recinfo_t *info, char *name)
+static int idbm_verify_param(recinfo_t *info, char *name, session_state_e 
state)
 {
        int i;
 
@@ -588,11 +588,22 @@ static int idbm_verify_param(recinfo_t *info, char *name)
                        continue;
 
                log_debug(7, "verify %s %d\n", name, info[i].can_modify);
-               if (info[i].can_modify)
+               if (info[i].can_modify == ATTR_IMMEDIATE)
                        return 0;
-               else {
-                       log_error("Cannot modify %s. It is used to look up "
-                                 "the record and cannot be changed.", name);
+               else if (info[i].can_modify == ATTR_DEFERRED) {
+                       if (state == SESSION_NOT_ACTIVE)
+                               return 0;
+                       else if (state == SESSION_ACTIVE) {
+                               log_error("Cannot modify %s. Please logout 
before modifing it", name);
+                               return EINVAL;
+                       } else if (state == SESSION_FORCE_CHANGE) {
+                               log_warning("Modify %s while in active session. 
"
+                                       "Changes will take effect only in the 
next login", name);
+                               return 0;
+                       }
+               } else if (info[i].can_modify == ATTR_IMMUTABLE) {
+                       log_error("Cannot modify %s. This value is immutable "
+                       "and cannot be modified", name);
                        return EINVAL;
                }
        }
@@ -1022,7 +1033,7 @@ int iface_conf_update(idbm_t *db, struct db_set_param 
*param,
                return ENOMEM;
 
        idbm_recinfo_iface(iface, info);
-       rc = idbm_verify_param(info, param->name);
+       rc = idbm_verify_param(info, param->name, param->state);
        if (rc)
                goto free_info;
 
@@ -2657,6 +2668,7 @@ int idbm_node_set_param(idbm_t *db, void *data, 
node_rec_t *rec)
        struct db_set_param *param = data;
        recinfo_t *info;
        int rc = 0;
+       session_state_e state = param->state;
 
        info = idbm_recinfo_alloc(MAX_KEYS);
        if (!info)
@@ -2664,7 +2676,7 @@ int idbm_node_set_param(idbm_t *db, void *data, 
node_rec_t *rec)
 
        idbm_recinfo_node(rec, info);
 
-       rc = idbm_verify_param(info, param->name);
+       rc = idbm_verify_param(info, param->name, state);
        if (rc)
                goto free_info;
        /*
diff --git a/usr/idbm.h b/usr/idbm.h
index 060a5a8..22f057f 100644
--- a/usr/idbm.h
+++ b/usr/idbm.h
@@ -41,6 +41,19 @@
 #define NAME_MAXVAL    128   /* the maximum length of key name */
 #define VALUE_MAXVAL   256   /* the maximum length of 223 bytes in the RFC. */
 #define OPTS_MAXVAL    8
+
+typedef enum session_state_e {
+       SESSION_NOT_ACTIVE,     /* session is not active */
+       SESSION_ACTIVE,         /* session is active */
+       SESSION_FORCE_CHANGE    /* session change forced by the user */
+} session_state_e;
+
+typedef enum modify_attr_e {
+       ATTR_IMMUTABLE,         /* can not be changed at all */
+       ATTR_DEFERRED,          /* can be changed only when session is not 
active */
+       ATTR_IMMEDIATE          /* can be changed while in session */
+} modify_attr_e;
+
 typedef struct recinfo {
        int             type;
        char            name[NAME_MAXVAL];
@@ -50,12 +63,7 @@ typedef struct recinfo {
        int             visible;
        char*           opts[OPTS_MAXVAL];
        int             numopts;
-       /*
-        * bool indicating if we can change it or not.
-        * TODO: make it a enum that can indicate wheter it also requires
-        * a relogin to pick up if a session is running.
-        */
-       int             can_modify;
+       modify_attr_e   can_modify;
 } recinfo_t;
 
 typedef char *(idbm_get_config_file_fn)(void);
@@ -80,6 +88,7 @@ struct db_set_param {
        char *name;
        char *value;
        struct idbm *db;
+       session_state_e state;
 };
 
 typedef int (idbm_iface_op_fn)(idbm_t *db, void *data, node_rec_t *rec);
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index 433c4e6..c60914d 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -85,9 +85,10 @@ static struct option const long_options[] =
        {"show", no_argument, NULL, 'S'},
        {"version", no_argument, NULL, 'V'},
        {"help", no_argument, NULL, 'h'},
+       {"force", no_argument, NULL, 'f'},
        {NULL, 0, NULL, 0},
 };
-static char *short_options = "RlVhm:p:P:T:H:I:U:k:L:d:r:n:v:o:sSt:u";
+static char *short_options = "RlVhfm:p:P:T:H:I:U:k:L:d:r:n:v:o:sSt:u";
 
 static void usage(int status)
 {
@@ -99,9 +100,9 @@ static void usage(int status)
 iscsiadm -m discovery [ -hV ] [ -d debug_level ] [-P printlevel] [ -t type -p 
ip:port -I ifaceN ... [ -l ] ] | [ -p ip:port ] \
 [ -o operation ] [ -n name ] [ -v value ]\n\
 iscsiadm -m node [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -L 
all,manual,automatic ] [ -U all,manual,automatic ] [ -S ] [ [ -T targetname -p 
ip:port -I ifaceN ] [ -l | -u | -R | -s] ] \
-[ [ -o  operation  ] [ -n name ] [ -v value ] ]\n\
+[ [ -o  operation  ] [ -n name ] [ -v value ] [ -f ] ]\n\
 iscsiadm -m session [ -hV ] [ -d debug_level ] [ -P  printlevel] [ -r 
sessionid | sysfsdir [ -R | -u | -s ] [ -o operation ] [ -n name ] [ -v value ] 
]\n\
-iscsiadm -m iface [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -I ifacename 
] [ [ -o  operation  ] [ -n name ] [ -v value ] ]\n\
+iscsiadm -m iface [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -I ifacename 
] [ [ -o  operation  ] [ -n name ] [ -v value ] [ -f ] ]\n\
 iscsiadm -m fw [ -l ]\n\
 iscsiadm -k priority\n");
        }
@@ -1737,7 +1738,7 @@ static void catch_sigint( int signo ) {
 }
 
 /* TODO: merge iter helpers and clean them up, so we can use them here */
-static int exec_iface_op(idbm_t *db, int op, int do_show, int info_level,
+static int exec_iface_op(idbm_t *db, int op, int do_show, int do_force, int 
info_level,
                         struct iface_rec *iface, char *name, char *value)
 {
        struct db_set_param set_param;
@@ -1853,6 +1854,14 @@ delete_fail:
                set_param.value = value;
 
                /* pass rec's iface because it has the db values */
+               if (check_for_session_through_iface(rec)) {
+                       if (do_force)
+                               set_param.state = SESSION_FORCE_CHANGE;
+                       else
+                               set_param.state = SESSION_ACTIVE;
+               } else
+                       set_param.state = SESSION_NOT_ACTIVE;
+
                rc = iface_conf_update(db, &set_param, &rec->iface);
                if (rc)
                        goto update_fail;
@@ -1892,7 +1901,7 @@ update_fail:
 
 /* TODO cleanup arguments */
 static int exec_node_op(idbm_t *db, int op, int do_login, int do_logout,
-                       int do_show, int do_rescan, int do_stats,
+                       int do_show, int do_rescan, int do_stats, int do_force,
                        int info_level, struct node_rec *rec,
                        char *name, char *value)
 {
@@ -1986,6 +1995,13 @@ static int exec_node_op(idbm_t *db, int op, int 
do_login, int do_logout,
                set_param.db = db;
                set_param.name = name;
                set_param.value = value;
+               if (check_for_session_through_iface(rec)) {
+                       if (do_force)
+                               set_param.state = SESSION_FORCE_CHANGE;
+                       else
+                               set_param.state = SESSION_ACTIVE;
+               } else
+                       set_param.state = SESSION_NOT_ACTIVE;
 
                if (for_each_rec(db, rec, &set_param, idbm_node_set_param))     
                        rc = -1;
@@ -2124,7 +2140,7 @@ main(int argc, char **argv)
 {
        char *ip = NULL, *name = NULL, *value = NULL;
        char *targetname = NULL, *group_session_mgmt_mode = NULL;
-       int ch, longindex, mode=-1, port=-1, do_login=0, do_rescan=0;
+       int ch, longindex, mode=-1, port=-1, do_login=0, do_rescan=0, 
do_force=0;
        int rc=0, sid=-1, op=OP_NOOP, type=-1, do_logout=0, do_stats=0;
        int do_login_all=0, do_logout_all=0, info_level=-1, num_ifaces = 0;
        int tpgt = PORTAL_GROUP_TAG_UNKNOWN, killiscsid=-1, do_show=0;
@@ -2245,6 +2261,9 @@ main(int argc, char **argv)
                        list_add_tail(&iface->list, &ifaces);
                        num_ifaces++;
                        break;
+               case 'f':
+                       do_force = 1;
+                       break;
                case 'V':
                        printf("%s version %s\n", program_name,
                                ISCSI_VERSION_STR);
@@ -2290,7 +2309,7 @@ main(int argc, char **argv)
 
        switch (mode) {
        case MODE_IFACE:
-               if ((rc = verify_mode_params(argc, argv, "IdnvmPo", 0))) {
+               if ((rc = verify_mode_params(argc, argv, "IdnvmPof", 0))) {
                        log_error("iface mode: option '-%c' is not "
                                  "allowed/supported", rc);
                        rc = -1;
@@ -2305,8 +2324,8 @@ main(int argc, char **argv)
                                          "interface. Using the first one "
                                          "%s.", iface->name);
                }
-               rc = exec_iface_op(db, op, do_show, info_level, iface,
-                                  name, value);
+               rc = exec_iface_op(db, op, do_show, do_force, info_level,
+                                       iface, name, value);
                break;
        case MODE_DISCOVERY:
                if ((rc = verify_mode_params(argc, argv, "IPdmtplo", 0))) {
@@ -2413,7 +2432,7 @@ main(int argc, char **argv)
                }
                break;
        case MODE_NODE:
-               if ((rc = verify_mode_params(argc, argv, "RsPIdmlSonvupTUL",
+               if ((rc = verify_mode_params(argc, argv, "RsPIdmlSonvupTULf",
                                             0))) {
                        log_error("node mode: option '-%c' is not "
                                  "allowed/supported", rc);
@@ -2450,8 +2469,8 @@ main(int argc, char **argv)
                }
 
                rc = exec_node_op(db, op, do_login, do_logout, do_show,
-                                 do_rescan, do_stats, info_level, rec,
-                                 name, value);
+                                 do_rescan, do_stats, do_force, info_level,
+                                 rec, name, value);
                break;
        case MODE_SESSION:
                if ((rc = verify_mode_params(argc, argv,
@@ -2509,7 +2528,7 @@ main(int argc, char **argv)
 
                        /* drop down to node ops */
                        rc = exec_node_op(db, op, do_login, do_logout, do_show,
-                                         do_rescan, do_stats, info_level,
+                                         do_rescan, do_stats, do_force, 
info_level,
                                          rec, name, value);
 free_info:
                        free(info);
@@ -2517,7 +2536,7 @@ free_info:
                } else {
                        if (do_logout || do_rescan || do_stats) {
                                rc = exec_node_op(db, op, do_login, do_logout,
-                                                do_show, do_rescan, do_stats,
+                                                do_show, do_rescan, do_stats, 
do_force,
                                                 info_level, NULL, name, value);
                                goto out;
                        }
-- 
1.5.3.8

Hi Mike,
Sorry for all the mess with this patch.
I have sent two patches because I thought each
of them is one logical change, but we can
also look on both of the patches as one
logical change.
So I have combined them into one patch.

Thanks,
Doron


--~--~---------~--~----~------------~-------~--~----~
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 [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/open-iscsi
-~----------~----~----~----~------~----~------~--~---

Reply via email to