[launchd-changes] [22864] trunk/launchd/src

source_changes at macosforge.org source_changes at macosforge.org
Thu Sep 21 12:19:36 PDT 2006


Revision: 22864
          http://trac.macosforge.org/projects/launchd/changeset/22864
Author:   zarzycki at apple.com
Date:     2006-09-21 12:19:35 -0700 (Thu, 21 Sep 2006)

Log Message:
-----------
This hack makes it easier to debug shutdown related hangs caused by launchd jobs.

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

Modified: trunk/launchd/src/launchd.c
===================================================================
--- trunk/launchd/src/launchd.c	2006-09-21 17:50:27 UTC (rev 22863)
+++ trunk/launchd/src/launchd.c	2006-09-21 19:19:35 UTC (rev 22864)
@@ -104,6 +104,7 @@
 
 sigset_t blocked_signals = 0;
 bool shutdown_in_progress = false;
+bool debug_shutdown_hangs = false;
 bool network_up = false;
 int batch_disabler_count = 0;
 
@@ -378,19 +379,24 @@
 void
 launchd_shutdown(void)
 {
+	struct stat sb;
+
 	if (shutdown_in_progress)
 		return;
 
 	shutdown_in_progress = true;
 
-	runtime_force_on_demand(true);
-	
+	if (stat("/var/db/debugShutdownHangs", &sb) != -1) {
+		debug_shutdown_hangs = true;
+	}
+
 	rlcj = NULL;
 
 	job_remove_all_inactive(root_job);
 
-	if (getpid() == 1)
+	if (getpid() == 1) {
 		catatonia();
+	}
 }
 
 void

Modified: trunk/launchd/src/launchd.h
===================================================================
--- trunk/launchd/src/launchd.h	2006-09-21 17:50:27 UTC (rev 22863)
+++ trunk/launchd/src/launchd.h	2006-09-21 19:19:35 UTC (rev 22864)
@@ -35,6 +35,7 @@
 extern kq_callback kqsimple_zombie_reaper;
 extern sigset_t blocked_signals;
 extern bool shutdown_in_progress;
+extern bool debug_shutdown_hangs;
 extern bool network_up;
 extern int batch_disabler_count;
 extern mach_port_t inherited_bootstrap_port;

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2006-09-21 17:50:27 UTC (rev 22863)
+++ trunk/launchd/src/launchd_core_logic.c	2006-09-21 19:19:35 UTC (rev 22864)
@@ -236,6 +236,7 @@
 static void job_setup_attributes(job_t j);
 static bool job_setup_machport(job_t j);
 static void job_postfork_become_user(job_t j);
+static void job_force_sampletool(job_t j);
 static void job_callback(void *obj, struct kevent *kev);
 static pid_t job_fork(job_t j);
 static size_t job_prep_log_preface(job_t j, char *buf);
@@ -433,8 +434,13 @@
 
 	if (!job_active(j)) {
 		job_remove(j);
-	} else if (getpid() != 1) {
-		job_stop(j);
+	} else {
+		if (debug_shutdown_hangs) {
+			job_assumes(j, kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_ADD|EV_ONESHOT, NOTE_SECONDS, 8, j) != -1);
+		}
+		if (getpid() != 1) {
+			job_stop(j);
+		}
 	}
 }
 
@@ -539,7 +545,7 @@
 		free(j->stderrpath);
 
 	if (j->start_interval)
-		kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
+		job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1);
 
 	kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
 	free(j);
@@ -979,10 +985,11 @@
 	case 't':
 	case 'T':
 		if (strcasecmp(key, LAUNCH_JOBKEY_TIMEOUT) == 0) {
-			if (value <= 0)
+			if (value <= 0) {
 				job_log(j, LOG_WARNING, "Timeout less than or equal to zero. Ignoring.");
-			else
+			} else {
 				j->timeout = value;
+			}
 		} else if (strcasecmp(key, LAUNCH_JOBKEY_THROTTLEINTERVAL) == 0) {
 			if (value < 0) {
 				job_log(j, LOG_WARNING, "%s less than zero. Ignoring.", LAUNCH_JOBKEY_THROTTLEINTERVAL);
@@ -1001,12 +1008,14 @@
 	case 's':
 	case 'S':
 		if (strcasecmp(key, LAUNCH_JOBKEY_STARTINTERVAL) == 0) {
-			if (value <= 0)
+			if (value <= 0) {
 				job_log(j, LOG_WARNING, "StartInterval is not greater than zero, ignoring");
-			else
+			} else {
 				j->start_interval = value;
-			if (-1 == kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, value, j))
+			}
+			if (-1 == kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, value, j)) {
 				job_log_error(j, LOG_ERR, "adding kevent timer");
+			}
 		}
 		break;
 	default:
@@ -1410,7 +1419,13 @@
 		}
 		break;
 	case EVFILT_TIMER:
-		if ((uintptr_t)j == kev->ident || (uintptr_t)&j->start_interval == kev->ident) {
+		if ((uintptr_t)j == kev->ident) {
+			if (j->p && job_assumes(j, debug_shutdown_hangs)) {
+				job_force_sampletool(j);
+			} else {
+				job_dispatch(j, true);
+			}
+		} else if ((uintptr_t)&j->start_interval == kev->ident) {
 			job_dispatch(j, true);
 		} else {
 			calendarinterval_callback(j, kev);
@@ -2962,6 +2977,27 @@
 	return j->p;
 }
 
+void
+job_force_sampletool(job_t j)
+{
+	char pidstr[100];
+	pid_t sp;
+	
+	sprintf(pidstr, "%u", j->p);
+
+	switch ((sp = fork())) {
+	case -1:
+		job_log_error(j, LOG_DEBUG, "Failed to spawn sample tool");
+		break;
+	case 0:
+		job_assumes(j, execlp("sample", "sample", pidstr, "1", "-mayDie", NULL) != -1);
+		_exit(EXIT_FAILURE);
+	default:
+		job_assumes(j, kevent_mod(sp, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, &kqsimple_zombie_reaper) != -1);
+		break;
+	}
+}
+
 bool
 semaphoreitem_new(job_t j, semaphore_reason_t why, const char *what)
 {

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


More information about the launchd-changes mailing list