iscsi-initiator-utils/iscsi-initiator-utils-fix-dd-stop.patch
2010-05-19 10:38:36 +00:00

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;
}