This patch is a prototype for dynamic reconfiguration (USERSPACE TODO ITEM #3). This patch defines some parameters update interface in iscsiadm session mode.
Examples of the user interface in this patch is as follows. # iscsiadm -m session -o update -n PARAM_NAME -v VALUE => Update node DB and session parameter in all running sessions. # iscsiadm -m session -o nonpersistent -n PARAM_NAME -v VALUE => Update session parameter in all running sessions (not update node DB). # iscsiadm -m session -o update -n PARAM_NAME -v VALUE -r SESSION_ID => Update node DB and session parameter in a specified session. # iscsiadm -m session -o nonpersistent -n PARAM_NAME -v VALUE -r SESSION_ID => Update session parameter in a specified session (not update node DB). 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.conn[0].timeo.noop_out_timeout node.conn[0].timeo.noop_out_interval There is a concern about the user interface in this patch. Currently following option is drop down to node ops in iscsiadm. # iscsiadm -m session -o update -n PARAM_NAME -v VALUE So I'm worried about modifying a session parameter unintentionally. But I can't come up with the better user interface. Any comments are welcome. Signed-off-by: Tomoaki Nishimura <t-nishim...@hf.jp.nec.com> --- usr/iscsiadm.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- usr/mgmt_ipc.c | 33 ++++++++++ usr/mgmt_ipc.h | 1 + 3 files changed, 222 insertions(+), 4 deletions(-) diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c index f886d39..a7b6109 100644 --- a/usr/iscsiadm.c +++ b/usr/iscsiadm.c @@ -29,6 +29,7 @@ #include <signal.h> #include <time.h> #include <sys/stat.h> +#include <dirent.h> #include "initiator.h" #include "discovery.h" @@ -3209,6 +3210,166 @@ ping_exit: return rc; } +static int +session_set_rec_from_params(node_rec_t *rec, struct list_head *params) +{ + int rc; + struct user_param *param; + char id[256]; + + rc = verify_node_params(params, rec); + if (rc) + return rc; + + snprintf(id, sizeof(id), "session%d", rec->session.sid); + sysfs_get_int(id, "iscsi_session", "recovery_tmo", + &rec->session.timeo.replacement_timeout); + sysfs_get_int(id, "iscsi_session", "fast_abort", + &rec->session.iscsi.FastAbort); + sysfs_get_int(id, "iscsi_session", "abort_tmo", + &rec->session.err_timeo.abort_timeout); + sysfs_get_int(id, "iscsi_session", "lu_reset_tmo", + &rec->session.err_timeo.lu_reset_timeout); + + snprintf(id, sizeof(id), "connection%d:0", rec->session.sid); + sysfs_get_int(id, "iscsi_connection", "ping_tmo", + &rec->conn[0].timeo.noop_out_timeout); + sysfs_get_int(id, "iscsi_connection", "recv_tmo", + &rec->conn[0].timeo.noop_out_interval); + + list_for_each_entry(param, params, list) { + if (strcmp(param->name, + "node.session.timeo.replacement_timeout") == 0) { + rec->session.timeo.replacement_timeout = + strtoul(param->value, NULL, 10); + } else if (strcmp(param->name, + "node.session.iscsi.FastAbort") == 0) { + if (strcmp(param->value, "Yes") == 0) { + rec->session.iscsi.FastAbort = 1; + } else if (strcmp(param->value, "No") == 0) { + rec->session.iscsi.FastAbort = 0; + } + } else if (strcmp(param->name, + "node.session.err_timeo.abort_timeout") == 0) { + rec->session.err_timeo.abort_timeout = + strtoul(param->value, NULL, 10); + } else if (strcmp(param->name, + "node.session.err_timeo.lu_reset_timeout") == 0) { + rec->session.err_timeo.lu_reset_timeout = + strtoul(param->value, NULL, 10); + } else if (strcmp(param->name, + "node.conn[0].timeo.noop_out_timeout") == 0) { + rec->conn[0].timeo.noop_out_timeout = + strtoul(param->value, NULL, 10); + } else if (strcmp(param->name, + "node.conn[0].timeo.noop_out_interval") == 0) { + rec->conn[0].timeo.noop_out_interval = + strtoul(param->value, NULL, 10); + } else { + printf("%s is not supported in session update\n", + param->name); + return -1; + } + } + return 0; +} + +static int session_update(node_rec_t *node_rec, struct session_info *info) +{ + int rc; + iscsiadm_req_t req; + iscsiadm_req_t rsp; + + if (!iscsi_match_session(node_rec, info)) + return -1; + /* + rc = iscsid_req_by_rec(MGMT_IPC_SESSION_UPDATE, rec); + */ + 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 0; +} + +static int trans_filter(const struct dirent *dir) +{ + return strcmp(dir->d_name, ".") && strcmp(dir->d_name, ".."); +} + +static int session_update_all(struct list_head *params) +{ + struct dirent **namelist; + int rc = 0, n, i; + struct session_info *info; + struct node_rec *rec = NULL; + + info = calloc(1, sizeof(*info)); + if (!info) + return ISCSI_ERR_NOMEM; + + n = scandir("/sys/class/iscsi_session", &namelist, trans_filter, + alphasort); + if (n <= 0) + goto free_info; + + for (i = 0; i < n; i++) { + rc = iscsi_sysfs_get_sessioninfo_by_id(info, + namelist[i]->d_name); + if (rc) { + log_error("could not find session info for %s", + namelist[i]->d_name); + /* raced. session was shutdown while looping */ + rc = 0; + continue; + } + + rec = idbm_create_rec(info->targetname, + info->tpgt, + info->persistent_address, + info->persistent_port, + &info->iface, 1); + if (!rec) { + log_error("create rec for %s failed", + namelist[i]->d_name); + goto free_info; + } + rec->session.info = info; + rec->session.sid = info->sid; + + rc = session_set_rec_from_params(rec, params); + if (rc) { + log_error("set params for %s failed, error %d", + namelist[i]->d_name, rc); + goto free_info; + } + rc = session_update(rec, info); + free(rec); + if (rc) { + log_error("update session for %s failed, error %d", + namelist[i]->d_name, rc); + goto free_info; + } + } + + + for (i = 0; i < n; i++) + free(namelist[i]); + free(namelist); + +free_info: + free(info); + return rc; +} + int main(int argc, char **argv) { @@ -3647,14 +3808,37 @@ 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, ¶ms); + if (!(op & OP_NONPERSISTENT)) { + rc = exec_node_op(op, do_login, do_logout, + do_show, do_rescan, + do_stats, info_level, + rec, ¶ms); + if (rc) + goto free_info; + } + if (op == OP_UPDATE || op == OP_NONPERSISTENT) { + rc = session_set_rec_from_params(rec, ¶ms); + if (rc) + goto free_info; + rc = session_update(rec, 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, + ¶ms); + if (rc) + goto out; + } + rc = session_update_all(¶ms); + 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..b96946d 100644 --- a/usr/mgmt_ipc.c +++ b/usr/mgmt_ipc.c @@ -295,6 +295,38 @@ 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 sid = qtask->req.u.session.sid; + node_rec_t *rec = &qtask->req.u.session.rec; + iscsi_session_t *session; + struct iscsi_conn *conn; + int rc; + + session = session_find_by_sid(sid); + if (!session) + return ISCSI_ERR_SESS_NOT_FOUND; + + session->replacement_timeout = rec->session.timeo.replacement_timeout; + session->fast_abort = rec->session.iscsi.FastAbort; + session->abort_timeout = rec->session.err_timeo.abort_timeout; + session->lu_reset_timeout = rec->session.err_timeo.lu_reset_timeout; + + conn = &session->conn[0]; + conn->noop_out_timeout = rec->conn[0].timeo.noop_out_timeout; + conn->noop_out_interval = rec->conn[0].timeo.noop_out_interval; + + rc = iscsi_session_set_params(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 +561,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.