[launchd-changes] [23052] trunk/launchd/src/launchd_core_logic.c

source_changes at macosforge.org source_changes at macosforge.org
Fri Feb 9 14:31:37 PST 2007


Revision: 23052
          http://trac.macosforge.org/projects/launchd/changeset/23052
Author:   zarzycki at apple.com
Date:     2007-02-09 14:31:36 -0800 (Fri, 09 Feb 2007)

Log Message:
-----------
Even better shutdown debugging.

Modified Paths:
--------------
    trunk/launchd/src/launchd_core_logic.c

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2007-02-09 17:56:21 UTC (rev 23051)
+++ trunk/launchd/src/launchd_core_logic.c	2007-02-09 22:31:36 UTC (rev 23052)
@@ -32,6 +32,7 @@
 #include <mach/host_info.h>
 #include <mach/mach_host.h>
 #include <mach/exception.h>
+#include <mach/host_reboot.h>
 #include <sys/types.h>
 #include <sys/queue.h>
 #include <sys/event.h>
@@ -199,6 +200,7 @@
 	char *jm_stdout;
 	char *jm_stderr;
 	unsigned int global_on_demand_cnt;
+	unsigned int would_have_sigkilled;
 	unsigned int transfer_bstrap:1, sent_stop_to_hopeful_jobs:1, shutting_down:1;
 	char name[0];
 };
@@ -209,6 +211,7 @@
 static jobmgr_t jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t checkin_port);
 static jobmgr_t jobmgr_parent(jobmgr_t jm);
 static jobmgr_t jobmgr_tickle(jobmgr_t jm);
+static void jobmgr_log_stray_children(jobmgr_t jm);
 static void jobmgr_remove(jobmgr_t jm);
 static void jobmgr_dispatch_all(jobmgr_t jm);
 static job_t jobmgr_new_anonymous(jobmgr_t jm);
@@ -305,6 +308,7 @@
 static const char *job_prog(job_t j);
 static pid_t job_get_pid(job_t j);
 static jobmgr_t job_get_bs(job_t j);
+static void job_kill(job_t j);
 static void job_uncork_fork(job_t j);
 static void job_log_stdouterr(job_t j);
 static void job_logv(job_t j, int pri, int err, const char *msg, va_list ap);
@@ -337,6 +341,7 @@
 static bool cronemu_hour(struct tm *wtm, int hour, int min);
 static bool cronemu_min(struct tm *wtm, int min);
 
+static unsigned int total_children;
 static int dir_has_files(job_t j, const char *path);
 static char **mach_cmd2argv(const char *string);
 jobmgr_t root_jobmgr;
@@ -1628,6 +1633,8 @@
 		return;
 	}
 
+	total_children--;
+
 	/* Performance hack */
 	TAILQ_REMOVE(&j->mgr->jobs, j, sle);
 	TAILQ_INSERT_TAIL(&j->mgr->jobs, j, sle);
@@ -1756,6 +1763,19 @@
 }
 
 void
+job_kill(job_t j)
+{
+	if (debug_shutdown_hangs) {
+		j->mgr->would_have_sigkilled++;
+		if (j->mgr->would_have_sigkilled >= total_children) {
+			job_assumes(j, host_reboot(mach_host_self(), HOST_REBOOT_DEBUGGER) == 0);
+		}
+	} else {
+		job_assumes(j, kill(j->p, SIGKILL) != -1);
+	}
+}
+
+void
 job_callback(void *obj, struct kevent *kev)
 {
 	job_t j = obj;
@@ -1771,7 +1791,7 @@
 		} else if ((uintptr_t)&j->exit_timeout == kev->ident) {
 			job_force_sampletool(j);
 			job_log(j, LOG_WARNING, "Exit timeout elapsed (%u seconds). Killing.", j->exit_timeout);
-			job_assumes(j, kill(j->p, SIGKILL) != -1);
+			job_kill(j);
 		} else {
 			calendarinterval_callback(j, kev);
 		}
@@ -1883,6 +1903,8 @@
 		job_start_child(j);
 		break;
 	default:
+		total_children++;
+
 		/* Performance hack */
 		TAILQ_REMOVE(&j->mgr->jobs, j, sle);
 		TAILQ_INSERT_HEAD(&j->mgr->jobs, j, sle);
@@ -2810,16 +2832,7 @@
 		job_log(j, LOG_INFO, "Exited. Was only configured to run once.");
 		return true;
 	} else if (j->mgr->shutting_down) {
-		unsigned int cnt = 0;
-		job_t ji;
-
-		TAILQ_FOREACH(ji, &j->mgr->jobs, sle) {
-			if (ji->p) {
-				cnt++;
-			}
-		}
-
-		job_log(j, LOG_INFO, "Exited while shutdown in progress. Processes remaining: %u", cnt);
+		job_log(j, LOG_NOTICE, "Exited while shutdown in progress. Processes remaining: %u", total_children);
 		return true;
 	} else if (!j->checkedin && (!SLIST_EMPTY(&j->sockets) || !SLIST_EMPTY(&j->machservices))) {
 		job_log(j, LOG_WARNING, "Failed to check-in!");
@@ -3197,6 +3210,7 @@
 	jm->sent_stop_to_hopeful_jobs = true;
 
 	if (jobmgr_is_idle(jm)) {
+		jobmgr_log_stray_children(jm);
 		jobmgr_remove(jm);
 		return NULL;
 	}
@@ -3204,6 +3218,42 @@
 	return jm;
 }
 
+void
+jobmgr_log_stray_children(jobmgr_t jm)
+{
+	int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
+	size_t i, kp_cnt, len = 10*1024*1024;
+	struct kinfo_proc *kp;
+
+	if (jm->parentmgr || getpid() != 1) {
+		return;
+	}
+
+	if (!jobmgr_assumes(jm, (kp = malloc(len)) != NULL)) {
+		return;
+	}
+	if (!jobmgr_assumes(jm, sysctl(mib, 3, kp, &len, NULL, 0) != -1)) {
+		goto out;
+	}
+
+	kp_cnt = len / sizeof(struct kinfo_proc);
+
+	for (i = 0; i < kp_cnt; i++) {
+		pid_t p_i = kp[i].kp_proc.p_pid;
+		pid_t pp_i = kp[i].kp_eproc.e_ppid;
+
+		if (p_i == 0 || p_i == 1) {
+			continue;
+		}
+
+		jobmgr_log(jm, LOG_WARNING, "Stray process at shutdown: PID %u PPID %u %s", p_i, pp_i, kp[i].kp_proc.p_comm);
+		jobmgr_assumes(jm, kill(p_i, SIGKILL) != -1);
+	}
+
+out:
+	free(kp);
+}
+
 bool
 jobmgr_is_idle(jobmgr_t jm)
 {

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20070209/3ce0759e/attachment.html


More information about the launchd-changes mailing list