Projects
Browse Source     Search     Timeline     Wiki

Changeset 23480

Show
Ignore:
Timestamp:
01/11/08 07:17:14 (11 months ago)
Author:
zarzycki@…
Message:

Misc updates.

Location:
trunk/launchd/src
Files:
5 modified

Legend:

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

    r23479 r23480  
    8383extern char **environ; 
    8484 
    85 static void pfsystem_callback(void *, struct kevent *); 
     85INTERNAL_ABI static void pfsystem_callback(void *, struct kevent *); 
    8686 
    8787static kq_callback kqpfsystem_callback = pfsystem_callback; 
     
    377377} 
    378378 
    379 void 
     379INTERNAL_ABI void 
    380380pfsystem_callback(void *obj __attribute__((unused)), struct kevent *kev) 
    381381{ 
     
    393393} 
    394394 
    395 INTERNAL_ABI bool 
     395INTERNAL_ABI void 
    396396_log_launchd_bug(const char *rcs_rev, const char *path, unsigned int line, const char *test) 
    397397{ 
     
    418418 
    419419        runtime_syslog(LOG_NOTICE, "Bug: %s:%u (%s):%u: %s", file, line, buf, saved_errno, test); 
    420  
    421         return false; 
    422 } 
     420} 
  • trunk/launchd/src/launchd_core_logic.c

    r23479 r23480  
    264264        LIST_HEAD(, job_s) active_jobs[ACTIVE_JOB_HASH_SIZE]; 
    265265        LIST_HEAD(, machservice) ms_hash[MACHSERVICE_HASH_SIZE]; 
     266        LIST_HEAD(, job_s) global_env_jobs; 
    266267        mach_port_t jm_port; 
    267268        mach_port_t req_port; 
     
    276277 
    277278#define jobmgr_assumes(jm, e)   \ 
    278         (likely(e) ? true : jobmgr_log_bug(jm, __LINE__)) 
     279        (unlikely(!(e)) ? jobmgr_log_bug(jm, __LINE__), false : true) 
    279280 
    280281static jobmgr_t jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag, const char *name); 
     
    290291static job_t job_mig_intran2(jobmgr_t jm, mach_port_t mport, pid_t upid); 
    291292static void job_export_all2(jobmgr_t jm, launch_data_t where); 
    292 static void jobmgr_callback(void *obj, struct kevent *kev); 
     293INTERNAL_ABI static void jobmgr_callback(void *obj, struct kevent *kev); 
    293294static void jobmgr_setup_env_from_other_jobs(jobmgr_t jm); 
    294295static void jobmgr_export_env_from_other_jobs(jobmgr_t jm, launch_data_t dict); 
     
    297298static void jobmgr_log(jobmgr_t jm, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4))); 
    298299/* static void jobmgr_log_error(jobmgr_t jm, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4))); */ 
    299 static bool jobmgr_log_bug(jobmgr_t jm, unsigned int line); 
     300static void jobmgr_log_bug(jobmgr_t jm, unsigned int line); 
    300301 
    301302#define DO_RUSAGE_SUMMATION 0 
     
    308309        LIST_ENTRY(job_s) pid_hash_sle; 
    309310        LIST_ENTRY(job_s) label_hash_sle; 
     311        LIST_ENTRY(job_s) global_env_sle; 
    310312        SLIST_HEAD(, socketgroup) sockets; 
    311313        SLIST_HEAD(, calendarinterval) cal_intervals; 
     
    376378 
    377379#define job_assumes(j, e)       \ 
    378         (likely(e) ? true : job_log_bug(j, __LINE__)) 
     380        (unlikely(!(e)) ? job_log_bug(j, __LINE__), false : true) 
    379381 
    380382static void job_import_keys(launch_data_t obj, const char *key, void *context); 
     
    402404static void job_setup_exception_port(job_t j, task_t target_task); 
    403405static void job_reparent_hack(job_t j, const char *where); 
    404 static void job_callback(void *obj, struct kevent *kev); 
     406INTERNAL_ABI static void job_callback(void *obj, struct kevent *kev); 
    405407static void job_callback_proc(job_t j, int fflags); 
    406408static void job_callback_timer(job_t j, void *ident); 
     
    418420static void job_logv(job_t j, int pri, int err, const char *msg, va_list ap) __attribute__((format(printf, 4, 0))); 
    419421static void job_log_error(job_t j, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4))); 
    420 static bool job_log_bug(job_t j, unsigned int line); 
     422static void job_log_bug(job_t j, unsigned int line); 
    421423static void job_log_stdouterr2(job_t j, const char *msg, ...); 
    422424static void job_set_exeception_port(job_t j, mach_port_t port); 
     
    681683} 
    682684 
    683 static void 
     685INTERNAL_ABI static void 
    684686still_alive_with_check(void) 
    685687{ 
     
    786788        struct envitem *ei; 
    787789 
    788         if (j->p && j->anonymous) { 
    789                 job_reap(j); 
    790         } else if (j->p) { 
    791                 job_log(j, LOG_DEBUG, "Removal pended until the job exits"); 
    792  
    793                 if (!j->removal_pending) { 
    794                         j->removal_pending = true; 
    795                         job_stop(j); 
    796                 } 
    797  
    798                 return; 
     790        if (unlikely(j->p)) { 
     791                if (j->anonymous) { 
     792                        job_reap(j); 
     793                } else { 
     794                        job_log(j, LOG_DEBUG, "Removal pended until the job exits"); 
     795 
     796                        if (!j->removal_pending) { 
     797                                j->removal_pending = true; 
     798                                job_stop(j); 
     799                        } 
     800                        return; 
     801                } 
    799802        } 
    800803 
     
    867870                free(j->prog); 
    868871        } 
    869         if (likely(j->argv)) { 
     872        if (j->argv) { 
    870873                free(j->argv); 
    871874        } 
     
    10181021 
    10191022        /* jobs can easily be denied creation during shutdown */ 
    1020         if (!jr) { 
     1023        if (unlikely(jr == NULL)) { 
    10211024                goto out_bad; 
    10221025        } 
     
    10821085        } 
    10831086 
    1084         if (len != sizeof(kp)) { 
     1087        if (unlikely(len != sizeof(kp))) { 
    10851088                jobmgr_log(jm, LOG_DEBUG, "Tried to create an anonymous job for nonexistent PID: %u", anonpid); 
    10861089                errno = ESRCH; 
     
    10971100        } 
    10981101 
    1099         if (kp.kp_proc.p_flag & P_SUGID) { 
     1102        if (unlikely(kp.kp_proc.p_flag & P_SUGID)) { 
    11001103                jobmgr_log(jm, LOG_APPLEONLY, "Inconsistency: P_SUGID is set on PID %u: %s", anonpid, kp.kp_proc.p_comm); 
    11011104        } 
     
    11081111        kp_svgid = kp.kp_eproc.e_pcred.p_svgid; 
    11091112 
    1110         if (kp_euid != kp_uid || kp_euid != kp_svuid || kp_uid != kp_svuid || kp_egid != kp_gid || kp_egid != kp_svgid || kp_gid != kp_svgid) { 
     1113        if (unlikely(kp_euid != kp_uid || kp_euid != kp_svuid || kp_uid != kp_svuid || kp_egid != kp_gid || kp_egid != kp_svgid || kp_gid != kp_svgid)) { 
    11111114                jobmgr_log(jm, LOG_APPLEONLY, "Inconsistency: Mixed credentials (e/r/s UID %u/%u/%u GID %u/%u/%u) detected on PID %u: %s", 
    11121115                                kp_euid, kp_uid, kp_svuid, kp_egid, kp_gid, kp_svgid, anonpid, kp.kp_proc.p_comm); 
     
    11291132        } 
    11301133 
    1131         if (jp && !jp->anonymous && !(kp.kp_proc.p_flag & P_EXEC)) { 
     1134        if (jp && !jp->anonymous && unlikely(!(kp.kp_proc.p_flag & P_EXEC))) { 
    11321135                job_log(jp, LOG_APPLEONLY, "Performance and sanity: fork() without exec*(). Please switch to posix_spawn()"); 
    11331136        } 
     
    11351138 
    11361139        /* A total hack: Normally, job_new() returns an error during shutdown, but anonymous jobs are special. */ 
    1137         if ((shutdown_state = jm->shutting_down)) { 
     1140        if (unlikely(shutdown_state = jm->shutting_down)) { 
    11381141                jm->shutting_down = false; 
    11391142        } 
     
    11591162                } 
    11601163 
    1161                 if (shutdown_state && jm->hopefully_first_cnt == 0) { 
     1164                if (unlikely(shutdown_state && jm->hopefully_first_cnt == 0)) { 
    11621165                        job_log(jr, LOG_APPLEONLY, "This process showed up to the party while all the guests were leaving. Odds are that it will have a miserable time."); 
    11631166                } 
     
    11661169        } 
    11671170 
    1168         if (shutdown_state) { 
     1171        if (unlikely(shutdown_state)) { 
    11691172                jm->shutting_down = true; 
    11701173        } 
     
    11961199        } 
    11971200 
    1198         if (label == AUTO_PICK_LEGACY_LABEL) { 
     1201        if (unlikely(label == AUTO_PICK_LEGACY_LABEL)) { 
    11991202                bn = prog ? prog : basename((char *)argv[0]); /* prog for auto labels is kp.kp_kproc.p_comm */ 
    12001203                snprintf(auto_label, sizeof(auto_label), "%s.%s", sizeof(void *) == 8 ? "0xdeadbeeffeedface" : "0xbabecafe", bn); 
     
    12121215        } 
    12131216 
    1214         if (label == auto_label) { 
     1217        if (unlikely(label == auto_label)) { 
    12151218                snprintf((char *)j->label, strlen(label) + 1, "%p.%s", j, bn); 
    12161219        } else { 
     
    14301433        } 
    14311434 
    1432         if (!found_key) { 
     1435        if (unlikely(!found_key)) { 
    14331436                job_log(j, LOG_WARNING, "Unknown key for boolean: %s", key); 
    14341437        } 
     
    15321535        } 
    15331536 
    1534         if (where2put) { 
     1537        if (likely(where2put)) { 
    15351538                job_assumes(j, (*where2put = strdup(value)) != NULL); 
    15361539        } else { 
     
    18221825        job_t j; 
    18231826 
    1824         if (!launchd_assumes(pload != NULL)) { 
     1827        if (!jobmgr_assumes(jm, pload != NULL)) { 
    18251828                errno = EINVAL; 
    18261829                return NULL; 
     
    19021905 
    19031906        LIST_FOREACH(ji, &label_hash[hash_label(label)], label_hash_sle) { 
    1904                 if (ji->removal_pending) { 
    1905                         continue; /* 5351245 */ 
    1906                 } else if (ji->mgr->shutting_down) { 
    1907                         continue; /* 5488633 */ 
     1907                if (unlikely(ji->removal_pending || ji->mgr->shutting_down)) { 
     1908                        continue; /* 5351245 and 5488633 respectively */ 
    19081909                } 
    19091910 
     
    19201921jobmgr_find_by_pid(jobmgr_t jm, pid_t p, bool create_anon) 
    19211922{ 
    1922         job_t ji = NULL; 
     1923        job_t ji; 
    19231924 
    19241925        LIST_FOREACH(ji, &jm->active_jobs[ACTIVE_JOB_HASH(p)], pid_hash_sle) { 
    19251926                if (ji->p == p) { 
    1926                         break; 
    1927                 } 
    1928         } 
    1929  
    1930         if (ji) { 
    1931                 return ji; 
    1932         } else if (create_anon) { 
    1933                 return job_new_anonymous(jm, p); 
    1934         } else { 
    1935                 return NULL; 
    1936         } 
     1927                        return ji; 
     1928                } 
     1929        } 
     1930 
     1931        return create_anon ? job_new_anonymous(jm, p) : NULL; 
    19371932} 
    19381933 
     
    20142009         */ 
    20152010 
    2016         if (j && j != workaround_5477111 && j->unload_at_mig_return) { 
     2011        if (unlikely(j && (j != workaround_5477111) && j->unload_at_mig_return)) { 
    20172012                job_log(j, LOG_NOTICE, "Unloading PID %u at MIG return.", j->p); 
    20182013                job_remove(j); 
     
    24672462                } else { 
    24682463                        job_force_sampletool(j); 
    2469                         if (j->debug_before_kill) { 
     2464                        if (unlikely(j->debug_before_kill)) { 
    24702465                                job_log(j, LOG_NOTICE, "Exit timeout elapsed. Entering the kernel debugger."); 
    24712466                                job_assumes(j, host_reboot(mach_host_self(), HOST_REBOOT_DEBUGGER) == KERN_SUCCESS); 
     
    25072502} 
    25082503 
    2509 void 
     2504INTERNAL_ABI void 
    25102505jobmgr_callback(void *obj, struct kevent *kev) 
    25112506{ 
     
    25162511        case EVFILT_PROC: 
    25172512                jobmgr_reap_bulk(jm, kev); 
    2518                 if (launchd_assumes(root_jobmgr != NULL)) { 
    2519                         root_jobmgr = jobmgr_do_garbage_collection(root_jobmgr); 
    2520                 } 
     2513                root_jobmgr = jobmgr_do_garbage_collection(root_jobmgr); 
    25212514                break; 
    25222515        case EVFILT_SIGNAL: 
     
    25672560} 
    25682561 
    2569 void 
     2562INTERNAL_ABI void 
    25702563job_callback(void *obj, struct kevent *kev) 
    25712564{ 
     
    28882881        } 
    28892882 
    2890         LIST_FOREACH(ji, &jm->jobs, sle) { 
     2883        LIST_FOREACH(ji, &jm->global_env_jobs, global_env_sle) { 
    28912884                SLIST_FOREACH(ei, &ji->global_env, sle) { 
    28922885                        setenv(ei->key, ei->value, 1); 
     
    32403233} 
    32413234 
    3242 bool 
     3235void 
    32433236jobmgr_log_bug(jobmgr_t jm, unsigned int line) 
    32443237{ 
     
    32643257                runtime_syslog(LOG_NOTICE, "Bug: %s:%u (%s):%u", file, line, buf, saved_errno); 
    32653258        } 
    3266  
    3267         return false; 
    3268 } 
    3269  
    3270 bool 
     3259} 
     3260 
     3261void 
    32713262job_log_bug(job_t j, unsigned int line) 
    32723263{ 
     
    32923283                runtime_syslog(LOG_NOTICE, "Bug: %s:%u (%s):%u", file, line, buf, saved_errno); 
    32933284        } 
    3294  
    3295         return false; 
    32963285} 
    32973286 
     
    37853774 
    37863775        if (global) { 
     3776                if (SLIST_EMPTY(&j->global_env)) { 
     3777                        LIST_INSERT_HEAD(&j->mgr->global_env_jobs, j, global_env_sle); 
     3778                } 
    37873779                SLIST_INSERT_HEAD(&j->global_env, ei, sle); 
    37883780        } else { 
     
    38003792        if (global) { 
    38013793                SLIST_REMOVE(&j->global_env, ei, envitem, sle); 
     3794                if (SLIST_EMPTY(&j->global_env)) { 
     3795                        LIST_REMOVE(j, global_env_sle); 
     3796                } 
    38023797        } else { 
    38033798                SLIST_REMOVE(&j->env, ei, envitem, sle); 
     
    39513946         * launchctl.c for the other half of this hack. 
    39523947         */ 
    3953         if (j->mgr->global_on_demand_cnt > 0 && strcmp(j->label, "com.apple.kextd") != 0) { 
     3948        if (unlikely(j->mgr->global_on_demand_cnt > 0 && strcmp(j->label, "com.apple.kextd") != 0)) { 
    39543949                return false; 
    39553950        } 
    39563951#else 
    3957         if (j->mgr->global_on_demand_cnt > 0) { 
     3952        if (unlikely(j->mgr->global_on_demand_cnt > 0)) { 
    39583953                return false; 
    39593954        } 
     
    39773972                } 
    39783973                if (status.mps_msgcount) { 
    3979                         job_log(j, LOG_DEBUG, "KeepAlive check: job restarted due to %d queued Mach messages on service: %s", 
     3974                        job_log(j, LOG_DEBUG, "KeepAlive check: %d queued Mach messages on service: %s", 
    39803975                                        status.mps_msgcount, ms->name); 
    39813976                        return true; 
     
    41404135        ms->per_pid = pid_local; 
    41414136 
    4142         if (*serviceport == MACH_PORT_NULL) { 
     4137        if (likely(*serviceport == MACH_PORT_NULL)) { 
    41434138                if (!job_assumes(j, launchd_mport_create_recv(&ms->port) == KERN_SUCCESS)) { 
    41444139                        goto out_bad; 
     
    41884183        mach_port_t exc_port = the_exception_server; 
    41894184 
    4190         if (j->alt_exc_handler) { 
     4185        if (unlikely(j->alt_exc_handler)) { 
    41914186                ms = jobmgr_lookup_service(j->mgr, j->alt_exc_handler, true, 0); 
    4192                 if (ms) { 
     4187                if (likely(ms)) { 
    41934188                        exc_port = machservice_port(ms); 
    41944189                } else { 
    41954190                        job_log(j, LOG_WARNING, "Falling back to default Mach exception handler. Could not find: %s", j->alt_exc_handler); 
    41964191                } 
    4197         } else if (j->internal_exc_handler) { 
     4192        } else if (unlikely(j->internal_exc_handler)) { 
    41984193                exc_port = runtime_get_kernel_port(); 
    4199         } else if (!exc_port) { 
     4194        } else if (unlikely(!exc_port)) { 
    42004195                return; 
    42014196        } 
     
    42074202#endif 
    42084203 
    4209         if (target_task) { 
     4204        if (likely(target_task)) { 
    42104205                job_assumes(j, task_set_exception_ports(target_task, EXC_MASK_CRASH, exc_port, 
    42114206                                        EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, f) == KERN_SUCCESS); 
     
    42224217job_set_exeception_port(job_t j, mach_port_t port) 
    42234218{ 
    4224         if (!the_exception_server) { 
     4219        if (unlikely(!the_exception_server)) { 
    42254220                the_exception_server = port; 
    42264221                job_setup_exception_port(j, 0); 
     
    42994294        mach_port_t p = MACH_PORT_NULL; 
    43004295 
    4301         if ((ms = jobmgr_lookup_service(j->mgr, key, false, 0))) { 
     4296        if (unlikely(ms = jobmgr_lookup_service(j->mgr, key, false, 0))) { 
    43024297                job_log(j, LOG_WARNING, "Conflict with job: %s over Mach service: %s", ms->job->label, key); 
    43034298                return; 
    43044299        } 
    43054300 
    4306         if ((ms = machservice_new(j, key, &p, false)) == NULL) { 
    4307                 job_log_error(j, LOG_WARNING, "Cannot add service: %s", key); 
     4301        if (!job_assumes(j, (ms = machservice_new(j, key, &p, false)) != NULL)) { 
    43084302                return; 
    43094303        } 
     
    43264320        } 
    43274321 
    4328         if (!jm->shutting_down) { 
     4322        if (likely(!jm->shutting_down)) { 
    43294323                return jm; 
    43304324        } 
     
    43944388        struct kinfo_proc *kp; 
    43954389 
    4396         if (jm->parentmgr || getpid() != 1) { 
     4390        if (likely(jm->parentmgr || getpid() != 1)) { 
    43974391                return; 
    43984392        } 
     
    44144408                const char *n = kp[i].kp_proc.p_comm; 
    44154409 
    4416                 if (p_i == 0 || p_i == 1) { 
     4410                if (unlikely(p_i == 0 || p_i == 1)) { 
    44174411                        kp_skipped++; 
    44184412                        continue; 
     
    44634457        launchd_assert(offsetof(struct jobmgr_s, kqjobmgr_callback) == 0); 
    44644458 
    4465         if (jm && requestorport == MACH_PORT_NULL) { 
     4459        if (unlikely(jm && requestorport == MACH_PORT_NULL)) { 
    44664460                jobmgr_log(jm, LOG_ERR, "Mach sub-bootstrap create request requires a requester port"); 
    44674461                return NULL; 
     
    46104604        if (jm == root_jobmgr) { 
    46114605                if (port == inherited_bootstrap_port) { 
    4612                         launchd_assumes(launchd_mport_deallocate(port) == KERN_SUCCESS); 
     4606                        jobmgr_assumes(jm, launchd_mport_deallocate(port) == KERN_SUCCESS); 
    46134607                        inherited_bootstrap_port = MACH_PORT_NULL; 
    46144608 
     
    46394633{ 
    46404634        struct machservice *ms; 
     4635        job_t target_j; 
    46414636 
    46424637        if (target_pid) { 
    4643                 jobmgr_assumes(jm, !check_parent); 
    4644         } 
    4645  
    4646         LIST_FOREACH(ms, &jm->ms_hash[hash_ms(name)], name_hash_sle) { 
    4647                 if ((target_pid && ms->per_pid && ms->job->p == target_pid) || (!target_pid && !ms->per_pid)) { 
    4648                         if (strcmp(name, ms->name) == 0) { 
     4638                //jobmgr_assumes(jm, !check_parent); 
     4639 
     4640                if (unlikely((target_j = jobmgr_find_by_pid(jm, target_pid, false)) == NULL)) { 
     4641                        return NULL; 
     4642                } 
     4643 
     4644                SLIST_FOREACH(ms, &target_j->machservices, sle) { 
     4645                        if (ms->per_pid && strcmp(name, ms->name) == 0) { 
    46494646                                return ms; 
    46504647                        } 
    46514648                } 
    4652         } 
    4653  
    4654         if (jm->parentmgr == NULL) { 
     4649 
    46554650                return NULL; 
    46564651        } 
    46574652 
    4658         if (!check_parent) { 
     4653        LIST_FOREACH(ms, &jm->ms_hash[hash_ms(name)], name_hash_sle) { 
     4654                if (!ms->per_pid && strcmp(name, ms->name) == 0) { 
     4655                        return ms; 
     4656                } 
     4657        } 
     4658 
     4659        if (jm->parentmgr == NULL || !check_parent) { 
    46594660                return NULL; 
    46604661        } 
     
    46964697machservice_delete(job_t j, struct machservice *ms, bool port_died) 
    46974698{ 
    4698         if (ms->debug_on_close) { 
     4699        if (unlikely(ms->debug_on_close)) { 
    46994700                job_log(j, LOG_NOTICE, "About to enter kernel debugger because of Mach port: 0x%x", ms->port); 
    47004701                job_assumes(j, host_reboot(mach_host_self(), HOST_REBOOT_DEBUGGER) == KERN_SUCCESS); 
     
    47074708        job_assumes(j, launchd_mport_deallocate(ms->port) == KERN_SUCCESS); 
    47084709 
    4709         if (ms->port == the_exception_server) { 
     4710        if (unlikely(ms->port == the_exception_server)) { 
    47104711                the_exception_server = 0; 
    47114712        } 
     
    52775278#ifdef LET_MERE_MORTALS_ADD_SERVERS_TO_PID1 
    52785279        if (getpid() == 1) { 
    5279                 if (ldc.euid && server_uid && (ldc.euid != server_uid)) { 
     5280                if (unlikely(ldc.euid && server_uid && (ldc.euid != server_uid))) { 
    52805281                        job_log(j, LOG_WARNING, "Server create: \"%s\": Will run as UID %d, not UID %d as they told us to", 
    52815282                                        server_cmd, ldc.euid, server_uid); 
     
    52855286#endif 
    52865287        if (getuid()) { 
    5287                 if (server_uid != getuid()) { 
     5288                if (unlikely(server_uid != getuid())) { 
    52885289                        job_log(j, LOG_WARNING, "Server create: \"%s\": As UID %d, we will not be able to switch to UID %d", 
    52895290                                        server_cmd, getuid(), server_uid); 
     
    52945295</