290 lines
7.5 KiB
Diff
290 lines
7.5 KiB
Diff
|
diff -aurp open-iscsi-2.0-872-rc1-bnx2i.base/usr/discoveryd.c open-iscsi-2.0-872-rc1-bnx2i.work/usr/discoveryd.c
|
||
|
--- open-iscsi-2.0-872-rc1-bnx2i.base/usr/discoveryd.c 2010-05-18 17:58:00.000000000 -0500
|
||
|
+++ open-iscsi-2.0-872-rc1-bnx2i.work/usr/discoveryd.c 2010-05-19 03:09:54.000000000 -0500
|
||
|
@@ -54,6 +54,7 @@
|
||
|
#define DISC_DEF_POLL_INVL 30
|
||
|
|
||
|
static LIST_HEAD(iscsi_targets);
|
||
|
+static int stop_discoveryd;
|
||
|
|
||
|
static LIST_HEAD(isns_initiators);
|
||
|
static LIST_HEAD(isns_refresh_list);
|
||
|
@@ -66,27 +67,64 @@ static void isns_reg_refresh_by_eid_qry(
|
||
|
typedef void (do_disc_and_login_fn)(const char *def_iname, char *addr,
|
||
|
int port, int poll_inval);
|
||
|
|
||
|
-static int logout_stale_session(void *data, struct list_head *list,
|
||
|
- struct session_info *info)
|
||
|
+static int logout_session(void *data, struct list_head *list,
|
||
|
+ struct session_info *info)
|
||
|
{
|
||
|
- struct list_head *stale_rec_list = data;
|
||
|
+ struct list_head *rec_list = data;
|
||
|
struct node_rec *rec;
|
||
|
|
||
|
- list_for_each_entry(rec, stale_rec_list, list) {
|
||
|
+ list_for_each_entry(rec, rec_list, list) {
|
||
|
if (iscsi_match_session(rec, info))
|
||
|
return iscsi_logout_portal(info, list);
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
-static void free_curr_targets(void)
|
||
|
+static void discoveryd_stop(void)
|
||
|
{
|
||
|
struct node_rec *rec, *tmp_rec;
|
||
|
+ int nr_found = 0;
|
||
|
|
||
|
+ if (list_empty(&iscsi_targets))
|
||
|
+ goto done;
|
||
|
+
|
||
|
+ /*
|
||
|
+ * User requested to just login and exit.
|
||
|
+ */
|
||
|
+ if (!stop_discoveryd)
|
||
|
+ goto done;
|
||
|
+
|
||
|
+ iscsi_logout_portals(&iscsi_targets, &nr_found, 1, logout_session);
|
||
|
list_for_each_entry_safe(rec, tmp_rec, &iscsi_targets, list) {
|
||
|
list_del(&rec->list);
|
||
|
free(rec);
|
||
|
}
|
||
|
+
|
||
|
+done:
|
||
|
+ exit(0);
|
||
|
+}
|
||
|
+
|
||
|
+static void catch_signal(int signo)
|
||
|
+{
|
||
|
+ log_debug(1, "%d caught signal -%d...", signo, getpid());
|
||
|
+ switch (signo) {
|
||
|
+ case SIGTERM:
|
||
|
+ stop_discoveryd = 1;
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ break;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static void setup_signal_handler(void)
|
||
|
+{
|
||
|
+ struct sigaction sa_old;
|
||
|
+ struct sigaction sa_new;
|
||
|
+
|
||
|
+ sa_new.sa_handler = catch_signal;
|
||
|
+ sigemptyset(&sa_new.sa_mask);
|
||
|
+ sa_new.sa_flags = 0;
|
||
|
+ sigaction(SIGTERM, &sa_new, &sa_old );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
@@ -158,7 +196,7 @@ static void update_sessions(struct list_
|
||
|
|
||
|
if (!list_empty(&stale_rec_list)) {
|
||
|
iscsi_logout_portals(&stale_rec_list, &nr_found, 0,
|
||
|
- logout_stale_session);
|
||
|
+ logout_session);
|
||
|
list_for_each_entry_safe(rec, tmp_rec, &stale_rec_list, list) {
|
||
|
list_del(&rec->list);
|
||
|
free(rec);
|
||
|
@@ -194,6 +232,7 @@ static void do_disc_to_addrs(const char
|
||
|
|
||
|
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)
|
||
|
@@ -201,6 +240,7 @@ static void do_disc_to_addrs(const char
|
||
|
"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();
|
||
|
}
|
||
|
@@ -872,8 +912,7 @@ static int isns_scn_recv(isns_server_t *
|
||
|
|
||
|
log_debug(1, "isns_scn_recv");
|
||
|
|
||
|
- while (1) {
|
||
|
-
|
||
|
+ while (!stop_discoveryd) {
|
||
|
/* reap disc/login procs */
|
||
|
reap_proc();
|
||
|
/*
|
||
|
@@ -999,7 +1038,6 @@ static int isns_eventd(const char *def_i
|
||
|
isns_cancel_refresh_timers();
|
||
|
fail:
|
||
|
isns_clear_refresh_list();
|
||
|
- free_curr_targets();
|
||
|
|
||
|
list_for_each_entry_safe(node, tmp_node, &isns_initiators, list) {
|
||
|
list_del(&node->list);
|
||
|
@@ -1028,6 +1066,7 @@ static void start_isns(const char *def_i
|
||
|
|
||
|
rc = isns_eventd(def_iname, disc_addr, port, poll_inval);
|
||
|
log_debug(1, "start isns done %d.", rc);
|
||
|
+ discoveryd_stop();
|
||
|
}
|
||
|
|
||
|
/* SendTargets */
|
||
|
@@ -1087,9 +1126,9 @@ static void do_st_disc_and_login(const c
|
||
|
__do_st_disc_and_login(disc_addr, port);
|
||
|
if (!poll_inval)
|
||
|
break;
|
||
|
- } while (!sleep(poll_inval));
|
||
|
+ } while (!stop_discoveryd && !sleep(poll_inval));
|
||
|
|
||
|
- free_curr_targets();
|
||
|
+ discoveryd_stop();
|
||
|
}
|
||
|
|
||
|
void discoveryd_start(const char *def_iname)
|
||
|
diff -aurp open-iscsi-2.0-872-rc1-bnx2i.base/usr/event_poll.c open-iscsi-2.0-872-rc1-bnx2i.work/usr/event_poll.c
|
||
|
--- open-iscsi-2.0-872-rc1-bnx2i.base/usr/event_poll.c 2010-05-18 17:58:00.000000000 -0500
|
||
|
+++ open-iscsi-2.0-872-rc1-bnx2i.work/usr/event_poll.c 2010-05-19 04:26:20.000000000 -0500
|
||
|
@@ -62,21 +62,75 @@ void reap_proc(void)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+static LIST_HEAD(shutdown_callbacks);
|
||
|
+
|
||
|
+struct shutdown_callback {
|
||
|
+ struct list_head list;
|
||
|
+ pid_t pid;
|
||
|
+};
|
||
|
+
|
||
|
+int shutdown_callback(pid_t pid)
|
||
|
+{
|
||
|
+ struct shutdown_callback *cb;
|
||
|
+
|
||
|
+ cb = calloc(1, sizeof(*cb));
|
||
|
+ if (!cb)
|
||
|
+ return ENOMEM;
|
||
|
+
|
||
|
+ INIT_LIST_HEAD(&cb->list);
|
||
|
+ cb->pid = pid;
|
||
|
+ log_debug(1, "adding %d for shutdown cb\n", pid);
|
||
|
+ list_add_tail(&cb->list, &shutdown_callbacks);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static void shutdown_notify_pids(void)
|
||
|
+{
|
||
|
+ struct shutdown_callback *cb;
|
||
|
+
|
||
|
+ list_for_each_entry(cb, &shutdown_callbacks, list) {
|
||
|
+ log_debug(1, "Killing %d\n", cb->pid);
|
||
|
+ kill(cb->pid, SIGTERM);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static int shutdown_wait_pids(void)
|
||
|
+{
|
||
|
+ struct shutdown_callback *cb, *tmp;
|
||
|
+
|
||
|
+ list_for_each_entry_safe(cb, tmp, &shutdown_callbacks, list) {
|
||
|
+ /*
|
||
|
+ * the proc reaper could clean it up, so wait for any
|
||
|
+ * sign that it is gone.
|
||
|
+ */
|
||
|
+ if (waitpid(cb->pid, NULL, WNOHANG)) {
|
||
|
+ log_debug(1, "%d done\n", cb->pid);
|
||
|
+ list_del(&cb->list);
|
||
|
+ free(cb);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ return list_empty(&shutdown_callbacks);
|
||
|
+}
|
||
|
+
|
||
|
#define POLL_CTRL 0
|
||
|
#define POLL_IPC 1
|
||
|
#define POLL_MAX 2
|
||
|
|
||
|
static int event_loop_stop;
|
||
|
+static queue_task_t *shutdown_qtask;
|
||
|
+
|
||
|
|
||
|
-void event_loop_exit(void)
|
||
|
+void event_loop_exit(queue_task_t *qtask)
|
||
|
{
|
||
|
+ shutdown_qtask = qtask;
|
||
|
event_loop_stop = 1;
|
||
|
}
|
||
|
|
||
|
void event_loop(struct iscsi_ipc *ipc, int control_fd, int mgmt_ipc_fd)
|
||
|
{
|
||
|
struct pollfd poll_array[POLL_MAX];
|
||
|
- int res;
|
||
|
+ int res, has_shutdown_children = 0;
|
||
|
|
||
|
poll_array[POLL_CTRL].fd = control_fd;
|
||
|
poll_array[POLL_CTRL].events = POLLIN;
|
||
|
@@ -84,7 +138,16 @@ void event_loop(struct iscsi_ipc *ipc, i
|
||
|
poll_array[POLL_IPC].events = POLLIN;
|
||
|
|
||
|
event_loop_stop = 0;
|
||
|
- while (!event_loop_stop) {
|
||
|
+ while (1) {
|
||
|
+ if (event_loop_stop) {
|
||
|
+ if (!has_shutdown_children) {
|
||
|
+ has_shutdown_children = 1;
|
||
|
+ shutdown_notify_pids();
|
||
|
+ }
|
||
|
+ if (shutdown_wait_pids())
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
res = poll(poll_array, POLL_MAX, ACTOR_RESOLUTION);
|
||
|
if (res > 0) {
|
||
|
log_debug(6, "poll result %d", res);
|
||
|
@@ -110,4 +173,6 @@ void event_loop(struct iscsi_ipc *ipc, i
|
||
|
*/
|
||
|
sysfs_cleanup();
|
||
|
}
|
||
|
+ if (shutdown_qtask)
|
||
|
+ mgmt_ipc_write_rsp(shutdown_qtask, MGMT_IPC_OK);
|
||
|
}
|
||
|
diff -aurp open-iscsi-2.0-872-rc1-bnx2i.base/usr/event_poll.h open-iscsi-2.0-872-rc1-bnx2i.work/usr/event_poll.h
|
||
|
--- open-iscsi-2.0-872-rc1-bnx2i.base/usr/event_poll.h 2010-05-18 17:58:00.000000000 -0500
|
||
|
+++ open-iscsi-2.0-872-rc1-bnx2i.work/usr/event_poll.h 2010-05-19 03:24:24.000000000 -0500
|
||
|
@@ -20,10 +20,12 @@
|
||
|
#define EVENT_POLL_H
|
||
|
|
||
|
struct iscsi_ipc;
|
||
|
+struct queue_task;
|
||
|
|
||
|
+int shutdown_callback(pid_t pid);
|
||
|
void reap_proc(void);
|
||
|
void reap_inc(void);
|
||
|
void event_loop(struct iscsi_ipc *ipc, int control_fd, int mgmt_ipc_fd);
|
||
|
-void event_loop_exit(void);
|
||
|
+void event_loop_exit(struct queue_task *qtask);
|
||
|
|
||
|
#endif
|
||
|
diff -aurp open-iscsi-2.0-872-rc1-bnx2i.base/usr/mgmt_ipc.c open-iscsi-2.0-872-rc1-bnx2i.work/usr/mgmt_ipc.c
|
||
|
--- open-iscsi-2.0-872-rc1-bnx2i.base/usr/mgmt_ipc.c 2010-05-18 17:58:00.000000000 -0500
|
||
|
+++ open-iscsi-2.0-872-rc1-bnx2i.work/usr/mgmt_ipc.c 2010-05-19 03:24:33.000000000 -0500
|
||
|
@@ -74,7 +74,7 @@ mgmt_ipc_listen(void)
|
||
|
void
|
||
|
mgmt_ipc_close(int fd)
|
||
|
{
|
||
|
- event_loop_exit();
|
||
|
+ event_loop_exit(NULL);
|
||
|
if (fd >= 0)
|
||
|
close(fd);
|
||
|
}
|
||
|
@@ -190,8 +190,7 @@ mgmt_ipc_conn_add(queue_task_t *qtask)
|
||
|
static mgmt_ipc_err_e
|
||
|
mgmt_ipc_immediate_stop(queue_task_t *qtask)
|
||
|
{
|
||
|
- event_loop_exit();
|
||
|
- mgmt_ipc_write_rsp(qtask, MGMT_IPC_OK);
|
||
|
+ event_loop_exit(qtask);
|
||
|
return MGMT_IPC_OK;
|
||
|
}
|
||
|
|