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