diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2010-01-18 22:12:03 -0600 |
---|---|---|
committer | Mike Christie <michaelc@cs.wisc.edu> | 2010-03-22 17:32:06 -0500 |
commit | 38030899b5fda60fc853b6319c85ac59d9910b3a (patch) | |
tree | 6aee11708aa6737a2bc6ed5e602143d35019b0de | |
parent | 213c88562f68875bad2c9cbdf74d869e5a57c295 (diff) | |
download | open-iscsi-38030899b5fda60fc853b6319c85ac59d9910b3a.tar.gz |
iscsiadm: mv session management functions to new file
This mvs the session management functions to a new file
so they can be used by the discovery daemons.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
-rw-r--r-- | etc/iscsid.conf | 1 | ||||
-rw-r--r-- | usr/Makefile | 3 | ||||
-rw-r--r-- | usr/idbm.h | 1 | ||||
-rw-r--r-- | usr/iscsiadm.c | 341 | ||||
-rw-r--r-- | usr/session_mgmt.c | 301 | ||||
-rw-r--r-- | usr/session_mgmt.h | 19 |
6 files changed, 370 insertions, 296 deletions
diff --git a/etc/iscsid.conf b/etc/iscsid.conf index e8b62f0..b0ac7c9 100644 --- a/etc/iscsid.conf +++ b/etc/iscsid.conf @@ -46,6 +46,7 @@ iscsid.startup = /sbin/iscsid # To manually startup the session set to "manual". The default is manual. node.startup = manual + # ************* # CHAP Settings # ************* diff --git a/usr/Makefile b/usr/Makefile index 1caf4f1..166e717 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -50,7 +50,8 @@ all: $(PROGRAMS) iscsid: $(ISCSI_LIB_SRCS) $(IPC_OBJ) $(INITIATOR_SRCS) iscsid.o $(CC) $(CFLAGS) $^ -o $@ -iscsiadm: $(ISCSI_LIB_SRCS) $(FW_BOOT_SRCS) strings.o discovery.o iscsiadm.o +iscsiadm: $(ISCSI_LIB_SRCS) $(FW_BOOT_SRCS) strings.o discovery.o iscsiadm.o \ + session_mgmt.o $(CC) $(CFLAGS) $^ -o $@ iscsistart: $(IPC_OBJ) $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(FW_BOOT_SRCS) \ @@ -22,6 +22,7 @@ #ifndef IDBM_H #define IDBM_H +#include <stdio.h> #include <sys/types.h> #include "initiator.h" #include "config.h" diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c index 75cd520..5c171f9 100644 --- a/usr/iscsiadm.c +++ b/usr/iscsiadm.c @@ -45,6 +45,7 @@ #include "host.h" #include "sysdeps.h" #include "idbm_fields.h" +#include "session_mgmt.h" struct iscsi_ipc *ipc = NULL; /* dummy */ static char program_name[] = "iscsiadm"; @@ -281,80 +282,6 @@ match_startup_mode(node_rec_t *rec, char *mode) return -1; } -static void log_login_msg(struct node_rec *rec, int rc) -{ - if (rc) { - log_error("Could not login to [iface: %s, target: %s, " - "portal: %s,%d].", rec->iface.name, - rec->name, rec->conn[0].address, - rec->conn[0].port); - iscsid_handle_error(rc); - } else - printf("Login to [iface: %s, target: %s, portal: " - "%s,%d] successful.\n", rec->iface.name, - rec->name, rec->conn[0].address, - rec->conn[0].port); -} - -struct iscsid_async_req { - struct list_head list; - void *data; - int fd; -}; - -static int iscsid_login_reqs_wait(struct list_head *list) -{ - struct iscsid_async_req *tmp, *curr; - struct node_rec *rec; - int ret = 0; - - list_for_each_entry_safe(curr, tmp, list, list) { - int err; - - rec = curr->data; - err = iscsid_req_wait(MGMT_IPC_SESSION_LOGIN, curr->fd); - log_login_msg(rec, err); - list_del(&curr->list); - free(curr); - } - return ret; -} - -static void log_logout_msg(struct session_info *info, int rc) -{ - if (rc) { - log_error("Could not logout of [sid: %d, target: %s, " - "portal: %s,%d].", info->sid, - info->targetname, - info->persistent_address, info->port); - iscsid_handle_error(rc); - } else - printf("Logout of [sid: %d, target: %s, " - "portal: %s,%d] successful.\n", - info->sid, info->targetname, - info->persistent_address, info->port); -} - -static int iscsid_logout_reqs_wait(struct list_head *list) -{ - struct iscsid_async_req *tmp, *curr; - struct session_info *info; - int ret = 0; - - list_for_each_entry_safe(curr, tmp, list, list) { - int err; - - info = curr->data; - err = iscsid_req_wait(MGMT_IPC_SESSION_LOGOUT, curr->fd); - log_logout_msg(info, err); - if (err) - ret = err; - list_del(&curr->list); - free(curr); - } - return ret; -} - static int for_each_session(struct node_rec *rec, iscsi_sysfs_session_op_fn *fn) { @@ -386,90 +313,6 @@ static int link_recs(void *data, struct node_rec *rec) return 0; } -static int __logout_portal(struct session_info *info, struct list_head *list) -{ - struct iscsid_async_req *async_req = NULL; - int fd, rc; - - /* TODO: add fn to add session prefix info like dev_printk */ - printf("Logging out of session [sid: %d, target: %s, portal: %s,%d]\n", - info->sid, info->targetname, info->persistent_address, - info->port); - - async_req = calloc(1, sizeof(*async_req)); - if (!async_req) { - log_error("Could not allocate memory for async logout " - "handling. Using sequential logout instead."); - rc = iscsid_req_by_sid(MGMT_IPC_SESSION_LOGOUT, info->sid); - } else { - INIT_LIST_HEAD(&async_req->list); - rc = iscsid_req_by_sid_async(MGMT_IPC_SESSION_LOGOUT, - info->sid, &fd); - } - - /* we raced with another app or instance of iscsiadm */ - if (rc) { - log_logout_msg(info, rc); - if (async_req) - free(async_req); - - if (rc == MGMT_IPC_ERR_NOT_FOUND) - return 0; - - return EIO; - } - - if (async_req) { - list_add_tail(&async_req->list, list); - async_req->fd = fd; - async_req->data = info; - } else - log_logout_msg(info, rc); - - return 0; -} - -static int -__logout_portals(void *data, int *nr_found, - int (*logout_fn)(void *, struct list_head *, - struct session_info *)) -{ - struct session_info *curr_info; - struct session_link_info link_info; - struct list_head session_list, logout_list; - int ret = 0, err; - - INIT_LIST_HEAD(&session_list); - INIT_LIST_HEAD(&logout_list); - - memset(&link_info, 0, sizeof(link_info)); - link_info.list = &session_list; - link_info.data = NULL; - link_info.match_fn = NULL; - *nr_found = 0; - - err = iscsi_sysfs_for_each_session(&link_info, nr_found, - session_info_create_list); - if (err || !*nr_found) - return err; - - *nr_found = 0; - list_for_each_entry(curr_info, &session_list, list) { - err = logout_fn(data, &logout_list, curr_info); - if (err > 0 && !ret) - ret = err; - if (!err) - (*nr_found)++; - } - - err = iscsid_logout_reqs_wait(&logout_list); - if (err) - ret = err; - - session_info_free_list(&session_list); - return ret; -} - static int __logout_by_startup(void *data, struct list_head *list, struct session_info *info) @@ -503,7 +346,7 @@ __logout_by_startup(void *data, struct list_head *list, return -1; if (!match_startup_mode(&rec, mode)) - rc = __logout_portal(info, list); + rc = iscsi_logout_portal(info, list); return rc; } @@ -519,116 +362,7 @@ logout_by_startup(char *mode) return EINVAL; } - return __logout_portals(mode, &nr_found, __logout_by_startup); -} - -static int -logout_portal(void *data, struct list_head *list, struct session_info *info) -{ - struct node_rec *pattern_rec = data; - struct iscsi_transport *t; - - t = iscsi_sysfs_get_transport_by_sid(info->sid); - if (!t) - return -1; - - if (!iscsi_match_session(pattern_rec, info)) - return -1; - - /* we do not support this yet */ - if (t->caps & CAP_FW_DB) { - log_error("Could not logout session of [sid: %d, " - "target: %s, portal: %s,%d].", info->sid, - info->targetname, info->persistent_address, - info->port); - log_error("Logout not supported for driver: %s.", t->name); - return -1; - } - return __logout_portal(info, list); -} - -static int logout_portals(struct node_rec *pattern_rec) -{ - int nr_found; - - return __logout_portals(pattern_rec, &nr_found, logout_portal); -} - -static int login_portal(void *data, struct list_head *list, - struct node_rec *rec) -{ - struct iscsid_async_req *async_req = NULL; - int rc = 0, fd; - - printf("Logging in to [iface: %s, target: %s, portal: %s,%d]\n", - rec->iface.name, rec->name, rec->conn[0].address, - rec->conn[0].port); - - if (list) { - async_req = calloc(1, sizeof(*async_req)); - if (!async_req) - log_error("Could not allocate memory for async login " - "handling. Using sequential login instead."); - else - INIT_LIST_HEAD(&async_req->list); - } - - if (async_req) - rc = iscsid_req_by_rec_async(MGMT_IPC_SESSION_LOGIN, - rec, &fd); - else - rc = iscsid_req_by_rec(MGMT_IPC_SESSION_LOGIN, rec); - - if (rc) { - log_login_msg(rec, rc); - if (async_req) - free(async_req); - /* we raced with another app or instance of iscsiadm */ - if (rc == MGMT_IPC_ERR_EXISTS) - return 0; - - return ENOTCONN; - } - - if (async_req) { - list_add_tail(&async_req->list, list); - async_req->fd = fd; - async_req->data = rec; - } else - log_login_msg(rec, rc); - - return 0; -} - -static int __login_portals(void *data, int *nr_found, - struct list_head *rec_list, - int (* login_fn)(void *, struct list_head *, - struct node_rec *)) -{ - struct node_rec *curr_rec, *tmp; - struct list_head login_list; - int ret = 0, err; - - *nr_found = 0; - INIT_LIST_HEAD(&login_list); - - list_for_each_entry(curr_rec, rec_list, list) { - err = login_fn(data, &login_list, curr_rec); - if (err > 0 && !ret) - ret = err; - if (!err) - (*nr_found)++; - } - - err = iscsid_login_reqs_wait(&login_list); - if (err && !ret) - ret = err; - - list_for_each_entry_safe(curr_rec, tmp, rec_list, list) { - list_del(&curr_rec->list); - free(curr_rec); - } - return ret; + return iscsi_logout_portals(mode, &nr_found, __logout_by_startup); } /* @@ -649,7 +383,7 @@ __login_by_startup(void *data, struct list_head *list, struct node_rec *rec) if (match_startup_mode(rec, mode)) return -1; - login_portal(NULL, list, rec); + iscsi_login_portal(NULL, list, rec); return 0; } @@ -668,8 +402,8 @@ login_by_startup(char *mode) INIT_LIST_HEAD(&rec_list); rc = idbm_for_each_rec(&nr_found, &rec_list, link_recs); - err = __login_portals(mode, &nr_found, &rec_list, - __login_by_startup); + err = iscsi_login_portals(mode, &nr_found, &rec_list, + __login_by_startup); if (err && !rc) rc = err; @@ -682,6 +416,37 @@ login_by_startup(char *mode) return rc; } +/** + * iscsi_logout_matched_portal - logout of targets matching the rec info + * @data: record to session with + * @list: list to add logout rec to + * @info: session to match with rec + */ +static int iscsi_logout_matched_portal(void *data, struct list_head *list, + struct session_info *info) +{ + struct node_rec *pattern_rec = data; + struct iscsi_transport *t; + + t = iscsi_sysfs_get_transport_by_sid(info->sid); + if (!t) + return -1; + + if (!iscsi_match_session(pattern_rec, info)) + return -1; + + /* we do not support this yet */ + if (t->caps & CAP_FW_DB) { + log_error("Could not logout session of [sid: %d, " + "target: %s, portal: %s,%d].", info->sid, + info->targetname, info->persistent_address, + info->port); + log_error("Logout not supported for driver: %s.", t->name); + return -1; + } + return iscsi_logout_portal(info, list); +} + static int iface_fn(void *data, node_rec_t *rec) { struct rec_op_data *op_data = data; @@ -732,8 +497,8 @@ static int login_portals(struct node_rec *pattern_rec) INIT_LIST_HEAD(&rec_list); ret = for_each_rec(pattern_rec, &rec_list, link_recs); - err = __login_portals(NULL, &nr_found, &rec_list, - login_portal); + err = iscsi_login_portals(NULL, &nr_found, &rec_list, + iscsi_login_portal); if (err && !ret) ret = err; return ret; @@ -1023,24 +788,6 @@ do_offload_sendtargets(discovery_rec_t *drec, int host_no, int do_login) return discovery_offload_sendtargets(host_no, do_login, drec); } -static int login_discovered_portal(void *data, struct list_head *list, - node_rec_t *rec) -{ - discovery_rec_t *drec = data; - - if (rec->disc_type != drec->type || - rec->disc_port != drec->port || - strcmp(rec->disc_address, drec->address)) - return -1; - - login_portal(NULL, list, rec); - /* - * This is used during the initial setup, so we want to see - * what portals we can or cannot log into and we will just continue - */ - return 0; -} - /* TODO merge with initiator.c implementation */ /* And add locking */ static int check_for_session_through_iface(struct node_rec *rec) @@ -1144,7 +891,8 @@ exec_disc_op_on_recs(discovery_rec_t *drec, struct list_head *rec_list, if (!do_login) return 0; - err = __login_portals(drec, &found, rec_list, login_discovered_portal); + err = iscsi_login_portals(NULL, &found, rec_list, + iscsi_login_portal); if (err && !rc) rc = err; return rc; @@ -1509,7 +1257,10 @@ static int exec_node_op(int op, int do_login, int do_logout, } if (do_logout) { - if (logout_portals(rec)) + int nr_found; + + if (iscsi_logout_portals(rec, &nr_found, + iscsi_logout_matched_portal)) rc = -1; goto out; } @@ -1695,7 +1446,7 @@ static int exec_fw_op(discovery_rec_t *drec, struct list_head *ifaces, break; } - login_portal(NULL, NULL, rec); + iscsi_login_portal(NULL, NULL, rec); free(rec); } } else { diff --git a/usr/session_mgmt.c b/usr/session_mgmt.c new file mode 100644 index 0000000..c22d730 --- /dev/null +++ b/usr/session_mgmt.c @@ -0,0 +1,301 @@ +/* + * iSCSI session management helpers + * + * Copyright (C) 2010 Mike Christie + * Copyright (C) 2010 Red Hat, Inc. All rights reserved. + + * maintained by open-iscsi@googlegroups.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * See the file COPYING included with this distribution for more details. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> + +#include "idbm.h" +#include "list.h" +#include "util.h" +#include "mgmt_ipc.h" +#include "session_info.h" +#include "iscsi_sysfs.h" +#include "log.h" + +static void log_login_msg(struct node_rec *rec, int rc) +{ + if (rc) { + log_error("Could not login to [iface: %s, target: %s, " + "portal: %s,%d].", rec->iface.name, + rec->name, rec->conn[0].address, + rec->conn[0].port); + iscsid_handle_error(rc); + } else + printf("Login to [iface: %s, target: %s, portal: " + "%s,%d] successful.\n", rec->iface.name, + rec->name, rec->conn[0].address, + rec->conn[0].port); +} + +struct iscsid_async_req { + struct list_head list; + void *data; + int fd; +}; + +static int iscsid_login_reqs_wait(struct list_head *list) +{ + struct iscsid_async_req *tmp, *curr; + struct node_rec *rec; + int ret = 0; + + list_for_each_entry_safe(curr, tmp, list, list) { + int err; + + rec = curr->data; + err = iscsid_req_wait(MGMT_IPC_SESSION_LOGIN, curr->fd); + log_login_msg(rec, err); + list_del(&curr->list); + free(curr); + } + return ret; +} + +/** + * iscsi_login_portal - request iscsid to login to portal + * @data: Unused. Only needed so this can be used in iscsi_login_portals + * @list: If async, list to add session to + * @rec: portal rec to log into + */ +int iscsi_login_portal(void *data, struct list_head *list, struct node_rec *rec) +{ + struct iscsid_async_req *async_req = NULL; + int rc = 0, fd; + + printf("Logging in to [iface: %s, target: %s, portal: %s,%d]\n", + rec->iface.name, rec->name, rec->conn[0].address, + rec->conn[0].port); + + if (list) { + async_req = calloc(1, sizeof(*async_req)); + if (!async_req) + log_error("Could not allocate memory for async login " + "handling. Using sequential login instead."); + else + INIT_LIST_HEAD(&async_req->list); + } + + if (async_req) + rc = iscsid_req_by_rec_async(MGMT_IPC_SESSION_LOGIN, + rec, &fd); + else + rc = iscsid_req_by_rec(MGMT_IPC_SESSION_LOGIN, rec); + + if (rc) { + log_login_msg(rec, rc); + if (async_req) + free(async_req); + /* we raced with another app or instance of iscsiadm */ + if (rc == MGMT_IPC_ERR_EXISTS) + return 0; + + return ENOTCONN; + } + + if (async_req) { + list_add_tail(&async_req->list, list); + async_req->fd = fd; + async_req->data = rec; + } else + log_login_msg(rec, rc); + + return 0; +} + +/** + * iscsi_login_portals - login into portals on @rec_list, + * @data: data to pass to login_fn + * @nr_found: returned with number of portals logged into + * @rec_list: list of portals to log into + * @login_fn: list iter function + * + * This will loop over the list of portals and login. It + * will attempt to login asynchronously, and then wait for + * them to complete. + */ +int iscsi_login_portals(void *data, int *nr_found, + struct list_head *rec_list, + int (* login_fn)(void *, struct list_head *, + struct node_rec *)) +{ + struct node_rec *curr_rec, *tmp; + struct list_head login_list; + int ret = 0, err; + + *nr_found = 0; + INIT_LIST_HEAD(&login_list); + + list_for_each_entry(curr_rec, rec_list, list) { + err = login_fn(data, &login_list, curr_rec); + if (err > 0 && !ret) + ret = err; + if (!err) + (*nr_found)++; + } + + err = iscsid_login_reqs_wait(&login_list); + if (err && !ret) + ret = err; + + list_for_each_entry_safe(curr_rec, tmp, rec_list, list) { + list_del(&curr_rec->list); + free(curr_rec); + } + return ret; +} + +static void log_logout_msg(struct session_info *info, int rc) +{ + if (rc) { + log_error("Could not logout of [sid: %d, target: %s, " + "portal: %s,%d].", info->sid, + info->targetname, + info->persistent_address, info->port); + iscsid_handle_error(rc); + } else + printf("Logout of [sid: %d, target: %s, " + "portal: %s,%d] successful.\n", + info->sid, info->targetname, + info->persistent_address, info->port); +} + +static int iscsid_logout_reqs_wait(struct list_head *list) +{ + struct iscsid_async_req *tmp, *curr; + struct session_info *info; + int ret = 0; + + list_for_each_entry_safe(curr, tmp, list, list) { + int err; + + info = curr->data; + err = iscsid_req_wait(MGMT_IPC_SESSION_LOGOUT, curr->fd); + log_logout_msg(info, err); + if (err) + ret = err; + list_del(&curr->list); + free(curr); + } + return ret; +} + +/** + * iscsi_logout_portal - logou tof portal + * @info: session to log out of + * @list: if async, this is the list to add the logout req to + */ +int iscsi_logout_portal(struct session_info *info, struct list_head *list) +{ + struct iscsid_async_req *async_req = NULL; + int fd, rc; + + /* TODO: add fn to add session prefix info like dev_printk */ + printf("Logging out of session [sid: %d, target: %s, portal: %s,%d]\n", + info->sid, info->targetname, info->persistent_address, + info->port); + + if (list) { + async_req = calloc(1, sizeof(*async_req)); + if (!async_req) + log_error("Could not allocate memory for async logout " + "handling. Using sequential logout instead."); + } + + if (!async_req) + rc = iscsid_req_by_sid(MGMT_IPC_SESSION_LOGOUT, info->sid); + else { + INIT_LIST_HEAD(&async_req->list); + rc = iscsid_req_by_sid_async(MGMT_IPC_SESSION_LOGOUT, + info->sid, &fd); + } + + /* we raced with another app or instance of iscsiadm */ + if (rc) { + log_logout_msg(info, rc); + if (async_req) + free(async_req); + + if (rc == MGMT_IPC_ERR_NOT_FOUND) + return 0; + + return EIO; + } + + if (async_req) { + list_add_tail(&async_req->list, list); + async_req->fd = fd; + async_req->data = info; + } else + log_logout_msg(info, rc); + + return 0; +} + +/** + * iscsi_logout_portals - logout portals + * @data: data to pass to iter logout_fn + * @nr_found: number of sessions logged out + * @logout_fn: logout iter function + * + * This will loop over the list of sessions and run the logout fn + * on them. It will attempt to logout asynchronously, and then wait for + * them to complete. + */ +int iscsi_logout_portals(void *data, int *nr_found, + int (*logout_fn)(void *, struct list_head *, + struct session_info *)) +{ + struct session_info *curr_info; + struct session_link_info link_info; + struct list_head session_list, logout_list; + int ret = 0, err; + + INIT_LIST_HEAD(&session_list); + INIT_LIST_HEAD(&logout_list); + + memset(&link_info, 0, sizeof(link_info)); + link_info.list = &session_list; + link_info.data = NULL; + link_info.match_fn = NULL; + *nr_found = 0; + + err = iscsi_sysfs_for_each_session(&link_info, nr_found, + session_info_create_list); + if (err || !*nr_found) + return err; + + *nr_found = 0; + list_for_each_entry(curr_info, &session_list, list) { + err = logout_fn(data, &logout_list, curr_info); + if (err > 0 && !ret) + ret = err; + if (!err) + (*nr_found)++; + } + + err = iscsid_logout_reqs_wait(&logout_list); + if (err) + ret = err; + + session_info_free_list(&session_list); + return ret; +} diff --git a/usr/session_mgmt.h b/usr/session_mgmt.h new file mode 100644 index 0000000..a101175 --- /dev/null +++ b/usr/session_mgmt.h @@ -0,0 +1,19 @@ +#ifndef _SESSION_MGMT_H_ +#define _SESSION_MGMT_H_ + +struct node_rec; +struct list_head; +struct session_info; + +extern int iscsi_login_portal(void *data, struct list_head *list, + struct node_rec *rec); +extern int iscsi_login_portals(void *data, int *nr_found, + struct list_head *rec_list, + int (* login_fn)(void *, struct list_head *, + struct node_rec *)); +extern int iscsi_logout_portal(struct session_info *info, + struct list_head *list); +extern int iscsi_logout_portals(void *data, int *nr_found, + int (*logout_fn)(void *, struct list_head *, + struct session_info *)); +#endif |