Changeset 23052
- Timestamp:
- 02/09/07 14:31:36 (22 months ago)
- Files:
-
- 1 modified
-
trunk/launchd/src/launchd_core_logic.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/launchd/src/launchd_core_logic.c
r23051 r23052 33 33 #include <mach/mach_host.h> 34 34 #include <mach/exception.h> 35 #include <mach/host_reboot.h> 35 36 #include <sys/types.h> 36 37 #include <sys/queue.h> … … 200 201 char *jm_stderr; 201 202 unsigned int global_on_demand_cnt; 203 unsigned int would_have_sigkilled; 202 204 unsigned int transfer_bstrap:1, sent_stop_to_hopeful_jobs:1, shutting_down:1; 203 205 char name[0]; … … 210 212 static jobmgr_t jobmgr_parent(jobmgr_t jm); 211 213 static jobmgr_t jobmgr_tickle(jobmgr_t jm); 214 static void jobmgr_log_stray_children(jobmgr_t jm); 212 215 static void jobmgr_remove(jobmgr_t jm); 213 216 static void jobmgr_dispatch_all(jobmgr_t jm); … … 306 309 static pid_t job_get_pid(job_t j); 307 310 static jobmgr_t job_get_bs(job_t j); 311 static void job_kill(job_t j); 308 312 static void job_uncork_fork(job_t j); 309 313 static void job_log_stdouterr(job_t j); … … 338 342 static bool cronemu_min(struct tm *wtm, int min); 339 343 344 static unsigned int total_children; 340 345 static int dir_has_files(job_t j, const char *path); 341 346 static char **mach_cmd2argv(const char *string); … … 1628 1633 return; 1629 1634 } 1635 1636 total_children--; 1630 1637 1631 1638 /* Performance hack */ … … 1757 1764 1758 1765 void 1766 job_kill(job_t j) 1767 { 1768 if (debug_shutdown_hangs) { 1769 j->mgr->would_have_sigkilled++; 1770 if (j->mgr->would_have_sigkilled >= total_children) { 1771 job_assumes(j, host_reboot(mach_host_self(), HOST_REBOOT_DEBUGGER) == 0); 1772 } 1773 } else { 1774 job_assumes(j, kill(j->p, SIGKILL) != -1); 1775 } 1776 } 1777 1778 void 1759 1779 job_callback(void *obj, struct kevent *kev) 1760 1780 { … … 1772 1792 job_force_sampletool(j); 1773 1793 job_log(j, LOG_WARNING, "Exit timeout elapsed (%u seconds). Killing.", j->exit_timeout); 1774 job_ assumes(j, kill(j->p, SIGKILL) != -1);1794 job_kill(j); 1775 1795 } else { 1776 1796 calendarinterval_callback(j, kev); … … 1884 1904 break; 1885 1905 default: 1906 total_children++; 1907 1886 1908 /* Performance hack */ 1887 1909 TAILQ_REMOVE(&j->mgr->jobs, j, sle); … … 2811 2833 return true; 2812 2834 } else if (j->mgr->shutting_down) { 2813 unsigned int cnt = 0; 2814 job_t ji; 2815 2816 TAILQ_FOREACH(ji, &j->mgr->jobs, sle) { 2817 if (ji->p) { 2818 cnt++; 2819 } 2820 } 2821 2822 job_log(j, LOG_INFO, "Exited while shutdown in progress. Processes remaining: %u", cnt); 2835 job_log(j, LOG_NOTICE, "Exited while shutdown in progress. Processes remaining: %u", total_children); 2823 2836 return true; 2824 2837 } else if (!j->checkedin && (!SLIST_EMPTY(&j->sockets) || !SLIST_EMPTY(&j->machservices))) { … … 3198 3211 3199 3212 if (jobmgr_is_idle(jm)) { 3213 jobmgr_log_stray_children(jm); 3200 3214 jobmgr_remove(jm); 3201 3215 return NULL; … … 3203 3217 3204 3218 return jm; 3219 } 3220 3221 void 3222 jobmgr_log_stray_children(jobmgr_t jm) 3223 { 3224 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL }; 3225 size_t i, kp_cnt, len = 10*1024*1024; 3226 struct kinfo_proc *kp; 3227 3228 if (jm->parentmgr || getpid() != 1) { 3229 return; 3230 } 3231 3232 if (!jobmgr_assumes(jm, (kp = malloc(len)) != NULL)) { 3233 return; 3234 } 3235 if (!jobmgr_assumes(jm, sysctl(mib, 3, kp, &len, NULL, 0) != -1)) { 3236 goto out; 3237 } 3238 3239 kp_cnt = len / sizeof(struct kinfo_proc); 3240 3241 for (i = 0; i < kp_cnt; i++) { 3242 pid_t p_i = kp[i].kp_proc.p_pid; 3243 pid_t pp_i = kp[i].kp_eproc.e_ppid; 3244 3245 if (p_i == 0 || p_i == 1) { 3246 continue; 3247 } 3248 3249 jobmgr_log(jm, LOG_WARNING, "Stray process at shutdown: PID %u PPID %u %s", p_i, pp_i, kp[i].kp_proc.p_comm); 3250 jobmgr_assumes(jm, kill(p_i, SIGKILL) != -1); 3251 } 3252 3253 out: 3254 free(kp); 3205 3255 } 3206 3256

