I cleaned up the previous patch.
There is no change in user interface from the previous patch.

This patch makes following parameters to be modifiable in running session. 

 node.session.timeo.replacement_timeout 
 node.session.iscsi.FastAbort 
 node.session.err_timeo.abort_timeout 
 node.session.err_timeo.lu_reset_timeout 
 node.session.err_timeo.tgt_reset_timeout
 node.conn[0].timeo.noop_out_timeout
 node.conn[0].timeo.noop_out_interval


Signed-off-by: Tomoaki Nishimura <t-nishim...@hf.jp.nec.com>
---
 usr/iscsiadm.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 usr/mgmt_ipc.c |  53 ++++++++++++++++++++
 usr/mgmt_ipc.h |   1 +
 3 files changed, 204 insertions(+), 4 deletions(-)

diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index f886d39..a14ce4a 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -58,6 +58,10 @@
 static char program_name[] = "iscsiadm";
 static char config_file[TARGET_NAME_MAXLEN];
 extern struct iscsi_ipc *ipc;
+static struct iscsi_rec_params {
+       struct node_rec         *rec;
+       struct list_head        *params;
+};
 
 enum iscsiadm_mode {
        MODE_DISCOVERY,
@@ -3209,6 +3213,125 @@ ping_exit:
        return rc;
 }
 
