summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README15
-rw-r--r--etc/iscsid.conf34
-rw-r--r--usr/config.h2
-rw-r--r--usr/discoveryd.c107
-rw-r--r--usr/idbm.c73
-rw-r--r--usr/idbm.h4
-rw-r--r--usr/idbm_fields.h2
7 files changed, 130 insertions, 107 deletions
diff --git a/README b/README
index 074fb56..558058c 100644
--- a/README
+++ b/README
@@ -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();
}
diff --git a/usr/idbm.c b/usr/idbm.c
index d83e9dc..22928fa 100644
--- a/usr/idbm.c
+++ b/usr/idbm.c
@@ -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;
diff --git a/usr/idbm.h b/usr/idbm.h
index 57b9295..46c01ac 100644
--- a/usr/idbm.h
+++ b/usr/idbm.h
@@ -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"