diff options
author | mnc <mnc@d7303112-9cec-0310-bdd2-e83a94d6c2b6> | 2006-11-08 17:58:56 +0000 |
---|---|---|
committer | mnc <mnc@d7303112-9cec-0310-bdd2-e83a94d6c2b6> | 2006-11-08 17:58:56 +0000 |
commit | 95e2e89a23e7c85cebdd97ca373bf0cffcafeca3 (patch) | |
tree | 7c246191cd239bf18a68312f03e776d5efbc298f | |
parent | 0cabf50bbf127f374ebaf6a9b9770e527dd7888e (diff) | |
download | open-iscsi-95e2e89a23e7c85cebdd97ca373bf0cffcafeca3.tar.gz |
add login/logout all commands
git-svn-id: svn://svn.berlios.de/open-iscsi@722 d7303112-9cec-0310-bdd2-e83a94d6c2b6
-rw-r--r-- | README | 8 | ||||
-rw-r--r-- | doc/iscsiadm.8 | 19 | ||||
-rw-r--r-- | usr/config.h | 1 | ||||
-rw-r--r-- | usr/idbm.c | 7 | ||||
-rw-r--r-- | usr/idbm.h | 3 | ||||
-rw-r--r-- | usr/iscsiadm.c | 192 |
6 files changed, 218 insertions, 12 deletions
@@ -186,6 +186,14 @@ Usage: iscsiadm [OPTION] [new], [delete], [update] or [show]. In case of [update], you have to provide [name] and [value] you wish to update + -m node --logoutall=[all,manual,automatic] + Logout "all" the running sessions or just the ones + with startup value manial or automatic. + Nodes marked as ONBOOT are skipped. + -m node --loginall=[all,manual,automatic] + Login "all" the running sessions or just the ones + with startup value manial or automatic. + Nodes marked as ONBOOT are skipped. -m session display all active sessions and connections -m session --sid=[sid] [--logout] perform operation for specific session with diff --git a/doc/iscsiadm.8 b/doc/iscsiadm.8 index 3a200a7..6368d0d 100644 --- a/doc/iscsiadm.8 +++ b/doc/iscsiadm.8 @@ -5,7 +5,7 @@ iscsiadm \- open-iscsi administration utility \fBiscsiadm\fR -m discovery [ -dhV ] [ -t type -p ip:port [ -l ] ] | [ -o operation ] [ -n name ] [ -v value ] -\fBiscsiadm\fR -m node [ -dhV ] [ -S ] [ [ -T targetname -p ip:port | -M sysdir ] [ -l | -u ] ] +\fBiscsiadm\fR -m node [ -dhV ] [ -L all,manual,automatic ] [ -U all,manual,automatic ] [ -S ] [ [ -T targetname -p ip:port | -M sysdir ] [ -l | -u ] ] [ [ -o operation ] [ -n name ] [ -v value ] [ -p ip:port ] ] \fBiscsiadm\fR -m session [ -dhV ] [ -r sessionid [ -u | -s ] ] @@ -36,6 +36,15 @@ all discovered targets. This option is only valid for discovery and node modes. .TP +\fB\-L\fR, \fB\-\-loginall==\fI[all,manual,automatic]\fR +For node mode, login all sessions with the node.startup values passed in +or all running sesssion, except ones marked onboot, if all is passed in. +.IP +This option is only valid for node mode (it is valid but not functional +for session mode). + + +.TP \fB\-m, \-\-mode \fIop\fR specify the mode. \fIop\fR must be one of \fIdiscovery\fR, \fInode\fR, or \fIsession\fR. @@ -126,6 +135,14 @@ This option is only valid for node mode (it is valid but not functional for session mode). .TP +\fB\-U\fR, \fB\-\-logoutall==\fI[all,manual,automatic]\fR +logout all sessions with the node.startup values passed in or all +running sesssion, except ones marked onboot, if all is passed in. +.IP +This option is only valid for node mode (it is valid but not functional +for session mode). + +.TP \fB\-v\fR, \fB\-\-value=\fIvalue\fR Specify a \fIvalue\fR for use with the \fIupdate\fR operator. .IP diff --git a/usr/config.h b/usr/config.h index 35deed8..7d00238 100644 --- a/usr/config.h +++ b/usr/config.h @@ -160,6 +160,7 @@ struct iscsi_slp_config { typedef enum iscsi_startup { ISCSI_STARTUP_MANUAL, ISCSI_STARTUP_AUTOMATIC, + ISCSI_STARTUP_ONBOOT, } iscsi_startup_e; typedef enum discovery_type { @@ -646,7 +646,8 @@ int idbm_print_all_discovery(idbm_t *db) return found; } -int idbm_print_nodes(idbm_t *db) +int idbm_for_each_node(idbm_t *db, void *data, + int (* fn)(void *data, node_rec_t *rec)) { DIR *node_dirfd, *portal_dirfd; struct dirent *node_dent, *portal_dent; @@ -689,9 +690,7 @@ int idbm_print_nodes(idbm_t *db) tmp_ip, tmp_port)) continue; - printf("%s:%d,%d %s\n", - rec.conn[0].address, rec.conn[0].port, - rec.tpgt, rec.name); + fn(data, &rec); found++; } closedir(portal_dirfd); @@ -64,7 +64,8 @@ extern char* get_iscsi_initiatoralias(char *pathname); extern idbm_t* idbm_init(char *configfile); extern void idbm_terminate(idbm_t *db); extern int idbm_print_node(idbm_t *db, node_rec_t *rec, int show); -extern int idbm_print_nodes(idbm_t *db); +extern int idbm_for_each_node(idbm_t *db, void *data, + int (* fn)(void *data, node_rec_t *rec)); extern int idbm_print_discovery(idbm_t *db, discovery_rec_t *rec, int show); extern int idbm_print_all_discovery(idbm_t *db); extern int idbm_delete_discovery(idbm_t *db, discovery_rec_t *rec); diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c index 8ad40e7..b482359 100644 --- a/usr/iscsiadm.c +++ b/usr/iscsiadm.c @@ -74,7 +74,9 @@ static struct option const long_options[] = {"value", required_argument, NULL, 'v'}, {"sid", required_argument, NULL, 'r'}, {"login", no_argument, NULL, 'l'}, + {"loginall", required_argument, NULL, 'L'}, {"logout", no_argument, NULL, 'u'}, + {"logoutall", required_argument, NULL, 'U'}, {"stats", no_argument, NULL, 's'}, {"debug", required_argument, NULL, 'g'}, {"map", required_argument, NULL, 'M'}, @@ -83,7 +85,7 @@ static struct option const long_options[] = {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0}, }; -static char *short_options = "lVhm:M:p:T:d:r:n:v:o:sSt:u"; +static char *short_options = "lVhm:M:p:T:U:L:d:r:n:v:o:sSt:u"; static void usage(int status) { @@ -94,7 +96,7 @@ static void usage(int status) printf("\ iscsiadm -m discovery [ -dhV ] [ -t type -p ip:port [ -l ] ] | [ -p ip:port ] \ [ -o operation ] [ -n name ] [ -v value ]\n\ -iscsiadm -m node [ -dhV ] [ -S ] [ [ -T targetname -p ip:port | -M sysdir ] [ -l | -u ] ] \ +iscsiadm -m node [ -dhV ] [ -L all,manual,automatic ] [ -U all,manual,automatic ] [ -S ] [ [ -T targetname -p ip:port | -M sysdir ] [ -l | -u ] ] \ [ [ -o operation ] [ -n name ] [ -v value ] [ -p ip:port ] ]\n\ iscsiadm -m session [ -dhV ] [ -r sessionid [ -u | -s ] ]\n"); } @@ -288,6 +290,164 @@ session_logout(node_rec_t *rec) } static int +match_startup_mode(node_rec_t *rec, char *mode) +{ + /* + * we always skip onboot because this should be handled by + * something else + */ + if (rec->startup == ISCSI_STARTUP_ONBOOT) + return -1; + + if ((!strcmp(mode, "automatic") && + rec->startup == ISCSI_STARTUP_AUTOMATIC) || + (!strcmp(mode, "manual") && + rec->startup == ISCSI_STARTUP_MANUAL) || + !strcmp(mode, "all")) + return 0; + + /* support conn or session startup params */ + if ((!strcmp(mode, "automatic") && + rec->conn[0].startup == ISCSI_STARTUP_AUTOMATIC) || + (!strcmp(mode, "manual") && + rec->conn[0].startup == ISCSI_STARTUP_MANUAL) || + !strcmp(mode, "all")) + return 0; + + return -1; +} + +struct session_mgmt_fn { + idbm_t *db; + char *mode; +}; + +static int +__group_logout(void *data, char *targetname, int tpgt, char *address, + int port, int sid) +{ + struct session_mgmt_fn *mgmt = data; + char *mode = mgmt->mode; + idbm_t *db = mgmt->db; + node_rec_t rec; + int rc = 0; + + log_debug(7, "logout all [%d][%s,%s.%d]\n", sid, targetname, + address, port); + + /* for now skip qlogic and other HW and offload drivers */ + if (!get_transport_by_sid(sid)) + return 0; + + if (idbm_node_read(db, &rec, targetname, address, port)) { + /* + * this is due to a HW driver or some other driver + * not hooked in + */ + log_debug(7, "could not read data for [%s,%s.%d]\n", + targetname, address, port); + return 0; + } + /* + * we always skip on boot because if the user killed this on + * they would not be able to do anything + */ + if (rec.startup == ISCSI_STARTUP_ONBOOT) + return 0; + + if (!match_startup_mode(&rec, mode)) { + rc = session_logout(&rec); + /* we raced with another app or instance of iscsiadm */ + if (rc == MGMT_IPC_ERR_NOT_FOUND) + rc = 0; + if (rc > 0) { + iscsid_handle_error(rc); + /* continue trying to logout the rest of them */ + rc = 0; + } + } + + return rc; +} + +static int +group_logout(idbm_t *db, char *mode) +{ + int num_found; + struct session_mgmt_fn mgmt; + + if (!mode || !(!strcmp(mode, "automatic") || !strcmp(mode, "all") || + !strcmp(mode,"manual"))) { + log_error("Invalid logoutall option %s.", mode); + usage(0); + return -EINVAL; + } + + mgmt.mode = mode; + mgmt.db = db; + + return sysfs_for_each_session(&mgmt, &num_found, __group_logout); +} + +static int +__group_login(void *data, node_rec_t *rec) +{ + struct session_mgmt_fn *mgmt = data; + char *mode = mgmt->mode; + int rc; + + log_debug(7, "group login %s:%d,%d %s\n", rec->conn[0].address, + rec->conn[0].port, rec->tpgt, rec->name); + /* + * we always skip onboot because this should be handled by + * something else + */ + if (rec->startup == ISCSI_STARTUP_ONBOOT) + return 0; + + if (!match_startup_mode(rec, mode)) { + rc = session_login(rec); + /* we raced with another app or instance of iscsiadm */ + if (rc == MGMT_IPC_ERR_EXISTS) + rc = 0; + if (rc > 0) { + iscsid_handle_error(rc); + /* continue trying to login the rest of them */ + rc = 0; + } + } + + return 0; +} + +static int +group_login(idbm_t *db, char *mode) +{ + struct session_mgmt_fn mgmt; + + if (!mode || !(!strcmp(mode, "automatic") || !strcmp(mode, "all") || + !strcmp(mode,"manual"))) { + log_error("Invalid loginall option %s.", mode); + usage(0); + return -EINVAL; + } + + mgmt.mode = mode; + mgmt.db = db; + + idbm_for_each_node(db, &mgmt, __group_login); + return 0; +} + +static int +print_node_info(void *data, node_rec_t *rec) +{ + printf("%s:%d,%d %s\n", rec->conn[0].address, rec->conn[0].port, + rec->tpgt, rec->name); + return 0; +} + +static int config_init(void) { int rc; @@ -444,7 +604,7 @@ do_sendtargets(idbm_t *db, struct iscsi_sendtargets_config *cfg) discovery_rec_t *drec; if ((drec = idbm_new_discovery(db, cfg->address, cfg->port, DISCOVERY_TYPE_SENDTARGETS, info.buffer))) { - idbm_print_nodes(db); + idbm_for_each_node(db, NULL, print_node_info); free(drec); } } @@ -484,9 +644,10 @@ int main(int argc, char **argv) { char *ip = NULL, *name = NULL, *value = NULL, *sysfs_device = NULL; - char *targetname = NULL; + char *targetname = NULL, *group_session_mgmt_mode = NULL; int ch, longindex, mode=-1, port=-1, do_login=0; int rc=0, sid=-1, op=-1, type=-1, do_logout=0, do_stats=0, do_show=0; + int do_login_all=0, do_logout_all=0; idbm_t *db; struct sigaction sa_old; struct sigaction sa_new; @@ -544,6 +705,14 @@ main(int argc, char **argv) case 'u': do_logout = 1; break; + case 'U': + do_logout_all = 1; + group_session_mgmt_mode= optarg; + break; + case 'L': + do_login_all= 1; + group_session_mgmt_mode= optarg; + break; case 's': do_stats = 1; break; @@ -691,12 +860,23 @@ main(int argc, char **argv) node_rec_t rec; memset(&rec, 0, sizeof(node_rec_t)); - if ((rc = verify_mode_params(argc, argv, "dmMlSonvupT", 0))) { + if ((rc = verify_mode_params(argc, argv, "dmMlSonvupTUL", 0))) { log_error("node mode: option '-%c' is not " "allowed/supported", rc); rc = -1; goto out; } + + if (do_login_all) { + rc = group_login(db, group_session_mgmt_mode); + goto out; + } + + if (do_logout_all) { + rc = group_logout(db, group_session_mgmt_mode); + goto out; + } + if (sysfs_device) { if (targetname && ip) { log_error("only one of map and " @@ -780,7 +960,7 @@ found_node_rec: goto out; } } else if (op < 0 || op == OP_SHOW) { - if (!idbm_print_nodes(db)) { + if (!idbm_for_each_node(db, NULL, print_node_info)) { log_error("no records found!"); rc = -1; goto out; |