+static int verify_session_update_params(struct list_head *params)
+{
+       int i;
+       struct user_param *param;
+       char key[NAME_MAXVAL];
+
+       list_for_each_entry(param, params, list) {
+               if (strcmp(param->name, SESSION_REPLACEMENT_TMO) == 0)
+                       continue;
+               else if (strcmp(param->name, SESSION_ABORT_TMO) == 0)
+                       continue;
+               else if (strcmp(param->name, SESSION_FAST_ABORT) == 0)
+                       continue;
+               else if (strcmp(param->name, SESSION_LU_RESET_TMO) == 0)
+                       continue;
+               else if (strcmp(param->name, SESSION_TGT_RESET_TMO) == 0)
+                       continue;
+               else {
+                       for (i = 0; i < ISCSI_CONN_MAX; i++) {
+
+                               sprintf(key, CONN_NOP_INT, i);
+                               if (strcmp(param->name, key) == 0)
+                                       continue;
+
+                               sprintf(key, CONN_NOP_TMO, i);
+                               if (strcmp(param->name, key) == 0)
+                                       continue;
+
+                               printf("%s is unsupported in session update.\n",
+                                       param->name);
+                               return ISCSI_ERR;
+                       }
+               }
+       }
+
+       return ISCSI_SUCCESS;
+}
+
+static void init_rec_for_session_update(node_rec_t *rec)
+{
+       int i, noupdate = -1;
+
+       rec->session.timeo.replacement_timeout = noupdate;
+       rec->session.err_timeo.abort_timeout = noupdate;
+       rec->session.iscsi.FastAbort = noupdate;
+       rec->session.err_timeo.lu_reset_timeout = noupdate;
+       rec->session.err_timeo.tgt_reset_timeout = noupdate;
+       for (i = 0; i < ISCSI_CONN_MAX; i++) {
+               rec->conn[i].timeo.noop_out_interval = noupdate;
+               rec->conn[i].timeo.noop_out_timeout = noupdate;
+       }
+}
+
+static int
+session_update(struct iscsi_rec_params *rec_params, struct session_info *info)
+{
+       int rc;
+       node_rec_t *node_rec;
+       struct list_head *params = rec_params->params;
+       iscsiadm_req_t req;
+       iscsiadm_rsp_t rsp;
+
+       if (!rec_params->rec) {
+               rec_params->rec = idbm_create_rec(info->targetname, info->tpgt,
+                                       info->persistent_address,
+                                       info->persistent_port, &info->iface, 1);
+               if (!rec_params->rec)
+                       return ISCSI_ERR_NOMEM;
+       }
+       node_rec = rec_params->rec;
+
+       rc = verify_session_update_params(params);
+       if (rc)
+               return rc;
+
+       init_rec_for_session_update(node_rec);
+
+       rc = idbm_node_set_rec_from_param(params, node_rec, 1);
+       if (rc) {
+               log_error("Set rec from params failed.\n");
+               return rc;
+       }
+
+       req.command = MGMT_IPC_SESSION_UPDATE;
+       req.u.session.sid = info->sid;
+       memcpy(&req.u.session.rec, node_rec, sizeof(node_rec_t));
+       rc = iscsid_exec_req(&req, &rsp, 1);
+       if (rc)
+               return rc;
+
+       printf("Session update [sid: %d, target: %s, portal: %s,%d]\n",
+               info->sid, info->targetname, info->persistent_address,
+               info->port);
+
+       return rc;
+}
+
+static int session_update_all(struct list_head *params)
+{
+       int rc, num_found = 0;
+       struct iscsi_rec_params rec_params;
+
+       rec_params.rec = NULL;
+       rec_params.params = params;
+
+       rc = iscsi_sysfs_for_each_session(&rec_params, &num_found,
+                                                       session_update, 1);
+       if (rc) {
+               log_error("Could not execute operation on all sessions: %s",
+                       iscsi_err_to_str(rc));
+               return rc;
+       } else if (!num_found) {
+               log_error("No session found.");
+               return ISCSI_ERR_NO_OBJS_FOUND;
+       }
+
+       return ISCSI_SUCCESS;
+}
+
 int
 main(int argc, char **argv)
 {
@@ -3230,6 +3353,7 @@ main(int argc, char **argv)
        uint64_t index = ULLONG_MAX;
        struct user_param *param;
        struct list_head params;
+       struct iscsi_rec_params rec_params;
 
        INIT_LIST_HEAD(&params);
        INIT_LIST_HEAD(&ifaces);
@@ -3647,14 +3771,36 @@ main(int argc, char **argv)
                                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,
-                                         rec, &params);
+                       if (!(op & OP_NONPERSISTENT)) {
+                               rc = exec_node_op(op, do_login, do_logout,
+                                                       do_show, do_rescan,
+                                                       do_stats, info_level,
+                                                       rec, &params);
+                               if (rc)
+                                       goto free_info;
+                       }
+                       if (op == OP_UPDATE || op == OP_NONPERSISTENT) {
+                               rec_params.rec = rec;
+                               rec_params.params = &params;
+                               rc = session_update(&rec_params, info);
+                       }
 free_info:
                        free(info);
                        goto out;
                } else {
+                       if (op == OP_UPDATE || op == OP_NONPERSISTENT) {
+                               if (!(op & OP_NONPERSISTENT)) {
+                                       rc = exec_node_op(op, do_login,
+                                                       do_logout, do_show,
+                                                       do_rescan, do_stats,
+                                                       info_level, rec,
+                                                       &params);
+                                       if (rc)
+                                               goto out;
+                               }
+                               rc = session_update_all(&params);
+                               goto out;
+                       }
                        if (op == OP_NEW) {
                                log_error("session mode: Operation 'new' only "
                                          "allowed with specific session IDs");
diff --git a/usr/mgmt_ipc.c b/usr/mgmt_ipc.c
index ee037d9..7220b26 100644
--- a/usr/mgmt_ipc.c
+++ b/usr/mgmt_ipc.c
@@ -295,6 +295,58 @@ mgmt_ipc_notify_common(queue_task_t *qtask, int 
(*handler)(int, char **))
        return ISCSI_SUCCESS;
 }
 
+static int mgmt_ipc_session_update(queue_task_t *qtask)
+{
+       int rc, i, sid = qtask->req.u.session.sid;
+       node_rec_t *rec = &qtask->req.u.session.rec;
+       iscsi_session_t *session;
+       struct iscsi_conn *conn;
+
+       session = session_find_by_sid(sid);
+       if (!session)
+               return ISCSI_ERR_SESS_NOT_FOUND;
+
+       if (rec->session.timeo.replacement_timeout >= 0)
+               session->replacement_timeout =
+                               rec->session.timeo.replacement_timeout;
+
+       if (rec->session.iscsi.FastAbort >= 0)
+               session->fast_abort = rec->session.iscsi.FastAbort;
+
+       if (rec->session.err_timeo.abort_timeout >= 0)
+               session->abort_timeout = rec->session.err_timeo.abort_timeout;
+
+       if (rec->session.err_timeo.lu_reset_timeout >= 0)
+               session->lu_reset_timeout =
+                               rec->session.err_timeo.lu_reset_timeout;
+
+       if (rec->session.err_timeo.tgt_reset_timeout >= 0)
+               session->tgt_reset_timeout =
+                               rec->session.err_timeo.tgt_reset_timeout;
+
+       for (i = 0; i < ISCSI_CONN_MAX; i++) {
+               conn = &session->conn[i];
+
+               if (rec->conn[i].timeo.noop_out_timeout >= 0)
+                       conn->noop_out_timeout =
+                               rec->conn[i].timeo.noop_out_timeout;
+
+               if (rec->conn[i].timeo.noop_out_interval >= 0)
+                       conn->noop_out_interval =
+                               rec->conn[i].timeo.noop_out_interval;
+       }
+
+       rc = iscsi_session_set_params(session->conn);
+       if (rc) {
+               log_error("iscsi_session_set_params(): IPC error %d session"
+                       " [%02d]" , rc, sid);
+               return ISCSI_ERR_INTERNAL;
+       }
+
+       mgmt_ipc_write_rsp(qtask, ISCSI_SUCCESS);
+       return ISCSI_SUCCESS;
+}
+
 /* Replace these dummies as you implement them
    elsewhere */
 static int
@@ -529,6 +581,7 @@ static mgmt_ipc_fn_t *      
mgmt_ipc_functions[__MGMT_IPC_MAX_COMMAND] = {
 [MGMT_IPC_NOTIFY_DEL_NODE]     = mgmt_ipc_notify_del_node,
 [MGMT_IPC_NOTIFY_ADD_PORTAL]   = mgmt_ipc_notify_add_portal,
 [MGMT_IPC_NOTIFY_DEL_PORTAL]   = mgmt_ipc_notify_del_portal,
+[MGMT_IPC_SESSION_UPDATE]      = mgmt_ipc_session_update,
 };
 
 void mgmt_ipc_handle(int accept_fd)
diff --git a/usr/mgmt_ipc.h b/usr/mgmt_ipc.h
index 55972ed..1a06403 100644
--- a/usr/mgmt_ipc.h
+++ b/usr/mgmt_ipc.h
@@ -46,6 +46,7 @@ typedef enum iscsiadm_cmd {
        MGMT_IPC_NOTIFY_DEL_NODE        = 17,
        MGMT_IPC_NOTIFY_ADD_PORTAL      = 18,
        MGMT_IPC_NOTIFY_DEL_PORTAL      = 19,
+       MGMT_IPC_SESSION_UPDATE         = 20,
 
        __MGMT_IPC_MAX_COMMAND
 } iscsiadm_cmd_e;
-- 
1.9.3

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To post to this group, send email to open-iscsi@googlegroups.com.
Visit this group at http://groups.google.com/group/open-iscsi.
For more options, visit https://groups.google.com/d/optout.

Reply via email to