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

source_changes at macosforge.org source_changes at macosforge.org
Wed Feb 7 15:39:59 PST 2007


Revision: 23040
          http://trac.macosforge.org/projects/launchd/changeset/23040
Author:   zarzycki at apple.com
Date:     2007-02-07 15:39:58 -0800 (Wed, 07 Feb 2007)

Log Message:
-----------
Add a per job exit timeout.

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

Modified: trunk/launchd/src/launchd.plist.5
===================================================================
--- trunk/launchd/src/launchd.plist.5	2007-02-07 21:07:49 UTC (rev 23039)
+++ trunk/launchd/src/launchd.plist.5	2007-02-07 23:39:58 UTC (rev 23040)
@@ -176,6 +176,10 @@
 The recommended idle time out (in seconds) to pass to the job. If no value is specified, a default time out will be supplied by
 .Nm launchd
 for use by the job at check in time.
+.It Sy ExitTimeOut <integer>
+The amount of time
+.Nm launchd
+waits before sending a SIGKILL signal. The default value is 20 seconds. The value zero is interpreted as infinity.
 .It Sy ThrottleInterval <integer>
 This key lets one override the default throttling policy imposed on jobs by
 .Nm launchd .

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2007-02-07 21:07:49 UTC (rev 23039)
+++ trunk/launchd/src/launchd_core_logic.c	2007-02-07 23:39:58 UTC (rev 23040)
@@ -87,6 +87,7 @@
 
 #define LAUNCHD_MIN_JOB_RUN_TIME 10
 #define LAUNCHD_ADVISABLE_IDLE_TIMEOUT 30
+#define LAUNCHD_DEFAULT_EXIT_TIMEOUT 20
 
 extern char **environ;
 
@@ -254,8 +255,10 @@
 	int forkfd;
 	int log_redirect_fd;
 	int nice;
-	int timeout;
+	unsigned int timeout;
+	unsigned int exit_timeout;
 	int stdout_err_fd;
+	struct timeval sent_sigterm_time;
 	time_t start_time;
 	time_t min_run_time;
 	unsigned int start_interval;
@@ -405,6 +408,11 @@
 {
 	if (j->p) {
 		job_assumes(j, kill(j->p, SIGTERM) != -1);
+		job_assumes(j, gettimeofday(&j->sent_sigterm_time, NULL) != -1);
+		if (j->exit_timeout) {
+			job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER,
+						EV_ADD|EV_ONESHOT, NOTE_SECONDS, j->exit_timeout, j) != -1);
+		}
 	}
 }
 
@@ -516,9 +524,6 @@
 		if (!job_active(ji)) {
 			job_remove(ji);
 		} else {
-			if (debug_shutdown_hangs) {
-				job_assumes(ji, kevent_mod((uintptr_t)ji, EVFILT_TIMER, EV_ADD|EV_ONESHOT, NOTE_SECONDS, 8, ji) != -1);
-			}
 			job_stop(ji);
 		}
 	}
@@ -662,6 +667,9 @@
 	if (j->start_interval) {
 		job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1);
 	}
+	if (j->exit_timeout) {
+		kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
+	}
 
 	kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
 	free(j);
@@ -907,6 +915,7 @@
 	j->mgr = jm;
 	j->min_run_time = LAUNCHD_MIN_JOB_RUN_TIME;
 	j->timeout = LAUNCHD_ADVISABLE_IDLE_TIMEOUT;
+	j->exit_timeout = LAUNCHD_DEFAULT_EXIT_TIMEOUT;
 	j->currently_ignored = true;
 	j->ondemand = true;
 	j->checkedin = true;
@@ -1162,6 +1171,16 @@
 job_import_integer(job_t j, const char *key, long long value)
 {
 	switch (key[0]) {
+	case 'e':
+	case 'E':
+		if (strcasecmp(key, LAUNCH_JOBKEY_EXITTIMEOUT) == 0) {
+			if (value < 0) {
+				job_log(j, LOG_WARNING, "Exit timeout less zero. Ignoring.");
+			} else {
+				j->exit_timeout = value;
+			}
+		}
+		break;
 	case 'n':
 	case 'N':
 		if (strcasecmp(key, LAUNCH_JOBKEY_NICE) == 0) {
@@ -1577,6 +1596,7 @@
 void
 job_reap(job_t j)
 {
+	struct timeval tve, tvd;
 	struct rusage ru;
 	int status;
 
@@ -1596,12 +1616,24 @@
 		return;
 	}
 
+	job_assumes(j, gettimeofday(&tve, NULL) != -1);
+
 	if (j->wait_reply_port) {
 		job_log(j, LOG_DEBUG, "MPM wait reply being sent");
 		job_assumes(j, job_mig_wait_reply(j->wait_reply_port, 0, status) == 0);
 		j->wait_reply_port = MACH_PORT_NULL;
 	}
 
+	if (j->sent_sigterm_time.tv_sec) {
+		double delta;
+
+		timersub(&tve, &j->sent_sigterm_time,  &tvd);
+
+		delta = (double)tvd.tv_sec + (double)tvd.tv_usec / (double)1000000;
+
+		job_log(j, tvd.tv_sec ? LOG_NOTICE : LOG_INFO, "Exited %f seconds after SIGTERM was sent", delta);
+	}
+
 	timeradd(&ru.ru_utime, &j->ru.ru_utime, &j->ru.ru_utime);
 	timeradd(&ru.ru_stime, &j->ru.ru_stime, &j->ru.ru_stime);
 	j->ru.ru_maxrss += ru.ru_maxrss;
@@ -1724,14 +1756,14 @@
 		}
 		break;
 	case EVFILT_TIMER:
-		if ((uintptr_t)j == kev->ident) {
-			if (j->p && job_assumes(j, debug_shutdown_hangs)) {
+		if ((uintptr_t)j == kev->ident || (uintptr_t)&j->start_interval == kev->ident) {
+			job_dispatch(j, true);
+		} else if ((uintptr_t)&j->exit_timeout == kev->ident) {
+			if (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);
+			job_log(j, LOG_WARNING, "Exit timeout elapsed (%u seconds). Killing.", j->exit_timeout);
+			job_assumes(j, kill(j->p, SIGKILL) != -1);
 		} else {
 			calendarinterval_callback(j, kev);
 		}
@@ -1788,6 +1820,9 @@
 
 	job_log(j, LOG_DEBUG, "Starting");
 
+	j->sent_sigterm_time.tv_sec = 0;
+	j->sent_sigterm_time.tv_usec = 0;
+
 	/* FIXME, using stdinpath is a hack for re-reading the conf file */
 	if (j->stdinpath) {
 	       sipc = true;

Modified: trunk/launchd/src/liblaunch_public.h
===================================================================
--- trunk/launchd/src/liblaunch_public.h	2007-02-07 21:07:49 UTC (rev 23039)
+++ trunk/launchd/src/liblaunch_public.h	2007-02-07 23:39:58 UTC (rev 23040)
@@ -58,6 +58,7 @@
 #define LAUNCH_JOBKEY_USERNAME			"UserName"
 #define LAUNCH_JOBKEY_GROUPNAME			"GroupName"
 #define LAUNCH_JOBKEY_TIMEOUT			"TimeOut"
+#define LAUNCH_JOBKEY_EXITTIMEOUT		"ExitTimeOut"
 #define LAUNCH_JOBKEY_INITGROUPS		"InitGroups"
 #define LAUNCH_JOBKEY_SOCKETS			"Sockets"
 #define LAUNCH_JOBKEY_MACHSERVICES		"MachServices"

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


More information about the launchd-changes mailing list