Projects
Browse Source     Search     Timeline     Wiki

Changeset 23040

Show
Ignore:
Timestamp:
02/07/07 15:39:58 (22 months ago)
Author:
zarzycki@…
Message:

Add a per job exit timeout.

Location:
trunk/launchd/src
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/launchd/src/launchd.plist.5

    r23033 r23040  
    177177.Nm launchd 
    178178for use by the job at check in time. 
     179.It Sy ExitTimeOut <integer> 
     180The amount of time 
     181.Nm launchd 
     182waits before sending a SIGKILL signal. The default value is 20 seconds. The value zero is interpreted as infinity. 
    179183.It Sy ThrottleInterval <integer> 
    180184This key lets one override the default throttling policy imposed on jobs by 
  • trunk/launchd/src/launchd_core_logic.c

    r23038 r23040  
    8888#define LAUNCHD_MIN_JOB_RUN_TIME 10 
    8989#define LAUNCHD_ADVISABLE_IDLE_TIMEOUT 30 
     90#define LAUNCHD_DEFAULT_EXIT_TIMEOUT 20 
    9091 
    9192extern char **environ; 
     
    255256        int log_redirect_fd; 
    256257        int nice; 
    257         int timeout; 
     258        unsigned int timeout; 
     259        unsigned int exit_timeout; 
    258260        int stdout_err_fd; 
     261        struct timeval sent_sigterm_time; 
    259262        time_t start_time; 
    260263        time_t min_run_time; 
     
    406409        if (j->p) { 
    407410                job_assumes(j, kill(j->p, SIGTERM) != -1); 
     411                job_assumes(j, gettimeofday(&j->sent_sigterm_time, NULL) != -1); 
     412                if (j->exit_timeout) { 
     413                        job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, 
     414                                                EV_ADD|EV_ONESHOT, NOTE_SECONDS, j->exit_timeout, j) != -1); 
     415                } 
    408416        } 
    409417} 
     
    517525                        job_remove(ji); 
    518526                } else { 
    519                         if (debug_shutdown_hangs) { 
    520                                 job_assumes(ji, kevent_mod((uintptr_t)ji, EVFILT_TIMER, EV_ADD|EV_ONESHOT, NOTE_SECONDS, 8, ji) != -1); 
    521                         } 
    522527                        job_stop(ji); 
    523528                } 
     
    663668                job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1); 
    664669        } 
     670        if (j->exit_timeout) { 
     671                kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); 
     672        } 
    665673 
    666674        kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); 
     
    908916        j->min_run_time = LAUNCHD_MIN_JOB_RUN_TIME; 
    909917        j->timeout = LAUNCHD_ADVISABLE_IDLE_TIMEOUT; 
     918        j->exit_timeout = LAUNCHD_DEFAULT_EXIT_TIMEOUT; 
    910919        j->currently_ignored = true; 
    911920        j->ondemand = true; 
     
    11631172{ 
    11641173        switch (key[0]) { 
     1174        case 'e': 
     1175        case 'E': 
     1176                if (strcasecmp(key, LAUNCH_JOBKEY_EXITTIMEOUT) == 0) { 
     1177                        if (value < 0) { 
     1178                                job_log(j, LOG_WARNING, "Exit timeout less zero. Ignoring."); 
     1179                        } else { 
     1180                                j->exit_timeout = value; 
     1181                        } 
     1182                } 
     1183                break; 
    11651184        case 'n': 
    11661185        case 'N': 
     
    15781597job_reap(job_t j) 
    15791598{ 
     1599        struct timeval tve, tvd; 
    15801600        struct rusage ru; 
    15811601        int status; 
     
    15961616                return; 
    15971617        } 
     1618 
     1619        job_assumes(j, gettimeofday(&tve, NULL) != -1); 
    15981620 
    15991621        if (j->wait_reply_port) { 
     
    16011623                job_assumes(j, job_mig_wait_reply(j->wait_reply_port, 0, status) == 0); 
    16021624                j->wait_reply_port = MACH_PORT_NULL; 
     1625        } 
     1626 
     1627        if (j->sent_sigterm_time.tv_sec) { 
     1628                double delta; 
     1629 
     1630                timersub(&tve, &j->sent_sigterm_time,  &tvd); 
     1631 
     1632                delta = (double)tvd.tv_sec + (double)tvd.tv_usec / (double)1000000; 
     1633 
     1634                job_log(j, tvd.tv_sec ? LOG_NOTICE : LOG_INFO, "Exited %f seconds after SIGTERM was sent", delta); 
    16031635        } 
    16041636 
     
    17251757                break; 
    17261758        case EVFILT_TIMER: 
    1727                 if ((uintptr_t)j == kev->ident) { 
    1728                         if (j->p && job_assumes(j, debug_shutdown_hangs)) { 
     1759                if ((uintptr_t)j == kev->ident || (uintptr_t)&j->start_interval == kev->ident) { 
     1760                        job_dispatch(j, true); 
     1761                } else if ((uintptr_t)&j->exit_timeout == kev->ident) { 
     1762                        if (debug_shutdown_hangs) { 
    17291763                                job_force_sampletool(j); 
    1730                         } else { 
    1731                                 job_dispatch(j, true); 
    17321764                        } 
    1733                 } else if ((uintptr_t)&j->start_interval == kev->ident) { 
    1734                         job_dispatch(j, true); 
     1765                        job_log(j, LOG_WARNING, "Exit timeout elapsed (%u seconds). Killing.", j->exit_timeout); 
     1766                        job_assumes(j, kill(j->p, SIGKILL) != -1); 
    17351767                } else { 
    17361768                        calendarinterval_callback(j, kev); 
     
    17881820 
    17891821        job_log(j, LOG_DEBUG, "Starting"); 
     1822 
     1823        j->sent_sigterm_time.tv_sec = 0; 
     1824        j->sent_sigterm_time.tv_usec = 0; 
    17901825 
    17911826        /* FIXME, using stdinpath is a hack for re-reading the conf file */ 
  • trunk/launchd/src/liblaunch_public.h

    r22994 r23040  
    5959#define LAUNCH_JOBKEY_GROUPNAME                 "GroupName" 
    6060#define LAUNCH_JOBKEY_TIMEOUT                   "TimeOut" 
     61#define LAUNCH_JOBKEY_EXITTIMEOUT               "ExitTimeOut" 
    6162#define LAUNCH_JOBKEY_INITGROUPS                "InitGroups" 
    6263#define LAUNCH_JOBKEY_SOCKETS                   "Sockets"