[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