Revision: 23081 http://trac.macosforge.org/projects/launchd/changeset/23081 Author: zarzycki@apple.com Date: 2007-02-18 10:48:19 -0800 (Sun, 18 Feb 2007) Log Message: ----------- Miscellaneous. Modified Paths: -------------- trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/launchd_runtime.c Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2007-02-16 18:12:03 UTC (rev 23080) +++ trunk/launchd/src/launchd_core_logic.c 2007-02-18 18:48:19 UTC (rev 23081) @@ -92,6 +92,7 @@ #define LAUNCHD_MIN_JOB_RUN_TIME 10 #define LAUNCHD_ADVISABLE_IDLE_TIMEOUT 30 #define LAUNCHD_DEFAULT_EXIT_TIMEOUT 20 +#define LAUNCHD_SIGKILL_TIMEOUT 5 extern char **environ; @@ -276,7 +277,7 @@ mode_t mask; unsigned int globargv:1, wait4debugger:1, unload_at_exit:1, stall_before_exec:1, only_once:1, currently_ignored:1, forced_peers_to_demand_mode:1, setnice:1, hopefully_exits_last:1, removal_pending:1, - wait4pipe_eof:1; + wait4pipe_eof:1, sent_sigkill:1; char label[0]; }; @@ -1709,7 +1710,12 @@ } } + if (!j->checkedin && (!SLIST_EMPTY(&j->sockets) || !SLIST_EMPTY(&j->machservices))) { + job_log(j, LOG_WARNING, "Failed to check-in!"); + } + j->last_exit_status = status; + j->sent_sigkill = false; j->p = 0; } @@ -1743,12 +1749,8 @@ if (job_useless(j)) { job_remove(j); return NULL; - } else if (kickstart) { - job_log(j, LOG_DEBUG, "Kick-starting."); + } else if (kickstart || job_keepalive(j)) { job_start(j); - } else if (job_keepalive(j)) { - job_log(j, LOG_DEBUG, "Keeping alive..."); - job_start(j); } else { job_watch(j); } @@ -1795,6 +1797,11 @@ job_kill(job_t j) { job_assumes(j, kill(j->p, SIGKILL) != -1); + + j->sent_sigkill = true; + + job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, + EV_ADD|EV_ONESHOT, NOTE_SECONDS, LAUNCHD_SIGKILL_TIMEOUT, j) != -1); } void @@ -1824,9 +1831,16 @@ if (j == ident || &j->start_interval == ident) { job_dispatch(j, true); } else if (&j->exit_timeout == ident) { - job_force_sampletool(j); - job_log(j, LOG_WARNING, "Exit timeout elapsed (%u seconds). Killing.", j->exit_timeout); - job_kill(j); + if (j->sent_sigkill) { + job_log(j, LOG_ERR, "Did not die after sending SIGKILL %u seconds ago...", LAUNCHD_SIGKILL_TIMEOUT); + if (debug_shutdown_hangs) { + job_assumes(j, host_reboot(mach_host_self(), HOST_REBOOT_DEBUGGER) == KERN_SUCCESS); + } + } else { + job_force_sampletool(j); + job_log(j, LOG_WARNING, "Exit timeout elapsed (%u seconds). Killing.", j->exit_timeout); + job_kill(j); + } } else { calendarinterval_callback(j, ident); } @@ -2888,12 +2902,14 @@ } else if (j->mgr->shutting_down) { job_log(j, LOG_DEBUG, "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!"); - return true; - } else if (j->legacy_mach_job && SLIST_EMPTY(&j->machservices)) { - job_log(j, LOG_INFO, "Garbage collecting"); - return true; + } else if (j->legacy_mach_job) { + if (SLIST_EMPTY(&j->machservices)) { + job_log(j, LOG_INFO, "Garbage collecting"); + return true; + } else if (!j->checkedin) { + job_log(j, LOG_WARNING, "Failed to check-in!"); + return true; + } } return false; @@ -2946,8 +2962,7 @@ wanted_state = true; case NETWORK_DOWN: if (network_up == wanted_state) { - job_log(j, LOG_DEBUG, "KeepAlive check: job configured to run while the network is %s.", - wanted_state ? "up" : "down"); + job_log(j, LOG_DEBUG, "KeepAlive: The network is %s.", wanted_state ? "up" : "down"); return true; } break; @@ -2955,8 +2970,7 @@ wanted_state = true; case FAILED_EXIT: if (good_exit == wanted_state) { - job_log(j, LOG_DEBUG, "KeepAlive check: job configured to run while the exit state was %s.", - wanted_state ? "successful" : "failure"); + job_log(j, LOG_DEBUG, "KeepAlive: The exit state was %s.", wanted_state ? "successful" : "failure"); return true; } break; @@ -2964,12 +2978,11 @@ wanted_state = true; case PATH_MISSING: if ((bool)(stat(si->what, &sb) == 0) == wanted_state) { - job_log(j, LOG_DEBUG, "KeepAlive check: job configured to run while the following path %s: %s", - wanted_state ? "exists" : "is missing", si->what); if (si->fd != -1) { job_assumes(j, close(si->fd) == 0); si->fd = -1; } + job_log(j, LOG_DEBUG, "KeepAlive: The following path %s: %s", wanted_state ? "exists" : "is missing", si->what); return true; } break; @@ -2979,6 +2992,7 @@ if (-1 == (qdir_file_cnt = dir_has_files(j, si->what))) { job_log_error(j, LOG_ERR, "dir_has_files(\"%s\", ...)", si->what); } else if (qdir_file_cnt > 0) { + job_log(j, LOG_DEBUG, "KeepAlive: Directory is not empty: %s", si->what); return true; } break; Modified: trunk/launchd/src/launchd_runtime.c =================================================================== --- trunk/launchd/src/launchd_runtime.c 2007-02-16 18:12:03 UTC (rev 23080) +++ trunk/launchd/src/launchd_runtime.c 2007-02-18 18:48:19 UTC (rev 23081) @@ -343,12 +343,16 @@ } if (status.mps_msgcount) { EV_SET(&kev, members[i], EVFILT_MACHPORT, 0, 0, 0, jobmgr_find_by_service_port(root_jobmgr, members[i])); +#if 0 if (launchd_assumes(kev.udata != NULL)) { +#endif log_kevent_struct(LOG_DEBUG, &kev); (*((kq_callback *)kev.udata))(kev.udata, &kev); +#if 0 } else { log_kevent_struct(LOG_ERR, &kev); } +#endif /* the callback may have tainted our ability to continue this for loop */ break; } @@ -381,18 +385,23 @@ { struct timespec ts = { 0, 0 }; struct kevent kev; - Dl_info dli; int kevr; launchd_assumes((kevr = kevent(fd, NULL, 0, &kev, 1, &ts)) != -1); if (kevr == 1) { +#if 0 + Dl_info dli; + if (launchd_assumes(malloc_size(kev.udata) || dladdr(kev.udata, &dli))) { +#endif log_kevent_struct(LOG_DEBUG, &kev); (*((kq_callback *)kev.udata))(kev.udata, &kev); +#if 0 } else { log_kevent_struct(LOG_ERR, &kev); } +#endif } launchd_post_kevent();