diff options
-rw-r--r-- | README | 15 | ||||
-rw-r--r-- | etc/iscsid.conf | 34 | ||||
-rw-r--r-- | usr/config.h | 2 | ||||
-rw-r--r-- | usr/discoveryd.c | 107 | ||||
-rw-r--r-- | usr/idbm.c | 73 | ||||
-rw-r--r-- | usr/idbm.h | 4 | ||||
-rw-r--r-- | usr/idbm_fields.h | 2 |
7 files changed, 130 insertions, 107 deletions
@@ -870,15 +870,18 @@ will usually get you started. When iscsid starts it will check iscsid.conf for: -discovery.daemon.sendtargets.addresses = -discovery.daemon.sendtargets.poll_interval = - discovery.daemon.isns.addresses = discovery.daemon.isns.poll_interval = -being set. If an address or addresses are set, iscsid will perform discovery -to the address every poll_interval seconds, and it will log into any portals -found from the discovery source using the ifaces in /etc/iscsi/ifaces. +being set and it will check for discovery records in +/etc/iscsi/send_targets that have the setting: + +discovery.sendtargets.use_discoveryd = Yes + +If an address or addresses are set or the use_discoveryd is Yes, +iscsid will perform discovery to the address every poll_interval seconds, +and it will log into any portals found from the discovery source using +the ifaces in /etc/iscsi/ifaces. Note that for iSNS the poll_interval does not have to be set. If not set, iscsid will only perform rediscovery when it gets a SCN from the server. diff --git a/etc/iscsid.conf b/etc/iscsid.conf index 78c225c..de4252d 100644 --- a/etc/iscsid.conf +++ b/etc/iscsid.conf @@ -23,40 +23,6 @@ iscsid.startup = /sbin/iscsid - - -############################## -# SendTargets Discovery Daemon -############################## -# If instead of doing discovery with iscsiadm and then logging -# into the targets stored in the node db, set the following value -# to have iscsid perform SendTargets discovery and log into all -# the portals found. -# -# This will use the ifaces that are set up when iscsid is started up. -# -# This value for this is a list of addresses and ports. The address and -# port should be separated by a comma. Each address port tuple should be -# separated by a space. The port is optional. If not set then the iSCSI -# default 3260 will be used. -# -# Example (first address has a port and the final two use the default 3260): -# -# discovery.daemon.sendtargets.addresses = 192.168.0.21,1234 192.168.1.20 192.168.10.10 -# -# By default iscsid will check the discovery addresses above every 30 -# seconds. To change this change the following value. poll_interval is -# in seconds, and 0 will instruct iscsid to not poll (will do discovery -# once then complete). -# -# discovery.daemon.sendtargets.poll_interval = 30 -# -# Note: This currently only logs into new portals. It does not -# log out of portals that are no longer returned from SendTargets. -# To remove them run "iscsiadm -m session -r $SID -u" - - - ####################### # iSNS Discovery Daemon ####################### diff --git a/usr/config.h b/usr/config.h index c3c1c7f..7da906e 100644 --- a/usr/config.h +++ b/usr/config.h @@ -137,6 +137,8 @@ struct iscsi_session_operational_config { struct iscsi_sendtargets_config { int reopen_max; + int use_discoveryd; + int discoveryd_poll_inval; struct iscsi_auth_config auth; struct iscsi_connection_timeout_config conn_timeo; struct iscsi_conn_operational_config iscsi; diff --git a/usr/discoveryd.c b/usr/discoveryd.c index 3a817a0..d4aa665 100644 --- a/usr/discoveryd.c +++ b/usr/discoveryd.c @@ -48,9 +48,6 @@ #define DISC_ISNS_ADDR_CFG_STR "discovery.daemon.isns.addresses" #define DISC_ISNS_POLL_INVL "discovery.daemon.isns.poll_interval" -#define DISC_ST_ADDR_CFG_STR "discovery.daemon.sendtargets.addresses" -#define DISC_ST_POLL_INVL "discovery.daemon.sendtargets.poll_interval" - #define DISC_DEF_POLL_INVL 30 static LIST_HEAD(iscsi_targets); @@ -64,8 +61,8 @@ static int isns_register_nodes = 1; static void isns_reg_refresh_by_eid_qry(void *data); -typedef void (do_disc_and_login_fn)(const char *def_iname, char *addr, - int port, int poll_inval); +typedef void (do_disc_and_login_fn)(const char *def_iname, + struct discovery_rec *drec, int poll_inval); static int logout_session(void *data, struct list_head *list, struct session_info *info) @@ -204,13 +201,34 @@ static void update_sessions(struct list_head *new_rec_list, } } -static void do_disc_to_addrs(const char *def_iname, char *disc_addrs, - int poll_inval, - do_disc_and_login_fn *do_disc_and_login) +static void fork_disc(const char *def_iname, struct discovery_rec *drec, + int poll_inval, do_disc_and_login_fn *do_disc_and_login) { pid_t pid; + + pid = fork(); + if (pid == 0) { + setup_signal_handler(); + do_disc_and_login(def_iname, drec, poll_inval); + exit(0); + } else if (pid < 0) + log_error("Fork failed (err %d - %s). Will not be able " + "to perform discovery to %s.\n", + errno, strerror(errno), drec->address); + else { + shutdown_callback(pid); + log_debug(1, "iSCSI disc and login helper pid=%d", pid); + reap_inc(); + } +} + +static void parse_portals(const char *def_iname, char *disc_addrs, + int poll_inval, + do_disc_and_login_fn *do_disc_and_login) +{ + struct discovery_rec drec; int portn; - char *saveptr1, *saveptr2; + char *saveptr1 = NULL, *saveptr2 = NULL; char *ip_str, *addr, *port_str; addr = strtok_r(disc_addrs, " ", &saveptr1); @@ -230,20 +248,11 @@ static void do_disc_to_addrs(const char *def_iname, char *disc_addrs, else portn = atoi(port_str); - pid = fork(); - if (pid == 0) { - setup_signal_handler(); - do_disc_and_login(def_iname, ip_str, portn, poll_inval); - exit(0); - } else if (pid < 0) - log_error("Fork failed (err %d - %s). Will not be able " - "to perform discovery to %s.\n", - errno, strerror(errno), ip_str); - else { - shutdown_callback(pid); - log_debug(1, "iSCSI disc and login helper pid=%d", pid); - reap_inc(); - } + memset(&drec, 0, sizeof(struct discovery_rec)); + strlcpy(drec.address, ip_str, sizeof(drec.address)); + drec.port = portn; + + fork_disc(def_iname, &drec, poll_inval, do_disc_and_login); } while ((addr = strtok_r(NULL, " ", &saveptr1))); } @@ -267,8 +276,7 @@ static void __discoveryd_start(const char *def_iname, char *addr_cfg_str, log_debug(1, "%s=%s poll interval %d", addr_cfg_str, disc_addrs, disc_poll_invl); - do_disc_to_addrs(def_iname, disc_addrs, disc_poll_invl, - do_disc_and_login); + parse_portals(def_iname, disc_addrs, disc_poll_invl, do_disc_and_login); free(disc_addrs); } @@ -1056,23 +1064,22 @@ fail: return rc; } -static void start_isns(const char *def_iname, char *disc_addr, int port, +static void start_isns(const char *def_iname, struct discovery_rec *drec, int poll_inval) { - int rc; + int rc, port = drec->port; if (port < 0) port = ISNS_DEFAULT_PORT; - rc = isns_eventd(def_iname, disc_addr, port, poll_inval); + rc = isns_eventd(def_iname, drec->address, port, poll_inval); log_debug(1, "start isns done %d.", rc); discoveryd_stop(); } /* SendTargets */ -static void __do_st_disc_and_login(char *disc_addr, int port) +static void __do_st_disc_and_login(struct discovery_rec *drec) { - discovery_rec_t drec; struct list_head rec_list, setup_ifaces; struct iface_rec *iface, *tmp_iface; int rc; @@ -1080,17 +1087,11 @@ static void __do_st_disc_and_login(char *disc_addr, int port) INIT_LIST_HEAD(&rec_list); INIT_LIST_HEAD(&setup_ifaces); - idbm_sendtargets_defaults(&drec.u.sendtargets); - strlcpy(drec.address, disc_addr, sizeof(drec.address)); - if (port < 0) - port = ISCSI_LISTEN_PORT; - drec.port = port; - /* * The disc daemon will try again in poll_interval secs * so no need to retry here */ - drec.u.sendtargets.reopen_max = 0; + drec->u.sendtargets.reopen_max = 0; iface_link_ifaces(&setup_ifaces); /* @@ -1099,11 +1100,11 @@ static void __do_st_disc_and_login(char *disc_addr, int port) */ ipc = NULL; - rc = idbm_bind_ifaces_to_nodes(discovery_sendtargets, &drec, + rc = idbm_bind_ifaces_to_nodes(discovery_sendtargets, drec, &setup_ifaces, &rec_list); if (rc) { - log_error("Could not perform SendTargets to %s.", - disc_addr); + log_error("Could not perform SendTargets to %s:%d.", + drec->address, drec->port); goto free_ifaces; } @@ -1116,14 +1117,14 @@ free_ifaces: } } -static void do_st_disc_and_login(const char *def_iname, char *disc_addr, - int port, int poll_inval) +static void do_st_disc_and_login(const char *def_iname, + struct discovery_rec *drec, int poll_inval) { if (poll_inval < 0) poll_inval = DISC_DEF_POLL_INVL; do { - __do_st_disc_and_login(disc_addr, port); + __do_st_disc_and_login(drec); if (!poll_inval) break; } while (!stop_discoveryd && !sleep(poll_inval)); @@ -1131,10 +1132,26 @@ static void do_st_disc_and_login(const char *def_iname, char *disc_addr, discoveryd_stop(); } +static int st_start(void *data, struct discovery_rec *drec) +{ + log_debug(1, "st_start %s:%d %d", drec->address, drec->port, + drec->u.sendtargets.use_discoveryd); + if (!drec->u.sendtargets.use_discoveryd) + return ENOSYS; + + fork_disc(NULL, drec, drec->u.sendtargets.discoveryd_poll_inval, + do_st_disc_and_login); + return 0; +} + +static void discoveryd_st_start(void) +{ + idbm_for_each_st_drec(NULL, st_start); +} + void discoveryd_start(const char *def_iname) { __discoveryd_start(def_iname, DISC_ISNS_ADDR_CFG_STR, DISC_ISNS_POLL_INVL, start_isns); - __discoveryd_start(def_iname, DISC_ST_ADDR_CFG_STR, DISC_ST_POLL_INVL, - do_st_disc_and_login); + discoveryd_st_start(); } @@ -162,7 +162,13 @@ idbm_recinfo_discovery(discovery_rec_t *r, recinfo_t *ri) __recinfo_int(DISC_ST_LOGIN_TMO, ri, r, u.sendtargets.conn_timeo.login_timeout, IDBM_SHOW, num, 1); - __recinfo_int(DISC_ST_REOPEN_MAX,ri, r, + __recinfo_int_o2(DISC_ST_USE_DISC_DAEMON, ri, r, + u.sendtargets.use_discoveryd, + IDBM_SHOW, "No", "Yes", num, 1); + __recinfo_int(DISC_ST_DISC_DAEMON_POLL_INVAL, ri, r, + u.sendtargets.discoveryd_poll_inval, + IDBM_SHOW, num, 1); + __recinfo_int(DISC_ST_REOPEN_MAX, ri, r, u.sendtargets.reopen_max, IDBM_SHOW, num, 1); __recinfo_int(DISC_ST_AUTH_TMO, ri, r, @@ -411,6 +417,8 @@ idbm_discovery_setup_defaults(discovery_rec_t *rec, discovery_type_e type) rec->startup = ISCSI_STARTUP_MANUAL; rec->type = type; if (type == DISCOVERY_TYPE_SENDTARGETS) { + rec->u.sendtargets.discoveryd_poll_inval = 30; + rec->u.sendtargets.use_discoveryd = 0; rec->u.sendtargets.reopen_max = 5; rec->u.sendtargets.auth.authmethod = 0; rec->u.sendtargets.auth.password_length = 0; @@ -959,7 +967,7 @@ no_match: return -1; } -int idbm_print_discovered(struct discovery_rec *drec, int info_level) +int idbm_print_discovered(discovery_rec_t *drec, int info_level) { int num_found = 0; @@ -979,17 +987,17 @@ int idbm_print_discovered(struct discovery_rec *drec, int info_level) return num_found; } -static int idbm_print_all_st(int info_level) +int idbm_for_each_st_drec(void *data, idbm_st_drec_op_fn *fn) { DIR *entity_dirfd; struct dirent *entity_dent; int found = 0; - char *disc_dir; - char *tmp_port; + discovery_rec_t drec; + char *disc_dir, *tmp_port; disc_dir = malloc(PATH_MAX); if (!disc_dir) - return 0; + return ENOMEM; entity_dirfd = opendir(ST_CONFIG_DIR); if (!entity_dirfd) @@ -1007,24 +1015,16 @@ static int idbm_print_all_st(int info_level) continue; *tmp_port++ = '\0'; - if (info_level >= 1) { - struct discovery_rec drec; - - printf("DiscoveryAddress: %s,%s\n", - entity_dent->d_name, tmp_port); - - memset(&drec, 0, sizeof(struct discovery_rec)); - strlcpy(drec.address, entity_dent->d_name, - sizeof(drec.address)); - drec.port = atoi(tmp_port); - drec.type = DISCOVERY_TYPE_SENDTARGETS; + memset(&drec, 0, sizeof(drec)); + if (idbm_discovery_read(&drec, entity_dent->d_name, + atoi(tmp_port))) { + log_error("Could not read discovery record for " + "%s:%s.", entity_dent->d_name, tmp_port); + continue; + } - found += idbm_print_discovered(&drec, info_level); - } else { - printf("%s:%s via sendtargets\n", entity_dent->d_name, - tmp_port); + if (!fn(data, &drec)) found++; - } } closedir(entity_dirfd); free_disc: @@ -1032,6 +1032,35 @@ free_disc: return found; } +static int __idbm_print_all_st(void *data, struct discovery_rec *drec) +{ + int info_level = *(int *)data; + int rc; + + if (info_level >= 1) { + printf("DiscoveryAddress: %s,%d\n", + drec->address, drec->port); + rc = idbm_print_discovered(drec, info_level); + if (rc) + return 0; + else + return ENODEV; + } else { + printf("%s:%d via sendtargets\n", drec->address, drec->port); + return 0; + } +} + +static int idbm_print_all_st(int info_level) +{ + int rc; + + rc = idbm_for_each_st_drec(&info_level, __idbm_print_all_st); + if (rc < 0) + return 0; + return rc; +} + int idbm_print_all_discovery(int info_level) { discovery_rec_t *drec; @@ -102,6 +102,10 @@ extern int idbm_for_each_node(int *found, void *data, extern int idbm_for_each_rec(int *found, void *data, idbm_iface_op_fn *fn); + +typedef int (idbm_st_drec_op_fn)(void *data, discovery_rec_t *drec); +extern int idbm_for_each_st_drec(void *data, idbm_st_drec_op_fn *fn); + extern int idbm_init(idbm_get_config_file_fn *fn); extern void idbm_node_setup_from_conf(node_rec_t *rec); diff --git a/usr/idbm_fields.h b/usr/idbm_fields.h index 8b79bf3..cd637fd 100644 --- a/usr/idbm_fields.h +++ b/usr/idbm_fields.h @@ -92,6 +92,8 @@ #define DISC_ST_PASSWORD_IN_LEN "discovery.sendtargets.auth.password_in_length" #define DISC_ST_LOGIN_TMO "discovery.sendtargets.timeo.login_timeout" #define DISC_ST_REOPEN_MAX "discovery.sendtargets.reopen_max" +#define DISC_ST_DISC_DAEMON_POLL_INVAL "discovery.sendtargets.discoveryd_poll_inval" +#define DISC_ST_USE_DISC_DAEMON "discovery.sendtargets.use_discoveryd" #define DISC_ST_AUTH_TMO "discovery.sendtargets.timeo.auth_timeout" #define DISC_ST_ACTIVE_TMO "discovery.sendtargets.timeo.active_timeout" #define DISC_ST_MAX_RECV_DLEN "discovery.sendtargets.iscsi.MaxRecvDataSegmentLength" |