Modified: trunk/launchd/src/launchd_core_logic.c (23871 => 23872)
--- trunk/launchd/src/launchd_core_logic.c 2009-03-26 21:48:16 UTC (rev 23871)
+++ trunk/launchd/src/launchd_core_logic.c 2009-03-28 07:38:54 UTC (rev 23872)
@@ -160,18 +160,6 @@
static bool waiting4exit_new(job_t j, mach_port_t rp);
static void waiting4exit_delete(job_t j, struct waiting_for_exit *w4e);
-struct mspolicy {
- SLIST_ENTRY(mspolicy) sle;
- unsigned int allow:1, per_pid:1, __junk:30;
- const char name[0];
-};
-
-static bool mspolicy_new(job_t j, const char *name, bool allow, bool pid_local, bool skip_check);
-static bool mspolicy_copy(job_t j_to, job_t j_from);
-static void mspolicy_setup(launch_data_t obj, const char *key, void *context);
-static bool mspolicy_check(job_t j, const char *name, bool pid_local);
-static void mspolicy_delete(job_t j, struct mspolicy *msp);
-
struct machservice {
SLIST_ENTRY(machservice) sle;
SLIST_ENTRY(machservice) special_port_sle;
@@ -429,7 +417,6 @@
SLIST_HEAD(, envitem) global_env;
SLIST_HEAD(, envitem) env;
SLIST_HEAD(, limititem) limits;
- SLIST_HEAD(, mspolicy) mspolicies;
SLIST_HEAD(, machservice) machservices;
SLIST_HEAD(, semaphoreitem) semaphores;
SLIST_HEAD(, waiting_for_removal) removal_watchers;
@@ -633,10 +620,8 @@
static size_t our_strhash(const char *s) __attribute__((pure));
static void extract_rcsid_substr(const char *i, char *o, size_t osz);
static void simulate_pid1_crash(void);
-static pid_t spawn_sync(job_t j);
static pid_t basic_spawn(job_t j, void (*what_to_do)(job_t));
static void take_sample(job_t j);
-static void do_sync(job_t j);
void eliminate_double_reboot(void);
@@ -665,6 +650,7 @@
mach_port_t inherited_bootstrap_port;
jobmgr_t root_jobmgr;
bool g_shutdown_debugging = false;
+bool g_verbose_boot = false;
void
job_ignore(job_t j)
@@ -1028,7 +1014,6 @@
struct socketgroup *sg;
struct machservice *ms;
struct limititem *li;
- struct mspolicy *msp;
struct envitem *ei;
if (unlikely(j->p)) {
@@ -1082,9 +1067,6 @@
job_assumes(j, launchd_mport_deallocate(j->wait_reply_port) == KERN_SUCCESS);
}
- while ((msp = SLIST_FIRST(&j->mspolicies))) {
- mspolicy_delete(j, msp);
- }
while ((sg = SLIST_FIRST(&j->sockets))) {
socketgroup_delete(j, sg);
}
@@ -1420,12 +1402,8 @@
jr->unload_at_mig_return = true;
}
- if (jp) {
- job_assumes(jr, mspolicy_copy(jr, jp));
- }
-
if (unlikely(shutdown_state && jm->hopefully_first_cnt == 0)) {
- 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.");
+ job_log(jr, LOG_SCOLDING, "This process showed up to the party while all the guests were leaving. Odds are that it will have a miserable time.");
}
job_log(jr, LOG_DEBUG, "Created PID %u anonymously by PPID %u%s%s", anonpid, kp.kp_eproc.e_ppid, jp ? ": " : "", jp ? jp->label : "");
@@ -2047,8 +2025,6 @@
case 'M':
if (strcasecmp(key, LAUNCH_JOBKEY_MACHSERVICES) == 0) {
launch_data_dict_iterate(value, machservice_setup, j);
- } else if (strcasecmp(key, LAUNCH_JOBKEY_MACHSERVICELOOKUPPOLICIES) == 0) {
- launch_data_dict_iterate(value, mspolicy_setup, j);
}
break;
default:
@@ -2686,8 +2662,10 @@
while( (ji = LIST_FIRST(&j->suspended_perusers)) ) {
job_log(j, LOG_ERR, "Job exited before resuming per-user launchd for UID %u. Will forcibly resume.", ji->mach_uid);
ji->peruser_suspend_count--;
+ if( ji->peruser_suspend_count == 0 ) {
+ LIST_REMOVE(ji, suspended_peruser_sle);
+ }
job_dispatch(ji, false);
- LIST_REMOVE(ji, suspended_peruser_sle);
}
struct waiting_for_exit *w4e = NULL;
@@ -2754,42 +2732,7 @@
}
}
-/* Maybe someday... */
pid_t
-spawn_sync(job_t j)
-{
- pid_t p = 0;
- char *sync_args[] = { "/bin/sync", NULL };
- switch( (p = vfork()) ) {
- case 0 :
- execve("/bin/sync", sync_args, environ);
- _exit(EXIT_FAILURE);
- case -1 :
- job_log(j, LOG_NOTICE, "vfork(2) failed: %d", errno);
- break;
- default :
- break;
- }
-
- int r = -1;
- if( p != -1 ) {
- /* Let us know when the process is done. ONESHOT is implicit if we're just interested in NOTE_EXIT. */
- if( !job_assumes(j, (r = kevent_mod(p, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, j)) != -1) ) {
- if( errno != ESRCH ) {
- job_assumes(j, runtime_kill(p, SIGKILL) != -1);
- }
- }
-
- int status = 0;
- if( r == -1 ) {
- job_assumes(j, waitpid(p, &status, WNOHANG) != -1);
- }
- }
-
- return p;
-}
-
-pid_t
basic_spawn(job_t j, void (*what_to_do)(job_t))
{
pid_t p = 0;
@@ -2869,14 +2812,6 @@
_exit(EXIT_FAILURE);
}
-void
-do_sync(job_t j __attribute__((unused)))
-{
- char *sync_args[] = { "/bin/sync", NULL };
- execve(sync_args[0], sync_args, environ);
- _exit(EXIT_FAILURE);
-}
-
void
jobmgr_dequeue_next_sample(jobmgr_t jm)
{
@@ -2941,7 +2876,7 @@
}
if( strncmp(si->what, j->label, strlen(j->label)) == 0 ) {
- job_log(ji, LOG_NOTICE | LOG_CONSOLE, "Dispatching out of interest in \"%s\".", j->label);
+ job_log(ji, LOG_DEBUG, "Dispatching out of interest in \"%s\".", j->label);
job_dispatch(ji, false);
/* ji could be removed here, so don't do anything with it or its semaphores
@@ -3213,7 +3148,7 @@
return;
} else if( j->tracing_pid && !j->reap_after_trace ) {
/* The job exited before our sample completed. */
- job_log(j, LOG_NOTICE | LOG_CONSOLE, "Job has exited. Will reap after tracing PID %i exits.", j->tracing_pid);
+ job_log(j, LOG_DEBUG | LOG_CONSOLE, "Job has exited. Will reap after tracing PID %i exits.", j->tracing_pid);
j->reap_after_trace = true;
return;
}
@@ -3281,19 +3216,13 @@
job_log(j, LOG_DEBUG, "&j->start_interval == ident (%p)", ident);
j->start_pending = true;
job_dispatch(j, false);
- } else if( do_sync == ident ) {
- pid_t p = spawn_sync(j);
- if( job_assumes(j, p != -1) ) {
- job_log(j, LOG_NOTICE, "Starting update job (PID %i)", p);
- s_update_pid = p;
- }
} else if (&j->exit_timeout == ident) {
if( !job_assumes(j, j->p != 0) ) {
return;
}
if( j->clean_kill ) {
- job_log(j, LOG_DEBUG | LOG_CONSOLE, "Clean job failed to exit %u second after receiving SIGKILL.", LAUNCHD_CLEAN_KILL_TIMER);
+ job_log(j, LOG_ERR | LOG_CONSOLE, "Clean job failed to exit %u second after receiving SIGKILL.", LAUNCHD_CLEAN_KILL_TIMER);
job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, EV_DELETE, 0, 0, NULL));
j->clean_exit_timer_expired = true;
@@ -4087,7 +4016,7 @@
};
if( !launchd_assumes(setaudit_addr(&auinfo, sizeof(auinfo)) != -1) ) {
- runtime_syslog(LOG_WARNING | LOG_CONSOLE, "Could not set audit session! (errno = %d)", errno);
+ runtime_syslog(LOG_WARNING, "Could not set audit session! (errno = %d)", errno);
_exit(EXIT_FAILURE);
} else {
job_log(j, LOG_DEBUG, "Created new security session for per-user launchd.");
@@ -4949,7 +4878,7 @@
if( strncmp(LAUNCHD_TRUSTED_FD_ENV, key, sizeof(LAUNCHD_TRUSTED_FD_ENV) - 1) != 0 ) {
envitem_new(j, key, launch_data_get_string(obj), j->importing_global_env, true);
} else {
- job_log(j, LOG_WARNING, "Ignoring reserved environmental variable: %s", key);
+ job_log(j, LOG_DEBUG, "Ignoring reserved environmental variable: %s", key);
}
}
@@ -5173,7 +5102,7 @@
wanted_state = true;
case PATH_MISSING:
if ((bool)(stat(si->what, &sb) == 0) == wanted_state) {
- job_log(j, LOG_NOTICE, "KeepAlive: The following path %s: %s", wanted_state ? "exists" : "is missing", si->what);
+ job_log(j, LOG_DEBUG, "KeepAlive: The following path %s: %s", wanted_state ? "exists" : "is missing", si->what);
return true;
} else {
if( wanted_state ) { /* File is not there but we wish it was. */
@@ -5700,12 +5629,12 @@
/* We might have some jobs hanging around that we've decided to shut down in spite of. */
job_t j = jobmgr_find_by_pid(jm, p_i, false);
if( !j || (j && j->anonymous) ) {
- jobmgr_log(jm, LOG_WARNING | LOG_CONSOLE, "Stray %s %s at shutdown: PID %u PPID %u PGID %u %s", z, j ? "anonymous job" : "process", p_i, pp_i, pg_i, n);
+ jobmgr_log(jm, LOG_INFO | LOG_CONSOLE, "Stray %s %s at shutdown: PID %u PPID %u PGID %u %s", z, j ? "anonymous job" : "process", p_i, pp_i, pg_i, n);
int status = 0;
if( pp_i == getpid() && !jobmgr_assumes(jm, kp[i].kp_proc.p_stat != SZOMB) ) {
if( jobmgr_assumes(jm, waitpid(p_i, &status, WNOHANG) == 0) ) {
- jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "Unreaped zombie stray exited with status %i.", WEXITSTATUS(status));
+ jobmgr_log(jm, LOG_INFO | LOG_CONSOLE, "Unreaped zombie stray exited with status %i.", WEXITSTATUS(status));
}
kp_skipped++;
} else {
@@ -5717,7 +5646,7 @@
}
if( (kp_cnt - kp_skipped > 0) && kill_strays ) {
- jobmgr_kill_stray_children(jm, ps, kp_cnt - kp_skipped);
+ jobmgr_kill_stray_children(jm, ps, kp_cnt);
}
free(ps);
@@ -5940,7 +5869,7 @@
}
if (jm->req_port == port) {
- jobmgr_log(jm, LOG_DEBUG, "Request port died: 0x%x", port);
+ jobmgr_log(jm, LOG_INFO, "Request port died: 0x%x", port);
return jobmgr_shutdown(jm);
}
@@ -6034,7 +5963,7 @@
return;
}
- job_log(ms->job, LOG_NOTICE, "Draining %s...", ms->name);
+ job_log(ms->job, LOG_INFO, "Draining %s...", ms->name);
char req_buff[sizeof(union __RequestUnion__catch_mach_exc_subsystem) * 2];
char rep_buff[sizeof(union __ReplyUnion__catch_mach_exc_subsystem)];
@@ -6875,7 +6804,7 @@
goto out_bad;
}
- job_log(j, LOG_DEBUG | LOG_CONSOLE, "Location of job cache database: %s", launch_data_get_string(output_obj));
+ job_log(j, LOG_DEBUG, "Location of job cache database: %s", launch_data_get_string(output_obj));
launch_data_free(output_obj);
break;
@@ -6892,7 +6821,7 @@
case VPROC_GSK_ENVIRONMENT:
if( launch_data_get_type(input_obj) == LAUNCH_DATA_DICTIONARY ) {
if( j->p ) {
- job_log(j, LOG_NOTICE, "Setting environment for a currently active job. This environment will take effect on the next invocation of the job.");
+ job_log(j, LOG_INFO, "Setting environment for a currently active job. This environment will take effect on the next invocation of the job.");
}
launch_data_dict_iterate(input_obj, envitem_setup_one_shot, j);
}
@@ -7082,11 +7011,17 @@
j->wait4debugger_oneshot = inval;
break;
case VPROC_GSK_SHUTDOWN_DEBUGGING:
- if( pid1_magic && j->is_bootstrapper ) {
- runtime_syslog(LOG_NOTICE | LOG_CONSOLE, "*** Shutdown debugging is enabled. ***");
- g_shutdown_debugging = true;
+ if( pid1_magic && j->is_bootstrapper && inval ) {
+ runtime_syslog(LOG_NOTICE | LOG_CONSOLE_FORCE, "*** Shutdown debugging is enabled. ***");
+ g_shutdown_debugging = inval;
}
break;
+ case VPROC_GSK_VERBOSE_BOOT:
+ if( pid1_magic && j->is_bootstrapper && inval ) {
+ g_verbose_boot = inval;
+ runtime_syslog(LOG_NOTICE | LOG_CONSOLE, "*** Verbose boot, will log to /dev/console. ***");
+ }
+ break;
case VPROC_GSK_PERUSER_SUSPEND:
if( pid1_magic && ldc->euid == 0 ) {
mach_port_t junk = MACH_PORT_NULL;
@@ -7363,6 +7298,7 @@
#if TARGET_OS_EMBEDDED
/* There is no need for per-user launchd's on embedded. */
+ job_log(j, LOG_ERR, "Per-user launchds are not supported on this platform.");
return BOOTSTRAP_NOT_PRIVILEGED;
#endif
@@ -7376,7 +7312,7 @@
return BOOTSTRAP_NO_MEMORY;
}
- job_log(j, LOG_DEBUG, "Looking up per user launchd for UID: %u", which_user);
+ job_log(j, LOG_INFO, "Looking up per user launchd for UID: %u", which_user);
if (unlikely(!pid1_magic)) {
job_log(j, LOG_ERR, "Only PID 1 supports per user launchd lookups.");
@@ -7422,14 +7358,14 @@
}
if (!(j->anonymous || j->legacy_LS_job || j->legacy_mach_job)) {
- job_log(j, LOG_APPLEONLY, "Please add the following service to the configuration file for this job: %s", servicename);
+ job_log(j, LOG_SCOLDING, "Please add the following service to the configuration file for this job: %s", servicename);
}
} else {
if (unlikely((jo = machservice_job(ms)) != j)) {
static pid_t last_warned_pid;
if (last_warned_pid != ldc->pid) {
- job_log(j, LOG_NOTICE, "Check-in of Mach service failed. The service \"%s\" is owned by: %s", servicename, jo->label);
+ job_log(jo, LOG_WARNING, "The following job tried to hijack the service \"%s\" from this job: %s", servicename, j->label);
last_warned_pid = ldc->pid;
}
@@ -7461,7 +7397,7 @@
}
if (!(flags & BOOTSTRAP_PER_PID_SERVICE) && !j->legacy_LS_job) {
- job_log(j, LOG_APPLEONLY, "Performance: bootstrap_register() is deprecated. Service: %s", servicename);
+ job_log(j, LOG_SCOLDING, "Performance: bootstrap_register() is deprecated. Service: %s", servicename);
}
job_log(j, LOG_DEBUG, "%sMach service registration attempt: %s", flags & BOOTSTRAP_PER_PID_SERVICE ? "Per PID " : "", servicename);
@@ -7530,11 +7466,6 @@
}
#endif
- if (unlikely(!mspolicy_check(j, servicename, per_pid_lookup))) {
- job_log(j, LOG_NOTICE, "Policy denied Mach service lookup: %s", servicename);
- return BOOTSTRAP_NOT_PRIVILEGED;
- }
-
#if HAVE_SANDBOX
if (unlikely(sandbox_check(ldc->pid, "mach-lookup", per_pid_lookup ? SANDBOX_FILTER_LOCAL_NAME : SANDBOX_FILTER_GLOBAL_NAME, servicename) > 0)) {
return BOOTSTRAP_NOT_PRIVILEGED;
@@ -7629,7 +7560,7 @@
return BOOTSTRAP_NO_MEMORY;
}
- jm = g_flat_mach_namespace ? root_jobmgr : j->mgr;
+ jm = (g_flat_mach_namespace && !j->mgr->created_via_subset) ? root_jobmgr : j->mgr;
unsigned int i = 0;
struct machservice *msi = NULL;
@@ -8380,7 +8311,10 @@
return BOOTSTRAP_NO_MEMORY;
}
- if (!job_assumes(j, (jmr = jobmgr_new(j->mgr, requestorport, MACH_PORT_NULL, false, NULL, j->audit_session)) != NULL)) {
+ char name[NAME_MAX];
+ snprintf(name, sizeof(name), "bootstrap_subset(%u)->%s[%i]", requestorport, j->anonymous ? j->prog : j->label, j->p);
+
+ if (!job_assumes(j, (jmr = jobmgr_new(j->mgr, requestorport, MACH_PORT_NULL, false, name, j->audit_session)) != NULL)) {
if (unlikely(requestorport == MACH_PORT_NULL)) {
return BOOTSTRAP_NOT_PRIVILEGED;
}
@@ -8650,87 +8584,6 @@
}
bool
-mspolicy_copy(job_t j_to, job_t j_from)
-{
- struct mspolicy *msp;
-
- SLIST_FOREACH(msp, &j_from->mspolicies, sle) {
- if (!mspolicy_new(j_to, msp->name, msp->allow, msp->per_pid, true)) {
- return false;
- }
- }
-
- return true;
-}
-
-bool
-mspolicy_new(job_t j, const char *name, bool allow, bool pid_local, bool skip_check)
-{
- struct mspolicy *msp;
-
- if (!skip_check) SLIST_FOREACH(msp, &j->mspolicies, sle) {
- if (msp->per_pid != pid_local) {
- continue;
- } else if (strcmp(msp->name, name) == 0) {
- errno = EEXIST;
- return false;
- }
- }
-
- msp = calloc(1, sizeof(struct mspolicy) + strlen(name) + 1);
-
- if (!job_assumes(j, msp != NULL)) {
- return false;
- }
-
- strcpy((char *)msp->name, name);
- msp->per_pid = pid_local;
- msp->allow = allow;
-
- SLIST_INSERT_HEAD(&j->mspolicies, msp, sle);
-
- return true;
-}
-
-void
-mspolicy_setup(launch_data_t obj, const char *key, void *context)
-{
- job_t j = context;
-
- if (launch_data_get_type(obj) != LAUNCH_DATA_BOOL) {
- job_log(j, LOG_WARNING, "Invalid object type for Mach service policy key: %s", key);
- return;
- }
-
- job_assumes(j, mspolicy_new(j, key, launch_data_get_bool(obj), false, false));
-}
-
-bool
-mspolicy_check(job_t j, const char *name, bool pid_local)
-{
- struct mspolicy *mspi;
-
- SLIST_FOREACH(mspi, &j->mspolicies, sle) {
- if (mspi->per_pid != pid_local) {
- continue;
- } else if (strcmp(mspi->name, name) != 0) {
- continue;
- }
- return mspi->allow;
- }
-
- return !j->deny_unknown_mslookups;
-}
-
-void
-mspolicy_delete(job_t j, struct mspolicy *msp)
-{
- SLIST_REMOVE(&j->mspolicies, msp, mspolicy, sle);
-
- free(msp);
-}
-
-bool
waiting4removal_new(job_t j, mach_port_t rp)
{
struct waiting_for_removal *w4r;