Projects
Browse Source     Search     Timeline     Wiki

Changeset 23052

Show
Ignore:
Timestamp:
02/09/07 14:31:36 (22 months ago)
Author:
zarzycki@…
Message:

Even better shutdown debugging.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/launchd/src/launchd_core_logic.c

    r23051 r23052  
    3333#include <mach/mach_host.h> 
    3434#include <mach/exception.h> 
     35#include <mach/host_reboot.h> 
    3536#include <sys/types.h> 
    3637#include <sys/queue.h> 
     
    200201        char *jm_stderr; 
    201202        unsigned int global_on_demand_cnt; 
     203        unsigned int would_have_sigkilled; 
    202204        unsigned int transfer_bstrap:1, sent_stop_to_hopeful_jobs:1, shutting_down:1; 
    203205        char name[0]; 
     
    210212static jobmgr_t jobmgr_parent(jobmgr_t jm); 
    211213static jobmgr_t jobmgr_tickle(jobmgr_t jm); 
     214static void jobmgr_log_stray_children(jobmgr_t jm); 
    212215static void jobmgr_remove(jobmgr_t jm); 
    213216static void jobmgr_dispatch_all(jobmgr_t jm); 
     
    306309static pid_t job_get_pid(job_t j); 
    307310static jobmgr_t job_get_bs(job_t j); 
     311static void job_kill(job_t j); 
    308312static void job_uncork_fork(job_t j); 
    309313static void job_log_stdouterr(job_t j); 
     
    338342static bool cronemu_min(struct tm *wtm, int min); 
    339343 
     344static unsigned int total_children; 
    340345static int dir_has_files(job_t j, const char *path); 
    341346static char **mach_cmd2argv(const char *string); 
     
    16281633                return; 
    16291634        } 
     1635 
     1636        total_children--; 
    16301637 
    16311638        /* Performance hack */ 
     
    17571764 
    17581765void 
     1766job_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 
     1778void 
    17591779job_callback(void *obj, struct kevent *kev) 
    17601780{ 
     
    17721792                        job_force_sampletool(j); 
    17731793                        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); 
    17751795                } else { 
    17761796                        calendarinterval_callback(j, kev); 
     
    18841904                break; 
    18851905        default: 
     1906                total_children++; 
     1907 
    18861908                /* Performance hack */ 
    18871909                TAILQ_REMOVE(&j->mgr->jobs, j, sle); 
     
    28112833                return true; 
    28122834        } 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); 
    28232836                return true; 
    28242837        } else if (!j->checkedin && (!SLIST_EMPTY(&j->sockets) || !SLIST_EMPTY(&j->machservices))) { 
     
    31983211 
    31993212        if (jobmgr_is_idle(jm)) { 
     3213                jobmgr_log_stray_children(jm); 
    32003214                jobmgr_remove(jm); 
    32013215                return NULL; 
     
    32033217 
    32043218        return jm; 
     3219} 
     3220 
     3221void 
     3222jobmgr_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 
     3253out: 
     3254        free(kp); 
    32053255} 
    32063256