summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/config.h1
-rw-r--r--usr/discovery.c16
-rw-r--r--usr/event_poll.c2
-rw-r--r--usr/host.c2
-rw-r--r--usr/iscsi_sysfs.c1
-rw-r--r--usr/iscsiadm.c12
-rw-r--r--usr/iscsid.c5
-rw-r--r--usr/iscsid_req.c51
-rw-r--r--usr/iscsid_req.h15
-rw-r--r--usr/iscsistart.c4
-rw-r--r--usr/session_info.c14
-rw-r--r--usr/session_info.h5
12 files changed, 84 insertions, 44 deletions
diff --git a/usr/config.h b/usr/config.h
index fd31a54..5b1bb1d 100644
--- a/usr/config.h
+++ b/usr/config.h
@@ -315,6 +315,7 @@ typedef struct discovery_rec {
discovery_type_e type;
char address[NI_MAXHOST];
int port;
+ int iscsid_req_tmo;
union {
struct iscsi_sendtargets_config sendtargets;
struct iscsi_slp_config slp;
diff --git a/usr/discovery.c b/usr/discovery.c
index 593d226..6ee8bd9 100644
--- a/usr/discovery.c
+++ b/usr/discovery.c
@@ -64,7 +64,7 @@ static char initiator_name[TARGET_NAME_MAXLEN + 1];
static char initiator_alias[TARGET_NAME_MAXLEN + 1];
static struct iscsi_ev_context ipc_ev_context;
-static int request_initiator_name(void)
+static int request_initiator_name(int tmo)
{
int rc;
iscsiadm_req_t req;
@@ -78,7 +78,7 @@ static int request_initiator_name(void)
memset(&req, 0, sizeof(req));
req.command = MGMT_IPC_CONFIG_INAME;
- rc = iscsid_exec_req(&req, &rsp, 1);
+ rc = iscsid_exec_req(&req, &rsp, 1, tmo);
if (rc)
return rc;
@@ -88,7 +88,7 @@ static int request_initiator_name(void)
memset(&req, 0, sizeof(req));
req.command = MGMT_IPC_CONFIG_IALIAS;
- rc = iscsid_exec_req(&req, &rsp, 0);
+ rc = iscsid_exec_req(&req, &rsp, 0, tmo);
if (rc)
/* alias is optional so return ok */
return 0;
@@ -344,7 +344,7 @@ int discovery_isns(void *data, struct iface_rec *iface,
if (iface && strlen(iface->iname))
iname = iface->iname;
else {
- rc = request_initiator_name();
+ rc = request_initiator_name(drec->iscsid_req_tmo);
if (rc) {
log_error("Cannot perform discovery. Initiatorname "
"required.");
@@ -454,7 +454,7 @@ int discovery_offload_sendtargets(int host_no, int do_login,
* and get back the results. We should do this since it would
* allows us to then process the results like software iscsi.
*/
- rc = iscsid_exec_req(&req, &rsp, 1);
+ rc = iscsid_exec_req(&req, &rsp, 1, drec->iscsid_req_tmo);
if (rc) {
log_error("Could not offload sendtargets to %s.",
drec->address);
@@ -802,7 +802,7 @@ static void iscsi_free_session(struct iscsi_session *session)
static iscsi_session_t *
iscsi_alloc_session(struct iscsi_sendtargets_config *config,
- struct iface_rec *iface, int *rc)
+ struct iface_rec *iface, int *rc, int tmo)
{
iscsi_session_t *session;
@@ -848,7 +848,7 @@ iscsi_alloc_session(struct iscsi_sendtargets_config *config,
strcpy(initiator_name, iface->iname);
/* MNC TODO add iface alias */
} else {
- *rc = request_initiator_name();
+ *rc = request_initiator_name(tmo);
if (*rc) {
log_error("Cannot perform discovery. Initiatorname "
"required.");
@@ -1573,7 +1573,7 @@ int discovery_sendtargets(void *fndata, struct iface_rec *iface,
iscsi_timer_clear(&connection_timer);
/* allocate a new session, and initialize default values */
- session = iscsi_alloc_session(config, iface, &rc);
+ session = iscsi_alloc_session(config, iface, &rc, drec->iscsid_req_tmo);
if (rc)
return rc;
diff --git a/usr/event_poll.c b/usr/event_poll.c
index 209ee02..ac25044 100644
--- a/usr/event_poll.c
+++ b/usr/event_poll.c
@@ -123,7 +123,7 @@ static int shutdown_wait_pids(void)
#define POLL_ALARM 2
#define POLL_MAX 3
-static int event_loop_stop;
+static volatile int event_loop_stop;
static queue_task_t *shutdown_qtask;
void event_loop_exit(queue_task_t *qtask)
diff --git a/usr/host.c b/usr/host.c
index 6333490..7e88e57 100644
--- a/usr/host.c
+++ b/usr/host.c
@@ -251,7 +251,7 @@ static int host_info_print_tree(void *data, struct host_info *hinfo)
printf("\tSessions:\n");
printf("\t*********\n");
- session_info_print_tree(&sessions, "\t", session_info_flags, 0);
+ session_info_print_tree(&sessions, "\t", session_info_flags, 0, -1);
session_info_free_list(&sessions);
return 0;
}
diff --git a/usr/iscsi_sysfs.c b/usr/iscsi_sysfs.c
index 84c396c..8ca668f 100644
--- a/usr/iscsi_sysfs.c
+++ b/usr/iscsi_sysfs.c
@@ -1420,6 +1420,7 @@ int iscsi_sysfs_for_each_session(void *data, int *nr_found,
if (!info)
return ISCSI_ERR_NOMEM;
+ info->iscsid_req_tmo = -1;
n = scandir(ISCSI_SESSION_DIR, &namelist, trans_filter,
alphasort);
if (n <= 0)
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index 9602f6c..4b2bd34 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -252,7 +252,7 @@ str_to_portal_type(char *str)
return ptype;
}
-static void kill_iscsid(int priority)
+static void kill_iscsid(int priority, int tmo)
{
iscsiadm_req_t req;
iscsiadm_rsp_t rsp;
@@ -274,7 +274,7 @@ static void kill_iscsid(int priority)
memset(&req, 0, sizeof(req));
req.command = MGMT_IPC_IMMEDIATE_STOP;
- rc = iscsid_exec_req(&req, &rsp, 0);
+ rc = iscsid_exec_req(&req, &rsp, 0, tmo);
if (rc) {
iscsi_err_print_msg(rc);
log_error("Could not stop iscsid. Trying sending iscsid "
@@ -741,7 +741,7 @@ static char *get_config_file(void)
memset(&req, 0, sizeof(req));
req.command = MGMT_IPC_CONFIG_FILE;
- rc = iscsid_exec_req(&req, &rsp, 1);
+ rc = iscsid_exec_req(&req, &rsp, 1, ISCSID_REQ_TIMEOUT);
if (rc)
return NULL;
@@ -791,7 +791,7 @@ session_stats(void *data, struct session_info *info)
req.command = MGMT_IPC_SESSION_STATS;
req.u.session.sid = info->sid;
- rc = iscsid_exec_req(&req, &rsp, 1);
+ rc = iscsid_exec_req(&req, &rsp, 1, info->iscsid_req_tmo);
if (rc)
return rc;
@@ -2956,6 +2956,7 @@ static int exec_disc_op(int disc_type, char *ip, int port,
int rc = 0;
memset(&drec, 0, sizeof(struct discovery_rec));
+ drec.iscsid_req_tmo = -1;
switch (disc_type) {
case DISCOVERY_TYPE_SENDTARGETS:
@@ -3263,6 +3264,7 @@ main(int argc, char **argv)
int packet_size=32, ping_count=1, ping_interval=0;
int do_discover = 0, sub_mode = -1;
int portal_type = -1;
+ int timeout = ISCSID_REQ_TIMEOUT;
struct sigaction sa_old;
struct sigaction sa_new;
struct list_head ifaces;
@@ -3448,7 +3450,7 @@ main(int argc, char **argv)
}
if (killiscsid >= 0) {
- kill_iscsid(killiscsid);
+ kill_iscsid(killiscsid, timeout);
goto free_ifaces;
}
diff --git a/usr/iscsid.c b/usr/iscsid.c
index 8dd72a4..81a14f2 100644
--- a/usr/iscsid.c
+++ b/usr/iscsid.c
@@ -274,7 +274,7 @@ static int sync_session(void *data, struct session_info *info)
memcpy(&req.u.session.rec, &rec, sizeof(node_rec_t));
retry:
- rc = iscsid_exec_req(&req, &rsp, 0);
+ rc = iscsid_exec_req(&req, &rsp, 0, info->iscsid_req_tmo);
if (rc == ISCSI_ERR_ISCSID_NOTCONN && retries < 30) {
retries++;
sleep(1);
@@ -313,8 +313,7 @@ static void catch_signal(int signo)
switch (signo) {
case SIGTERM:
- iscsid_shutdown();
- exit(0);
+ event_loop_exit(NULL);
break;
default:
break;
diff --git a/usr/iscsid_req.c b/usr/iscsid_req.c
index 2950d74..a2e6d6e 100644
--- a/usr/iscsid_req.c
+++ b/usr/iscsid_req.c
@@ -24,6 +24,7 @@
#include <errno.h>
#include <fcntl.h>
#include <sys/un.h>
+#include <poll.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -33,6 +34,7 @@
#include "iscsi_util.h"
#include "config.h"
#include "iscsi_err.h"
+#include "iscsid_req.h"
#include "uip_mgmt_ipc.h"
static void iscsid_startup(void)
@@ -118,16 +120,45 @@ int iscsid_request(int *fd, iscsiadm_req_t *req, int start_iscsid)
return ISCSI_SUCCESS;
}
-int iscsid_response(int fd, iscsiadm_cmd_e cmd, iscsiadm_rsp_t *rsp)
+int iscsid_response(int fd, iscsiadm_cmd_e cmd, iscsiadm_rsp_t *rsp,
+ int timeout)
{
- int iscsi_err;
+ size_t len = sizeof(*rsp);
+ int iscsi_err = ISCSI_ERR_ISCSID_COMM_ERR;
int err;
+ int poll_wait = 0;
- if ((err = recv(fd, rsp, sizeof(*rsp), MSG_WAITALL)) != sizeof(*rsp)) {
- log_error("got read error (%d/%d), daemon died?", err, errno);
- iscsi_err = ISCSI_ERR_ISCSID_COMM_ERR;
- } else
- iscsi_err = rsp->err;
+ if (timeout == -1) {
+ timeout = ISCSID_REQ_TIMEOUT;
+ poll_wait = 1;
+ }
+ while (len) {
+ struct pollfd pfd;
+
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+ err = poll(&pfd, 1, timeout);
+ if (!err) {
+ if (poll_wait)
+ continue;
+ return ISCSI_ERR_ISCSID_NOTCONN;
+ } else if (err < 0) {
+ if (errno == EINTR)
+ continue;
+ log_error("got poll error (%d/%d), daemon died?",
+ err, errno);
+ return ISCSI_ERR_ISCSID_COMM_ERR;
+ } else if (pfd.revents & POLLIN) {
+ err = recv(fd, rsp, sizeof(*rsp), MSG_WAITALL);
+ if (err < 0) {
+ log_error("read error (%d/%d), daemon died?",
+ err, errno);
+ break;
+ }
+ len -= err;
+ iscsi_err = rsp->err;
+ }
+ }
close(fd);
if (!iscsi_err && cmd != rsp->command)
@@ -136,7 +167,7 @@ int iscsid_response(int fd, iscsiadm_cmd_e cmd, iscsiadm_rsp_t *rsp)
}
int iscsid_exec_req(iscsiadm_req_t *req, iscsiadm_rsp_t *rsp,
- int start_iscsid)
+ int start_iscsid, int tmo)
{
int fd;
int err;
@@ -145,7 +176,7 @@ int iscsid_exec_req(iscsiadm_req_t *req, iscsiadm_rsp_t *rsp,
if (err)
return err;
- return iscsid_response(fd, req->command, rsp);
+ return iscsid_response(fd, req->command, rsp, tmo);
}
int iscsid_req_wait(iscsiadm_cmd_e cmd, int fd)
@@ -153,7 +184,7 @@ int iscsid_req_wait(iscsiadm_cmd_e cmd, int fd)
iscsiadm_rsp_t rsp;
memset(&rsp, 0, sizeof(iscsiadm_rsp_t));
- return iscsid_response(fd, cmd, &rsp);
+ return iscsid_response(fd, cmd, &rsp, -1);
}
int iscsid_req_by_rec_async(iscsiadm_cmd_e cmd, node_rec_t *rec, int *fd)
diff --git a/usr/iscsid_req.h b/usr/iscsid_req.h
index 8cb4a92..67e509e 100644
--- a/usr/iscsid_req.h
+++ b/usr/iscsid_req.h
@@ -21,17 +21,20 @@
#ifndef ISCSID_REQ_H_
#define ISCSID_REQ_H
+#define ISCSID_REQ_TIMEOUT 1000
+
struct iscsiadm_req;
struct iscsiadm_rsp;
struct node_rec;
extern int iscsid_exec_req(struct iscsiadm_req *req, struct iscsiadm_rsp *rsp,
- int iscsid_start);
-extern int iscsid_req_wait(int cmd, int fd);
-extern int iscsid_req_by_rec_async(int cmd, struct node_rec *rec, int *fd);
-extern int iscsid_req_by_rec(int cmd, struct node_rec *rec);
-extern int iscsid_req_by_sid_async(int cmd, int sid, int *fd);
-extern int iscsid_req_by_sid(int cmd, int sid);
+ int iscsid_start, int tmo);
+extern int iscsid_req_wait(iscsiadm_cmd_e cmd, int fd);
+extern int iscsid_req_by_rec_async(iscsiadm_cmd_e cmd, struct node_rec *rec,
+ int *fd);
+extern int iscsid_req_by_rec(iscsiadm_cmd_e cmd, struct node_rec *rec);
+extern int iscsid_req_by_sid_async(iscsiadm_cmd_e cmd, int sid, int *fd);
+extern int iscsid_req_by_sid(iscsiadm_cmd_e cmd, int sid);
extern int uip_broadcast(void *buf, size_t buf_len, int fd_flags,
uint32_t *status);
diff --git a/usr/iscsistart.c b/usr/iscsistart.c
index 16a12ef..5cf0972 100644
--- a/usr/iscsistart.c
+++ b/usr/iscsistart.c
@@ -123,7 +123,7 @@ static int stop_event_loop(void)
memset(&req, 0, sizeof(req));
req.command = MGMT_IPC_IMMEDIATE_STOP;
- rc = iscsid_exec_req(&req, &rsp, 0);
+ rc = iscsid_exec_req(&req, &rsp, 0, -1);
if (rc) {
iscsi_err_print_msg(rc);
log_error("Could not stop event_loop");
@@ -235,7 +235,7 @@ static int login_session(struct node_rec *rec)
memcpy(&req.u.session.rec, rec, sizeof(*rec));
retry:
- rc = iscsid_exec_req(&req, &rsp, 0);
+ rc = iscsid_exec_req(&req, &rsp, 0, ISCSID_REQ_TIMEOUT);
/*
* handle race where iscsid proc is starting up while we are
* trying to connect.
diff --git a/usr/session_info.c b/usr/session_info.c
index 89422d8..9dc6e25 100644
--- a/usr/session_info.c
+++ b/usr/session_info.c
@@ -93,7 +93,7 @@ static int session_info_print_flat(void *data, struct session_info *info)
return 0;
}
-static int print_iscsi_state(int sid, char *prefix)
+static int print_iscsi_state(int sid, char *prefix, int tmo)
{
iscsiadm_req_t req;
iscsiadm_rsp_t rsp;
@@ -120,7 +120,7 @@ static int print_iscsi_state(int sid, char *prefix)
req.command = MGMT_IPC_SESSION_INFO;
req.u.session.sid = sid;
- err = iscsid_exec_req(&req, &rsp, 1);
+ err = iscsid_exec_req(&req, &rsp, 1, tmo);
/*
* for drivers like qla4xxx, iscsid does not display
* anything here since it does not know about it.
@@ -236,7 +236,7 @@ static int print_scsi_state(int sid, char *prefix, unsigned int flags)
}
void session_info_print_tree(struct list_head *list, char *prefix,
- unsigned int flags, int do_show)
+ unsigned int flags, int do_show, int tmo)
{
struct session_info *curr, *prev = NULL;
@@ -289,7 +289,7 @@ void session_info_print_tree(struct list_head *list, char *prefix,
if (flags & SESSION_INFO_ISCSI_STATE) {
printf("%s\t\tSID: %d\n", prefix, curr->sid);
- print_iscsi_state(curr->sid, prefix);
+ print_iscsi_state(curr->sid, prefix, tmo);
}
if (flags & SESSION_INFO_ISCSI_TIM) {
@@ -407,7 +407,8 @@ int session_info_print(int info_level, struct session_info *info, int do_show)
if (info) {
INIT_LIST_HEAD(&info->list);
list_add_tail(&list, &info->list);
- session_info_print_tree(&list, "", flags, do_show);
+ session_info_print_tree(&list, "", flags, do_show,
+ info->iscsid_req_tmo);
num_found = 1;
break;
}
@@ -422,7 +423,8 @@ int session_info_print(int info_level, struct session_info *info, int do_show)
if (err || !num_found)
break;
- session_info_print_tree(&list, "", flags, do_show);
+ session_info_print_tree(&list, "", flags, do_show,
+ info->iscsid_req_tmo);
session_info_free_list(&list);
break;
default:
diff --git a/usr/session_info.h b/usr/session_info.h
index 726aefd..179b088 100644
--- a/usr/session_info.h
+++ b/usr/session_info.h
@@ -28,6 +28,7 @@ struct session_info {
/* local info */
struct iface_rec iface;
int sid;
+ int iscsid_req_tmo;
struct session_timeout tmo;
struct session_CHAP chap;
@@ -60,8 +61,8 @@ struct session_link_info {
extern int session_info_create_list(void *data, struct session_info *info);
extern void session_info_free_list(struct list_head *list);
extern int session_info_print(int info_level, struct session_info *match_info,
- int do_show);
+ int do_show);
extern void session_info_print_tree(struct list_head *list, char *prefix,
- unsigned int flags, int do_show);
+ unsigned int flags, int do_show, int tmo);
#endif