Blob Blame History Raw
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;
 }