From source_changes at macosforge.org Mon Feb 2 13:29:54 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Mon, 2 Feb 2009 13:29:54 -0800 (PST) Subject: [launchd-changes] [23792] branches/SULeopard Message-ID: <20090202212955.1ABA7E41926@beta.macosforge.org> Revision: 23792 http://trac.macosforge.org/projects/launchd/changeset/23792 Author: dsorresso at apple.com Date: 2009-02-02 13:29:53 -0800 (Mon, 02 Feb 2009) Log Message: ----------- Greyhound: launchd not going past 532 processes on 9G3534, causing tests to fail SULeopard: Sporadic Failure of XServe Netboot Modified Paths: -------------- branches/SULeopard/launchd/src/launchctl.c branches/SULeopard/launchd/src/launchd_core_logic.c branches/SULeopard/launchd/src/launchd_unix_ipc.c branches/SULeopard/launchd/src/rc.netboot branches/SULeopard/launchd.xcodeproj/project.pbxproj Modified: branches/SULeopard/launchd/src/launchctl.c =================================================================== --- branches/SULeopard/launchd/src/launchctl.c 2009-01-29 22:46:48 UTC (rev 23791) +++ branches/SULeopard/launchd/src/launchctl.c 2009-02-02 21:29:53 UTC (rev 23792) @@ -1409,11 +1409,6 @@ loopback_setup_ipv4(); loopback_setup_ipv6(); - if (path_check("/etc/rc.server")) { - const char *rcserver_tool[] = { _PATH_BSHELL, "/etc/rc.server", NULL }; - assumes(fwexec(rcserver_tool, true) != -1); - } - #if TARGET_OS_EMBEDDED if (path_check("/etc/rc.boot")) { const char *rcboot_tool[] = { "/etc/rc.boot", NULL }; @@ -1438,6 +1433,11 @@ do_potential_fsck(); } + if (path_check("/etc/rc.server")) { + const char *rcserver_tool[] = { _PATH_BSHELL, "/etc/rc.server", NULL }; + assumes(fwexec(rcserver_tool, true) != -1); + } + read_launchd_conf(); if (path_check("/var/account/acct")) { Modified: branches/SULeopard/launchd/src/launchd_core_logic.c =================================================================== --- branches/SULeopard/launchd/src/launchd_core_logic.c 2009-01-29 22:46:48 UTC (rev 23791) +++ branches/SULeopard/launchd/src/launchd_core_logic.c 2009-02-02 21:29:53 UTC (rev 23792) @@ -4205,9 +4205,9 @@ return; } -#if defined (__ppc__) +#if defined (__ppc__) || defined (__ppc64__) f = PPC_THREAD_STATE64; -#elif defined(__i386__) +#elif defined(__i386__) || defined(__x86_64__) f = x86_THREAD_STATE; #elif defined(__arm__) f = ARM_THREAD_STATE; Modified: branches/SULeopard/launchd/src/launchd_unix_ipc.c =================================================================== --- branches/SULeopard/launchd/src/launchd_unix_ipc.c 2009-01-29 22:46:48 UTC (rev 23791) +++ branches/SULeopard/launchd/src/launchd_unix_ipc.c 2009-02-02 21:29:53 UTC (rev 23792) @@ -466,8 +466,8 @@ break; case RLIMIT_NPROC: /* kernel will not clamp to this value, we must */ - if (gval > (2048 + 20)) { - gval = 2048 + 20; + if (gval > 2500) { + gval = 2500; } break; default: Modified: branches/SULeopard/launchd/src/rc.netboot =================================================================== --- branches/SULeopard/launchd/src/rc.netboot 2009-01-29 22:46:48 UTC (rev 23791) +++ branches/SULeopard/launchd/src/rc.netboot 2009-02-02 21:29:53 UTC (rev 23792) @@ -27,6 +27,8 @@ Failed() { echo rc.netboot: $1 + echo rc.netboot: $1 > /dev/console + sleep 5 exit 1 } @@ -74,11 +76,24 @@ local_mount() { - volinfo=`autodiskmount -F 2>/dev/null` - if [ $? -ne 0 ]; then - echo "autodiskmount -F found no local drives" - return 1 - fi + tries=0 + limit=11 + while [ $tries -lt $limit ]; do + tries=$(( tries + 1 )) + volinfo=`autodiskmount -F 2>/dev/null` + if [ $? -ne 0 ]; then + if [ $tries -lt $limit ]; then + echo "Waiting for local drives..." + echo "Waiting for local drives (retry ${tries}/$(( limit - 1 )))..." > /dev/console + sleep 5 + else + echo "autodiskmount -F found no local drives" + return 1 + fi + else + tries=$limit + fi + done set ${volinfo} devname=$1 fstype=$2 Modified: branches/SULeopard/launchd.xcodeproj/project.pbxproj =================================================================== --- branches/SULeopard/launchd.xcodeproj/project.pbxproj 2009-01-29 22:46:48 UTC (rev 23791) +++ branches/SULeopard/launchd.xcodeproj/project.pbxproj 2009-02-02 21:29:53 UTC (rev 23792) @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 45; objects = { /* Begin PBXAggregateTarget section */ -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Mon Feb 2 13:35:16 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Mon, 2 Feb 2009 13:35:16 -0800 (PST) Subject: [launchd-changes] [23793] tags/launchd-258.22/ Message-ID: <20090202213516.5CF8FE41A30@beta.macosforge.org> Revision: 23793 http://trac.macosforge.org/projects/launchd/changeset/23793 Author: dsorresso at apple.com Date: 2009-02-02 13:35:16 -0800 (Mon, 02 Feb 2009) Log Message: ----------- "Tagging launchd-258.22 from https://svn.macosforge.org/repository/launchd/branches/SULeopard" Added Paths: ----------- tags/launchd-258.22/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 10 17:24:50 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 10 Feb 2009 17:24:50 -0800 (PST) Subject: [launchd-changes] [23794] trunk Message-ID: <20090211012451.15CE4F010E5@beta.macosforge.org> Revision: 23794 http://trac.macosforge.org/projects/launchd/changeset/23794 Author: dsorresso at apple.com Date: 2009-02-10 17:24:50 -0800 (Tue, 10 Feb 2009) Log Message: ----------- Add SPI to disable/enable per-user launchd's audit start up and shut down integration in launchd Allow a session to be bootstrapped in on-demand mode Roll back fix for SnowLeopard: launchd console: gssd-agent errors K3: 10a261: Black screen hang during restart test. Modified Paths: -------------- trunk/launchd/src/config.h trunk/launchd/src/launchctl.c trunk/launchd/src/launchd.c trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/launchd_core_logic.h trunk/launchd/src/launchd_runtime.c trunk/launchd/src/launchd_runtime.h trunk/launchd/src/launchd_unix_ipc.c trunk/launchd/src/launchproxy.c trunk/launchd/src/libvproc.c trunk/launchd/src/protocol_job_reply.defs trunk/launchd/src/protocol_vproc.defs trunk/launchd/src/vproc_priv.h trunk/launchd.xcodeproj/project.pbxproj Modified: trunk/launchd/src/config.h =================================================================== --- trunk/launchd/src/config.h 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/config.h 2009-02-11 01:24:50 UTC (rev 23794) @@ -4,4 +4,5 @@ #define HAVE_QUARANTINE TARGET_HAVE_QUARANTINE #define HAVE_SANDBOX TARGET_HAVE_SANDBOX #define HAVE_SECURITY !TARGET_HAVE_EMBEDDED_SECURITY +#define HAVE_LIBAUDITD !TARGET_OS_EMBEDDED #endif /* __CONFIG_H__ */ Modified: trunk/launchd/src/launchctl.c =================================================================== --- trunk/launchd/src/launchctl.c 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/launchctl.c 2009-02-11 01:24:50 UTC (rev 23794) @@ -20,6 +20,7 @@ static const char *const __rcs_file_version__ = "$Revision$"; +#include "config.h" #include "launch.h" #include "launch_priv.h" #include "bootstrap.h" @@ -81,6 +82,13 @@ #include #include +#if HAVE_LIBAUDITD +#include +#ifndef AUDITD_PLIST_FILE +#define AUDITD_PLIST_FILE "/System/Library/LaunchDaemons/com.apple.auditd.plist" +#endif +#endif + extern char **environ; @@ -1756,6 +1764,9 @@ int hnmib[] = { CTL_KERN, KERN_HOSTNAME }; struct kevent kev; int kq; +#if HAVE_LIBAUDITD + launch_data_t lda, ldb; +#endif do_sysversion_sysctl(); @@ -1862,10 +1873,23 @@ assumes(touch_file(_PATH_VARRUN "/.systemStarterRunning", DEFFILEMODE) != -1); #endif +#if HAVE_LIBAUDITD + /* + * Only start auditing if not "Disabled" in auditd plist. + */ + if ((lda = read_plist_file(AUDITD_PLIST_FILE, false, false)) != NULL && + ((ldb = launch_data_dict_lookup(lda, LAUNCH_JOBKEY_DISABLED)) == NULL || + job_disabled_logic(ldb) == false)) + { + assumes(audit_quick_start() == 0); + launch_data_free(lda); + } +#else if (path_check("/etc/security/rc.audit")) { const char *audit_tool[] = { _PATH_BSHELL, "/etc/security/rc.audit", NULL }; assumes(fwexec(audit_tool, NULL) != -1); } +#endif do_BootCache_magic(BOOTCACHE_START); @@ -2079,7 +2103,7 @@ if (strcasecmp(session_type, VPROCMGR_SESSION_BACKGROUND) == 0) { read_launchd_conf(); -#if HAVE_SECURITY +#if 0 /* XXX PR-6456403 */ assumes(SessionCreate(sessionKeepCurrentBootstrap, 0) == 0); #endif } Modified: trunk/launchd/src/launchd.c =================================================================== --- trunk/launchd/src/launchd.c 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/launchd.c 2009-02-11 01:24:50 UTC (rev 23794) @@ -71,6 +71,10 @@ #include #include +#if HAVE_LIBAUDITD +#include +#endif + #include "bootstrap.h" #include "vproc.h" #include "vproc_priv.h" @@ -261,6 +265,12 @@ void do_pid1_crash_diagnosis_mode(void) { + if( g_wsp ) { + kill(g_wsp, SIGKILL); + sleep(3); + g_wsp = 0; + } + while( g_shutdown_debugging && !do_pid1_crash_diagnosis_mode2() ) { sleep(1); } @@ -269,7 +279,7 @@ int basic_fork(void) { - int wstatus; + int wstatus = 0; pid_t p; switch ((p = fork())) { @@ -279,7 +289,14 @@ case 0: return p; default: + #if 0 + /* If we attach with the debugger, the kernel reparenting could + * cause this to return prematurely. + */ waitpid(p, &wstatus, 0); + #else + sleep(UINT_MAX); + #endif if (WIFEXITED(wstatus)) { if (WEXITSTATUS(wstatus) == EXIT_SUCCESS) { return 1; @@ -326,9 +343,9 @@ fprintf(stdout, "The PID 1 launchd has crashed. It has fork(2)ed itself for debugging.\n"); fprintf(stdout, "To debug the main thread of PID 1:\n"); fprintf(stdout, " gdb attach %d\n", getppid()); - fprintf(stdout, "To exit this shell, capture a sample of launchd and shut down:\n"); - fprintf(stdout, " exit\n"); - fprintf(stdout, "A sample of PID 1 will be written to %s\n", PID1_CRASH_LOGFILE); + fprintf(stdout, "To exit this shell and shut down:\n"); + fprintf(stdout, " kill -9 1\n"); + fprintf(stdout, "A sample of PID 1 has been written to %s\n", PID1_CRASH_LOGFILE); fprintf(stdout, "\n"); fflush(stdout); @@ -347,8 +364,6 @@ crash_addr = si->si_addr; crash_pid = si->si_pid; - - do_pid1_crash_diagnosis_mode(); unlink(PID1_CRASH_LOGFILE); @@ -364,6 +379,8 @@ break; } + do_pid1_crash_diagnosis_mode(); + switch (sig) { default: case 0: @@ -428,6 +445,12 @@ runtime_syslog(LOG_NOTICE, "%s%s began", term_who, pid1_magic ? "" : g_username); launchd_assert(jobmgr_shutdown(root_jobmgr) != NULL); + +#if HAVE_LIBAUDITD + if( pid1_magic ) { + launchd_assumes(audit_quick_stop() == 0); + } +#endif } void Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/launchd_core_logic.c 2009-02-11 01:24:50 UTC (rev 23794) @@ -148,6 +148,14 @@ static bool waiting4removal_new(job_t j, mach_port_t rp); static void waiting4removal_delete(job_t j, struct waiting_for_removal *w4r); +struct waiting_for_exit { + LIST_ENTRY(waiting_for_exit) sle; + mach_port_t rp; +}; + +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; @@ -363,7 +371,7 @@ static void jobmgr_reap_bulk(jobmgr_t jm, struct kevent *kev); static void jobmgr_log_stray_children(jobmgr_t jm, bool kill_strays); static void jobmgr_kill_stray_child(jobmgr_t jm, pid_t p); -static void jobmgr_remove(jobmgr_t jm, bool expect_real_jobs); +static void jobmgr_remove(jobmgr_t jm); static void jobmgr_dispatch_all(jobmgr_t jm, bool newmounthack); static void jobmgr_dequeue_next_sample(jobmgr_t jm); static job_t jobmgr_init_session(jobmgr_t jm, const char *session_type, bool sflag); @@ -371,6 +379,7 @@ static job_t jobmgr_find_by_pid(jobmgr_t jm, pid_t p, bool create_anon); static jobmgr_t jobmgr_find_by_name(jobmgr_t jm, const char *where); static job_t job_mig_intran2(jobmgr_t jm, mach_port_t mport, pid_t upid); +static job_t jobmgr_lookup_per_user_context_internal(job_t j, uid_t which_user, bool dispatch, mach_port_t *mp); static void job_export_all2(jobmgr_t jm, launch_data_t where); static void jobmgr_callback(void *obj, struct kevent *kev); static void jobmgr_setup_env_from_other_jobs(jobmgr_t jm); @@ -390,8 +399,11 @@ LIST_ENTRY(job_s) pid_hash_sle; LIST_ENTRY(job_s) label_hash_sle; LIST_ENTRY(job_s) global_env_sle; + LIST_ENTRY(job_s) suspended_peruser_sle; STAILQ_ENTRY(job_s) pending_samples_sle; SLIST_ENTRY(job_s) curious_jobs_sle; + LIST_HEAD(, job_s) suspended_perusers; + LIST_HEAD(, waiting_for_exit) exit_watchers; SLIST_HEAD(, socketgroup) sockets; SLIST_HEAD(, calendarinterval) cal_intervals; SLIST_HEAD(, envitem) global_env; @@ -444,6 +456,7 @@ uint64_t start_time; uint32_t min_run_time; uint32_t start_interval; + uint32_t peruser_suspend_count; /* The number of jobs that have disabled this per-user launchd. */ #if 0 /* someday ... */ enum { @@ -494,6 +507,7 @@ deny_job_creation :1, /* Don't let this job create new 'job_t' objects in launchd */ kill_via_shmem :1, /* man launchd.plist --> EnableTransactions */ sent_kill_via_shmem :1, /* We need to 'kill_via_shmem' once-and-only-once */ + clean_kill :1, /* The job was sent SIGKILL because it was clean. */ pending_sample :1, /* This job needs to be sampled for some reason. */ kill_after_sample :1, /* The job is to be killed after sampling. */ is_being_sampled :1, /* We've spawned a sample tool to sample the job. */ @@ -505,6 +519,7 @@ jetsam_frontmost :1, /* The job is considered "frontmost" by Jetsam. */ needs_kickoff :1, /* The job is to be kept alive continuously, but it must be initially kicked off. */ is_bootstrapper :1, /* The job is a bootstrapper. */ + has_console :1, /* The job owns the console. */ migratory :1; /* The (anonymous) job called vprocmgr_switch_to_session(). */ mode_t mask; pid_t tracing_pid; @@ -598,6 +613,10 @@ static void extract_rcsid_substr(const char *i, char *o, size_t osz); static void do_first_per_user_launchd_hack(void); 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); @@ -613,6 +632,7 @@ static bool did_first_per_user_launchd_BootCache_hack; #define JOB_BOOTCACHE_HACK_CHECK(j) (unlikely(j->per_user && !did_first_per_user_launchd_BootCache_hack && (j->mach_uid >= 500) && (j->mach_uid != (uid_t)-2))) static job_t workaround_5477111; +static pid_t s_update_pid = 0; /* process wide globals */ mach_port_t inherited_bootstrap_port; @@ -711,6 +731,7 @@ j->sent_signal_time = runtime_get_opaque_time(); if (newval < 0) { + j->clean_kill = true; job_kill(j); } else { /* @@ -892,11 +913,10 @@ } LIST_FOREACH(ji, &jm->jobs, sle) { - why_active = job_active(ji); - - job_log(ji, LOG_DEBUG | LOG_CONSOLE, "%s", why_active ? why_active : "Inactive"); + if( (why_active = job_active(ji)) ) { + job_log(ji, LOG_DEBUG | LOG_CONSOLE, "%s", why_active); + } } - } static void @@ -926,7 +946,7 @@ } void -jobmgr_remove(jobmgr_t jm, bool expect_real_jobs) +jobmgr_remove(jobmgr_t jm) { jobmgr_t jmi; job_t ji; @@ -934,22 +954,16 @@ jobmgr_log(jm, LOG_DEBUG, "Removing job manager."); if (!jobmgr_assumes(jm, SLIST_EMPTY(&jm->submgrs))) { while ((jmi = SLIST_FIRST(&jm->submgrs))) { - jobmgr_remove(jmi, false); + jobmgr_remove(jmi); } } while( (ji = LIST_FIRST(&jm->jobs)) ) { - if( !expect_real_jobs && ji->p && !job_assumes(ji, ji->anonymous) ) { - job_log(ji, LOG_WARNING | LOG_CONSOLE, "%s() called incorrectly with non-anonymous job still active. Forcing removal.", __func__); - job_remove(ji, true); - } else { - if( !ji->anonymous && ji->p ) { - job_log(ji, LOG_WARNING | LOG_CONSOLE, "Job has overstayed its welcome. Forcing removal."); - job_remove(ji, true); - } else { - job_remove(ji, false); - } + if( !ji->anonymous && ji->p ) { + job_log(ji, LOG_WARNING | LOG_CONSOLE, "Job has overstayed its welcome. Forcing removal."); + ji->p = 0; } + job_remove(ji); } if (jm->req_port) { @@ -979,7 +993,7 @@ } void -job_remove(job_t j, bool force) +job_remove(job_t j) { struct waiting_for_removal *w4r; struct calendarinterval *ci; @@ -993,7 +1007,7 @@ if (unlikely(j->p)) { if (j->anonymous) { job_reap(j); - } else if( !force ) { + } else { job_log(j, LOG_DEBUG, "Removal pended until the job exits"); if (!j->removal_pending) { @@ -1256,7 +1270,7 @@ out_bad: if (jr) { - job_remove(jr, false); + job_remove(jr); } return NULL; } @@ -1484,6 +1498,10 @@ j->argv[i] = NULL; } + if( strcmp(j->label, "com.apple.WindowServer") == 0 ) { + j->has_console = true; + } + LIST_INSERT_HEAD(&jm->jobs, j, sle); LIST_INSERT_HEAD(&label_hash[hash_label(j->label)], j, label_hash_sle); @@ -2351,7 +2369,7 @@ if (unlikely(j && (j != workaround_5477111) && j->unload_at_mig_return)) { job_log(j, LOG_NOTICE, "Unloading PID %u at MIG return.", j->p); - job_remove(j, false); + job_remove(j); } workaround_5477111 = NULL; @@ -2509,15 +2527,6 @@ kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); } - if (j->anonymous) { - total_anon_children--; - if( j->migratory ) { - runtime_del_ref(); - } - } else { - runtime_del_ref(); - total_children--; - } LIST_REMOVE(j, pid_hash_sle); if (j->wait_reply_port) { @@ -2566,7 +2575,7 @@ int s = WTERMSIG(status); if ((SIGKILL == s || SIGTERM == s) && !j->stopped) { job_log(j, LOG_NOTICE, "Exited: %s", strsignal(s)); - } else { + } else if( !j->stopped && !j->clean_kill ) { switch( s ) { /* Signals which indicate a crash. */ case SIGILL : @@ -2607,6 +2616,33 @@ } } + job_t ji = NULL; + 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--; + job_dispatch(ji, false); + LIST_REMOVE(ji, suspended_peruser_sle); + } + + struct waiting_for_exit *w4e = NULL; + while( (w4e = LIST_FIRST(&j->exit_watchers)) ) { + waiting4exit_delete(j, w4e); + } + + if (j->anonymous) { + total_anon_children--; + if( j->migratory ) { + runtime_del_ref(); + } + } else { + runtime_del_ref(); + total_children--; + } + + if( j->has_console ) { + g_wsp = 0; + } + if (j->hopefully_exits_first) { j->mgr->hopefully_first_cnt--; } else if (!j->anonymous && !j->hopefully_exits_last) { @@ -2615,6 +2651,7 @@ j->last_exit_status = status; j->sent_signal_time = 0; j->sent_sigkill = false; + j->clean_kill = false; j->sampling_complete = false; j->sent_kill_via_shmem = false; j->lastlookup = NULL; @@ -2655,7 +2692,133 @@ } } +/* 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; + thread_state_flavor_t f = 0; +#if defined (__ppc__) || defined(__ppc64__) + f = PPC_THREAD_STATE64; +#elif defined(__i386__) || defined(__x86_64__) + f = x86_THREAD_STATE; +#elif defined(__arm__) + f = ARM_THREAD_STATE; +#else + #error "unknown architecture" +#endif + + int execpair[2] = { 0, 0 }; + job_assumes(j, socketpair(AF_UNIX, SOCK_STREAM, 0, execpair) != -1); + + switch( (p = fork()) ) { + case 0 : + job_assumes(j, runtime_close(execpair[0]) != -1); + /* Handle exceptions directly. */ + task_set_exception_ports(mach_task_self(), EXC_MASK_CRASH, runtime_get_kernel_port(), EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, f); + + /* Wait for the parent to attach a kevent. */ + read(_fd(execpair[1]), &p, sizeof(p)); + what_to_do(j); + _exit(EXIT_FAILURE); + case -1 : + job_assumes(j, runtime_close(execpair[0]) != -1); + job_assumes(j, runtime_close(execpair[1]) != -1); + execpair[0] = -1; + execpair[1] = -1; + job_log(j, LOG_NOTICE | LOG_CONSOLE, "fork(2) failed: %d", errno); + break; + default : + job_assumes(j, runtime_close(execpair[1]) != -1); + execpair[1] = -1; + break; + } + + int r = -1; + if( p != -1 ) { + /* Let us know when sample 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( !job_assumes(j, write(execpair[0], &p, sizeof(p)) == sizeof(p)) ) { + job_assumes(j, kevent_mod(p, EVFILT_PROC, EV_DELETE, 0, 0, NULL) != -1); + job_assumes(j, runtime_kill(p, SIGKILL) != -1); + r = -1; + p = -1; + } + } else { + job_assumes(j, runtime_kill(p, SIGKILL) != -1); + } + + int status = 0; + if( r == -1 ) { + job_assumes(j, waitpid(p, &status, WNOHANG) != -1); + } + } + + if( execpair[0] != -1 ) { + job_assumes(j, runtime_close(execpair[0]) != -1); + } + + if( execpair[1] != -1 ) { + job_assumes(j, runtime_close(execpair[0]) != -1); + } + + return p; +} + void +take_sample(job_t j) +{ + char pidstr[32]; + snprintf(pidstr, sizeof(pidstr), "%u", j->p); + char *sample_args[] = { "/usr/bin/sample", pidstr, "1", "-unsupportedShowArch", "-mayDie", "-file", j->mgr->sample_log_file, NULL }; + + execve(sample_args[0], sample_args, environ); + _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) { if( STAILQ_EMPTY(&jm->pending_samples) ) { @@ -2687,103 +2850,18 @@ snprintf(j->mgr->sample_log_file, sizeof(j->mgr->sample_log_file), SHUTDOWN_LOG_DIR "/%s-%u.sample.txt", j->label, j->p); if (job_assumes(j, unlink(jm->sample_log_file) != -1 || errno == ENOENT)) { - pid_t sp = 0; - char *sample_args[] = { "/usr/bin/sample", pidstr, "1", "-unsupportedShowArch", "-mayDie", "-file", j->mgr->sample_log_file, NULL }; - thread_state_flavor_t f = 0; - #if defined (__ppc__) || defined(__ppc64__) - f = PPC_THREAD_STATE64; - #elif defined(__i386__) || defined(__x86_64__) - f = x86_THREAD_STATE; - #elif defined(__arm__) - f = ARM_THREAD_STATE; - #else - #error "unknown architecture" - #endif + pid_t sp = basic_spawn(j, take_sample); - #if NEEDS_MULTI_THREADED_EXEC - posix_spawnattr_t psattr; - posix_spawnattr_init(psattr); - posix_spawnattr_setexceptionports_np(&psattr, EXC_MASK_CRASH, runtime_get_kernel_port(), EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES , f); - - if (!job_assumes(j, (errno = posix_spawnp(&sp, sample_args[0], NULL, &psattr, sample_args, environ)) == 0)) { + if( sp == -1 ) { job_log(j, LOG_ERR | LOG_CONSOLE, "Sampling for job failed!"); STAILQ_REMOVE(&jm->pending_samples, j, job_s, pending_samples_sle); + j->sampling_complete = true; jobmgr_dequeue_next_sample(jm); } else { j->tracing_pid = sp; - - /* Let us know when sample is done. ONESHOT is implicit if we're just interested in NOTE_EXIT. */ - job_assumes(j, kevent_mod(sp, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, j) != -1); - } - - posix_spawnattr_destroy(&psattr); - #else - int execpair[2] = { 0, 0 }; - job_assumes(j, socketpair(AF_UNIX, SOCK_STREAM, 0, execpair) != -1); - - switch( (sp = fork()) ) { - case 0 : - job_assumes(j, runtime_close(execpair[0]) != -1); - /* Handle sample's exceptions directly, since ReportCrash will not be able to. */ - task_set_exception_ports(mach_task_self(), EXC_MASK_CRASH, runtime_get_kernel_port(), EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, f); - - /* Wait for the parent to attach a kevent. */ - read(_fd(execpair[1]), &sp, sizeof(sp)); - execve(sample_args[0], sample_args, environ); - job_log(j, LOG_NOTICE | LOG_CONSOLE, "Could not exec(2): %d", errno); - _exit(EXIT_FAILURE); - case -1 : - job_assumes(j, runtime_close(execpair[0]) != -1); - job_assumes(j, runtime_close(execpair[1]) != -1); - execpair[0] = -1; - execpair[1] = -1; - job_log(j, LOG_NOTICE | LOG_CONSOLE, "fork(2) failed: %d", errno); - break; - default : - job_assumes(j, runtime_close(execpair[1]) != -1); - execpair[1] = -1; - break; - } - - int r = -1; - if( sp != -1 ) { - /* Let us know when sample is done. ONESHOT is implicit if we're just interested in NOTE_EXIT. */ - if( job_assumes(j, (r = kevent_mod(sp, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, j)) != -1) ) { - if( job_assumes(j, write(execpair[0], &sp, sizeof(sp)) == sizeof(sp)) ) { - j->tracing_pid = sp; - j->is_being_sampled = true; - } else { - job_assumes(j, kevent_mod(sp, EVFILT_PROC, EV_DELETE, 0, 0, NULL) != -1); - job_assumes(j, runtime_kill(sp, SIGKILL) != -1); - r = -1; - } - } else { - job_assumes(j, runtime_kill(sp, SIGKILL) != -1); - } - - int status = 0; - if( r == -1 ) { - job_assumes(j, waitpid(sp, &status, WNOHANG) != -1); - } - } - - if( execpair[0] != -1 ) { - job_assumes(j, runtime_close(execpair[0]) != -1); - } - - if( execpair[1] != -1 ) { - job_assumes(j, runtime_close(execpair[0]) != -1); - } - - if( r == -1 ) { - job_log(j, LOG_ERR | LOG_CONSOLE, "Sampling for job failed!"); - STAILQ_REMOVE(&jm->pending_samples, j, job_s, pending_samples_sle); - j->sampling_complete = true; - jobmgr_dequeue_next_sample(jm); - } else { + j->is_being_sampled = true; job_log(j, LOG_DEBUG | LOG_CONSOLE, "Sampling job (sample PID: %i, file: %s).", sp, j->mgr->sample_log_file); } - #endif } else { STAILQ_REMOVE(&jm->pending_samples, j, job_s, pending_samples_sle); j->sampling_complete = true; @@ -2823,9 +2901,13 @@ */ if (!job_active(j)) { if (job_useless(j)) { - job_remove(j, false); + job_remove(j); return NULL; - } + } + if( unlikely(j->per_user && j->peruser_suspend_count > 0) ) { + return NULL; + } + if (kickstart || job_keepalive(j)) { job_log(j, LOG_DEBUG, "Starting job (kickstart = %s)", kickstart ? "true" : "false"); job_start(j); @@ -3011,6 +3093,14 @@ int fflags = kev->fflags; if( fflags & NOTE_EXIT ) { + if( s_update_pid == (pid_t)kev->ident ) { + int status = 0; + job_assumes(j, waitpid(s_update_pid, &status, 0) == 0); + job_log(j, LOG_NOTICE, "Reaping update job (PID %i, exit status %i)", s_update_pid, WEXITSTATUS(status)); + + s_update_pid = 0; + } + if( j->p == (pid_t)kev->ident && !j->anonymous && !j->is_being_sampled ) { int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, j->p }; struct kinfo_proc kp; @@ -3086,7 +3176,7 @@ job_reap(j); if (j->anonymous) { - job_remove(j, false); + job_remove(j); j = NULL; } else { j = job_dispatch(j, false); @@ -3111,6 +3201,12 @@ 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; @@ -3403,6 +3499,10 @@ } } + if( j->has_console ) { + g_wsp = c; + } + runtime_add_ref(); total_children++; LIST_INSERT_HEAD(&j->mgr->active_jobs[ACTIVE_JOB_HASH(c)], j, pid_hash_sle); @@ -3822,9 +3922,24 @@ */ if (likely(!j->no_init_groups)) { + #if 1 if (!job_assumes(j, initgroups(loginname, desired_gid) != -1)) { _exit(EXIT_FAILURE); } + #else + /* Do our own little initgroups(). We do this to guarantee that we're + * always opted into dynamic group resolution in the kernel. initgroups(3) + * does not make this guarantee. + */ + int groups[NGROUPS], ngroups; + + /* A failure here isn't fatal, and we'll still get data we can use. */ + job_assumes(j, getgrouplist(j->username, desired_gid, groups, &ngroups) != -1); + + if( !job_assumes(j, syscall(SYS_initgroups, ngroups, groups, desired_uid) != -1) ) { + _exit(EXIT_FAILURE); + } + #endif } if (!job_assumes(j, setuid(desired_uid) != -1)) { @@ -5269,109 +5384,115 @@ jobmgr_t jobmgr_do_hopefully_first_shutdown_phase(jobmgr_t jm) { - jobmgr_t _jm = jm; if( !jm->shutting_down ) { - return _jm; + return jm; } + + if( jm->killed_hopefully_first_jobs ) { + return NULL; + } + + jobmgr_log(jm, LOG_DEBUG, "Doing first phase of garbage collection."); - bool should_proceed = !jm->killed_hopefully_first_jobs; - + uint32_t unkilled_cnt = 0; job_t ji = NULL, jn = NULL; - if( should_proceed ) { - jobmgr_log(jm, LOG_DEBUG, "Doing first phase of garbage collection."); - uint32_t unkilled_cnt = 0; - LIST_FOREACH_SAFE( ji, &jm->jobs, sle, jn ) { - if( jm->parentmgr ) { - job_log(ji, LOG_DEBUG, "Examining..."); - } - if( ji->hopefully_exits_first ) { - bool active = job_active(ji); - if( active && !ji->stopped ) { - job_stop(ji); - - /* We may have sent SIGKILL to the job in job_stop(). */ - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; - } else if( ji->stopped ) { - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; - } else if( !active ) { - job_remove(ji, false); - } - } + LIST_FOREACH_SAFE( ji, &jm->jobs, sle, jn ) { + if( !ji->hopefully_exits_first ) { + continue; } - /* If we've killed everyone, move on. */ - if( unkilled_cnt == 0 ) { - jm->killed_hopefully_first_jobs = true; - _jm = NULL; + bool active = job_active(ji); + if( active && !ji->stopped ) { + /* If the job is active and we haven't told it to stop yet, stop it. */ + job_stop(ji); + + /* We may have sent SIGKILL to the job in job_stop(). In this case, + * "clean" jobs should exit immediately, so we shouldn't have to wait + * for them. + */ + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else if( ji->stopped ) { + /* If the job is active and has been told to stop, disregard it + * after we've sent SIGKILL. + */ + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else if( !active ) { + /* If the job was not active when shutdown began, remove it. */ + job_remove(ji); } - } else { + } + + /* If we've killed everyone, move on. */ + if( unkilled_cnt == 0 ) { jm->killed_hopefully_first_jobs = true; - _jm = NULL; + jm = NULL; } - return _jm; + return jm; } jobmgr_t jobmgr_do_normal_shutdown_phase(jobmgr_t jm) { - jobmgr_t _jm = jm; if( !jm->shutting_down ) { - return _jm; + return jm; } - bool should_proceed = !jm->killed_normal_jobs; + if( jm->killed_normal_jobs ) { + return NULL; + } + jobmgr_log(jm, LOG_DEBUG, "Doing second phase of garbage collection."); + + uint32_t unkilled_cnt = 0; job_t ji = NULL, jn = NULL; - if( should_proceed ) { - jobmgr_log(jm, LOG_DEBUG, "Doing second phase of garbage collection."); - uint32_t unkilled_cnt = 0; - LIST_FOREACH_SAFE( ji, &jm->jobs, sle, jn ) { - if( jm->parentmgr ) { - job_log(ji, LOG_DEBUG, "Examining..."); - } - - if( !(ji->hopefully_exits_first || ji->hopefully_exits_last) ) { - if( !ji->anonymous ) { - bool active = job_active(ji); - if( active && !ji->stopped ) { - job_stop(ji); - - /* We may have sent SIGKILL to the job in job_stop(). */ - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; - } else if( ji->stopped ) { - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; - } else if( !active ) { - job_remove(ji, false); - } - } else if( ji->migratory && jm->parentmgr ) { - /* If a job has migrated into a sub-bootstrap, we want to - * keep the job manager around as long as the job is there. - */ - unkilled_cnt++; - } - } + LIST_FOREACH_SAFE( ji, &jm->jobs, sle, jn ) { + if( ji->migratory ) { + /* If we're shutting down, release the hold migratory jobs + * have on us. + */ + job_remove(ji); } - /* If we've killed everyone, move on. */ - if( unkilled_cnt == 0 ) { - jm->killed_normal_jobs = true; - _jm = NULL; + if( ji->anonymous || ji->hopefully_exits_first || ji->hopefully_exits_last ) { + continue; } - } else { - jm->killed_normal_jobs = true; - _jm = NULL; + + bool active = job_active(ji); + if( active && !ji->stopped ) { + /* If the job is active and we haven't told it to stop yet, stop it. */ + job_stop(ji); + + /* We may have sent SIGKILL to the job in job_stop(). In this case, + * "clean" jobs should exit immediately, so we shouldn't have to wait + * for them. + */ + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else if( ji->stopped ) { + /* If the job is active and has been told to stop, disregard it + * after we've sent SIGKILL. + */ + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else if( !active ) { + /* If the job was not active when shutdown began, remove it. */ + job_remove(ji); + } } - return _jm; + /* If we've killed everyone, move on. */ + if( unkilled_cnt == 0 ) { + jm->killed_hopefully_first_jobs = true; + jm = NULL; + } + + return jm; } jobmgr_t jobmgr_do_hopefully_last_shutdown_phase(jobmgr_t jm) { - jobmgr_t _jm = jm; if( !jm->shutting_down ) { - return _jm; + return jm; } if( jm == root_jobmgr ) { @@ -5384,42 +5505,46 @@ killed_stray_jobs = true; } - bool should_proceed = !jm->killed_hopefully_last_jobs && total_children != 0; + if( jm->killed_hopefully_last_jobs || total_children == 0 ) { + return NULL; + } + uint32_t unkilled_cnt = 0; job_t ji = NULL, jn = NULL; - if( should_proceed ) { - jobmgr_log(jm, LOG_DEBUG, "Doing third phase of garbage collection."); - uint32_t unkilled_cnt = 0; - LIST_FOREACH_SAFE( ji, &jm->jobs, sle, jn ) { - if( jm->parentmgr ) { - job_log(ji, LOG_DEBUG, "Examining..."); - } - if( ji->hopefully_exits_last ) { - bool active = job_active(ji); - if( active && !ji->stopped ) { - job_stop(ji); - - /* We may have sent SIGKILL to the job in job_stop(). */ - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; - } else if( ji->stopped ) { - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; - } else if( !active ) { - job_remove(ji, false); - } - } + jobmgr_log(jm, LOG_DEBUG, "Doing third phase of garbage collection."); + LIST_FOREACH_SAFE( ji, &jm->jobs, sle, jn ) { + if( !ji->hopefully_exits_last ) { + continue; } - /* If we've killed everyone, move on. */ - if( unkilled_cnt == 0 ) { - jm->killed_hopefully_last_jobs = true; - _jm = NULL; + bool active = job_active(ji); + if( active && !ji->stopped ) { + /* If the job is active and we haven't told it to stop yet, stop it. */ + job_stop(ji); + + /* We may have sent SIGKILL to the job in job_stop(). In this case, + * "clean" jobs should exit immediately, so we shouldn't have to wait + * for them. + */ + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else if( ji->stopped ) { + /* If the job is active and has been told to stop, disregard it + * after we've sent SIGKILL. + */ + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else if( !active ) { + /* If the job was not active when shutdown began, remove it. */ + job_remove(ji); } - } else { - jm->killed_hopefully_last_jobs = true; - _jm = NULL; } - return _jm; + /* If we've killed everyone, move on. */ + if( unkilled_cnt == 0 ) { + jm->killed_hopefully_first_jobs = true; + jm = NULL; + } + + return jm; } jobmgr_t @@ -5439,22 +5564,12 @@ _jm = jobmgr_do_normal_shutdown_phase(jm) ? : jobmgr_do_hopefully_last_shutdown_phase(jm); } - if( !_jm ) { + if( !_jm && SLIST_EMPTY(&jm->submgrs) ) { jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "Removing."); jobmgr_log_stray_children(jm, false); - - job_t ji = NULL; - LIST_FOREACH( ji, &jm->jobs, sle ) { - if( pid1_magic && !jm->parentmgr ) { - if( (ji->anonymous || ji->sent_sigkill) && ji->p ) { - job_log(ji, LOG_NOTICE | LOG_CONSOLE, "Job should be gone but is not."); - } - } else if( !pid1_magic && !ji->anonymous ) { - job_log(ji, LOG_NOTICE | LOG_CONSOLE, "Job should be gone but is not."); - } - } - - jobmgr_remove(jm, total_children != 0); + jobmgr_remove(jm); + } else { + _jm = jm; } return _jm; @@ -5692,7 +5807,7 @@ out_bad: if (jmr) { - jobmgr_remove(jmr, false); + jobmgr_remove(jmr); } return NULL; } @@ -5724,6 +5839,11 @@ #if TARGET_OS_EMBEDDED bootstrapper->stderrpath = strdup(_PATH_CONSOLE); #endif + + #if 0 + /* Start the update job. */ + jobmgr_assumes(jm, kevent_mod((uintptr_t)do_sync, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, 30, bootstrapper) != -1); + #endif } } @@ -6530,7 +6650,7 @@ return BOOTSTRAP_NOT_PRIVILEGED; } - job_remove(otherj, false); + job_remove(otherj); if (do_block) { job_log(j, LOG_DEBUG, "Blocking MIG return of job_remove(): %s", otherj->label); @@ -6885,6 +7005,45 @@ g_shutdown_debugging = true; } break; + case VPROC_GSK_PERUSER_SUSPEND: + if( pid1_magic && ldc->euid == 0 ) { + mach_port_t junk = MACH_PORT_NULL; + job_t jpu = jobmgr_lookup_per_user_context_internal(j, (uid_t)inval, false, &junk); + if( jpu ) { + job_t ji = NULL; + LIST_FOREACH( ji, &j->suspended_perusers, suspended_peruser_sle ) { + if( (int64_t)(ji->mach_uid) == inval ) { + job_log(j, LOG_WARNING, "Job tried to suspend per-user launchd for UID %u twice.", ji->mach_uid); + break; + } + } + + if( ji == NULL ) { + jpu->peruser_suspend_count++; + LIST_INSERT_HEAD(&j->suspended_perusers, jpu, suspended_peruser_sle); + job_stop(jpu); + } + } + } + break; + case VPROC_GSK_PERUSER_RESUME: + if( pid1_magic && ldc->euid == 0 ) { + job_t ji = NULL, jt = NULL; + LIST_FOREACH_SAFE( ji, &j->suspended_perusers, suspended_peruser_sle, jt ) { + if( (int64_t)(ji->mach_uid) == inval ) { + ji->peruser_suspend_count--; + LIST_REMOVE(ji, suspended_peruser_sle); + break; + } + } + + if( ji == NULL ) { + job_log(j, LOG_WARNING, "Job tried to resume per-user launchd for UID %llu that it did not suspend.", inval); + } else if( ji->peruser_suspend_count == 0 ) { + job_dispatch(ji, false); + } + } + break; case 0: break; default: @@ -7014,29 +7173,10 @@ return 0; } -kern_return_t -job_mig_lookup_per_user_context(job_t j, uid_t which_user, mach_port_t *up_cont) +job_t +jobmgr_lookup_per_user_context_internal(job_t j, uid_t which_user, bool dispatch, mach_port_t *mp) { - struct ldcred *ldc = runtime_get_caller_creds(); - job_t ji; - - if (!launchd_assumes(j != NULL)) { - return BOOTSTRAP_NO_MEMORY; - } - - job_log(j, LOG_DEBUG, "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."); - return BOOTSTRAP_NOT_PRIVILEGED; - } - - if (ldc->euid || ldc->uid) { - which_user = ldc->euid ?: ldc->uid; - } - - *up_cont = MACH_PORT_NULL; - + job_t ji = NULL; LIST_FOREACH(ji, &root_jobmgr->jobs, sle) { if (!ji->per_user) { continue; @@ -7052,42 +7192,65 @@ } break; } - - if (unlikely(ji == NULL)) { + + if( unlikely(ji == NULL) ) { struct machservice *ms; char lbuf[1024]; - + job_log(j, LOG_DEBUG, "Creating per user launchd job for UID: %u", which_user); - + sprintf(lbuf, "com.apple.launchd.peruser.%u", which_user); - + ji = job_new(root_jobmgr, lbuf, "/sbin/launchd", NULL); - - if (ji == NULL) { - return BOOTSTRAP_NO_MEMORY; + + if( ji != NULL ) { + ji->mach_uid = which_user; + ji->per_user = true; + ji->kill_via_shmem = true; + + if ((ms = machservice_new(ji, lbuf, mp, false)) == NULL) { + job_remove(ji); + ji = NULL; + } else { + ms->per_user_hack = true; + ms->hide = true; + + ji = dispatch ? job_dispatch(ji, false) : ji; + } } - - ji->mach_uid = which_user; - ji->per_user = true; - ji->kill_via_shmem = true; - - if ((ms = machservice_new(ji, lbuf, up_cont, false)) == NULL) { - job_remove(ji, false); - return BOOTSTRAP_NO_MEMORY; - } - - ms->per_user_hack = true; - ms->hide = true; - - ji = job_dispatch(ji, false); } else { + *mp = machservice_port(SLIST_FIRST(&ji->machservices)); job_log(j, LOG_DEBUG, "Per user launchd job found for UID: %u", which_user); } + + return ji; +} - if (job_assumes(j, ji != NULL)) { - *up_cont = machservice_port(SLIST_FIRST(&ji->machservices)); +kern_return_t +job_mig_lookup_per_user_context(job_t j, uid_t which_user, mach_port_t *up_cont) +{ + struct ldcred *ldc = runtime_get_caller_creds(); + job_t jpu; + + if (!launchd_assumes(j != NULL)) { + return BOOTSTRAP_NO_MEMORY; } - + + job_log(j, LOG_DEBUG, "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."); + return BOOTSTRAP_NOT_PRIVILEGED; + } + + if (ldc->euid || ldc->uid) { + which_user = ldc->euid ?: ldc->uid; + } + + *up_cont = MACH_PORT_NULL; + + jpu = jobmgr_lookup_per_user_context_internal(j, which_user, true, up_cont); + return 0; } @@ -7136,7 +7299,6 @@ job_log(j, LOG_WARNING, "Check-in of Mach service failed. Already active: %s", servicename); return BOOTSTRAP_SERVICE_ACTIVE; } - } job_checkin(j); @@ -7726,11 +7888,14 @@ */ if( flags & LAUNCH_GLOBAL_ON_DEMAND ) { /* This is so awful. */ - mach_port_t mp = MACH_PORT_NULL; - name_t target_name; - strlcpy(target_name, jmr->name, sizeof(target_name)); + /* Remove the job from its current job manager. */ + LIST_REMOVE(j, sle); + LIST_REMOVE(j, pid_hash_sle); + + /* Put the job into the target job manager. */ + LIST_INSERT_HEAD(&jmr->jobs, j, sle); + LIST_INSERT_HEAD(&jmr->active_jobs[ACTIVE_JOB_HASH(j->p)], j, pid_hash_sle); - kr = job_mig_switch_to_session(j, MACH_PORT_NULL, target_name, &mp); if( job_assumes(j, kr == KERN_SUCCESS) ) { job_set_global_on_demand(j, true); } else { @@ -8164,6 +8329,27 @@ } kern_return_t +job_mig_wait2(job_t j, job_t target_j, mach_port_t srp, integer_t *status __attribute__((unused))) +{ + if( !launchd_assumes(j != NULL) ) { + return BOOTSTRAP_NO_MEMORY; + } + if( !launchd_assumes(target_j != NULL) ) { + return BOOTSTRAP_NO_MEMORY; + } + + if( target_j->p == 0 ) { + return BOOTSTRAP_SUCCESS; + } + + if( !job_assumes(j, waiting4exit_new(target_j, srp) == true) ) { + return BOOTSTRAP_NO_MEMORY; + } + + return MIG_NO_REPLY; +} + +kern_return_t job_mig_uncork_fork(job_t j) { if (!launchd_assumes(j != NULL)) { @@ -8249,12 +8435,12 @@ } if (!job_assumes(jr, jr->p)) { - job_remove(jr, false); + job_remove(jr); return BOOTSTRAP_NO_MEMORY; } if (!job_setup_machport(jr)) { - job_remove(jr, false); + job_remove(jr); return BOOTSTRAP_NO_MEMORY; } @@ -8412,6 +8598,29 @@ free(w4r); } +bool +waiting4exit_new(job_t j, mach_port_t rp) +{ + struct waiting_for_exit *w4e = NULL; + if( !job_assumes(j, (w4e = malloc(sizeof(struct waiting_for_exit))) != NULL) ) { + return false; + } + + w4e->rp = rp; + LIST_INSERT_HEAD(&j->exit_watchers, w4e, sle); + + return true; +} + +void +waiting4exit_delete(job_t j, struct waiting_for_exit *w4e) +{ + job_assumes(j, job_mig_wait2_reply(w4e->rp, KERN_SUCCESS, j->last_exit_status) == KERN_SUCCESS); + LIST_REMOVE(w4e, sle); + + free(w4e); +} + size_t get_kern_max_proc(void) { Modified: trunk/launchd/src/launchd_core_logic.h =================================================================== --- trunk/launchd/src/launchd_core_logic.h 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/launchd_core_logic.h 2009-02-11 01:24:50 UTC (rev 23794) @@ -47,7 +47,7 @@ launch_data_t job_export(job_t j); void job_stop(job_t j); void job_checkin(job_t j); -void job_remove(job_t j, bool force); +void job_remove(job_t j); job_t job_import(launch_data_t pload); launch_data_t job_import_bulk(launch_data_t pload); job_t job_mig_intran(mach_port_t mp); Modified: trunk/launchd/src/launchd_runtime.c =================================================================== --- trunk/launchd/src/launchd_runtime.c 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/launchd_runtime.c 2009-02-11 01:24:50 UTC (rev 23794) @@ -90,7 +90,6 @@ static void mportset_callback(void); static kq_callback kqmportset_callback = (kq_callback)mportset_callback; static void *kqueue_demand_loop(void *arg); -static void log_kevent_struct(int level, struct kevent *kev_base, int indx); boolean_t launchd_internal_demux(mach_msg_header_t *Request, mach_msg_header_t *Reply); static void record_caller_creds(mach_msg_header_t *mh); @@ -134,6 +133,7 @@ bool g_flat_mach_namespace = true; bool g_simulate_pid1_crash = false; bool g_use_gmalloc = false; +pid_t g_wsp = 0; mach_port_t runtime_get_kernel_port(void) @@ -536,11 +536,11 @@ #if 0 if (launchd_assumes(kev.udata != NULL)) { #endif - log_kevent_struct(LOG_DEBUG, &kev, 0); + log_kevent_struct(LOG_DEBUG, &kev, i); (*((kq_callback *)kev.udata))(kev.udata, &kev); #if 0 } else { - log_kevent_struct(LOG_ERR, &kev, 0); + log_kevent_struct(LOG_ERR, &kev, i); } #endif /* the callback may have tainted our ability to continue this for loop */ @@ -586,30 +586,29 @@ bulk_kev = kev; if (launchd_assumes((bulk_kev_cnt = kevent(fd, NULL, 0, kev, BULK_KEV_MAX, &ts)) != -1)) { + #if 0 for (i = 0; i < bulk_kev_cnt; i++) { log_kevent_struct(LOG_DEBUG, kev, i); } + #endif for (i = 0; i < bulk_kev_cnt; i++) { bulk_kev_i = i; kevi = &kev[i]; if (kevi->filter) { -#if 0 Dl_info dli; /* Check if kevi->udata was either malloc(3)ed or is a valid function pointer. * If neither, it's probably an invalid pointer and we should log it. */ if (launchd_assumes(malloc_size(kevi->udata) || dladdr(kevi->udata, &dli))) { -#endif - runtime_ktrace(RTKT_LAUNCHD_BSD_KEVENT|DBG_FUNC_START, kevi->ident, kevi->filter, kevi->fflags); - (*((kq_callback *)kevi->udata))(kevi->udata, kevi); - runtime_ktrace0(RTKT_LAUNCHD_BSD_KEVENT|DBG_FUNC_END); -#if 0 + runtime_ktrace(RTKT_LAUNCHD_BSD_KEVENT|DBG_FUNC_START, kevi->ident, kevi->filter, kevi->fflags); + (*((kq_callback *)kevi->udata))(kevi->udata, kevi); + runtime_ktrace0(RTKT_LAUNCHD_BSD_KEVENT|DBG_FUNC_END); } else { + runtime_syslog(LOG_ERR, "The following kevent had invalid context data."); log_kevent_struct(LOG_EMERG, kevi, i); } -#endif } } } @@ -619,8 +618,6 @@ return 0; } - - void launchd_runtime(void) { @@ -852,6 +849,14 @@ if (flags & EV_ADD && !launchd_assumes(udata != NULL)) { errno = EINVAL; return -1; + } else if( (flags & EV_DELETE) && bulk_kev ) { + int i = 0; + for( i = bulk_kev_i + 1; i < bulk_kev_cnt; i++ ) { + if( bulk_kev[i].filter == filter && bulk_kev[i].ident == ident ) { + runtime_syslog(LOG_DEBUG, "Skipping PROC event for PID %lu", ident); + bulk_kev[i].filter = 0; + } + } } EV_SET(&kev, ident, filter, flags, fflags, data, udata); @@ -1349,7 +1354,31 @@ offset = (void *)*outval; +#if 0 + if( !ourlogfile && !pid1_magic && shutdown_in_progress ) { + char logfile[NAME_MAX]; + snprintf(logfile, sizeof(logfile), "/var/tmp/launchd-%s.shutdown.log", g_username); + + char logfile1[NAME_MAX]; + snprintf(logfile1, sizeof(logfile1), "/var/tmp/launchd-%s.shutdown.log.1", g_username); + + rename(logfile, logfile1); + ourlogfile = fopen(logfile, "a"); + } +#endif + + static int64_t shutdown_start = 0; + if( shutdown_start == 0 ) { + shutdown_start = runtime_get_wall_time(); + } + while ((lm = STAILQ_FIRST(&logmsg_queue))) { + int64_t log_delta = lm->when - shutdown_start; + if( !pid1_magic && ourlogfile ) { + fprintf(ourlogfile, "%8lld%6u %-40s%6u %-40s %s\n", log_delta, + lm->from_pid, lm->from_name, lm->about_pid, lm->about_name, lm->msg); + } + lm->from_name_offset = lm->from_name - (char *)lm; lm->about_name_offset = lm->about_name - (char *)lm; lm->msg_offset = lm->msg - (char *)lm; @@ -1361,6 +1390,10 @@ logmsg_remove(lm); } + + if( ourlogfile ) { + fflush(ourlogfile); + } return 0; } @@ -1447,6 +1480,8 @@ logmsg_remove(lm); } + + fflush(ourlogfile); } kern_return_t @@ -1533,6 +1568,11 @@ { if (!pid1_magic) { #if !TARGET_OS_EMBEDDED + if( _vproc_transaction_count() == 0 ) { + runtime_syslog(LOG_NOTICE, "Exiting cleanly."); + } + + runtime_closelog(); _vproc_transaction_end(); #endif } Modified: trunk/launchd/src/launchd_runtime.h =================================================================== --- trunk/launchd/src/launchd_runtime.h 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/launchd_runtime.h 2009-02-11 01:24:50 UTC (rev 23794) @@ -103,6 +103,7 @@ extern char g_username[128]; extern bool g_shutdown_debugging; extern bool g_use_gmalloc; +extern pid_t g_wsp; mach_port_t runtime_get_kernel_port(void); extern boolean_t launchd_internal_demux(mach_msg_header_t *Request, mach_msg_header_t *Reply); @@ -134,6 +135,7 @@ int kevent_bulk_mod(struct kevent *kev, size_t kev_cnt); int kevent_mod(uintptr_t ident, short filter, u_short flags, u_int fflags, intptr_t data, void *udata); +void log_kevent_struct(int level, struct kevent *kev_base, int indx); pid_t runtime_fork(mach_port_t bsport); Modified: trunk/launchd/src/launchd_unix_ipc.c =================================================================== --- trunk/launchd/src/launchd_unix_ipc.c 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/launchd_unix_ipc.c 2009-02-11 01:24:50 UTC (rev 23794) @@ -393,7 +393,7 @@ resp = launch_data_new_errno(errno); } else if (!strcmp(cmd, LAUNCH_KEY_REMOVEJOB)) { if ((j = job_find(launch_data_get_string(data))) != NULL) { - job_remove(j, false); + job_remove(j); errno = 0; } resp = launch_data_new_errno(errno); Modified: trunk/launchd/src/launchproxy.c =================================================================== --- trunk/launchd/src/launchproxy.c 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/launchproxy.c 2009-02-11 01:24:50 UTC (rev 23794) @@ -156,7 +156,7 @@ if ((r = accept((int)kev.ident, (struct sockaddr *)&ss, &slen)) == -1) { if (errno == EWOULDBLOCK) continue; - syslog(LOG_DEBUG, "accept(): %m"); + syslog(LOG_WARNING, "accept(): %m"); goto out; } else { if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6) { @@ -181,6 +181,9 @@ switch (fork()) { case -1: syslog(LOG_WARNING, "fork(): %m"); + if( errno != ENOMEM ) { + continue; + } goto out; case 0: break; Modified: trunk/launchd/src/libvproc.c =================================================================== --- trunk/launchd/src/libvproc.c 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/libvproc.c 2009-02-11 01:24:50 UTC (rev 23794) @@ -467,15 +467,7 @@ return (vproc_err_t)_vprocmgr_move_subset_to_user; } - /* Don't do things like setting up the exception port if we're tainted. This is primarily for - * loginwindow, which setuid(2)s to the logged-in user but still runs under the system Mach - * bootstrap. So we want the system launchd to spawn a crash reporter to report loginwindow - * crashes, not the per-user launchd, since that session will be wiped out of there is a loginwindow - * crash. - * - * See rdar://problem/5947376 for more details. - */ - return !issetugid() ? _vproc_post_fork_ping() : NULL; + return _vproc_post_fork_ping(); } vproc_err_t @@ -831,6 +823,21 @@ /* Once you're in the transaction model, you're in for good. Like the Mafia. */ s_cached_transactions_enabled = 1; break; + case VPROC_GSK_PERUSER_SUSPEND: + { + char peruser_label[NAME_MAX]; + snprintf(peruser_label, NAME_MAX - 1, "com.apple.launchd.peruser.%u", (uid_t)*inval); + + vproc_t pu_vp = vprocmgr_lookup_vproc(peruser_label); + if( pu_vp ) { + int status = 0; + kern_return_t kr = vproc_mig_wait2(bootstrap_port, pu_vp->j_port, &status); + vproc_release(pu_vp); + + syslog(LOG_DEBUG, "%u's suspended launchd exited with status %i (kr = 0x%x).", (uid_t)*inval, status, kr); + } + } + break; default: break; } Modified: trunk/launchd/src/protocol_job_reply.defs =================================================================== --- trunk/launchd/src/protocol_job_reply.defs 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/protocol_job_reply.defs 2009-02-11 01:24:50 UTC (rev 23794) @@ -78,3 +78,26 @@ __r_port : mach_port_move_send_once_t; __result : kern_return_t, RetCode; __outval : pointer_t); + +skip; /* log_forward */ + +skip; /* kickstart */ + +skip; /* embedded_wait */ + +skip; /* lookup_children */ + +skip; /* switch_to_session */ + +skip; /* transaction_count_for_pid */ + +skip; /* pid_is_managed */ + +skip; /* port_for_label */ + +skip; /* init_session */ + +simpleroutine job_mig_wait2_reply( + __r_port : mach_port_move_send_once_t; + __result : kern_return_t, RetCode; + __waitval : integer_t); Modified: trunk/launchd/src/protocol_vproc.defs =================================================================== --- trunk/launchd/src/protocol_vproc.defs 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/protocol_vproc.defs 2009-02-11 01:24:50 UTC (rev 23794) @@ -209,3 +209,9 @@ routine init_session( __bs_port : job_t; __session_name : name_t); + +routine wait2( + __bs_port : job_t; + __target_port : job_t; +sreplyport __rport : mach_port_make_send_once_t; +out __waitval : integer_t); Modified: trunk/launchd/src/vproc_priv.h =================================================================== --- trunk/launchd/src/vproc_priv.h 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd/src/vproc_priv.h 2009-02-11 01:24:50 UTC (rev 23794) @@ -62,6 +62,8 @@ VPROC_GSK_WEIRD_BOOTSTRAP, VPROC_GSK_WAITFORDEBUGGER, VPROC_GSK_SHUTDOWN_DEBUGGING, + VPROC_GSK_PERUSER_SUSPEND, + VPROC_GSK_PERUSER_RESUME, } vproc_gsk_t; typedef unsigned int vproc_flags_t; Modified: trunk/launchd.xcodeproj/project.pbxproj =================================================================== --- trunk/launchd.xcodeproj/project.pbxproj 2009-02-02 21:35:16 UTC (rev 23793) +++ trunk/launchd.xcodeproj/project.pbxproj 2009-02-11 01:24:50 UTC (rev 23794) @@ -51,9 +51,11 @@ /* Begin PBXBuildFile section */ 4B9EDCA20EAFC77E00A78496 /* DiskArbitration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B9EDCA10EAFC77E00A78496 /* DiskArbitration.framework */; }; + 7215DE4C0EFAF2EC00ABD81E /* libauditd.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7215DE4B0EFAF2EC00ABD81E /* libauditd.dylib */; }; 721FBEBC0EA7AE2F0057462B /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 721FBEBB0EA7AE2F0057462B /* Security.framework */; }; 726055EC0EA7EC2400D65FE7 /* mach_exc.defs in Sources */ = {isa = PBXBuildFile; fileRef = FC36291F0E9349410054F1A3 /* mach_exc.defs */; settings = {ATTRIBUTES = (Server, ); }; }; 726056090EA7FCF200D65FE7 /* launchd_ktrace.c in Sources */ = {isa = PBXBuildFile; fileRef = 72FDB15D0EA7D7B200B2AC84 /* launchd_ktrace.c */; }; + 72AFE8090EFAF3D9004BDA46 /* libauditd.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7215DE4B0EFAF2EC00ABD81E /* libauditd.dylib */; }; 72FDB15F0EA7D7B200B2AC84 /* launchd_ktrace.c in Sources */ = {isa = PBXBuildFile; fileRef = 72FDB15D0EA7D7B200B2AC84 /* launchd_ktrace.c */; }; 72FDB1C00EA7E21C00B2AC84 /* protocol_job_forward.defs in Sources */ = {isa = PBXBuildFile; fileRef = 72FDB1BF0EA7E21C00B2AC84 /* protocol_job_forward.defs */; }; FC3627BA0E9343220054F1A3 /* StartupItems.c in Sources */ = {isa = PBXBuildFile; fileRef = FC59A0FD0E8C8ADF00D41150 /* StartupItems.c */; }; @@ -288,6 +290,7 @@ /* Begin PBXFileReference section */ 4B9EDCA10EAFC77E00A78496 /* DiskArbitration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiskArbitration.framework; path = /System/Library/Frameworks/DiskArbitration.framework; sourceTree = ""; }; + 7215DE4B0EFAF2EC00ABD81E /* libauditd.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libauditd.dylib; path = /usr/lib/libauditd.dylib; sourceTree = ""; }; 721FBEA50EA7ABC40057462B /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config.h; path = launchd/src/config.h; sourceTree = ""; }; 721FBEBB0EA7AE2F0057462B /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = ""; }; 72FDB15D0EA7D7B200B2AC84 /* launchd_ktrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = launchd_ktrace.c; path = launchd/src/launchd_ktrace.c; sourceTree = ""; }; @@ -363,6 +366,7 @@ buildActionMask = 2147483647; files = ( FC36292D0E934AA40054F1A3 /* libbsm.dylib in Frameworks */, + 7215DE4C0EFAF2EC00ABD81E /* libauditd.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -380,6 +384,7 @@ FCC841CC0EA7138700C01666 /* IOKit.framework in Frameworks */, FC3628080E9345E10054F1A3 /* CoreFoundation.framework in Frameworks */, FCD713740E95DE49001B0111 /* libedit.dylib in Frameworks */, + 72AFE8090EFAF3D9004BDA46 /* libauditd.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -471,6 +476,7 @@ 4B9EDCA10EAFC77E00A78496 /* DiskArbitration.framework */, 721FBEBB0EA7AE2F0057462B /* Security.framework */, FC36292C0E934AA40054F1A3 /* libbsm.dylib */, + 7215DE4B0EFAF2EC00ABD81E /* libauditd.dylib */, FCD713730E95DE49001B0111 /* libedit.dylib */, FC3628070E9345E10054F1A3 /* CoreFoundation.framework */, FC36283E0E93463C0054F1A3 /* IOKit.framework */, -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 10 20:15:23 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 10 Feb 2009 20:15:23 -0800 (PST) Subject: [launchd-changes] [23795] trunk/launchd/src/launchd_core_logic.c Message-ID: <20090211041523.7A756F0711F@beta.macosforge.org> Revision: 23795 http://trac.macosforge.org/projects/launchd/changeset/23795 Author: dsorresso at apple.com Date: 2009-02-10 20:15:22 -0800 (Tue, 10 Feb 2009) Log Message: ----------- Fixed a small issue that could have become a bug in the future. Modified Paths: -------------- trunk/launchd/src/launchd_core_logic.c Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2009-02-11 01:24:50 UTC (rev 23794) +++ trunk/launchd/src/launchd_core_logic.c 2009-02-11 04:15:22 UTC (rev 23795) @@ -7896,11 +7896,7 @@ LIST_INSERT_HEAD(&jmr->jobs, j, sle); LIST_INSERT_HEAD(&jmr->active_jobs[ACTIVE_JOB_HASH(j->p)], j, pid_hash_sle); - if( job_assumes(j, kr == KERN_SUCCESS) ) { - job_set_global_on_demand(j, true); - } else { - job_log(j, LOG_WARNING, "Can't set global on-demand mode, unable to preemptively switch to %s job manager.", jmr->name); - } + job_set_global_on_demand(j, true); } for (l2l_i = 0; l2l_i < l2l_port_cnt; l2l_i++) { -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 10 21:51:19 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 10 Feb 2009 21:51:19 -0800 (PST) Subject: [launchd-changes] [23796] trunk/launchd/src/launchd_runtime.c Message-ID: <20090211055120.4D055F07C7F@beta.macosforge.org> Revision: 23796 http://trac.macosforge.org/projects/launchd/changeset/23796 Author: dsorresso at apple.com Date: 2009-02-10 21:51:19 -0800 (Tue, 10 Feb 2009) Log Message: ----------- Possible huge leak in launchd Modified Paths: -------------- trunk/launchd/src/launchd_runtime.c Modified: trunk/launchd/src/launchd_runtime.c =================================================================== --- trunk/launchd/src/launchd_runtime.c 2009-02-11 04:15:22 UTC (rev 23795) +++ trunk/launchd/src/launchd_runtime.c 2009-02-11 05:51:19 UTC (rev 23796) @@ -1499,12 +1499,24 @@ * It will return a valid pointer that can be passed to free(). If we don't * do this check, we'll wind up corrupting our heap in the subsequent * assignments. + * + * We break out if this check fails because, obj_sz is supposed to include + * the size of the logmsg_s struct. If it claims to be of zero size, we + * can't safely increment our counter because something obviously got screwed + * up along the way, since this should always be at least sizeof(struct logmsg_s). */ if( !launchd_assumes(lm_walk->obj_sz > 0) ) { - continue; + runtime_syslog(LOG_WARNING, "Encountered a log message of size 0 with %u bytes left in forwarded data. Ignoring remaining messages.", data_left); + break; } + + /* If malloc() keeps failing, we shouldn't put additional pressure on the system + * by attempting to add more messages to the log until it returns success + * log a failure, hope pressure lets off, and move on. + */ if (!launchd_assumes(lm = malloc(lm_walk->obj_sz))) { - continue; + runtime_syslog(LOG_WARNING, "Failed to allocate %llu bytes for log message with %u bytes left in forwarded data. Ignoring remaining messages.", lm_walk->obj_sz, data_left); + break; } memcpy(lm, lm_walk, lm_walk->obj_sz); -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 10 23:49:22 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 10 Feb 2009 23:49:22 -0800 (PST) Subject: [launchd-changes] [23797] trunk/launchd/src/launchd_core_logic.c Message-ID: <20090211074923.2117EF0A0AD@beta.macosforge.org> Revision: 23797 http://trac.macosforge.org/projects/launchd/changeset/23797 Author: dsorresso at apple.com Date: 2009-02-10 23:49:22 -0800 (Tue, 10 Feb 2009) Log Message: ----------- Allow the plist to specify whether a process can be safely suspended Modified Paths: -------------- trunk/launchd/src/launchd_core_logic.c Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2009-02-11 05:51:19 UTC (rev 23796) +++ trunk/launchd/src/launchd_core_logic.c 2009-02-11 07:49:22 UTC (rev 23797) @@ -75,6 +75,7 @@ #include #include #include +#include #if HAVE_SANDBOX #define __APPLE_API_PRIVATE #include @@ -4051,6 +4052,12 @@ setenv(LAUNCHD_DO_APPLE_INTERNAL_LOGGING, "true", 1); } +#if !TARGET_OS_EMBEDDED + if( j->jetsam_priority != LAUNCHD_JETSAM_PRIORITY_UNSET ) { + job_assumes(j, proc_setpcontrol(PROC_SETPC_TERMINATE) == 0); + } +#endif + /* * We'd like to call setsid() unconditionally, but we have reason to * believe that prevents launchd from being able to send signals to -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Wed Feb 11 14:52:28 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Wed, 11 Feb 2009 14:52:28 -0800 (PST) Subject: [launchd-changes] [23798] tags/launchd-299/ Message-ID: <20090211225229.99C4EF18F43@beta.macosforge.org> Revision: 23798 http://trac.macosforge.org/projects/launchd/changeset/23798 Author: dsorresso at apple.com Date: 2009-02-11 14:52:27 -0800 (Wed, 11 Feb 2009) Log Message: ----------- "Tagging launchd-299 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- tags/launchd-299/ Property changes on: tags/launchd-299 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Wed Feb 11 18:21:22 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Wed, 11 Feb 2009 18:21:22 -0800 (PST) Subject: [launchd-changes] [23799] trunk/launchd.xcodeproj/project.pbxproj Message-ID: <20090212022124.20CFEF1E189@beta.macosforge.org> Revision: 23799 http://trac.macosforge.org/projects/launchd/changeset/23799 Author: dsorresso at apple.com Date: 2009-02-11 18:21:17 -0800 (Wed, 11 Feb 2009) Log Message: ----------- Embedded build fixes. Modified Paths: -------------- trunk/launchd.xcodeproj/project.pbxproj Modified: trunk/launchd.xcodeproj/project.pbxproj =================================================================== --- trunk/launchd.xcodeproj/project.pbxproj 2009-02-11 22:52:27 UTC (rev 23798) +++ trunk/launchd.xcodeproj/project.pbxproj 2009-02-12 02:21:17 UTC (rev 23799) @@ -13,7 +13,7 @@ buildPhases = ( ); dependencies = ( - 726056230EA808AE00D65FE7 /* PBXTargetDependency */, + 4B10F1E20F43BEA900875782 /* PBXTargetDependency */, 726056250EA808B100D65FE7 /* PBXTargetDependency */, 726056270EA808B700D65FE7 /* PBXTargetDependency */, 726056290EA808B900D65FE7 /* PBXTargetDependency */, @@ -50,6 +50,24 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 4B10F1B90F43BE7E00875782 /* launchd_internal.defs in Sources */ = {isa = PBXBuildFile; fileRef = FC59A0BD0E8C8A2A00D41150 /* launchd_internal.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; + 4B10F1BA0F43BE7E00875782 /* protocol_vproc.defs in Sources */ = {isa = PBXBuildFile; fileRef = FC3627DF0E9344BF0054F1A3 /* protocol_vproc.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; + 4B10F1BB0F43BE7E00875782 /* protocol_job_reply.defs in Sources */ = {isa = PBXBuildFile; fileRef = FC3629160E9348390054F1A3 /* protocol_job_reply.defs */; }; + 4B10F1BC0F43BE7E00875782 /* mach_exc.defs in Sources */ = {isa = PBXBuildFile; fileRef = FC36291F0E9349410054F1A3 /* mach_exc.defs */; settings = {ATTRIBUTES = (Server, ); }; }; + 4B10F1BD0F43BE7E00875782 /* notify.defs in Sources */ = {isa = PBXBuildFile; fileRef = FC36290C0E93475F0054F1A3 /* notify.defs */; settings = {ATTRIBUTES = (Server, ); }; }; + 4B10F1BE0F43BE7E00875782 /* launchd.c in Sources */ = {isa = PBXBuildFile; fileRef = FC59A0C40E8C8A4700D41150 /* launchd.c */; }; + 4B10F1BF0F43BE7E00875782 /* launchd_runtime.c in Sources */ = {isa = PBXBuildFile; fileRef = FC59A0B50E8C8A1F00D41150 /* launchd_runtime.c */; settings = {COMPILER_FLAGS = "-I\"$SYMROOT\""; }; }; + 4B10F1C00F43BE7E00875782 /* launchd_runtime_kill.c in Sources */ = {isa = PBXBuildFile; fileRef = FC59A0B30E8C8A1F00D41150 /* launchd_runtime_kill.c */; }; + 4B10F1C10F43BE7E00875782 /* launchd_core_logic.c in Sources */ = {isa = PBXBuildFile; fileRef = FC59A0B70E8C8A1F00D41150 /* launchd_core_logic.c */; }; + 4B10F1C20F43BE7E00875782 /* launchd_unix_ipc.c in Sources */ = {isa = PBXBuildFile; fileRef = FC59A0B10E8C8A1F00D41150 /* launchd_unix_ipc.c */; }; + 4B10F1C30F43BE7E00875782 /* launchd_ktrace.c in Sources */ = {isa = PBXBuildFile; fileRef = 72FDB15D0EA7D7B200B2AC84 /* launchd_ktrace.c */; }; + 4B10F1C40F43BE7E00875782 /* protocol_job_forward.defs in Sources */ = {isa = PBXBuildFile; fileRef = 72FDB1BF0EA7E21C00B2AC84 /* protocol_job_forward.defs */; }; + 4B10F1C60F43BE7E00875782 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FC36292C0E934AA40054F1A3 /* libbsm.dylib */; }; + 4B10F1C90F43BE7E00875782 /* launchd.conf.5 in CopyFiles */ = {isa = PBXBuildFile; fileRef = FC59A0C30E8C8A4700D41150 /* launchd.conf.5 */; }; + 4B10F1CA0F43BE7E00875782 /* launchd.plist.5 in CopyFiles */ = {isa = PBXBuildFile; fileRef = FC59A0C10E8C8A4700D41150 /* launchd.plist.5 */; }; + 4B10F1CC0F43BE7E00875782 /* launchd.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = FC59A0C00E8C8A3A00D41150 /* launchd.8 */; }; + 4B10F1CD0F43BE7E00875782 /* rc.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = FC59A0F80E8C8AC300D41150 /* rc.8 */; }; + 4B10F1CF0F43BE7E00875782 /* rc.netboot in CopyFiles */ = {isa = PBXBuildFile; fileRef = FC59A0F90E8C8AC300D41150 /* rc.netboot */; }; 4B9EDCA20EAFC77E00A78496 /* DiskArbitration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B9EDCA10EAFC77E00A78496 /* DiskArbitration.framework */; }; 7215DE4C0EFAF2EC00ABD81E /* libauditd.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7215DE4B0EFAF2EC00ABD81E /* libauditd.dylib */; }; 721FBEBC0EA7AE2F0057462B /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 721FBEBB0EA7AE2F0057462B /* Security.framework */; }; @@ -109,12 +127,12 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 726056220EA808AE00D65FE7 /* PBXContainerItemProxy */ = { + 4B10F1E10F43BEA900875782 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = FC59A03F0E8C87FD00D41150 /* Project object */; proxyType = 1; - remoteGlobalIDString = FC59A0530E8C884700D41150; - remoteInfo = launchd; + remoteGlobalIDString = 4B10F1B70F43BE7E00875782 /* launchd-embedded */; + remoteInfo = "launchd-embedded"; }; 726056240EA808B100D65FE7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -182,6 +200,38 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + 4B10F1C80F43BE7E00875782 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = usr/share/man/man5; + dstSubfolderSpec = 0; + files = ( + 4B10F1C90F43BE7E00875782 /* launchd.conf.5 in CopyFiles */, + 4B10F1CA0F43BE7E00875782 /* launchd.plist.5 in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 4B10F1CB0F43BE7E00875782 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = usr/share/man/man8; + dstSubfolderSpec = 0; + files = ( + 4B10F1CC0F43BE7E00875782 /* launchd.8 in CopyFiles */, + 4B10F1CD0F43BE7E00875782 /* rc.8 in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 4B10F1CE0F43BE7E00875782 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = private/etc; + dstSubfolderSpec = 0; + files = ( + 4B10F1CF0F43BE7E00875782 /* rc.netboot in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; FC3627D60E9343B90054F1A3 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -289,6 +339,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 4B10F1D30F43BE7E00875782 /* launchd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = launchd; sourceTree = BUILT_PRODUCTS_DIR; }; 4B9EDCA10EAFC77E00A78496 /* DiskArbitration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiskArbitration.framework; path = /System/Library/Frameworks/DiskArbitration.framework; sourceTree = ""; }; 7215DE4B0EFAF2EC00ABD81E /* libauditd.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libauditd.dylib; path = /usr/lib/libauditd.dylib; sourceTree = ""; }; 721FBEA50EA7ABC40057462B /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config.h; path = launchd/src/config.h; sourceTree = ""; }; @@ -361,6 +412,14 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 4B10F1C50F43BE7E00875782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B10F1C60F43BE7E00875782 /* libbsm.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; FC59A0520E8C884700D41150 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -518,6 +577,7 @@ FC59A0910E8C892300D41150 /* SystemStarter */, FC59A0CE0E8C8A5C00D41150 /* launchproxy */, FCD7132B0E95D64D001B0111 /* wait4path */, + 4B10F1D30F43BE7E00875782 /* launchd */, ); name = Products; sourceTree = ""; @@ -609,6 +669,26 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 4B10F1B70F43BE7E00875782 /* launchd-embedded */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B10F1D10F43BE7E00875782 /* Build configuration list for PBXNativeTarget "launchd-embedded" */; + buildPhases = ( + 4B10F1B80F43BE7E00875782 /* Sources */, + 4B10F1C50F43BE7E00875782 /* Frameworks */, + 4B10F1C80F43BE7E00875782 /* CopyFiles */, + 4B10F1CB0F43BE7E00875782 /* CopyFiles */, + 4B10F1CE0F43BE7E00875782 /* CopyFiles */, + 4B10F1D00F43BE7E00875782 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "launchd-embedded"; + productName = launchd; + productReference = 4B10F1D30F43BE7E00875782 /* launchd */; + productType = "com.apple.product-type.tool"; + }; FC59A0530E8C884700D41150 /* launchd */ = { isa = PBXNativeTarget; buildConfigurationList = FC59A0590E8C884800D41150 /* Build configuration list for PBXNativeTarget "launchd" */; @@ -739,6 +819,7 @@ 726056200EA8088C00D65FE7 /* embedded */, FC59A07A0E8C88BB00D41150 /* launchd_libs */, FC59A0530E8C884700D41150 /* launchd */, + 4B10F1B70F43BE7E00875782 /* launchd-embedded */, FC59A06C0E8C888A00D41150 /* launchctl */, FC59A0CD0E8C8A5C00D41150 /* launchproxy */, FCD7132A0E95D64D001B0111 /* wait4path */, @@ -749,6 +830,20 @@ /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ + 4B10F1D00F43BE7E00875782 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "/Developer/Makefiles/bin/compress-man-pages.pl -d \"$DSTROOT\" /usr/share/man"; + showEnvVarsInLog = 0; + }; FC7B87B20EA7195F00542082 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; @@ -836,6 +931,25 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 4B10F1B80F43BE7E00875782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B10F1B90F43BE7E00875782 /* launchd_internal.defs in Sources */, + 4B10F1BA0F43BE7E00875782 /* protocol_vproc.defs in Sources */, + 4B10F1BB0F43BE7E00875782 /* protocol_job_reply.defs in Sources */, + 4B10F1BC0F43BE7E00875782 /* mach_exc.defs in Sources */, + 4B10F1BD0F43BE7E00875782 /* notify.defs in Sources */, + 4B10F1BE0F43BE7E00875782 /* launchd.c in Sources */, + 4B10F1BF0F43BE7E00875782 /* launchd_runtime.c in Sources */, + 4B10F1C00F43BE7E00875782 /* launchd_runtime_kill.c in Sources */, + 4B10F1C10F43BE7E00875782 /* launchd_core_logic.c in Sources */, + 4B10F1C20F43BE7E00875782 /* launchd_unix_ipc.c in Sources */, + 4B10F1C30F43BE7E00875782 /* launchd_ktrace.c in Sources */, + 4B10F1C40F43BE7E00875782 /* protocol_job_forward.defs in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; FC59A0510E8C884700D41150 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -904,10 +1018,10 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 726056230EA808AE00D65FE7 /* PBXTargetDependency */ = { + 4B10F1E20F43BEA900875782 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = FC59A0530E8C884700D41150 /* launchd */; - targetProxy = 726056220EA808AE00D65FE7 /* PBXContainerItemProxy */; + target = 4B10F1B70F43BE7E00875782 /* launchd-embedded */; + targetProxy = 4B10F1E10F43BEA900875782 /* PBXContainerItemProxy */; }; 726056250EA808B100D65FE7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -957,6 +1071,22 @@ /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ + 4B10F1D20F43BE7E00875782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + INSTALL_PATH = /sbin; + PREBINDING = NO; + PRODUCT_NAME = launchd; + STRIP_STYLE = debugging; + VALID_ARCHS = "armv5 armv6 armv7 i386 ppc ppc64 ppc7400 ppc970 x86_64"; + ZERO_LINK = NO; + }; + name = Release; + }; 726056210EA8088D00D65FE7 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1128,6 +1258,14 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 4B10F1D10F43BE7E00875782 /* Build configuration list for PBXNativeTarget "launchd-embedded" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B10F1D20F43BE7E00875782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 7260562B0EA808D800D65FE7 /* Build configuration list for PBXAggregateTarget "embedded" */ = { isa = XCConfigurationList; buildConfigurations = ( -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Wed Feb 11 18:23:27 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Wed, 11 Feb 2009 18:23:27 -0800 (PST) Subject: [launchd-changes] [23800] trunk/launchd.xcodeproj/project.pbxproj Message-ID: <20090212022328.07F4EF1E4DE@beta.macosforge.org> Revision: 23800 http://trac.macosforge.org/projects/launchd/changeset/23800 Author: dsorresso at apple.com Date: 2009-02-11 18:23:27 -0800 (Wed, 11 Feb 2009) Log Message: ----------- Yet more embedded build fixes. Modified Paths: -------------- trunk/launchd.xcodeproj/project.pbxproj Modified: trunk/launchd.xcodeproj/project.pbxproj =================================================================== --- trunk/launchd.xcodeproj/project.pbxproj 2009-02-12 02:21:17 UTC (rev 23799) +++ trunk/launchd.xcodeproj/project.pbxproj 2009-02-12 02:23:27 UTC (rev 23800) @@ -14,7 +14,7 @@ ); dependencies = ( 4B10F1E20F43BEA900875782 /* PBXTargetDependency */, - 726056250EA808B100D65FE7 /* PBXTargetDependency */, + 4B10F1F60F43BF8C00875782 /* PBXTargetDependency */, 726056270EA808B700D65FE7 /* PBXTargetDependency */, 726056290EA808B900D65FE7 /* PBXTargetDependency */, ); @@ -68,6 +68,11 @@ 4B10F1CC0F43BE7E00875782 /* launchd.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = FC59A0C00E8C8A3A00D41150 /* launchd.8 */; }; 4B10F1CD0F43BE7E00875782 /* rc.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = FC59A0F80E8C8AC300D41150 /* rc.8 */; }; 4B10F1CF0F43BE7E00875782 /* rc.netboot in CopyFiles */ = {isa = PBXBuildFile; fileRef = FC59A0F90E8C8AC300D41150 /* rc.netboot */; }; + 4B10F1E80F43BF5C00875782 /* launchctl.c in Sources */ = {isa = PBXBuildFile; fileRef = FC59A0AE0E8C8A0E00D41150 /* launchctl.c */; settings = {COMPILER_FLAGS = "-I\"$SDKROOT\"/System/Library/Frameworks/System.framework/PrivateHeaders"; }; }; + 4B10F1EA0F43BF5C00875782 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC36283E0E93463C0054F1A3 /* IOKit.framework */; }; + 4B10F1EB0F43BF5C00875782 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC3628070E9345E10054F1A3 /* CoreFoundation.framework */; }; + 4B10F1EC0F43BF5C00875782 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FCD713730E95DE49001B0111 /* libedit.dylib */; settings = {ATTRIBUTES = (Weak, ); }; }; + 4B10F1EF0F43BF5C00875782 /* launchctl.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = FC59A0AD0E8C8A0E00D41150 /* launchctl.1 */; }; 4B9EDCA20EAFC77E00A78496 /* DiskArbitration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B9EDCA10EAFC77E00A78496 /* DiskArbitration.framework */; }; 7215DE4C0EFAF2EC00ABD81E /* libauditd.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7215DE4B0EFAF2EC00ABD81E /* libauditd.dylib */; }; 721FBEBC0EA7AE2F0057462B /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 721FBEBB0EA7AE2F0057462B /* Security.framework */; }; @@ -134,12 +139,12 @@ remoteGlobalIDString = 4B10F1B70F43BE7E00875782 /* launchd-embedded */; remoteInfo = "launchd-embedded"; }; - 726056240EA808B100D65FE7 /* PBXContainerItemProxy */ = { + 4B10F1F50F43BF8C00875782 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = FC59A03F0E8C87FD00D41150 /* Project object */; proxyType = 1; - remoteGlobalIDString = FC59A06C0E8C888A00D41150; - remoteInfo = launchctl; + remoteGlobalIDString = 4B10F1E60F43BF5C00875782 /* launchctl-embedded */; + remoteInfo = "launchctl-embedded"; }; 726056260EA808B700D65FE7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -232,6 +237,16 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 4B10F1EE0F43BF5C00875782 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = usr/share/man/man1; + dstSubfolderSpec = 0; + files = ( + 4B10F1EF0F43BF5C00875782 /* launchctl.1 in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; FC3627D60E9343B90054F1A3 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -340,6 +355,7 @@ /* Begin PBXFileReference section */ 4B10F1D30F43BE7E00875782 /* launchd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = launchd; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B10F1F30F43BF5C00875782 /* launchctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = launchctl; sourceTree = BUILT_PRODUCTS_DIR; }; 4B9EDCA10EAFC77E00A78496 /* DiskArbitration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiskArbitration.framework; path = /System/Library/Frameworks/DiskArbitration.framework; sourceTree = ""; }; 7215DE4B0EFAF2EC00ABD81E /* libauditd.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libauditd.dylib; path = /usr/lib/libauditd.dylib; sourceTree = ""; }; 721FBEA50EA7ABC40057462B /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config.h; path = launchd/src/config.h; sourceTree = ""; }; @@ -420,6 +436,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B10F1E90F43BF5C00875782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B10F1EA0F43BF5C00875782 /* IOKit.framework in Frameworks */, + 4B10F1EB0F43BF5C00875782 /* CoreFoundation.framework in Frameworks */, + 4B10F1EC0F43BF5C00875782 /* libedit.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; FC59A0520E8C884700D41150 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -578,6 +604,7 @@ FC59A0CE0E8C8A5C00D41150 /* launchproxy */, FCD7132B0E95D64D001B0111 /* wait4path */, 4B10F1D30F43BE7E00875782 /* launchd */, + 4B10F1F30F43BF5C00875782 /* launchctl */, ); name = Products; sourceTree = ""; @@ -689,6 +716,24 @@ productReference = 4B10F1D30F43BE7E00875782 /* launchd */; productType = "com.apple.product-type.tool"; }; + 4B10F1E60F43BF5C00875782 /* launchctl-embedded */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B10F1F10F43BF5C00875782 /* Build configuration list for PBXNativeTarget "launchctl-embedded" */; + buildPhases = ( + 4B10F1E70F43BF5C00875782 /* Sources */, + 4B10F1E90F43BF5C00875782 /* Frameworks */, + 4B10F1EE0F43BF5C00875782 /* CopyFiles */, + 4B10F1F00F43BF5C00875782 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "launchctl-embedded"; + productName = launchctl; + productReference = 4B10F1F30F43BF5C00875782 /* launchctl */; + productType = "com.apple.product-type.tool"; + }; FC59A0530E8C884700D41150 /* launchd */ = { isa = PBXNativeTarget; buildConfigurationList = FC59A0590E8C884800D41150 /* Build configuration list for PBXNativeTarget "launchd" */; @@ -819,8 +864,9 @@ 726056200EA8088C00D65FE7 /* embedded */, FC59A07A0E8C88BB00D41150 /* launchd_libs */, FC59A0530E8C884700D41150 /* launchd */, + FC59A06C0E8C888A00D41150 /* launchctl */, 4B10F1B70F43BE7E00875782 /* launchd-embedded */, - FC59A06C0E8C888A00D41150 /* launchctl */, + 4B10F1E60F43BF5C00875782 /* launchctl-embedded */, FC59A0CD0E8C8A5C00D41150 /* launchproxy */, FCD7132A0E95D64D001B0111 /* wait4path */, FC59A0900E8C892300D41150 /* SystemStarter */, @@ -844,6 +890,20 @@ shellScript = "/Developer/Makefiles/bin/compress-man-pages.pl -d \"$DSTROOT\" /usr/share/man"; showEnvVarsInLog = 0; }; + 4B10F1F00F43BF5C00875782 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "install -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/System/Library/LaunchAgents\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/System/Library/LaunchDaemons\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/Library/LaunchAgents\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/Library/LaunchDaemons\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/private/etc/mach_init.d\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/private/etc/mach_init_per_login_session.d\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/private/etc/mach_init_per_user.d\n/Developer/Makefiles/bin/compress-man-pages.pl -d \"$DSTROOT\" /usr/share/man"; + showEnvVarsInLog = 0; + }; FC7B87B20EA7195F00542082 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; @@ -950,6 +1010,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B10F1E70F43BF5C00875782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B10F1E80F43BF5C00875782 /* launchctl.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; FC59A0510E8C884700D41150 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1023,10 +1091,10 @@ target = 4B10F1B70F43BE7E00875782 /* launchd-embedded */; targetProxy = 4B10F1E10F43BEA900875782 /* PBXContainerItemProxy */; }; - 726056250EA808B100D65FE7 /* PBXTargetDependency */ = { + 4B10F1F60F43BF8C00875782 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = FC59A06C0E8C888A00D41150 /* launchctl */; - targetProxy = 726056240EA808B100D65FE7 /* PBXContainerItemProxy */; + target = 4B10F1E60F43BF5C00875782 /* launchctl-embedded */; + targetProxy = 4B10F1F50F43BF8C00875782 /* PBXContainerItemProxy */; }; 726056270EA808B700D65FE7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -1087,6 +1155,23 @@ }; name = Release; }; + 4B10F1F20F43BF5C00875782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + INSTALL_PATH = /bin; + PREBINDING = NO; + PRODUCT_NAME = launchctl; + STRIP_STYLE = debugging; + VALID_ARCHS = "armv5 armv6 armv7 i386 ppc ppc64 ppc7400 ppc970 x86_64"; + ZERO_LINK = NO; + }; + name = Release; + }; 726056210EA8088D00D65FE7 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1266,6 +1351,14 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4B10F1F10F43BF5C00875782 /* Build configuration list for PBXNativeTarget "launchctl-embedded" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B10F1F20F43BF5C00875782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 7260562B0EA808D800D65FE7 /* Build configuration list for PBXAggregateTarget "embedded" */ = { isa = XCConfigurationList; buildConfigurations = ( -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Wed Feb 11 18:56:09 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Wed, 11 Feb 2009 18:56:09 -0800 (PST) Subject: [launchd-changes] [23801] tags/launchd-299.1/ Message-ID: <20090212025610.B0FA9F2004B@beta.macosforge.org> Revision: 23801 http://trac.macosforge.org/projects/launchd/changeset/23801 Author: dsorresso at apple.com Date: 2009-02-11 18:56:06 -0800 (Wed, 11 Feb 2009) Log Message: ----------- "Tagging launchd-299.1 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- tags/launchd-299.1/ Property changes on: tags/launchd-299.1 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 12 10:52:13 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 12 Feb 2009 10:52:13 -0800 (PST) Subject: [launchd-changes] [23802] trunk Message-ID: <20090212185214.15DF2F2A085@beta.macosforge.org> Revision: 23802 http://trac.macosforge.org/projects/launchd/changeset/23802 Author: dsorresso at apple.com Date: 2009-02-12 10:52:12 -0800 (Thu, 12 Feb 2009) Log Message: ----------- rebooting at the end of the restore takes longer than it used to Changed auto-label generation to distinguish between anonymous jobs and legacy mach_init jobs. Modified Paths: -------------- trunk/launchd/src/launchctl.c trunk/launchd/src/launchd_core_logic.c trunk/launchd.xcodeproj/project.pbxproj Modified: trunk/launchd/src/launchctl.c =================================================================== --- trunk/launchd/src/launchctl.c 2009-02-12 02:56:06 UTC (rev 23801) +++ trunk/launchd/src/launchctl.c 2009-02-12 18:52:12 UTC (rev 23802) @@ -1791,6 +1791,8 @@ #if TARGET_OS_EMBEDDED if (path_check("/etc/rc.boot")) { const char *rcboot_tool[] = { "/etc/rc.boot", NULL }; + + assumes(signal(SIGTERM, exit_at_sigterm) != SIG_ERR); assumes(fwexec(rcboot_tool, NULL) != -1); } #endif Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2009-02-12 02:56:06 UTC (rev 23801) +++ trunk/launchd/src/launchd_core_logic.c 2009-02-12 18:52:12 UTC (rev 23802) @@ -392,6 +392,7 @@ static void jobmgr_log_bug(jobmgr_t jm, unsigned int line); #define AUTO_PICK_LEGACY_LABEL (const char *)(~0) +#define AUTO_PICK_ANONYMOUS_LABEL (const char *)(~1) struct job_s { kq_callback kqjob_callback; /* MUST be first element of this structure for benefit of launchd's run loop. */ @@ -1373,7 +1374,7 @@ jm->shutting_down = false; } - if (jobmgr_assumes(jm, (jr = job_new(jm, AUTO_PICK_LEGACY_LABEL, kp.kp_proc.p_comm, NULL)) != NULL)) { + if (jobmgr_assumes(jm, (jr = job_new(jm, AUTO_PICK_ANONYMOUS_LABEL, kp.kp_proc.p_comm, NULL)) != NULL)) { u_int proc_fflags = NOTE_EXEC|NOTE_FORK|NOTE_EXIT|NOTE_REAP; total_anon_children++; @@ -1431,14 +1432,15 @@ return NULL; } - if (unlikely(label == AUTO_PICK_LEGACY_LABEL)) { + char *anon_or_legacy = ( label == AUTO_PICK_ANONYMOUS_LABEL ) ? "anonymous" : "mach_init"; + if (unlikely(label == AUTO_PICK_LEGACY_LABEL || label == AUTO_PICK_ANONYMOUS_LABEL)) { if (prog) { bn = prog; } else { strlcpy(tmp_path, argv[0], sizeof(tmp_path)); bn = basename(tmp_path); /* prog for auto labels is kp.kp_kproc.p_comm */ } - snprintf(auto_label, sizeof(auto_label), "%s.%s", sizeof(void *) == 8 ? "0xdeadbeeffeedface" : "0xbabecafe", bn); + snprintf(auto_label, sizeof(auto_label), "%s.%s.%s", sizeof(void *) == 8 ? "0xdeadbeeffeedface" : "0xbabecafe", anon_or_legacy, bn); label = auto_label; /* This is so we can do gross things later. See NOTE_EXEC for anonymous jobs */ minlabel_len = strlen(label) + MAXCOMLEN; @@ -1453,7 +1455,7 @@ } if (unlikely(label == auto_label)) { - snprintf((char *)j->label, strlen(label) + 1, "%p.%s", j, bn); + snprintf((char *)j->label, strlen(label) + 1, "%p.%s.%s", j, anon_or_legacy, bn); } else { strcpy((char *)j->label, label); } @@ -3153,7 +3155,7 @@ if (job_assumes(j, sysctl(mib, 4, &kp, &len, NULL, 0) != -1) && len == sizeof(kp)) { char newlabel[1000]; - snprintf(newlabel, sizeof(newlabel), "%p.%s", j, kp.kp_proc.p_comm); + snprintf(newlabel, sizeof(newlabel), "%p.anonymous.%s", j, kp.kp_proc.p_comm); job_log(j, LOG_INFO, "Program changed. Updating the label to: %s", newlabel); j->lastlookup = NULL; Modified: trunk/launchd.xcodeproj/project.pbxproj =================================================================== --- trunk/launchd.xcodeproj/project.pbxproj 2009-02-12 02:56:06 UTC (rev 23801) +++ trunk/launchd.xcodeproj/project.pbxproj 2009-02-12 18:52:12 UTC (rev 23802) @@ -136,14 +136,14 @@ isa = PBXContainerItemProxy; containerPortal = FC59A03F0E8C87FD00D41150 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4B10F1B70F43BE7E00875782 /* launchd-embedded */; + remoteGlobalIDString = 4B10F1B70F43BE7E00875782; remoteInfo = "launchd-embedded"; }; 4B10F1F50F43BF8C00875782 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = FC59A03F0E8C87FD00D41150 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4B10F1E60F43BF5C00875782 /* launchctl-embedded */; + remoteGlobalIDString = 4B10F1E60F43BF5C00875782; remoteInfo = "launchctl-embedded"; }; 726056260EA808B700D65FE7 /* PBXContainerItemProxy */ = { -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 12 12:48:11 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 12 Feb 2009 12:48:11 -0800 (PST) Subject: [launchd-changes] [23803] branches/PR-5063531/ Message-ID: <20090212204811.DBD93F2C8A9@beta.macosforge.org> Revision: 23803 http://trac.macosforge.org/projects/launchd/changeset/23803 Author: dsorresso at apple.com Date: 2009-02-12 12:48:11 -0800 (Thu, 12 Feb 2009) Log Message: ----------- "Branch for PR-5063531 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- branches/PR-5063531/ Property changes on: branches/PR-5063531 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 12 20:20:18 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 12 Feb 2009 20:20:18 -0800 (PST) Subject: [launchd-changes] [23804] branches/PR-5063531/launchd/src Message-ID: <20090213042019.1920DF34730@beta.macosforge.org> Revision: 23804 http://trac.macosforge.org/projects/launchd/changeset/23804 Author: dsorresso at apple.com Date: 2009-02-12 20:20:18 -0800 (Thu, 12 Feb 2009) Log Message: ----------- Implemented boot plist caching. We're saving about 0.6 seconds. Modified Paths: -------------- branches/PR-5063531/launchd/src/launchctl.c branches/PR-5063531/launchd/src/launchd_core_logic.c Modified: branches/PR-5063531/launchd/src/launchctl.c =================================================================== --- branches/PR-5063531/launchd/src/launchctl.c 2009-02-12 20:48:11 UTC (rev 23803) +++ branches/PR-5063531/launchd/src/launchctl.c 2009-02-13 04:20:18 UTC (rev 23804) @@ -81,6 +81,7 @@ #include #include #include +#include #if HAVE_LIBAUDITD #include @@ -89,9 +90,10 @@ #endif #endif +#define LAUNCHD_PLIST_CACHE "/var/db/launchd_plist_cache.plist" + extern char **environ; - #define LAUNCH_SECDIR _PATH_TMP "launch-XXXXXX" #define MACHINIT_JOBKEY_ONDEMAND "OnDemand" @@ -125,7 +127,7 @@ static launch_data_t read_plist_file(const char *file, bool editondisk, bool load); static CFPropertyListRef CreateMyPropertyListFromFile(const char *); static CFPropertyListRef CFPropertyListCreateFromFile(CFURLRef plistURL); -static void WriteMyPropertyListToFile(CFPropertyListRef, const char *); +static void WriteMyPropertyListToFile(CFPropertyListRef, const char *, bool); static bool path_goodness_check(const char *path, bool forceload); static void readpath(const char *, struct load_unload_state *); static void readfile(const char *, struct load_unload_state *); @@ -257,6 +259,10 @@ static bool rootuser_context; static bool g_shutdown_debugging = false; +static uint32_t g_plist_cache_changes = 0; +static time_t g_cache_creation_time = 0; +static CFMutableDictionaryRef g_plist_cache = NULL; + int main(int argc, char *const argv[]) { @@ -693,21 +699,56 @@ launch_data_t read_plist_file(const char *file, bool editondisk, bool load) { - CFPropertyListRef plist = CreateMyPropertyListFromFile(file); + CFPropertyListRef plist = NULL; + bool add_to_cache = false, file_changed = false; + + CFStringRef key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), file); + + struct stat sb; + if( assumes(stat(file, &sb) == 0) ) { + file_changed = sb.st_mtimespec.tv_sec > g_cache_creation_time; + if( file_changed ) { + fprintf(stdout, "File %s has changed.\n", file); + } + } + + if( g_plist_cache && !file_changed ) { + plist = CFDictionaryGetValue(g_plist_cache, key); + + if( plist && CFGetTypeID(plist) == CFDictionaryGetTypeID() ) { + CFRetain(plist); + } else { + fprintf(stdout, "Invalidating cache for %s...\n", file); + add_to_cache = true; + } + } else if( g_plist_cache ) { + add_to_cache = true; + } + + if( !plist ) { + plist = CreateMyPropertyListFromFile(file); + } + launch_data_t r = NULL; if (NULL == plist) { fprintf(stderr, "%s: no plist was returned for: %s\n", getprogname(), file); return NULL; + } else if( add_to_cache ) { + fprintf(stdout, "\tAdding %s to cache...\n", file); + CFDictionarySetValue(g_plist_cache, key, plist); + g_plist_cache_changes++; } + CFRelease(key); + if (editondisk) { if (load) { CFDictionaryRemoveValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED)); } else { CFDictionarySetValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED), kCFBooleanTrue); } - WriteMyPropertyListToFile(plist, file); + WriteMyPropertyListToFile(plist, file, false); } r = CF2launch_data(plist); @@ -1405,27 +1446,43 @@ } void -WriteMyPropertyListToFile(CFPropertyListRef plist, const char *posixfile) +WriteMyPropertyListToFile(CFPropertyListRef plist, const char *posixfile, bool binary) { - CFDataRef resourceData; CFURLRef fileURL; - SInt32 errorCode; + fprintf(stdout, "About to call CFURLCreateFromFileSystemRepresentation()...\n"); fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)posixfile, strlen(posixfile), false); if (!fileURL) { - fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile); + fprintf(stdout, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile); } + +#if 1 + CFWriteStreamRef ws = CFWriteStreamCreateWithFile(NULL, fileURL); + if( ws ) { + if( assumes(CFWriteStreamOpen(ws) == true) ) { + assumes(CFPropertyListWriteToStream(plist, ws, binary ? kCFPropertyListBinaryFormat_v1_0 : kCFPropertyListXMLFormat_v1_0, NULL)); + CFWriteStreamClose(ws); + } + CFRelease(ws); + } +#else + SInt32 errorCode; + CFDataRef resourceData; + fprintf(stdout, "About to call CFPropertyListCreateXMLData()...\n"); resourceData = CFPropertyListCreateXMLData(kCFAllocatorDefault, plist); if (resourceData == NULL) { - fprintf(stderr, "%s: CFPropertyListCreateXMLData(%s) failed", getprogname(), posixfile); + fprintf(stdout, "%s: CFPropertyListCreateXMLData(%s) failed", getprogname(), posixfile); } + + fprintf(stdout, "About to call CFURLWriteDataAndPropertiesToResource()...\n"); if (!CFURLWriteDataAndPropertiesToResource(fileURL, resourceData, NULL, &errorCode)) { - fprintf(stderr, "%s: CFURLWriteDataAndPropertiesToResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode); + fprintf(stdout, "%s: CFURLWriteDataAndPropertiesToResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode); } if( resourceData ) { CFRelease(resourceData); } +#endif } static inline Boolean __is_launch_data_t(launch_data_t obj) @@ -1908,11 +1965,34 @@ int load_launchd_items_cnt = 5; #endif + struct stat sb; if (is_safeboot()) { load_launchd_items[2] = "system"; + } else if( stat("/var/db/.launchd_disable_plist_cache", &sb) != 0 ) { + CFDictionaryRef plist_cache = (CFDictionaryRef)CreateMyPropertyListFromFile(LAUNCHD_PLIST_CACHE); + if( !plist_cache ) { + g_plist_cache = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + } else { + if( assumes(stat(LAUNCHD_PLIST_CACHE, &sb) == 0) ) { + g_cache_creation_time = sb.st_mtimespec.tv_sec; + } + + g_plist_cache = CFDictionaryCreateMutableCopy(NULL, 0, plist_cache); + CFRelease(plist_cache); + } } + uint64_t t0 = mach_absolute_time(); assumes(load_and_unload_cmd(load_launchd_items_cnt, load_launchd_items) == 0); + uint64_t t1 = mach_absolute_time(); + + fprintf(stdout, "It took %llu nanoseconds to load System jobs%s.\n", t1 - t0, !g_plist_cache ? " without the cache" : ""); + syslog(LOG_NOTICE, "It took %llu nanoseconds to load System jobs%s.\n", t1 - t0, !g_plist_cache ? " without the cache" : ""); + + if( g_plist_cache_changes > 0 ) { + fprintf(stdout, "Updating %u entries in launchd's plist cache.\n", g_plist_cache_changes); + WriteMyPropertyListToFile(g_plist_cache, LAUNCHD_PLIST_CACHE, true); + } /* * 5066316 Modified: branches/PR-5063531/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-5063531/launchd/src/launchd_core_logic.c 2009-02-12 20:48:11 UTC (rev 23803) +++ branches/PR-5063531/launchd/src/launchd_core_logic.c 2009-02-13 04:20:18 UTC (rev 23804) @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -613,7 +614,6 @@ static char **mach_cmd2argv(const char *string); 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 do_first_per_user_launchd_hack(void); 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)); @@ -631,8 +631,6 @@ static size_t total_children; static size_t total_anon_children; static mach_port_t the_exception_server; -static bool did_first_per_user_launchd_BootCache_hack; -#define JOB_BOOTCACHE_HACK_CHECK(j) (unlikely(j->per_user && !did_first_per_user_launchd_BootCache_hack && (j->mach_uid >= 500) && (j->mach_uid != (uid_t)-2))) static job_t workaround_5477111; static pid_t s_update_pid = 0; @@ -2470,6 +2468,10 @@ job_mig_swap_integer(j, VPROC_GSK_WEIRD_BOOTSTRAP, 0, 0, &junk); } + if( unlikely(j->forced_peers_to_demand_mode) ) { + job_set_global_on_demand(j, false); + } + j->wait4debugger_oneshot = false; if (j->log_redirect_fd && !j->legacy_LS_job) { @@ -3510,10 +3512,6 @@ total_children++; LIST_INSERT_HEAD(&j->mgr->active_jobs[ACTIVE_JOB_HASH(c)], j, pid_hash_sle); - if (JOB_BOOTCACHE_HACK_CHECK(j)) { - did_first_per_user_launchd_BootCache_hack = true; - } - if (likely(!j->legacy_mach_job)) { job_assumes(j, runtime_close(oepair[1]) != -1); } @@ -3543,23 +3541,6 @@ } void -do_first_per_user_launchd_hack(void) -{ - char *bcct_tool[] = { "/usr/sbin/BootCacheControl", "tag", NULL }; - int dummystatus; - pid_t bcp; - - if (launchd_assumes((bcp = vfork()) != -1)) { - if (bcp == 0) { - execve(bcct_tool[0], bcct_tool, environ); - _exit(EXIT_FAILURE); - } else { - launchd_assumes(waitpid(bcp, &dummystatus, 0) != -1); - } - } -} - -void job_start_child(job_t j) { typeof(posix_spawn) *psf; @@ -3572,10 +3553,6 @@ size_t binpref_out_cnt = 0; size_t i; - if (JOB_BOOTCACHE_HACK_CHECK(j)) { - do_first_per_user_launchd_hack(); - } - job_assumes(j, posix_spawnattr_init(&spattr) == 0); job_setup_attributes(j); -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Fri Feb 13 10:58:54 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Fri, 13 Feb 2009 10:58:54 -0800 (PST) Subject: [launchd-changes] [23805] branches/PR-5063531/launchd/src/launchctl.c Message-ID: <20090213185858.76577F473C3@beta.macosforge.org> Revision: 23805 http://trac.macosforge.org/projects/launchd/changeset/23805 Author: dsorresso at apple.com Date: 2009-02-13 10:58:48 -0800 (Fri, 13 Feb 2009) Log Message: ----------- More tweaks. Modified Paths: -------------- branches/PR-5063531/launchd/src/launchctl.c Modified: branches/PR-5063531/launchd/src/launchctl.c =================================================================== --- branches/PR-5063531/launchd/src/launchctl.c 2009-02-13 04:20:18 UTC (rev 23804) +++ branches/PR-5063531/launchd/src/launchctl.c 2009-02-13 18:58:48 UTC (rev 23805) @@ -707,9 +707,6 @@ struct stat sb; if( assumes(stat(file, &sb) == 0) ) { file_changed = sb.st_mtimespec.tv_sec > g_cache_creation_time; - if( file_changed ) { - fprintf(stdout, "File %s has changed.\n", file); - } } if( g_plist_cache && !file_changed ) { @@ -718,7 +715,6 @@ if( plist && CFGetTypeID(plist) == CFDictionaryGetTypeID() ) { CFRetain(plist); } else { - fprintf(stdout, "Invalidating cache for %s...\n", file); add_to_cache = true; } } else if( g_plist_cache ) { @@ -735,7 +731,6 @@ fprintf(stderr, "%s: no plist was returned for: %s\n", getprogname(), file); return NULL; } else if( add_to_cache ) { - fprintf(stdout, "\tAdding %s to cache...\n", file); CFDictionarySetValue(g_plist_cache, key, plist); g_plist_cache_changes++; } @@ -1987,11 +1982,10 @@ uint64_t t1 = mach_absolute_time(); fprintf(stdout, "It took %llu nanoseconds to load System jobs%s.\n", t1 - t0, !g_plist_cache ? " without the cache" : ""); - syslog(LOG_NOTICE, "It took %llu nanoseconds to load System jobs%s.\n", t1 - t0, !g_plist_cache ? " without the cache" : ""); if( g_plist_cache_changes > 0 ) { - fprintf(stdout, "Updating %u entries in launchd's plist cache.\n", g_plist_cache_changes); WriteMyPropertyListToFile(g_plist_cache, LAUNCHD_PLIST_CACHE, true); + fprintf(stdout, "Updated %u entr%s in launchd's plist cache.\n", g_plist_cache_changes, g_plist_cache_changes < 2 ? "y" : "ies"); } /* -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Fri Feb 13 15:55:31 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Fri, 13 Feb 2009 15:55:31 -0800 (PST) Subject: [launchd-changes] [23806] branches/PR-5063531/launchd/src/launchctl.c Message-ID: <20090213235532.21173F4F2E8@beta.macosforge.org> Revision: 23806 http://trac.macosforge.org/projects/launchd/changeset/23806 Author: dsorresso at apple.com Date: 2009-02-13 15:55:29 -0800 (Fri, 13 Feb 2009) Log Message: ----------- Changed implementation to be more like kextcache, where you have to touch the parent directory to update the cache. Modified Paths: -------------- branches/PR-5063531/launchd/src/launchctl.c Modified: branches/PR-5063531/launchd/src/launchctl.c =================================================================== --- branches/PR-5063531/launchd/src/launchctl.c 2009-02-13 18:58:48 UTC (rev 23805) +++ branches/PR-5063531/launchd/src/launchctl.c 2009-02-13 23:55:29 UTC (rev 23806) @@ -82,6 +82,8 @@ #include #include #include +#include +#include #if HAVE_LIBAUDITD #include @@ -111,7 +113,9 @@ launch_data_t pass1; launch_data_t pass2; char *session_type; - bool editondisk:1, load:1, forceload:1; + bool editondisk:1, load:1, forceload:1, usecache:1; + launch_data_t cached_plist; + CFMutableDictionaryRef cache_line; }; static void myCFDictionaryApplyFunction(const void *key, const void *value, void *context); @@ -699,57 +703,76 @@ launch_data_t read_plist_file(const char *file, bool editondisk, bool load) { + bool add_to_cache = false, file_changed = false; CFPropertyListRef plist = NULL; - bool add_to_cache = false, file_changed = false; + CFMutableDictionaryRef cache_line = NULL; + CFStringRef key = NULL; - CFStringRef key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), file); - - struct stat sb; - if( assumes(stat(file, &sb) == 0) ) { - file_changed = sb.st_mtimespec.tv_sec > g_cache_creation_time; - } - - if( g_plist_cache && !file_changed ) { - plist = CFDictionaryGetValue(g_plist_cache, key); + if( g_plist_cache ) { + key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), file); - if( plist && CFGetTypeID(plist) == CFDictionaryGetTypeID() ) { - CFRetain(plist); + CFStringRef cache_line_key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), dirname((char *)file)); + cache_line = (CFMutableDictionaryRef)CFDictionaryGetValue(g_plist_cache, cache_line_key); + if( !cache_line ) { + cache_line = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(g_plist_cache, cache_line_key, cache_line); + CFRelease(cache_line); } else { + struct stat sb; + if( assumes(stat(file, &sb) == 0) ) { + file_changed = sb.st_mtimespec.tv_sec > g_cache_creation_time; + } + } + + CFRelease(cache_line_key); + + if( !file_changed ) { + plist = CFDictionaryGetValue(cache_line, key); + + if( plist && CFGetTypeID(plist) == CFDictionaryGetTypeID() ) { + fprintf(stdout, "Using cache for %s.\n", file); + CFRetain(plist); + } else { + fprintf(stdout, "Invalidating cache for %s (file was not in cache).\n", file); + CFRetain(key); + add_to_cache = true; + plist = NULL; + } + } else { + fprintf(stdout, "Invalidating cache for %s (file was updated).\n", file); + CFRetain(key); add_to_cache = true; } - } else if( g_plist_cache ) { - add_to_cache = true; + CFRelease(key); } - - if( !plist ) { - plist = CreateMyPropertyListFromFile(file); + + if( !plist && !(plist = CreateMyPropertyListFromFile(file)) ) { + fprintf(stderr, "%s: no plist was returned for: %s\n", getprogname(), file); } - - launch_data_t r = NULL; - - if (NULL == plist) { - fprintf(stderr, "%s: no plist was returned for: %s\n", getprogname(), file); - return NULL; - } else if( add_to_cache ) { - CFDictionarySetValue(g_plist_cache, key, plist); + + if( plist && add_to_cache ) { + fprintf(stdout, "\tAdding %s to cache.\n", file); + CFDictionarySetValue(cache_line, key, plist); g_plist_cache_changes++; + CFRelease(key); } - CFRelease(key); - - if (editondisk) { - if (load) { - CFDictionaryRemoveValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED)); - } else { - CFDictionarySetValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED), kCFBooleanTrue); + launch_data_t r = NULL; + if( plist ) { + if (editondisk) { + if (load) { + CFDictionaryRemoveValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED)); + } else { + CFDictionarySetValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED), kCFBooleanTrue); + } + WriteMyPropertyListToFile(plist, file, false); } - WriteMyPropertyListToFile(plist, file, false); + + r = CF2launch_data(plist); + + CFRelease(plist); } - r = CF2launch_data(plist); - - CFRelease(plist); - return r; } @@ -804,8 +827,9 @@ gethostname(ourhostname, sizeof(ourhostname)); - if (NULL == (thejob = read_plist_file(what, lus->editondisk, lus->load))) { - fprintf(stderr, "%s: no plist was returned for: %s\n", getprogname(), what); + thejob = lus->cached_plist ? lus->cached_plist : read_plist_file(what, lus->editondisk, lus->load); + if( !thejob ) { + fprintf(stderr, "%s: no plist was returned for: %s%s\n", getprogname(), lus->cached_plist ? "cached " : "", what); return; } @@ -1002,6 +1026,37 @@ return true; } +static bool +CFStringCopyUTF8BytesIntoBuffer(CFStringRef string, char *buff, size_t size) +{ + bool result = false; + + CFIndex length = 0; + length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(string) + 1, kCFStringEncodingUTF8); + + if( size < LONG_MAX && length < (CFIndex)size ) { + result = CFStringGetCString(string, buff, size, kCFStringEncodingUTF8); + } + + return result; +} + +static void +slurp_from_cache(const void *key, const void *val, void *ctx) +{ + struct load_unload_state *lus = (struct load_unload_state *)ctx; + if( CFGetTypeID((CFTypeRef)key) == CFStringGetTypeID() && CFGetTypeID((CFTypeRef)val) == CFDictionaryGetTypeID() ) { + launch_data_t j = CF2launch_data(val); + + char path[PATH_MAX]; + CFStringCopyUTF8BytesIntoBuffer(key, path, sizeof(path)); + + lus->cached_plist = j; + readfile(path, lus); + lus->cached_plist = NULL; + } +} + void readpath(const char *what, struct load_unload_state *lus) { @@ -1021,24 +1076,39 @@ if (S_ISREG(sb.st_mode)) { readfile(what, lus); } else if (S_ISDIR(sb.st_mode)) { - if ((d = opendir(what)) == NULL) { - fprintf(stderr, "%s: opendir() failed to open the directory\n", getprogname()); - return; + CFMutableDictionaryRef cache_line = NULL; + if( g_plist_cache ) { + CFStringRef cfwhat = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), what); + cache_line = (CFMutableDictionaryRef)CFDictionaryGetValue(g_plist_cache, cfwhat); + CFRelease(cfwhat); + + if( cache_line ) { + cache_line = CFGetTypeID(cache_line) == CFDictionaryGetTypeID() ? cache_line : NULL; + } } - - while ((de = readdir(d))) { - if ((de->d_name[0] == '.')) { - continue; + + if( cache_line && sb.st_mtimespec.tv_sec <= g_cache_creation_time ) { + CFDictionaryApplyFunction(cache_line, slurp_from_cache, lus); + } else { + if ((d = opendir(what)) == NULL) { + fprintf(stderr, "%s: opendir() failed to open the directory\n", getprogname()); + return; } - snprintf(buf, sizeof(buf), "%s/%s", what, de->d_name); - - if (!path_goodness_check(buf, lus->forceload)) { - continue; + + while ((de = readdir(d))) { + if ((de->d_name[0] == '.')) { + continue; + } + snprintf(buf, sizeof(buf), "%s/%s", what, de->d_name); + + if (!path_goodness_check(buf, lus->forceload)) { + continue; + } + + readfile(buf, lus); } - - readfile(buf, lus); + closedir(d); } - closedir(d); } } -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Fri Feb 13 17:13:33 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Fri, 13 Feb 2009 17:13:33 -0800 (PST) Subject: [launchd-changes] [23807] branches/PR-5063531/launchd/src/launchctl.c Message-ID: <20090214011334.12132F51207@beta.macosforge.org> Revision: 23807 http://trac.macosforge.org/projects/launchd/changeset/23807 Author: dsorresso at apple.com Date: 2009-02-13 17:13:33 -0800 (Fri, 13 Feb 2009) Log Message: ----------- Adjusted benchmarking. Modified Paths: -------------- branches/PR-5063531/launchd/src/launchctl.c Modified: branches/PR-5063531/launchd/src/launchctl.c =================================================================== --- branches/PR-5063531/launchd/src/launchctl.c 2009-02-13 23:55:29 UTC (rev 23806) +++ branches/PR-5063531/launchd/src/launchctl.c 2009-02-14 01:13:33 UTC (rev 23807) @@ -2030,6 +2030,7 @@ int load_launchd_items_cnt = 5; #endif + uint64_t t0 = mach_absolute_time(); struct stat sb; if (is_safeboot()) { load_launchd_items[2] = "system"; @@ -2047,7 +2048,6 @@ } } - uint64_t t0 = mach_absolute_time(); assumes(load_and_unload_cmd(load_launchd_items_cnt, load_launchd_items) == 0); uint64_t t1 = mach_absolute_time(); -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Sat Feb 14 16:33:24 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Sat, 14 Feb 2009 16:33:24 -0800 (PST) Subject: [launchd-changes] [23808] branches/PR-6424345 Message-ID: <20090215003325.69D8BF63D45@beta.macosforge.org> Revision: 23808 http://trac.macosforge.org/projects/launchd/changeset/23808 Author: nectar at apple.com Date: 2009-02-14 16:33:23 -0800 (Sat, 14 Feb 2009) Log Message: ----------- merge from trunk r23790 Modified Paths: -------------- branches/PR-6424345/launchd/src/bootstrap_priv.h branches/PR-6424345/launchd/src/launch.h branches/PR-6424345/launchd/src/launch_priv.h branches/PR-6424345/launchd/src/launchctl.c branches/PR-6424345/launchd/src/launchd.c branches/PR-6424345/launchd/src/launchd.h branches/PR-6424345/launchd/src/launchd_core_logic.c branches/PR-6424345/launchd/src/launchd_runtime.c branches/PR-6424345/launchd/src/launchd_runtime.h branches/PR-6424345/launchd/src/launchd_unix_ipc.c branches/PR-6424345/launchd/src/libbootstrap.c branches/PR-6424345/launchd/src/liblaunch.c branches/PR-6424345/launchd/src/libvproc.c branches/PR-6424345/launchd/src/protocol_vproc.defs branches/PR-6424345/launchd/src/vproc_internal.h branches/PR-6424345/launchd/src/vproc_priv.h branches/PR-6424345/launchd.xcodeproj/project.pbxproj Property Changed: ---------------- branches/PR-6424345/ Property changes on: branches/PR-6424345 ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 /trunk:23759-23783 + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 /trunk:23759-23790 Modified: branches/PR-6424345/launchd/src/bootstrap_priv.h =================================================================== --- branches/PR-6424345/launchd/src/bootstrap_priv.h 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/bootstrap_priv.h 2009-02-15 00:33:23 UTC (rev 23808) @@ -27,13 +27,13 @@ #pragma GCC visibility push(default) -#define BOOTSTRAP_PER_PID_SERVICE 0x1 -#define BOOTSTRAP_ALLOW_LOOKUP 0x2 -#define BOOTSTRAP_DENY_JOB_CREATION 0x4 -#define BOOTSTRAP_PRIVILEGED_SERVER 0x8 +#define BOOTSTRAP_PER_PID_SERVICE 1 << 0 +#define BOOTSTRAP_ALLOW_LOOKUP 1 << 1 +#define BOOTSTRAP_DENY_JOB_CREATION 1 << 2 +#define BOOTSTRAP_PRIVILEGED_SERVER 1 << 3 -#define BOOTSTRAP_PROPERTY_SUBSET 1 << 1 -#define BOOTSTRAP_PROPERTY_PERUSER 1 << 2 +#define BOOTSTRAP_PROPERTY_SUBSET 1 << 0 +#define BOOTSTRAP_PROPERTY_PERUSER 1 << 1 kern_return_t bootstrap_register2(mach_port_t bp, name_t service_name, mach_port_t sp, uint64_t flags); Modified: branches/PR-6424345/launchd/src/launch.h =================================================================== --- branches/PR-6424345/launchd/src/launch.h 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/launch.h 2009-02-15 00:33:23 UTC (rev 23808) @@ -44,108 +44,109 @@ #endif -#define LAUNCH_KEY_SUBMITJOB "SubmitJob" -#define LAUNCH_KEY_REMOVEJOB "RemoveJob" -#define LAUNCH_KEY_STARTJOB "StartJob" -#define LAUNCH_KEY_STOPJOB "StopJob" -#define LAUNCH_KEY_GETJOB "GetJob" -#define LAUNCH_KEY_GETJOBS "GetJobs" -#define LAUNCH_KEY_CHECKIN "CheckIn" +#define LAUNCH_KEY_SUBMITJOB "SubmitJob" +#define LAUNCH_KEY_REMOVEJOB "RemoveJob" +#define LAUNCH_KEY_STARTJOB "StartJob" +#define LAUNCH_KEY_STOPJOB "StopJob" +#define LAUNCH_KEY_GETJOB "GetJob" +#define LAUNCH_KEY_GETJOBS "GetJobs" +#define LAUNCH_KEY_CHECKIN "CheckIn" -#define LAUNCH_JOBKEY_LABEL "Label" -#define LAUNCH_JOBKEY_DISABLED "Disabled" -#define LAUNCH_JOBKEY_USERNAME "UserName" -#define LAUNCH_JOBKEY_GROUPNAME "GroupName" -#define LAUNCH_JOBKEY_TIMEOUT "TimeOut" -#define LAUNCH_JOBKEY_EXITTIMEOUT "ExitTimeOut" -#define LAUNCH_JOBKEY_INITGROUPS "InitGroups" -#define LAUNCH_JOBKEY_SOCKETS "Sockets" -#define LAUNCH_JOBKEY_MACHSERVICES "MachServices" -#define LAUNCH_JOBKEY_MACHSERVICELOOKUPPOLICIES "MachServiceLookupPolicies" -#define LAUNCH_JOBKEY_INETDCOMPATIBILITY "inetdCompatibility" -#define LAUNCH_JOBKEY_ENABLEGLOBBING "EnableGlobbing" -#define LAUNCH_JOBKEY_PROGRAMARGUMENTS "ProgramArguments" -#define LAUNCH_JOBKEY_PROGRAM "Program" -#define LAUNCH_JOBKEY_ONDEMAND "OnDemand" -#define LAUNCH_JOBKEY_KEEPALIVE "KeepAlive" -#define LAUNCH_JOBKEY_LIMITLOADTOHOSTS "LimitLoadToHosts" -#define LAUNCH_JOBKEY_LIMITLOADFROMHOSTS "LimitLoadFromHosts" -#define LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE "LimitLoadToSessionType" -#define LAUNCH_JOBKEY_RUNATLOAD "RunAtLoad" -#define LAUNCH_JOBKEY_ROOTDIRECTORY "RootDirectory" -#define LAUNCH_JOBKEY_WORKINGDIRECTORY "WorkingDirectory" -#define LAUNCH_JOBKEY_ENVIRONMENTVARIABLES "EnvironmentVariables" -#define LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES "UserEnvironmentVariables" -#define LAUNCH_JOBKEY_UMASK "Umask" -#define LAUNCH_JOBKEY_NICE "Nice" -#define LAUNCH_JOBKEY_HOPEFULLYEXITSFIRST "HopefullyExitsFirst" -#define LAUNCH_JOBKEY_HOPEFULLYEXITSLAST "HopefullyExitsLast" -#define LAUNCH_JOBKEY_LOWPRIORITYIO "LowPriorityIO" -#define LAUNCH_JOBKEY_SESSIONCREATE "SessionCreate" -#define LAUNCH_JOBKEY_STARTONMOUNT "StartOnMount" -#define LAUNCH_JOBKEY_SOFTRESOURCELIMITS "SoftResourceLimits" -#define LAUNCH_JOBKEY_HARDRESOURCELIMITS "HardResourceLimits" -#define LAUNCH_JOBKEY_STANDARDINPATH "StandardInPath" -#define LAUNCH_JOBKEY_STANDARDOUTPATH "StandardOutPath" -#define LAUNCH_JOBKEY_STANDARDERRORPATH "StandardErrorPath" -#define LAUNCH_JOBKEY_DEBUG "Debug" -#define LAUNCH_JOBKEY_WAITFORDEBUGGER "WaitForDebugger" -#define LAUNCH_JOBKEY_QUEUEDIRECTORIES "QueueDirectories" -#define LAUNCH_JOBKEY_WATCHPATHS "WatchPaths" -#define LAUNCH_JOBKEY_STARTINTERVAL "StartInterval" -#define LAUNCH_JOBKEY_STARTCALENDARINTERVAL "StartCalendarInterval" -#define LAUNCH_JOBKEY_BONJOURFDS "BonjourFDs" -#define LAUNCH_JOBKEY_LASTEXITSTATUS "LastExitStatus" -#define LAUNCH_JOBKEY_PID "PID" -#define LAUNCH_JOBKEY_THROTTLEINTERVAL "ThrottleInterval" -#define LAUNCH_JOBKEY_LAUNCHONLYONCE "LaunchOnlyOnce" -#define LAUNCH_JOBKEY_ABANDONPROCESSGROUP "AbandonProcessGroup" -#define LAUNCH_JOBKEY_POLICIES "Policies" -#define LAUNCH_JOBKEY_ENABLETRANSACTIONS "EnableTransactions" +#define LAUNCH_JOBKEY_LABEL "Label" +#define LAUNCH_JOBKEY_DISABLED "Disabled" +#define LAUNCH_JOBKEY_USERNAME "UserName" +#define LAUNCH_JOBKEY_GROUPNAME "GroupName" +#define LAUNCH_JOBKEY_TIMEOUT "TimeOut" +#define LAUNCH_JOBKEY_EXITTIMEOUT "ExitTimeOut" +#define LAUNCH_JOBKEY_INITGROUPS "InitGroups" +#define LAUNCH_JOBKEY_SOCKETS "Sockets" +#define LAUNCH_JOBKEY_MACHSERVICES "MachServices" +#define LAUNCH_JOBKEY_MACHSERVICELOOKUPPOLICIES "MachServiceLookupPolicies" +#define LAUNCH_JOBKEY_INETDCOMPATIBILITY "inetdCompatibility" +#define LAUNCH_JOBKEY_ENABLEGLOBBING "EnableGlobbing" +#define LAUNCH_JOBKEY_PROGRAMARGUMENTS "ProgramArguments" +#define LAUNCH_JOBKEY_PROGRAM "Program" +#define LAUNCH_JOBKEY_ONDEMAND "OnDemand" +#define LAUNCH_JOBKEY_KEEPALIVE "KeepAlive" +#define LAUNCH_JOBKEY_LIMITLOADTOHOSTS "LimitLoadToHosts" +#define LAUNCH_JOBKEY_LIMITLOADFROMHOSTS "LimitLoadFromHosts" +#define LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE "LimitLoadToSessionType" +#define LAUNCH_JOBKEY_RUNATLOAD "RunAtLoad" +#define LAUNCH_JOBKEY_ROOTDIRECTORY "RootDirectory" +#define LAUNCH_JOBKEY_WORKINGDIRECTORY "WorkingDirectory" +#define LAUNCH_JOBKEY_ENVIRONMENTVARIABLES "EnvironmentVariables" +#define LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES "UserEnvironmentVariables" +#define LAUNCH_JOBKEY_UMASK "Umask" +#define LAUNCH_JOBKEY_NICE "Nice" +#define LAUNCH_JOBKEY_HOPEFULLYEXITSFIRST "HopefullyExitsFirst" +#define LAUNCH_JOBKEY_HOPEFULLYEXITSLAST "HopefullyExitsLast" +#define LAUNCH_JOBKEY_LOWPRIORITYIO "LowPriorityIO" +#define LAUNCH_JOBKEY_SESSIONCREATE "SessionCreate" +#define LAUNCH_JOBKEY_STARTONMOUNT "StartOnMount" +#define LAUNCH_JOBKEY_SOFTRESOURCELIMITS "SoftResourceLimits" +#define LAUNCH_JOBKEY_HARDRESOURCELIMITS "HardResourceLimits" +#define LAUNCH_JOBKEY_STANDARDINPATH "StandardInPath" +#define LAUNCH_JOBKEY_STANDARDOUTPATH "StandardOutPath" +#define LAUNCH_JOBKEY_STANDARDERRORPATH "StandardErrorPath" +#define LAUNCH_JOBKEY_DEBUG "Debug" +#define LAUNCH_JOBKEY_WAITFORDEBUGGER "WaitForDebugger" +#define LAUNCH_JOBKEY_QUEUEDIRECTORIES "QueueDirectories" +#define LAUNCH_JOBKEY_WATCHPATHS "WatchPaths" +#define LAUNCH_JOBKEY_STARTINTERVAL "StartInterval" +#define LAUNCH_JOBKEY_STARTCALENDARINTERVAL "StartCalendarInterval" +#define LAUNCH_JOBKEY_BONJOURFDS "BonjourFDs" +#define LAUNCH_JOBKEY_LASTEXITSTATUS "LastExitStatus" +#define LAUNCH_JOBKEY_PID "PID" +#define LAUNCH_JOBKEY_THROTTLEINTERVAL "ThrottleInterval" +#define LAUNCH_JOBKEY_LAUNCHONLYONCE "LaunchOnlyOnce" +#define LAUNCH_JOBKEY_ABANDONPROCESSGROUP "AbandonProcessGroup" +#define LAUNCH_JOBKEY_POLICIES "Policies" +#define LAUNCH_JOBKEY_ENABLETRANSACTIONS "EnableTransactions" -#define LAUNCH_JOBPOLICY_DENYCREATINGOTHERJOBS "DenyCreatingOtherJobs" +#define LAUNCH_JOBPOLICY_DENYCREATINGOTHERJOBS "DenyCreatingOtherJobs" -#define LAUNCH_JOBINETDCOMPATIBILITY_WAIT "Wait" +#define LAUNCH_JOBINETDCOMPATIBILITY_WAIT "Wait" -#define LAUNCH_JOBKEY_MACH_RESETATCLOSE "ResetAtClose" -#define LAUNCH_JOBKEY_MACH_HIDEUNTILCHECKIN "HideUntilCheckIn" +#define LAUNCH_JOBKEY_MACH_RESETATCLOSE "ResetAtClose" +#define LAUNCH_JOBKEY_MACH_HIDEUNTILCHECKIN "HideUntilCheckIn" -#define LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT "SuccessfulExit" -#define LAUNCH_JOBKEY_KEEPALIVE_NETWORKSTATE "NetworkState" -#define LAUNCH_JOBKEY_KEEPALIVE_PATHSTATE "PathState" -#define LAUNCH_JOBKEY_KEEPALIVE_OTHERJOBACTIVE "OtherJobActive" -#define LAUNCH_JOBKEY_KEEPALIVE_OTHERJOBENABLED "OtherJobEnabled" +#define LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT "SuccessfulExit" +#define LAUNCH_JOBKEY_KEEPALIVE_NETWORKSTATE "NetworkState" +#define LAUNCH_JOBKEY_KEEPALIVE_PATHSTATE "PathState" +#define LAUNCH_JOBKEY_KEEPALIVE_OTHERJOBACTIVE "OtherJobActive" +#define LAUNCH_JOBKEY_KEEPALIVE_OTHERJOBENABLED "OtherJobEnabled" +#define LAUNCH_JOBKEY_KEEPALIVE_AFTERINITIALDEMAND "AfterInitialDemand" -#define LAUNCH_JOBKEY_CAL_MINUTE "Minute" -#define LAUNCH_JOBKEY_CAL_HOUR "Hour" -#define LAUNCH_JOBKEY_CAL_DAY "Day" -#define LAUNCH_JOBKEY_CAL_WEEKDAY "Weekday" -#define LAUNCH_JOBKEY_CAL_MONTH "Month" +#define LAUNCH_JOBKEY_CAL_MINUTE "Minute" +#define LAUNCH_JOBKEY_CAL_HOUR "Hour" +#define LAUNCH_JOBKEY_CAL_DAY "Day" +#define LAUNCH_JOBKEY_CAL_WEEKDAY "Weekday" +#define LAUNCH_JOBKEY_CAL_MONTH "Month" -#define LAUNCH_JOBKEY_RESOURCELIMIT_CORE "Core" -#define LAUNCH_JOBKEY_RESOURCELIMIT_CPU "CPU" -#define LAUNCH_JOBKEY_RESOURCELIMIT_DATA "Data" -#define LAUNCH_JOBKEY_RESOURCELIMIT_FSIZE "FileSize" -#define LAUNCH_JOBKEY_RESOURCELIMIT_MEMLOCK "MemoryLock" -#define LAUNCH_JOBKEY_RESOURCELIMIT_NOFILE "NumberOfFiles" -#define LAUNCH_JOBKEY_RESOURCELIMIT_NPROC "NumberOfProcesses" -#define LAUNCH_JOBKEY_RESOURCELIMIT_RSS "ResidentSetSize" -#define LAUNCH_JOBKEY_RESOURCELIMIT_STACK "Stack" +#define LAUNCH_JOBKEY_RESOURCELIMIT_CORE "Core" +#define LAUNCH_JOBKEY_RESOURCELIMIT_CPU "CPU" +#define LAUNCH_JOBKEY_RESOURCELIMIT_DATA "Data" +#define LAUNCH_JOBKEY_RESOURCELIMIT_FSIZE "FileSize" +#define LAUNCH_JOBKEY_RESOURCELIMIT_MEMLOCK "MemoryLock" +#define LAUNCH_JOBKEY_RESOURCELIMIT_NOFILE "NumberOfFiles" +#define LAUNCH_JOBKEY_RESOURCELIMIT_NPROC "NumberOfProcesses" +#define LAUNCH_JOBKEY_RESOURCELIMIT_RSS "ResidentSetSize" +#define LAUNCH_JOBKEY_RESOURCELIMIT_STACK "Stack" -#define LAUNCH_JOBKEY_DISABLED_MACHINETYPE "MachineType" -#define LAUNCH_JOBKEY_DISABLED_MODELNAME "ModelName" +#define LAUNCH_JOBKEY_DISABLED_MACHINETYPE "MachineType" +#define LAUNCH_JOBKEY_DISABLED_MODELNAME "ModelName" -#define LAUNCH_JOBSOCKETKEY_TYPE "SockType" -#define LAUNCH_JOBSOCKETKEY_PASSIVE "SockPassive" -#define LAUNCH_JOBSOCKETKEY_BONJOUR "Bonjour" -#define LAUNCH_JOBSOCKETKEY_SECUREWITHKEY "SecureSocketWithKey" -#define LAUNCH_JOBSOCKETKEY_PATHNAME "SockPathName" -#define LAUNCH_JOBSOCKETKEY_PATHMODE "SockPathMode" -#define LAUNCH_JOBSOCKETKEY_NODENAME "SockNodeName" -#define LAUNCH_JOBSOCKETKEY_SERVICENAME "SockServiceName" -#define LAUNCH_JOBSOCKETKEY_FAMILY "SockFamily" -#define LAUNCH_JOBSOCKETKEY_PROTOCOL "SockProtocol" -#define LAUNCH_JOBSOCKETKEY_MULTICASTGROUP "MulticastGroup" +#define LAUNCH_JOBSOCKETKEY_TYPE "SockType" +#define LAUNCH_JOBSOCKETKEY_PASSIVE "SockPassive" +#define LAUNCH_JOBSOCKETKEY_BONJOUR "Bonjour" +#define LAUNCH_JOBSOCKETKEY_SECUREWITHKEY "SecureSocketWithKey" +#define LAUNCH_JOBSOCKETKEY_PATHNAME "SockPathName" +#define LAUNCH_JOBSOCKETKEY_PATHMODE "SockPathMode" +#define LAUNCH_JOBSOCKETKEY_NODENAME "SockNodeName" +#define LAUNCH_JOBSOCKETKEY_SERVICENAME "SockServiceName" +#define LAUNCH_JOBSOCKETKEY_FAMILY "SockFamily" +#define LAUNCH_JOBSOCKETKEY_PROTOCOL "SockProtocol" +#define LAUNCH_JOBSOCKETKEY_MULTICASTGROUP "MulticastGroup" typedef struct _launch_data *launch_data_t; Modified: branches/PR-6424345/launchd/src/launch_priv.h =================================================================== --- branches/PR-6424345/launchd/src/launch_priv.h 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/launch_priv.h 2009-02-15 00:33:23 UTC (rev 23808) @@ -90,7 +90,8 @@ * * This returns 1 on success (it used to return otherwise), and -1 on failure. */ -#define LOAD_ONLY_SAFEMODE_LAUNCHAGENTS 1 +#define LOAD_ONLY_SAFEMODE_LAUNCHAGENTS 1 << 0 +#define LAUNCH_GLOBAL_ON_DEMAND 1 << 1 pid_t create_and_switch_to_per_session_launchd(const char * /* loginname */, int flags, ...); /* Also for LoginWindow. Modified: branches/PR-6424345/launchd/src/launchctl.c =================================================================== --- branches/PR-6424345/launchd/src/launchctl.c 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/launchctl.c 2009-02-15 00:33:23 UTC (rev 23808) @@ -172,6 +172,7 @@ static void fix_bogus_file_metadata(void); static void do_file_init(void) __attribute__((constructor)); static void setup_system_context(void); +static void tell_launchd_about_boot_args(void); typedef enum { BOOTCACHE_START = 1, @@ -200,12 +201,13 @@ static int umask_cmd(int argc, char *const argv[]); static int getrusage_cmd(int argc, char *const argv[]); static int bsexec_cmd(int argc, char *const argv[]); -static int _bslist_cmd(mach_port_t bport, unsigned int depth); +static int _bslist_cmd(mach_port_t bport, unsigned int depth, bool show_job); static int bslist_cmd(int argc, char *const argv[]); -static int _bstree_cmd(mach_port_t bsport, unsigned int depth); +static int _bstree_cmd(mach_port_t bsport, unsigned int depth, bool show_jobs); static int bstree_cmd(int argc __attribute__((unused)), char * const argv[] __attribute__((unused))); static int managerpid_cmd(int argc __attribute__((unused)), char * const argv[] __attribute__((unused))); static int manageruid_cmd(int argc __attribute__((unused)), char * const argv[] __attribute__((unused))); +static int managername_cmd(int argc __attribute__((unused)), char * const argv[] __attribute__((unused))); static int exit_cmd(int argc, char *const argv[]) __attribute__((noreturn)); static int help_cmd(int argc, char *const argv[]); @@ -214,36 +216,37 @@ int (*func)(int argc, char *const argv[]); const char *desc; } cmds[] = { - { "load", load_and_unload_cmd, "Load configuration files and/or directories" }, - { "unload", load_and_unload_cmd, "Unload configuration files and/or directories" }, -// { "reload", reload_cmd, "Reload configuration files and/or directories" }, - { "start", start_stop_remove_cmd, "Start specified job" }, - { "stop", start_stop_remove_cmd, "Stop specified job" }, - { "submit", submit_cmd, "Submit a job from the command line" }, - { "remove", start_stop_remove_cmd, "Remove specified job" }, - { "bootstrap", bootstrap_cmd, "Bootstrap launchd" }, - { "list", list_cmd, "List jobs and information about jobs" }, - { "setenv", setenv_cmd, "Set an environmental variable in launchd" }, - { "unsetenv", unsetenv_cmd, "Unset an environmental variable in launchd" }, - { "getenv", getenv_and_export_cmd, "Get an environmental variable from launchd" }, - { "export", getenv_and_export_cmd, "Export shell settings from launchd" }, - { "debug", wait4debugger_cmd, "Set the WaitForDebugger flag for the target job to true." }, - { "limit", limit_cmd, "View and adjust launchd resource limits" }, - { "stdout", stdio_cmd, "Redirect launchd's standard out to the given path" }, - { "stderr", stdio_cmd, "Redirect launchd's standard error to the given path" }, - { "shutdown", fyi_cmd, "Prepare for system shutdown" }, - { "singleuser", fyi_cmd, "Switch to single-user mode" }, - { "getrusage", getrusage_cmd, "Get resource usage statistics from launchd" }, - { "log", logupdate_cmd, "Adjust the logging level or mask of launchd" }, - { "umask", umask_cmd, "Change launchd's umask" }, - { "bsexec", bsexec_cmd, "Execute a process within a different Mach bootstrap subset" }, - { "bslist", bslist_cmd, "List Mach bootstrap services and optional servers" }, - { "bstree", bstree_cmd, "Show the entire Mach bootstrap tree. Requires root privileges." }, - { "managerpid", managerpid_cmd, "Print the PID of the launchd managing this Mach bootstrap." }, - { "manageruid", manageruid_cmd, "Print the UID of the launchd managing this Mach bootstrap." }, - { "exit", exit_cmd, "Exit the interactive invocation of launchctl" }, - { "quit", exit_cmd, "Quit the interactive invocation of launchctl" }, - { "help", help_cmd, "This help output" }, + { "load", load_and_unload_cmd, "Load configuration files and/or directories" }, + { "unload", load_and_unload_cmd, "Unload configuration files and/or directories" }, +// { "reload", reload_cmd, "Reload configuration files and/or directories" }, + { "start", start_stop_remove_cmd, "Start specified job" }, + { "stop", start_stop_remove_cmd, "Stop specified job" }, + { "submit", submit_cmd, "Submit a job from the command line" }, + { "remove", start_stop_remove_cmd, "Remove specified job" }, + { "bootstrap", bootstrap_cmd, "Bootstrap launchd" }, + { "list", list_cmd, "List jobs and information about jobs" }, + { "setenv", setenv_cmd, "Set an environmental variable in launchd" }, + { "unsetenv", unsetenv_cmd, "Unset an environmental variable in launchd" }, + { "getenv", getenv_and_export_cmd, "Get an environmental variable from launchd" }, + { "export", getenv_and_export_cmd, "Export shell settings from launchd" }, + { "debug", wait4debugger_cmd, "Set the WaitForDebugger flag for the target job to true." }, + { "limit", limit_cmd, "View and adjust launchd resource limits" }, + { "stdout", stdio_cmd, "Redirect launchd's standard out to the given path" }, + { "stderr", stdio_cmd, "Redirect launchd's standard error to the given path" }, + { "shutdown", fyi_cmd, "Prepare for system shutdown" }, + { "singleuser", fyi_cmd, "Switch to single-user mode" }, + { "getrusage", getrusage_cmd, "Get resource usage statistics from launchd" }, + { "log", logupdate_cmd, "Adjust the logging level or mask of launchd" }, + { "umask", umask_cmd, "Change launchd's umask" }, + { "bsexec", bsexec_cmd, "Execute a process within a different Mach bootstrap subset" }, + { "bslist", bslist_cmd, "List Mach bootstrap services and optional servers" }, + { "bstree", bstree_cmd, "Show the entire Mach bootstrap tree. Requires root privileges." }, + { "managerpid", managerpid_cmd, "Print the PID of the launchd managing this Mach bootstrap." }, + { "manageruid", manageruid_cmd, "Print the UID of the launchd managing this Mach bootstrap." }, + { "managername", managername_cmd, "Print the name of this Mach bootstrap." }, + { "exit", exit_cmd, "Exit the interactive invocation of launchctl" }, + { "quit", exit_cmd, "Quit the interactive invocation of launchctl" }, + { "help", help_cmd, "This help output" }, }; static bool istty; @@ -252,6 +255,7 @@ static bool do_apple_internal_magic; static bool system_context; static bool rootuser_context; +static bool g_shutdown_debugging = false; int main(int argc, char *const argv[]) @@ -466,7 +470,16 @@ CFDictionaryRef envPlist = NULL; launch_data_t req = NULL, launch_env_dict = NULL, resp = NULL; - plistPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s/.MacOSX/environment.plist"), getenv("HOME")); + char plist_path_str[PATH_MAX]; + plist_path_str[PATH_MAX - 1] = 0; + snprintf(plist_path_str, sizeof(plist_path_str), "%s/.MacOSX/environment.plist", getenv("HOME")); + + struct stat sb; + if( stat(plist_path_str, &sb) == -1 ) { + goto out; + } + + plistPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), plist_path_str); if( !assumes(plistPath != NULL) ) { goto out; } @@ -1375,10 +1388,18 @@ if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode)) { fprintf(stderr, "%s: CFURLCreateDataAndPropertiesFromResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode); } + propertyList = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resourceData, kCFPropertyListMutableContainers, &errorString); if (!propertyList) { fprintf(stderr, "%s: propertyList is NULL\n", getprogname()); } + if( fileURL ) { + CFRelease(fileURL); + } + + if( resourceData ) { + CFRelease(resourceData); + } return propertyList; } @@ -1401,6 +1422,10 @@ if (!CFURLWriteDataAndPropertiesToResource(fileURL, resourceData, NULL, &errorCode)) { fprintf(stderr, "%s: CFURLWriteDataAndPropertiesToResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode); } + + if( resourceData ) { + CFRelease(resourceData); + } } static inline Boolean __is_launch_data_t(launch_data_t obj) @@ -1522,10 +1547,11 @@ } result = CFArrayCreateCopy(NULL, mutResult); - + } + + if( mutResult ) { CFRelease(mutResult); } - return result; } @@ -1794,6 +1820,7 @@ assumes(fwexec(rcserver_tool, NULL) != -1); } + tell_launchd_about_boot_args(); read_launchd_conf(); if (path_check("/var/account/acct")) { @@ -2031,6 +2058,8 @@ * directory. */ if( getppid() != 1 ) { + the_argc_user = 5; + } #else /* This deadlocks against mount_url when logging in with a network home * directory. For now, we'll just load user Background agents when @@ -2039,9 +2068,9 @@ * but it satisfies the user expectation in 99% of cases. */ if( 0 ) { - #endif the_argc_user = 5; } + #endif } } else if (strcasecmp(session_type, VPROCMGR_SESSION_AQUA) == 0) { load_launchd_items[5] = "/etc/mach_init_per_user.d"; @@ -2511,18 +2540,19 @@ if( plistStr ) { CFShow(plistStr); + CFRelease(plistStr); r = 0; } } else { print_obj(resp, NULL, NULL); r = 0; } + launch_data_free(resp); } else { fprintf(stderr, "%s %s returned unknown response\n", getprogname(), argv[0]); r = 1; + launch_data_free(resp); } - - launch_data_free(resp); } else if( vproc_swap_complex(NULL, VPROC_GSK_ALLJOBS, NULL, &resp) == NULL ) { fprintf(stdout, "PID\tStatus\tLabel\n"); launch_data_dict_iterate(resp, print_jobs, NULL); @@ -2895,6 +2925,43 @@ bootstrap_port = rootbs; } +static void +tell_launchd_about_boot_args(void) +{ + if( !g_shutdown_debugging ) { + return; + } + + CFTypeRef value = NULL; + do { + io_registry_entry_t entry = IORegistryEntryFromPath(kIOMasterPortDefault, "IODeviceTree:/options"); + if( assumes(entry == IO_OBJECT_NULL) ) { + break; + } + + value = IORegistryEntryCreateCFProperty(entry, CFSTR("boot-args"), kCFAllocatorDefault, 0); + if( !assumes(value != NULL) ) { + break; + } + + IOObjectRelease(entry); + } while( 0 ); + + Boolean is_verbose = false; + if( value ) { + /* Normally I'd just use CFStringFind(), but the compiler whines about it returning a + * struct with -Wall. + */ + CFRange range = { 0, CFStringGetLength(value) }; + CFRange found_range = { 0, 0 }; + + is_verbose = CFStringFindWithOptions(value, CFSTR("-v"), range, 0, &found_range); + CFRelease(value); + + assumes(vproc_swap_integer(NULL, VPROC_GSK_SHUTDOWN_DEBUGGING, (int64_t *)&is_verbose, NULL) == KERN_SUCCESS); + } +} + int submit_cmd(int argc, char *const argv[]) { @@ -3102,11 +3169,12 @@ } int -_bslist_cmd(mach_port_t bport, unsigned int depth) +_bslist_cmd(mach_port_t bport, unsigned int depth, bool show_job) { kern_return_t result; name_array_t service_names; - mach_msg_type_number_t service_cnt, service_active_cnt; + name_array_t service_jobs; + mach_msg_type_number_t service_cnt, service_jobs_cnt, service_active_cnt; bootstrap_status_array_t service_actives; unsigned int i; @@ -3115,7 +3183,7 @@ return 1; } - result = bootstrap_info(bport, &service_names, &service_cnt, &service_actives, &service_active_cnt); + result = bootstrap_info(bport, &service_names, &service_cnt, &service_jobs, &service_jobs_cnt, &service_actives, &service_active_cnt); if (result != BOOTSTRAP_SUCCESS) { fprintf(stderr, "bootstrap_info(): %d\n", result); return 1; @@ -3124,7 +3192,11 @@ #define bport_state(x) (((x) == BOOTSTRAP_STATUS_ACTIVE) ? "A" : ((x) == BOOTSTRAP_STATUS_ON_DEMAND) ? "D" : "I") for (i = 0; i < service_cnt ; i++) { - fprintf(stdout, "%*s%-3s%s\n", depth, "", bport_state((service_actives[i])), service_names[i]); + fprintf(stdout, "%*s%-3s%s", depth, "", bport_state((service_actives[i])), service_names[i]); + if( show_job ) { + fprintf(stdout, " (%s)", service_jobs[i]); + } + fprintf(stdout, "\n"); } return 0; @@ -3134,20 +3206,29 @@ bslist_cmd(int argc, char *const argv[]) { mach_port_t bport = bootstrap_port; - if( argc == 2 ) { - bport = str2bsport(argv[1]); + bool show_jobs = false; + if( argc > 2 && strcmp(argv[2], "-j") == 0 ) { + show_jobs = true; } + if( argc > 1 ) { + if( show_jobs ) { + bport = str2bsport(argv[1]); + } else if( strcmp(argv[1], "-j") == 0 ) { + show_jobs = true; + } + } + if( bport == MACH_PORT_NULL ) { fprintf(stderr, "Invalid bootstrap port\n"); return 1; } - return _bslist_cmd(bport, 0); + return _bslist_cmd(bport, 0, show_jobs); } int -_bstree_cmd(mach_port_t bsport, unsigned int depth) +_bstree_cmd(mach_port_t bsport, unsigned int depth, bool show_jobs) { if( bsport == MACH_PORT_NULL ) { fprintf(stderr, "No root port!\n"); @@ -3171,13 +3252,13 @@ } unsigned int i = 0; - _bslist_cmd(bsport, depth); + _bslist_cmd(bsport, depth, show_jobs); for( i = 0; i < cnt; i++ ) { char *type = ( child_props[i] & BOOTSTRAP_PROPERTY_PERUSER ) ? "Per-user" : "Subset"; fprintf(stdout, "%*s%s (%s)/\n", depth, "", child_names[i], type); if( child_ports[i] != MACH_PORT_NULL ) { - _bstree_cmd(child_ports[i], depth + 4); + _bstree_cmd(child_ports[i], depth + 4, show_jobs); } } @@ -3185,16 +3266,20 @@ } int -bstree_cmd(int argc __attribute__((unused)), char * const argv[] __attribute__((unused))) +bstree_cmd(int argc, char * const argv[]) { + bool show_jobs = false; if( geteuid() != 0 ) { fprintf(stderr, "You must be root to perform this operation.\n"); return 1; } else { + if( argc == 2 && strcmp(argv[1], "-j") == 0 ) { + show_jobs = true; + } fprintf(stdout, "System/\n"); } - return _bstree_cmd(str2bsport("/"), 4); + return _bstree_cmd(str2bsport("/"), 4, show_jobs); } int @@ -3225,6 +3310,22 @@ return 0; } +int +managername_cmd(int argc __attribute__((unused)), char * const argv[] __attribute__((unused))) +{ + char *manager_name = NULL; + vproc_err_t verr = vproc_swap_string(NULL, VPROC_GSK_MGR_NAME, NULL, &manager_name); + if( verr ) { + fprintf(stdout, "Unknown job manager!\n"); + return 1; + } + + fprintf(stdout, "%s\n", manager_name); + free(manager_name); + + return 0; +} + bool is_legacy_mach_job(launch_data_t obj) { @@ -3337,10 +3438,13 @@ int wstatus2; pid_t p; - errno = posix_spawnp(&p, argv[0], NULL, NULL, (char **)argv, environ); + /* We'd use posix_spawnp(), but we want to workaround: 6288899 */ - if (errno) { + if ((p = vfork()) == -1) { return -1; + } else if (p == 0) { + execvp(argv[0], (char *const *)argv); + _exit(EXIT_FAILURE); } if (waitpid(p, wstatus ? wstatus : &wstatus2, 0) == -1) { @@ -3819,4 +3923,8 @@ if (stat("/AppleInternal", &sb) == 0 && stat("/var/db/disableAppleInternal", &sb) == -1) { do_apple_internal_magic = true; } + + if( stat("/var/db/.launchd_shutdown_debugging", &sb) == 0 ) { + g_shutdown_debugging = true; + } } Modified: branches/PR-6424345/launchd/src/launchd.c =================================================================== --- branches/PR-6424345/launchd/src/launchd.c 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/launchd.c 2009-02-15 00:33:23 UTC (rev 23808) @@ -69,6 +69,7 @@ #include #include #include +#include #if HAVE_LIBAUDITD #include @@ -100,6 +101,9 @@ static void monitor_networking_state(void); static void fatal_signal_handler(int sig, siginfo_t *si, void *uap); static void handle_pid1_crashes_separately(void); +static void do_pid1_crash_diagnosis_mode(void); +static int basic_fork(void); +static bool do_pid1_crash_diagnosis_mode2(void); static void *update_thread(void *nothing); @@ -111,7 +115,7 @@ bool shutdown_in_progress; bool fake_shutdown_in_progress; bool network_up; -char g_username[128] = "__UnknownUserToLaunchd_DontPanic_NotImportant__"; +char g_username[128] = "__Uninitialized__"; FILE *g_console = NULL; int @@ -125,8 +129,7 @@ testfd_or_openfd(STDOUT_FILENO, stdouterr_path, O_WRONLY); testfd_or_openfd(STDERR_FILENO, stdouterr_path, O_WRONLY); -#if 0 - if (pid1_magic) { + if (pid1_magic && g_use_gmalloc) { if (!getenv("DYLD_INSERT_LIBRARIES")) { setenv("DYLD_INSERT_LIBRARIES", "/usr/lib/libgmalloc.dylib", 1); setenv("MALLOC_STRICT_SIZE", "1", 1); @@ -136,7 +139,6 @@ unsetenv("MALLOC_STRICT_SIZE"); } } -#endif while ((ch = getopt(argc, argv, "s")) != -1) { switch (ch) { @@ -161,9 +163,9 @@ } else { if( !launchd_assumes((g_console = fopen(_PATH_CONSOLE, "w")) != NULL) ) { g_console = stdout; + } else { + _fd(fileno(g_console)); } - - _fd(fileno(g_console)); } } else { g_console = stdout; @@ -190,6 +192,9 @@ if( pid1_magic ) { runtime_syslog(LOG_NOTICE | LOG_CONSOLE, "*** launchd[1] has started up. ***"); + if( g_use_gmalloc ) { + runtime_syslog(LOG_NOTICE | LOG_CONSOLE, "*** Using libgmalloc ***"); + } struct stat sb; if( stat("/var/db/.launchd_flat_per_user_namespace", &sb) == 0 ) { @@ -258,6 +263,85 @@ static __attribute__((unused)) typeof(reboot) *__junk_dyld_trick3 = reboot; void +do_pid1_crash_diagnosis_mode(void) +{ + while( g_shutdown_debugging && !do_pid1_crash_diagnosis_mode2() ) { + sleep(1); + } +} + +int +basic_fork(void) +{ + int wstatus; + pid_t p; + + switch ((p = fork())) { + case -1: + runtime_syslog(LOG_ERR | LOG_CONSOLE, "Can't fork PID 1 copy for crash debugging: %m"); + return p; + case 0: + return p; + default: + waitpid(p, &wstatus, 0); + if (WIFEXITED(wstatus)) { + if (WEXITSTATUS(wstatus) == EXIT_SUCCESS) { + return 1; + } else { + fprintf(stdout, "PID 1 copy: exit status: %d\n", WEXITSTATUS(wstatus)); + } + } else { + fprintf(stdout, "PID 1 copy: %s\n", strsignal(WTERMSIG(wstatus))); + } + return 1; + } + + return -1; +} + +bool +do_pid1_crash_diagnosis_mode2(void) +{ + if( basic_fork() == 0 ) { + /* Neuter our bootstrap port so that the shell doesn't try talking to us while + * we're blocked waiting on it. + */ + fflush(g_console); + task_set_bootstrap_port(mach_task_self(), MACH_PORT_NULL); + if( basic_fork() != 0 ) { + fflush(g_console); + return true; + } + } else { + return true; + } + + int fd; + revoke(_PATH_CONSOLE); + if ((fd = open(_PATH_CONSOLE, O_RDWR)) == -1) { + _exit(2); + } + if (login_tty(fd) == -1) { + _exit(3); + } + setenv("TERM", "vt100", 1); + fprintf(stdout, "\n"); + fprintf(stdout, "Entering launchd PID 1 debugging mode...\n"); + fprintf(stdout, "The PID 1 launchd has crashed. It has fork(2)ed itself for debugging.\n"); + fprintf(stdout, "To debug the main thread of PID 1:\n"); + fprintf(stdout, " gdb attach %d\n", getppid()); + fprintf(stdout, "To exit this shell, capture a sample of launchd and shut down:\n"); + fprintf(stdout, " exit\n"); + fprintf(stdout, "A sample of PID 1 will be written to %s\n", PID1_CRASH_LOGFILE); + fprintf(stdout, "\n"); + fflush(stdout); + + execl(_PATH_BSHELL, "-sh", NULL); + syslog(LOG_ERR, "can't exec %s for PID 1 crash debugging: %m", _PATH_BSHELL); + _exit(EXIT_FAILURE); +} + +void fatal_signal_handler(int sig, siginfo_t *si, void *uap __attribute__((unused))) { const char *doom_why = "at instruction"; @@ -268,6 +352,8 @@ crash_addr = si->si_addr; crash_pid = si->si_pid; + do_pid1_crash_diagnosis_mode(); + unlink(PID1_CRASH_LOGFILE); switch ((sample_p = vfork())) { @@ -343,7 +429,7 @@ now = runtime_get_wall_time(); char *term_who = pid1_magic ? "System shutdown" : "Per-user launchd termination for "; - runtime_syslog(LOG_NOTICE, "%s%s began at: %lld.%06llu", term_who, pid1_magic ? "" : g_username, now / USEC_PER_SEC, now % USEC_PER_SEC); + runtime_syslog(LOG_NOTICE, "%s%s began", term_who, pid1_magic ? "" : g_username); launchd_assert(jobmgr_shutdown(root_jobmgr) != NULL); Modified: branches/PR-6424345/launchd/src/launchd.h =================================================================== --- branches/PR-6424345/launchd/src/launchd.h 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/launchd.h 2009-02-15 00:33:23 UTC (rev 23808) @@ -33,6 +33,7 @@ extern bool fake_shutdown_in_progress; extern bool network_up; extern bool g_force_old_kill_path; +extern bool g_simulate_pid1_crash; extern FILE *g_console; bool init_check_pid(pid_t); Modified: branches/PR-6424345/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6424345/launchd/src/launchd_core_logic.c 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/launchd_core_logic.c 2009-02-15 00:33:23 UTC (rev 23808) @@ -481,7 +481,7 @@ hopefully_exits_last :1, /* man launchd.plist --> HopefullyExitsLast */ removal_pending :1, /* a job was asked to be unloaded/removed while running, we'll remove it after it exits */ sent_sigkill :1, /* job_kill() was called */ - sampled :1, /* job_force_sampletool() was called (or is disabled) */ + sampling_complete :1, /* job_force_sampletool() was called (or is disabled) */ debug_before_kill :1, /* enter the kernel debugger before killing a job */ weird_bootstrap :1, /* a hack that launchd+launchctl use during jobmgr_t creation */ start_on_mount :1, /* man launchd.plist --> StartOnMount */ @@ -496,14 +496,18 @@ sent_kill_via_shmem :1, /* We need to 'kill_via_shmem' once-and-only-once */ pending_sample :1, /* This job needs to be sampled for some reason. */ kill_after_sample :1, /* The job is to be killed after sampling. */ - reap_after_sample :1, /* The job exited before sample did, so we should reap it after sample is done. */ + is_being_sampled :1, /* We've spawned a sample tool to sample the job. */ + reap_after_trace :1, /* The job exited before sample did, so we should reap it after sample is done. */ nosy :1, /* The job has an OtherJobEnabled KeepAlive criterion. */ crashed :1, /* The job is the default Mach exception handler, and it crashed. */ reaped :1, /* We've received NOTE_EXIT for the job. */ stopped :1, /* job_stop() was called. */ - jetsam_frontmost :1; /* The job is considered "frontmost" by Jetsam. */ + jetsam_frontmost :1, /* The job is considered "frontmost" by Jetsam. */ + needs_kickoff :1, /* The job is to be kept alive continuously, but it must be initially kicked off. */ + is_bootstrapper :1, /* The job is a bootstrapper. */ + migratory :1; /* The (anonymous) job called vprocmgr_switch_to_session(). */ mode_t mask; - pid_t sample_pid; + pid_t tracing_pid; const char label[0]; }; @@ -528,7 +532,7 @@ static const char *job_active(job_t j); static void job_watch(job_t j); static void job_ignore(job_t j); -static void job_reap_sample(job_t j); +static void job_cleanup_after_tracer(job_t j); static void job_reap(job_t j); static bool job_useless(job_t j); static bool job_keepalive(job_t j); @@ -593,6 +597,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 do_first_per_user_launchd_hack(void); +static void simulate_pid1_crash(void); + void eliminate_double_reboot(void); /* For Jetsam. */ @@ -611,6 +617,7 @@ /* process wide globals */ mach_port_t inherited_bootstrap_port; jobmgr_t root_jobmgr; +bool g_shutdown_debugging = false; void job_ignore(job_t j) @@ -721,7 +728,7 @@ job_assumes(j, runtime_kill(j->p, SIGTERM) != -1); if (timeout) { - j->sampled = !do_sample; + j->sampling_complete = !do_sample; job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, EV_ADD|EV_ONESHOT, NOTE_SECONDS, timeout, j) != -1); } @@ -2504,6 +2511,9 @@ if (j->anonymous) { total_anon_children--; + if( j->migratory ) { + runtime_del_ref(); + } } else { runtime_del_ref(); total_children--; @@ -2517,7 +2527,7 @@ } if( j->pending_sample ) { - job_log(j, LOG_NOTICE | LOG_CONSOLE, "Job exited before we could sample it."); + job_log(j, LOG_DEBUG | LOG_CONSOLE, "Job exited before we could sample it."); STAILQ_REMOVE(&j->mgr->pending_samples, j, job_s, pending_samples_sle); j->pending_sample = false; } @@ -2605,7 +2615,7 @@ j->last_exit_status = status; j->sent_signal_time = 0; j->sent_sigkill = false; - j->sampled = false; + j->sampling_complete = false; j->sent_kill_via_shmem = false; j->lastlookup = NULL; j->lastlookup_gennum = 0; @@ -2655,12 +2665,12 @@ /* Dequeue the next in line. */ job_t j = STAILQ_FIRST(&jm->pending_samples); - if( j->sample_pid ) { + if( j->is_being_sampled ) { job_log(j, LOG_DEBUG | LOG_CONSOLE, "Sampling is in progress. Not dequeuing next job."); return; } - if (j->sampled || j->per_user) { + if (j->sampling_complete || j->per_user) { return; } @@ -2700,7 +2710,7 @@ STAILQ_REMOVE(&jm->pending_samples, j, job_s, pending_samples_sle); jobmgr_dequeue_next_sample(jm); } else { - j->sample_pid = sp; + j->tracing_pid = sp; /* Let us know when sample is done. ONESHOT is implicit if we're just interested in NOTE_EXIT. */ job_assumes(j, kevent_mod(sp, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, j) != -1); @@ -2740,7 +2750,8 @@ /* Let us know when sample is done. ONESHOT is implicit if we're just interested in NOTE_EXIT. */ if( job_assumes(j, (r = kevent_mod(sp, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, j)) != -1) ) { if( job_assumes(j, write(execpair[0], &sp, sizeof(sp)) == sizeof(sp)) ) { - j->sample_pid = sp; + j->tracing_pid = sp; + j->is_being_sampled = true; } else { job_assumes(j, kevent_mod(sp, EVFILT_PROC, EV_DELETE, 0, 0, NULL) != -1); job_assumes(j, runtime_kill(sp, SIGKILL) != -1); @@ -2767,7 +2778,7 @@ if( r == -1 ) { job_log(j, LOG_ERR | LOG_CONSOLE, "Sampling for job failed!"); STAILQ_REMOVE(&jm->pending_samples, j, job_s, pending_samples_sle); - j->sampled = true; + j->sampling_complete = true; jobmgr_dequeue_next_sample(jm); } else { job_log(j, LOG_DEBUG | LOG_CONSOLE, "Sampling job (sample PID: %i, file: %s).", sp, j->mgr->sample_log_file); @@ -2775,7 +2786,7 @@ #endif } else { STAILQ_REMOVE(&jm->pending_samples, j, job_s, pending_samples_sle); - j->sampled = true; + j->sampling_complete = true; } j->pending_sample = false; @@ -2814,7 +2825,8 @@ if (job_useless(j)) { job_remove(j, false); return NULL; - } else if (kickstart || job_keepalive(j)) { + } + if (kickstart || job_keepalive(j)) { job_log(j, LOG_DEBUG, "Starting job (kickstart = %s)", kickstart ? "true" : "false"); job_start(j); } else { @@ -2867,8 +2879,10 @@ if (unlikely(rsz == 0)) { job_log(j, LOG_DEBUG, "Standard out/error pipe closed"); close_log_redir = true; - } else if (!job_assumes(j, rsz != -1 && errno != EAGAIN)) { - close_log_redir = true; + } else if (rsz == -1) { + if( !job_assumes(j, errno == EAGAIN) ) { + close_log_redir = true; + } } else { buf[rsz] = '\0'; @@ -2950,42 +2964,44 @@ } void -job_reap_sample(job_t j) +job_cleanup_after_tracer(job_t j) { - int wstatus = 0; - - if (!job_assumes(j, waitpid(j->sample_pid, &wstatus, 0) != -1)) { - goto out; - } - - job_assumes(j, WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0); - -out: - if( j->kill_after_sample ) { - if (unlikely(j->debug_before_kill)) { - job_log(j, LOG_NOTICE, "Exit timeout elapsed. Entering the kernel debugger"); - job_assumes(j, host_reboot(mach_host_self(), HOST_REBOOT_DEBUGGER) == KERN_SUCCESS); + jobmgr_t jm = NULL; + if( j->is_being_sampled ) { + int wstatus = 0; + job_log(j, LOG_DEBUG | LOG_CONSOLE, "sample[%i] finished with job.", j->tracing_pid); + if( job_assumes(j, waitpid(j->tracing_pid, &wstatus, 0) != -1) ) { + job_assumes(j, WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0); } + STAILQ_REMOVE(&j->mgr->pending_samples, j, job_s, pending_samples_sle); - job_log(j, LOG_NOTICE, "Killing..."); - job_kill(j); + if( j->kill_after_sample ) { + if (unlikely(j->debug_before_kill)) { + job_log(j, LOG_NOTICE, "Exit timeout elapsed. Entering the kernel debugger"); + job_assumes(j, host_reboot(mach_host_self(), HOST_REBOOT_DEBUGGER) == KERN_SUCCESS); + } + + job_log(j, LOG_NOTICE, "Killing..."); + job_kill(j); + } + j->sampling_complete = true; + j->is_being_sampled = false; + jm = j->mgr; } - job_log(j, LOG_DEBUG | LOG_CONSOLE, "sample[%i] finished with job.", j->sample_pid); - j->sample_pid = 0; - j->sampled = true; - STAILQ_REMOVE(&j->mgr->pending_samples, j, job_s, pending_samples_sle); - - if( j->reap_after_sample ) { - job_log(j, LOG_DEBUG | LOG_CONSOLE, "Reaping job now that sample is done."); + j->tracing_pid = 0; + if( j->reap_after_trace ) { + job_log(j, LOG_DEBUG | LOG_CONSOLE, "Reaping job now that attached tracer is gone."); struct kevent kev; - EV_SET(&kev, 1, 0, 0, NOTE_EXIT, 0, 0); + EV_SET(&kev, j->p, 0, 0, NOTE_EXIT, 0, 0); /* Fake a kevent to keep our logic consistent. */ job_callback_proc(j, &kev); } - jobmgr_dequeue_next_sample(j->mgr); + if( jm ) { + jobmgr_dequeue_next_sample(jm); + } } void @@ -2994,19 +3010,46 @@ bool program_changed = false; int fflags = kev->fflags; - if( j->sample_pid == (pid_t)kev->ident ) { - job_assumes(j, (fflags & NOTE_EXIT) != 0); + if( fflags & NOTE_EXIT ) { + if( j->p == (pid_t)kev->ident && !j->anonymous && !j->is_being_sampled ) { + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, j->p }; + struct kinfo_proc kp; + size_t len = sizeof(kp); + + /* Sometimes, the kernel says it succeeded but really didn't. */ + if( job_assumes(j, sysctl(mib, 4, &kp, &len, NULL, 0) != -1) && len == sizeof(kp) ) { + if( !job_assumes(j, kp.kp_eproc.e_ppid == getpid()) ) { + /* Someone has attached to the process with ptrace(). There's a race here. + * If we determine that we are not the parent process and then fail to attach + * a kevent to the parent PID (who is probably using ptrace()), we can take that as an + * indication that the parent exited between sysctl(3) and kevent_mod(). The + * reparenting of the PID should be atomic to us, so in that case, we reap the + * job as normal. + * + * Otherwise, we wait for the death of the parent tracer and then reap, just as we + * would if a job died while we were sampling it at shutdown. + */ + if( job_assumes(j, kevent_mod(kp.kp_eproc.e_ppid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, j) != -1) ) { + j->tracing_pid = kp.kp_eproc.e_ppid; + j->reap_after_trace = true; + return; + } + } + } + } else if( !j->anonymous ) { + if( j->tracing_pid == (pid_t)kev->ident ) { + job_cleanup_after_tracer(j); + + 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); + j->reap_after_trace = true; + return; + } + } + } - job_reap_sample(j); - - return; - } else if( j->sample_pid && !j->reap_after_sample ) { - /* The job exited before our sample completed. */ - job_log(j, LOG_NOTICE | LOG_CONSOLE, "Job has exited. Will reap after sample[%i] is complete.", j->sample_pid); - j->reap_after_sample = true; - return; - } - if (fflags & NOTE_EXEC) { program_changed = true; @@ -3082,7 +3125,7 @@ * with the long SIGKILL */ - bool was_is_or_will_be_sampled = ( j->sampled || j->sample_pid || j->pending_sample ); + bool was_is_or_will_be_sampled = ( j->sampling_complete || j->is_being_sampled || j->pending_sample ); bool should_enqueue = ( !was_is_or_will_be_sampled && do_apple_internal_logging ); if (j->sent_sigkill) { @@ -3106,12 +3149,12 @@ j->pending_sample = true; jobmgr_dequeue_next_sample(j->mgr); } else { - if( do_apple_internal_logging && !j->sampled ) { - if( j->sample_pid || j->pending_sample ) { + if( do_apple_internal_logging && !j->sampling_complete ) { + if( j->is_being_sampled || j->pending_sample ) { char pidstr[24] = { 0 }; - snprintf(pidstr, sizeof(pidstr), "[%i] ", j->sample_pid); + snprintf(pidstr, sizeof(pidstr), "[%i] ", j->tracing_pid); - job_log(j, LOG_DEBUG | LOG_CONSOLE, "Exit timeout elapsed (%u seconds). Will kill after sample%shas completed.", j->exit_timeout, j->sample_pid ? pidstr : " "); + job_log(j, LOG_DEBUG | LOG_CONSOLE, "Exit timeout elapsed (%u seconds). Will kill after sample%shas completed.", j->exit_timeout, j->tracing_pid ? pidstr : " "); j->kill_after_sample = true; } else { job_log(j, LOG_DEBUG | LOG_CONSOLE, "Exit timeout elapsed (%u seconds). Will sample and then kill.", j->exit_timeout); @@ -3347,11 +3390,19 @@ job_log(j, LOG_DEBUG, "Started as PID: %u", c); + j->checkedin = false; j->start_pending = false; j->reaped = false; j->crashed = false; j->stopped = false; + if( j->needs_kickoff ) { + j->needs_kickoff = false; + if( SLIST_EMPTY(&j->semaphores) ) { + j->ondemand = false; + } + } + runtime_add_ref(); total_children++; LIST_INSERT_HEAD(&j->mgr->active_jobs[ACTIVE_JOB_HASH(c)], j, pid_hash_sle); @@ -4233,8 +4284,27 @@ /* See 5321044 for why we do the do-while loop and 5415523 for why ENOENT is checked */ do { if (si->fd == -1) { - if ((si->fd = _fd(open(si->what, O_EVTONLY|O_NOCTTY))) == -1) { - si->watching_parent = job_assumes(j, (si->fd = _fd(open(parentdir, O_EVTONLY|O_NOCTTY))) != -1); + struct stat sb; + if( stat(si->what, &sb) == 0 ) { + /* If we're watching a character or block device, only watch the parent directory. + * See rdar://problem/6489900 for the gory details. Basically, holding an open file + * descriptor to a devnode could end up (a) blocking us on open(2) until someone else + * open(2)s the file (like a character device that waits for a carrier signal) or + * (b) preventing other processes from obtaining an exclusive lock on the file, even + * though we're opening it with O_EVTONLY. + * + * The main point of contention is that O_EVTONLY doesn't actually mean "event only". + * It means "Don't prevent unmounts of this descriptor's volume". We work around this + * for dev nodes by only watching the parent directory and stat(2)ing our desired file + * each time the parent changes to see if it appeared or disappeared. + */ + if( S_ISREG(sb.st_mode) || S_ISDIR(sb.st_mode) ) { + si->fd = _fd(open(si->what, O_EVTONLY | O_NOCTTY | O_NONBLOCK)); + } + } + + if( si->fd == -1 ) { + si->watching_parent = job_assumes(j, (si->fd = _fd(open(parentdir, O_EVTONLY | O_NOCTTY | O_NONBLOCK))) != -1); } else { si->watching_parent = false; } @@ -4656,7 +4726,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, false); } else { - job_log(j, LOG_WARNING, "Ignoring reserved environmental variable: %s", key); + job_log(j, LOG_DEBUG, "Ignoring reserved environmental variable: %s", key); } } @@ -4823,6 +4893,11 @@ return false; } + if( unlikely(j->needs_kickoff) ) { + job_log(j, LOG_DEBUG, "KeepAlive check: Job needs to be kicked off on-demand before KeepAlive sets in."); + return false; + } + if (j->start_pending) { job_log(j, LOG_DEBUG, "KeepAlive check: Pent-up non-IPC launch criteria."); return true; @@ -5256,17 +5331,24 @@ job_log(ji, LOG_DEBUG, "Examining..."); } - if( !(ji->hopefully_exits_first || ji->hopefully_exits_last) && !ji->anonymous ) { - bool active = job_active(ji); - if( active && !ji->stopped ) { - job_stop(ji); - - /* We may have sent SIGKILL to the job in job_stop(). */ - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; - } else if( ji->stopped ) { - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; - } else if( !active ) { - job_remove(ji, false); + if( !(ji->hopefully_exits_first || ji->hopefully_exits_last) ) { + if( !ji->anonymous ) { + bool active = job_active(ji); + if( active && !ji->stopped ) { + job_stop(ji); + + /* We may have sent SIGKILL to the job in job_stop(). */ + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else if( ji->stopped ) { + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else if( !active ) { + job_remove(ji, false); + } + } else if( ji->migratory && jm->parentmgr ) { + /* If a job has migrated into a sub-bootstrap, we want to + * keep the job manager around as long as the job is there. + */ + unkilled_cnt++; } } } @@ -5292,8 +5374,12 @@ return _jm; } + if( jm == root_jobmgr ) { + simulate_pid1_crash(); + } + static bool killed_stray_jobs = false; - if( !killed_stray_jobs ) { + if( !killed_stray_jobs && pid1_magic && jm == root_jobmgr ) { jobmgr_log_stray_children(jm, true); killed_stray_jobs = true; } @@ -5359,7 +5445,11 @@ job_t ji = NULL; LIST_FOREACH( ji, &jm->jobs, sle ) { - if( !job_assumes(ji, (ji->anonymous || ji->sent_sigkill) && ji->p) ) { + if( pid1_magic && !jm->parentmgr ) { + if( (ji->anonymous || ji->sent_sigkill) && ji->p ) { + job_log(ji, LOG_NOTICE | LOG_CONSOLE, "Job should be gone but is not."); + } + } else if( !pid1_magic && !ji->anonymous ) { job_log(ji, LOG_NOTICE | LOG_CONSOLE, "Job should be gone but is not."); } } @@ -5586,9 +5676,6 @@ } } - jmr->killed_hopefully_first_jobs = false; - jmr->killed_normal_jobs = false; - jmr->killed_hopefully_last_jobs = false; STAILQ_INIT(&jmr->pending_samples); jobmgr_log(jmr, LOG_DEBUG, "Created job manager%s%s", jm ? " with parent: " : ".", jm ? jm->name : ""); @@ -5621,6 +5708,7 @@ bootstrapper = job_new(jm, thelabel, NULL, bootstrap_tool); if (jobmgr_assumes(jm, bootstrapper != NULL) && (jm->parentmgr || getuid())) { + bootstrapper->is_bootstrapper = true; char buf[100]; /* launchd-201: can't ssh in with AFP OD account (hangs) */ @@ -5629,6 +5717,7 @@ bootstrapper->weird_bootstrap = true; jobmgr_assumes(jm, job_setup_machport(bootstrapper)); } else if( bootstrapper && strncmp(session_type, VPROCMGR_SESSION_SYSTEM, sizeof(VPROCMGR_SESSION_SYSTEM)) == 0 ) { + bootstrapper->is_bootstrapper = true; if( jobmgr_assumes(jm, pid1_magic) ) { /* Have our system bootstrapper print out to the console. */ bootstrapper->stdoutpath = strdup(_PATH_CONSOLE); @@ -6064,8 +6153,6 @@ if (si->fd != -1) { job_assumes(j, runtime_close(si->fd) != -1); } - - job_log(j, LOG_DEBUG, "Removing semaphore item... (what = %s, why = %u)", si->what, si->why); /* We'll need to rethink this if it ever becomes possible to dynamically add or remove semaphores. */ if( (si->why == OTHER_JOB_ENABLED || si->why == OTHER_JOB_DISABLED) && j->nosy ) { @@ -6103,6 +6190,8 @@ why = launch_data_get_bool(obj) ? SUCCESSFUL_EXIT : FAILED_EXIT; semaphoreitem_new(j, why, NULL); j->start_pending = true; + } else if( strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE_AFTERINITIALDEMAND) == 0 ) { + j->needs_kickoff = launch_data_get_bool(obj); } else { job_assumes(j, false); } @@ -6577,6 +6666,17 @@ } launch_data_free(output_obj); break; + case VPROC_GSK_MGR_NAME: + if( !job_assumes(j, (output_obj = launch_data_new_string(j->mgr->name)) != NULL) ) { + goto out_bad; + } + packed_size = launch_data_pack(output_obj, (void *)*outval, *outvalCnt, NULL, NULL); + if (!job_assumes(j, packed_size != 0)) { + goto out_bad; + } + + launch_data_free(output_obj); + break; case 0: mig_deallocate(*outval, *outvalCnt); *outval = 0; @@ -6700,6 +6800,7 @@ j->abandon_pg = (bool)inval; break; case VPROC_GSK_GLOBAL_ON_DEMAND: + job_log(j, LOG_NOTICE, "Job is setting global on-demand mode to %s (j->forced_peers_to_demand_mode = %s)", (bool)inval ? "true" : "false", j->forced_peers_to_demand_mode ? "true" : "false"); kr = job_set_global_on_demand(j, (bool)inval) ? 0 : 1; break; case VPROC_GSK_BASIC_KEEPALIVE: @@ -6778,6 +6879,12 @@ case VPROC_GSK_WAITFORDEBUGGER: 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; + } + break; case 0: break; default: @@ -7010,10 +7117,9 @@ ms->isActive = true; ms->recv = false; } - job_checkin(j); if (!(j->anonymous || j->legacy_LS_job || j->legacy_mach_job)) { - job_log(j, LOG_NOTICE, "Please add the following service to the configuration file for this job: %s", servicename); + job_log(j, LOG_APPLEONLY, "Please add the following service to the configuration file for this job: %s", servicename); } } else { if (unlikely((jo = machservice_job(ms)) != j)) { @@ -7033,6 +7139,7 @@ } + job_checkin(j); machservice_request_notifications(ms); job_log(j, LOG_INFO, "Check-in of service: %s", servicename); @@ -7206,10 +7313,12 @@ } kern_return_t -job_mig_info(job_t j, name_array_t *servicenamesp, unsigned int *servicenames_cnt, - bootstrap_status_array_t *serviceactivesp, unsigned int *serviceactives_cnt) +job_mig_info(job_t j, name_array_t *servicenamesp, unsigned int *servicenames_cnt, + name_array_t *servicejobsp, unsigned int *servicejobs_cnt, + bootstrap_status_array_t *serviceactivesp, unsigned int *serviceactives_cnt) { name_array_t service_names = NULL; + name_array_t service_jobs = NULL; bootstrap_status_array_t service_actives = NULL; unsigned int cnt = 0, cnt2 = 0; jobmgr_t jm; @@ -7237,6 +7346,11 @@ goto out_bad; } + mig_allocate((vm_address_t *)&service_jobs, cnt * sizeof(service_jobs[0])); + if (!job_assumes(j, service_jobs != NULL)) { + goto out_bad; + } + mig_allocate((vm_address_t *)&service_actives, cnt * sizeof(service_actives[0])); if (!job_assumes(j, service_actives != NULL)) { goto out_bad; @@ -7246,6 +7360,7 @@ LIST_FOREACH( msi, &jm->ms_hash[i], name_hash_sle ) { if( !msi->per_pid ) { strlcpy(service_names[cnt2], machservice_name(msi), sizeof(service_names[0])); + strlcpy(service_jobs[cnt2], msi->job->label, sizeof(service_jobs[0])); service_actives[cnt2] = machservice_status(msi); cnt2++; } @@ -7256,8 +7371,9 @@ out: *servicenamesp = service_names; + *servicejobsp = service_jobs; *serviceactivesp = service_actives; - *servicenames_cnt = *serviceactives_cnt = cnt; + *servicenames_cnt = *servicejobs_cnt = *serviceactives_cnt = cnt; return BOOTSTRAP_SUCCESS; @@ -7265,6 +7381,9 @@ if (service_names) { mig_deallocate((vm_address_t)service_names, cnt * sizeof(service_names[0])); } + if (service_jobs) { + mig_deallocate((vm_address_t)service_jobs, cnt * sizeof(service_jobs[0])); + } if (service_actives) { mig_deallocate((vm_address_t)service_actives, cnt * sizeof(service_actives[0])); } @@ -7522,7 +7641,7 @@ } kern_return_t -job_mig_move_subset(job_t j, mach_port_t target_subset, name_t session_type) +job_mig_move_subset(job_t j, mach_port_t target_subset, name_t session_type, uint64_t flags) { mach_msg_type_number_t l2l_i, l2l_port_cnt = 0; mach_port_array_t l2l_ports = NULL; @@ -7601,6 +7720,24 @@ goto out; } + /* This is a hack. We should be doing this in jobmgr_new(), but since we're in the middle of + * processing an IPC request, we'll do this action before the new job manager can get any IPC + * requests. This serialization is guaranteed since we are single-threaded in that respect. + */ + if( flags & LAUNCH_GLOBAL_ON_DEMAND ) { + /* This is so awful. */ + mach_port_t mp = MACH_PORT_NULL; + name_t target_name; + strlcpy(target_name, jmr->name, sizeof(target_name)); + + kr = job_mig_switch_to_session(j, MACH_PORT_NULL, target_name, &mp); + if( job_assumes(j, kr == KERN_SUCCESS) ) { + job_set_global_on_demand(j, true); + } else { + job_log(j, LOG_WARNING, "Can't set global on-demand mode, unable to preemptively switch to %s job manager.", jmr->name); + } + } + for (l2l_i = 0; l2l_i < l2l_port_cnt; l2l_i++) { launch_data_t tmp, obj_at_idx; struct machservice *ms; @@ -7653,6 +7790,53 @@ } kern_return_t +job_mig_init_session(job_t j, name_t session_type) +{ + job_t j2; + + kern_return_t kr = BOOTSTRAP_NO_MEMORY; + if (j->mgr->session_initialized) { + job_log(j, LOG_ERR, "Tried to initialize an already setup session!"); + kr = BOOTSTRAP_NOT_PRIVILEGED; + } else if (strcmp(session_type, VPROCMGR_SESSION_LOGINWINDOW) == 0) { + jobmgr_t jmi; + + /* + * 5330262 + * + * We're working around LoginWindow and the WindowServer. + * + * In practice, there is only one LoginWindow session. Unfortunately, for certain + * scenarios, the WindowServer spawns loginwindow, and in those cases, it frequently + * spawns a replacement loginwindow session before cleaning up the previous one. + * + * We're going to use the creation of a new LoginWindow context as a clue that the + * previous LoginWindow context is on the way out and therefore we should just + * kick-start the shutdown of it. + */ + + SLIST_FOREACH(jmi, &root_jobmgr->submgrs, sle) { + if (unlikely(jmi->shutting_down)) { + continue; + } else if (strcasecmp(jmi->name, session_type) == 0) { + jobmgr_shutdown(jmi); + break; + } + } + } + + jobmgr_log(j->mgr, LOG_DEBUG, "Initializing: %s", session_type); + strcpy(j->mgr->name_init, session_type); + + if (job_assumes(j, (j2 = jobmgr_init_session(j->mgr, session_type, false)))) { + job_assumes(j, job_dispatch(j2, true)); + kr = BOOTSTRAP_SUCCESS; + } + + return kr; +} + +kern_return_t job_mig_switch_to_session(job_t j, mach_port_t requestor_port, name_t session_name, mach_port_t *new_bsport) { job_log(j, LOG_NOTICE, "Job wants to move to %s session.", session_name); @@ -7709,8 +7893,17 @@ } j->mgr = target_jm; + j->migratory = true; *new_bsport = target_jm->jm_port; + /* Anonymous jobs which move around are particularly interesting to us, so we want to + * stick around while they're still around. + * For example, login calls into the PAM launchd module, which moves the process into + * the StandardIO session by default. So we'll hold a reference on that job to prevent + * ourselves from going away. + */ + runtime_add_ref(); + return KERN_SUCCESS; } @@ -8286,6 +8479,15 @@ } static void +simulate_pid1_crash(void) +{ + if( pid1_magic && g_simulate_pid1_crash ) { + runtime_syslog(LOG_EMERG | LOG_CONSOLE, "About to simulate a crash."); + raise(SIGSEGV); + } +} + +static void jetsam_priority_from_job(job_t j, bool front, jetsam_priority_entry_t *jp) { jp->pid = j->p; Modified: branches/PR-6424345/launchd/src/launchd_runtime.c =================================================================== --- branches/PR-6424345/launchd/src/launchd_runtime.c 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/launchd_runtime.c 2009-02-15 00:33:23 UTC (rev 23808) @@ -132,6 +132,8 @@ bool low_level_debug; bool g_force_old_kill_path = false; bool g_flat_mach_namespace = true; +bool g_simulate_pid1_crash = false; +bool g_use_gmalloc = false; mach_port_t runtime_get_kernel_port(void) @@ -1099,6 +1101,7 @@ case MACH_RCV_TIMED_OUT: if (to != MACH_MSG_TIMEOUT_NONE) { if (busy_cnt == 0) { + runtime_syslog(LOG_NOTICE, "Idle exiting. (This message will be removed before shipping.)"); launchd_shutdown(); } else if (runtime_idle_callback) { runtime_idle_callback(); @@ -1175,7 +1178,6 @@ tmp_options |= MACH_SEND_TIMEOUT; } } - } } @@ -1458,6 +1460,14 @@ } for (lm_walk = (struct logmsg_s *)inval; (data_left > 0) && (lm_walk->obj_sz <= data_left); lm_walk = ((void *)lm_walk + lm_walk->obj_sz)) { + /* malloc() does not return NULL if you ask it for an allocation of size 0. + * It will return a valid pointer that can be passed to free(). If we don't + * do this check, we'll wind up corrupting our heap in the subsequent + * assignments. + */ + if( !launchd_assumes(lm_walk->obj_sz > 0) ) { + continue; + } if (!launchd_assumes(lm = malloc(lm_walk->obj_sz))) { continue; } @@ -1746,4 +1756,12 @@ if( !pid1_magic && stat("/var/db/.launchd_no_flat_per_user_namespace", &sb) == 0 ) { g_flat_mach_namespace = false; } + + if( pid1_magic && stat("/var/db/.launchd_simulate_pid1_crash", &sb) == 0 ) { + g_simulate_pid1_crash = true; + } + + if( pid1_magic && stat("/var/db/.launchd_use_gmalloc", &sb) == 0 ) { + g_use_gmalloc = true; + } } Modified: branches/PR-6424345/launchd/src/launchd_runtime.h =================================================================== --- branches/PR-6424345/launchd/src/launchd_runtime.h 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/launchd_runtime.h 2009-02-15 00:33:23 UTC (rev 23808) @@ -101,6 +101,8 @@ extern bool pid1_magic; extern bool low_level_debug; extern char g_username[128]; +extern bool g_shutdown_debugging; +extern bool g_use_gmalloc; mach_port_t runtime_get_kernel_port(void); extern boolean_t launchd_internal_demux(mach_msg_header_t *Request, mach_msg_header_t *Reply); Modified: branches/PR-6424345/launchd/src/launchd_unix_ipc.c =================================================================== --- branches/PR-6424345/launchd/src/launchd_unix_ipc.c 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/launchd_unix_ipc.c 2009-02-15 00:33:23 UTC (rev 23808) @@ -235,9 +235,15 @@ } } -static void set_user_env(launch_data_t obj, const char *key, void *context __attribute__((unused))) +static void +set_user_env(launch_data_t obj, const char *key, void *context __attribute__((unused))) { - setenv(key, launch_data_get_string(obj), 1); + const char *v = launch_data_get_string(obj); + if( v ) { + setenv(key, v, 1); + } else { + runtime_syslog(LOG_WARNING, "Attempt to set NULL environment variable: %s (type = %d)", key, launch_data_get_type(obj)); + } } void Modified: branches/PR-6424345/launchd/src/libbootstrap.c =================================================================== --- branches/PR-6424345/launchd/src/libbootstrap.c 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/libbootstrap.c 2009-02-15 00:33:23 UTC (rev 23808) @@ -274,11 +274,11 @@ kern_return_t bootstrap_info(mach_port_t bp, - name_array_t *service_names, mach_msg_type_number_t *service_namesCnt, - bootstrap_status_array_t *service_active, mach_msg_type_number_t *service_activeCnt) + name_array_t *service_names, mach_msg_type_number_t *service_namesCnt, + name_array_t *service_jobs, mach_msg_type_number_t *service_jobsCnt, + bootstrap_status_array_t *service_active, mach_msg_type_number_t *service_activeCnt) { - return vproc_mig_info(bp, service_names, service_namesCnt, - service_active, service_activeCnt); + return vproc_mig_info(bp, service_names, service_namesCnt, service_jobs, service_jobsCnt, service_active, service_activeCnt); } const char * Modified: branches/PR-6424345/launchd/src/liblaunch.c =================================================================== --- branches/PR-6424345/launchd/src/liblaunch.c 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/liblaunch.c 2009-02-15 00:33:23 UTC (rev 23808) @@ -1267,17 +1267,18 @@ void load_launchd_jobs_at_loginwindow_prompt(int flags __attribute__((unused)), ...) { - _vprocmgr_init("LoginWindow"); + _vprocmgr_init(VPROCMGR_SESSION_LOGINWINDOW); } pid_t -create_and_switch_to_per_session_launchd(const char *login __attribute__((unused)), int flags __attribute__((unused)), ...) +create_and_switch_to_per_session_launchd(const char *login __attribute__((unused)), int flags, ...) { uid_t target_user = geteuid() ? geteuid() : getuid(); - - if (_vprocmgr_move_subset_to_user(target_user, "Aqua")) { + if (_vprocmgr_move_subset_to_user(target_user, VPROCMGR_SESSION_AQUA, flags)) { return -1; } return 1; } + + Modified: branches/PR-6424345/launchd/src/libvproc.c =================================================================== --- branches/PR-6424345/launchd/src/libvproc.c 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/libvproc.c 2009-02-15 00:33:23 UTC (rev 23808) @@ -189,8 +189,7 @@ if (unlikely(old < 0)) { if (vproc_shmem->vp_shmem_flags & VPROC_SHMEM_EXITING) { - raise(SIGKILL); - __crashreporter_info__ = "raise(SIGKILL) failed"; + _exit(0); } else { __crashreporter_info__ = "Unbalanced: vproc_transaction_begin()"; } @@ -293,8 +292,7 @@ runtime_ktrace(RTKT_VPROC_TRANSACTION_DECREMENT, newval, 0, 0); if (unlikely(newval < 0)) { if (vproc_shmem->vp_shmem_flags & VPROC_SHMEM_EXITING) { - raise(SIGKILL); - __crashreporter_info__ = "raise(SIGKILL) failed"; + _exit(0); } else { __crashreporter_info__ = "Unbalanced: vproc_transaction_end()"; } @@ -412,16 +410,10 @@ return vproc_mig_post_fork_ping(bootstrap_port, mach_task_self()) == 0 ? NULL : _vproc_post_fork_ping; } -static void -setup_env_hack(const launch_data_t obj, const char *key, void *context __attribute__((unused))) -{ - setenv(key, launch_data_get_string(obj), 1); -} - vproc_err_t _vprocmgr_init(const char *session_type) { - if (vproc_mig_move_subset(bootstrap_port, MACH_PORT_NULL, (char *)session_type) == 0) { + if (vproc_mig_init_session(bootstrap_port, (char *)session_type) == 0) { return NULL; } @@ -429,9 +421,8 @@ } vproc_err_t -_vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type) +_vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type, uint64_t flags) { - launch_data_t output_obj; kern_return_t kr = 0; bool is_bkgd = (strcmp(session_type, VPROCMGR_SESSION_BACKGROUND) == 0); int64_t ldpid, lduid; @@ -466,7 +457,7 @@ mach_port_deallocate(mach_task_self(), bootstrap_port); bootstrap_port = puc; } else { - kr = vproc_mig_move_subset(puc, bootstrap_port, (char *)session_type); + kr = vproc_mig_move_subset(puc, bootstrap_port, (char *)session_type, flags); mach_port_deallocate(mach_task_self(), puc); } @@ -476,16 +467,6 @@ return (vproc_err_t)_vprocmgr_move_subset_to_user; } - /* XXX We need to give 'nohup' a better API after Leopard ships */ - if (getprogname() && strcmp(getprogname(), "nohup") != 0) { - if (vproc_swap_complex(NULL, VPROC_GSK_ENVIRONMENT, NULL, &output_obj) == NULL) { - if (launch_data_get_type(output_obj) == LAUNCH_DATA_DICTIONARY) { - launch_data_dict_iterate(output_obj, setup_env_hack, NULL); - launch_data_free(output_obj); - } - } - } - /* Don't do things like setting up the exception port if we're tainted. This is primarily for * loginwindow, which setuid(2)s to the logged-in user but still runs under the system Mach * bootstrap. So we want the system launchd to spawn a crash reporter to report loginwindow @@ -502,7 +483,11 @@ { mach_port_t new_bsport = MACH_PORT_NULL; kern_return_t kr = KERN_FAILURE; - if( (kr = vproc_mig_switch_to_session(bootstrap_port, mach_task_self(), (char *)target_session, &new_bsport)) != KERN_SUCCESS ) { + + mach_port_t tnp = MACH_PORT_NULL; + task_name_for_pid(mach_task_self(), getpid(), &tnp); + + if( (kr = vproc_mig_switch_to_session(bootstrap_port, tnp, (char *)target_session, &new_bsport)) != KERN_SUCCESS ) { _vproc_log(LOG_NOTICE, "_vprocmgr_switch_to_session(): kr = 0x%x", kr); return (vproc_err_t)_vprocmgr_switch_to_session; } @@ -930,6 +915,28 @@ return rval; } +vproc_err_t +vproc_swap_string(vproc_t vp, vproc_gsk_t key, const char *instr, char **outstr) +{ + launch_data_t instr_data = instr ? launch_data_new_string(instr) : NULL; + launch_data_t outstr_data = NULL; + + vproc_err_t verr = vproc_swap_complex(vp, key, instr_data, &outstr_data); + if( !verr && outstr ) { + if( launch_data_get_type(outstr_data) == LAUNCH_DATA_STRING ) { + *outstr = strdup(launch_data_get_string(outstr_data)); + } else { + verr = (vproc_err_t)vproc_swap_string; + } + launch_data_free(outstr_data); + } + if( instr_data ) { + launch_data_free(instr_data); + } + + return verr; +} + void * reboot2(uint64_t flags) { Modified: branches/PR-6424345/launchd/src/protocol_vproc.defs =================================================================== --- branches/PR-6424345/launchd/src/protocol_vproc.defs 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/protocol_vproc.defs 2009-02-15 00:33:23 UTC (rev 23808) @@ -88,6 +88,7 @@ routine info( __bs_port : job_t; out __service_names : name_array_t, dealloc; +out __service_jobs : name_array_t, dealloc; out __service_active : bootstrap_status_array_t, dealloc); routine subset( @@ -145,7 +146,8 @@ routine move_subset( __bs_port : job_t; __target_port : mach_port_t; - __sessiontype : name_t); + __sessiontype : name_t; + __sessionflags : uint64_t); routine swap_complex( __bs_port : job_t; @@ -203,3 +205,7 @@ __bs_port : job_t; __label : name_t; out __mp : mach_port_make_send_t); + +routine init_session( + __bs_port : job_t; + __session_name : name_t); Modified: branches/PR-6424345/launchd/src/vproc_internal.h =================================================================== --- branches/PR-6424345/launchd/src/vproc_internal.h 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/vproc_internal.h 2009-02-15 00:33:23 UTC (rev 23808) @@ -103,12 +103,13 @@ kern_return_t -bootstrap_info( - mach_port_t bp, - name_array_t *service_names, - mach_msg_type_number_t *service_namesCnt, - bootstrap_status_array_t *service_active, - mach_msg_type_number_t *service_activeCnt); +bootstrap_info(mach_port_t bp, + name_array_t *service_names, + mach_msg_type_number_t *service_namesCnt, + name_array_t *service_jobs, + mach_msg_type_number_t *service_jobsCnt, + bootstrap_status_array_t *service_active, + mach_msg_type_number_t *service_activeCnt); #pragma GCC visibility pop Modified: branches/PR-6424345/launchd/src/vproc_priv.h =================================================================== --- branches/PR-6424345/launchd/src/vproc_priv.h 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd/src/vproc_priv.h 2009-02-15 00:33:23 UTC (rev 23808) @@ -48,6 +48,7 @@ VPROC_GSK_MGR_UID, VPROC_GSK_MGR_PID, VPROC_GSK_IS_MANAGED, + VPROC_GSK_MGR_NAME, VPROC_GSK_BASIC_KEEPALIVE, VPROC_GSK_START_INTERVAL, VPROC_GSK_IDLE_TIMEOUT, @@ -60,6 +61,7 @@ VPROC_GSK_TRANSACTIONS_ENABLED, VPROC_GSK_WEIRD_BOOTSTRAP, VPROC_GSK_WAITFORDEBUGGER, + VPROC_GSK_SHUTDOWN_DEBUGGING, } vproc_gsk_t; typedef unsigned int vproc_flags_t; @@ -72,6 +74,7 @@ vproc_err_t vproc_swap_integer(vproc_t vp, vproc_gsk_t key, int64_t *inval, int64_t *outval); vproc_err_t vproc_swap_complex(vproc_t vp, vproc_gsk_t key, launch_data_t inval, launch_data_t *outval); +vproc_err_t vproc_swap_string(vproc_t vp, vproc_gsk_t key, const char *instr, char **outstr); vproc_err_t _vproc_get_last_exit_status(int *wstatus); vproc_err_t _vproc_set_global_on_demand(bool val); @@ -94,7 +97,7 @@ #define VPROCMGR_SESSION_STANDARDIO "StandardIO" #define VPROCMGR_SESSION_SYSTEM "System" -vproc_err_t _vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type); +vproc_err_t _vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type, uint64_t flags); vproc_err_t _vprocmgr_switch_to_session(const char *target_session, vproc_flags_t flags); vproc_err_t _vprocmgr_detach_from_console(vproc_flags_t flags); Modified: branches/PR-6424345/launchd.xcodeproj/project.pbxproj =================================================================== --- branches/PR-6424345/launchd.xcodeproj/project.pbxproj 2009-02-14 01:13:33 UTC (rev 23807) +++ branches/PR-6424345/launchd.xcodeproj/project.pbxproj 2009-02-15 00:33:23 UTC (rev 23808) @@ -553,8 +553,8 @@ FC59A0C80E8C8A4E00D41150 /* launchproxy */ = { isa = PBXGroup; children = ( + FC59A0DB0E8C8A6900D41150 /* launchproxy.8 */, FC59A0DA0E8C8A6900D41150 /* launchproxy.c */, - FC59A0DB0E8C8A6900D41150 /* launchproxy.8 */, ); name = launchproxy; sourceTree = ""; -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Mon Feb 16 21:33:12 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Mon, 16 Feb 2009 21:33:12 -0800 (PST) Subject: [launchd-changes] [23809] branches/PR-6589133/ Message-ID: <20090217053312.2CD4EF9C6B4@beta.macosforge.org> Revision: 23809 http://trac.macosforge.org/projects/launchd/changeset/23809 Author: dsorresso at apple.com Date: 2009-02-16 21:33:11 -0800 (Mon, 16 Feb 2009) Log Message: ----------- "Branch for PR-6589133 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- branches/PR-6589133/ Property changes on: branches/PR-6589133 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Mon Feb 16 23:53:06 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Mon, 16 Feb 2009 23:53:06 -0800 (PST) Subject: [launchd-changes] [23810] branches/PR-6589133/launchd/src Message-ID: <20090217075308.08508F9F5E4@beta.macosforge.org> Revision: 23810 http://trac.macosforge.org/projects/launchd/changeset/23810 Author: dsorresso at apple.com Date: 2009-02-16 23:53:04 -0800 (Mon, 16 Feb 2009) Log Message: ----------- 10A274: hundreds of failing (ENOENT) opens of /dev/autofs_nowait in launchd at boot Modified Paths: -------------- branches/PR-6589133/launchd/src/launchd_core_logic.c branches/PR-6589133/launchd/src/launchd_runtime.c Modified: branches/PR-6589133/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6589133/launchd/src/launchd_core_logic.c 2009-02-17 05:33:11 UTC (rev 23809) +++ branches/PR-6589133/launchd/src/launchd_core_logic.c 2009-02-17 07:53:04 UTC (rev 23810) @@ -635,6 +635,7 @@ #define JOB_BOOTCACHE_HACK_CHECK(j) (unlikely(j->per_user && !did_first_per_user_launchd_BootCache_hack && (j->mach_uid >= 500) && (j->mach_uid != (uid_t)-2))) static job_t workaround_5477111; static pid_t s_update_pid = 0; +static int s_no_hang_fd = -1; /* process wide globals */ mach_port_t inherited_bootstrap_port; @@ -3362,6 +3363,17 @@ jobmgr_still_alive_with_check(jm); } break; + case EVFILT_VNODE: + if( kev->ident == (uintptr_t)s_no_hang_fd ) { + int _no_hang_fd = open("/dev/autofs_nowait", O_EVTONLY | O_NONBLOCK); + if( unlikely(_no_hang_fd != -1) ) { + jobmgr_log(root_jobmgr, LOG_DEBUG, "/dev/autofs_nowait has appeared!"); + jobmgr_assumes(root_jobmgr, kevent_mod((uintptr_t)s_no_hang_fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL) != -1); + jobmgr_assumes(root_jobmgr, runtime_close(s_no_hang_fd) != -1); + s_no_hang_fd = _fd(_no_hang_fd); + } + } + break; default: return (void)jobmgr_assumes(jm, false); } @@ -8466,6 +8478,15 @@ SLIST_INIT(&s_curious_jobs); launchd_assert((root_jobmgr = jobmgr_new(NULL, MACH_PORT_NULL, MACH_PORT_NULL, sflag, root_session_type)) != NULL); + + uint32_t fflags = NOTE_ATTRIB | NOTE_LINK | NOTE_REVOKE | NOTE_EXTEND | NOTE_WRITE; + s_no_hang_fd = open("/dev/autofs_nowait", O_EVTONLY | O_NONBLOCK); + if( likely(s_no_hang_fd == -1) ) { + if( jobmgr_assumes(root_jobmgr, (s_no_hang_fd = open("/dev", O_EVTONLY | O_NONBLOCK)) != -1) ) { + jobmgr_assumes(root_jobmgr, kevent_mod((uintptr_t)s_no_hang_fd, EVFILT_VNODE, EV_ADD, fflags, 0, root_jobmgr) != -1); + } + } + s_no_hang_fd = _fd(s_no_hang_fd); } size_t Modified: branches/PR-6589133/launchd/src/launchd_runtime.c =================================================================== --- branches/PR-6589133/launchd/src/launchd_runtime.c 2009-02-17 05:33:11 UTC (rev 23809) +++ branches/PR-6589133/launchd/src/launchd_runtime.c 2009-02-17 07:53:04 UTC (rev 23810) @@ -1142,16 +1142,6 @@ #endif record_caller_creds(&bufRequest->Head); - - /* - * This is a total hack. We really need a bit in the kernel's proc - * struct to declare our intent. - */ - static int no_hang_fd = -1; - if (unlikely(no_hang_fd == -1)) { - no_hang_fd = _fd(open("/dev/autofs_nowait", 0)); - } - runtime_ktrace(RTKT_LAUNCHD_MACH_IPC|DBG_FUNC_START, bufRequest->Head.msgh_local_port, bufRequest->Head.msgh_id, (long)the_demux); if (the_demux(&bufRequest->Head, &bufReply->Head) == FALSE) { -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Mon Feb 16 23:53:41 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Mon, 16 Feb 2009 23:53:41 -0800 (PST) Subject: [launchd-changes] [23811] branches/PR-6562592/ Message-ID: <20090217075341.2068EF9F608@beta.macosforge.org> Revision: 23811 http://trac.macosforge.org/projects/launchd/changeset/23811 Author: dsorresso at apple.com Date: 2009-02-16 23:53:40 -0800 (Mon, 16 Feb 2009) Log Message: ----------- "Branch for PR-6562592 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- branches/PR-6562592/ Property changes on: branches/PR-6562592 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 17 02:11:43 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 17 Feb 2009 02:11:43 -0800 (PST) Subject: [launchd-changes] [23812] branches/PR-6562592/launchd/src/launchd_core_logic.c Message-ID: <20090217101146.67B62FA236F@beta.macosforge.org> Revision: 23812 http://trac.macosforge.org/projects/launchd/changeset/23812 Author: dsorresso at apple.com Date: 2009-02-17 02:11:41 -0800 (Tue, 17 Feb 2009) Log Message: ----------- Capped the time we'll wait for all the stray processes at shutdown to exit at three seconds flat, so it won't grow linearly with the number of strays anymore. Modified Paths: -------------- branches/PR-6562592/launchd/src/launchd_core_logic.c Modified: branches/PR-6562592/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6562592/launchd/src/launchd_core_logic.c 2009-02-17 07:53:40 UTC (rev 23811) +++ branches/PR-6562592/launchd/src/launchd_core_logic.c 2009-02-17 10:11:41 UTC (rev 23812) @@ -371,7 +371,7 @@ static bool jobmgr_label_test(jobmgr_t jm, const char *str); static void jobmgr_reap_bulk(jobmgr_t jm, struct kevent *kev); static void jobmgr_log_stray_children(jobmgr_t jm, bool kill_strays); -static void jobmgr_kill_stray_child(jobmgr_t jm, pid_t p); +static void jobmgr_kill_stray_child(jobmgr_t jm, pid_t *p, size_t np); static void jobmgr_remove(jobmgr_t jm); static void jobmgr_dispatch_all(jobmgr_t jm, bool newmounthack); static void jobmgr_dequeue_next_sample(jobmgr_t jm); @@ -5585,7 +5585,7 @@ } void -jobmgr_kill_stray_child(jobmgr_t jm, pid_t p) +jobmgr_kill_stray_child(jobmgr_t jm, pid_t *p, size_t np) { struct timespec tts = { 2, 0 }; /* Wait 2 seconds for stray children to die after being SIGTERM'ed. */ struct timespec kts = { 1, 0 }; /* Wait 1 second for stray children to die after being SIGKILL'ed. */ @@ -5597,39 +5597,64 @@ return; } - EV_SET(&kev, p, EVFILT_PROC, EV_ADD, 0, 0, 0); - - if (!jobmgr_assumes(jm, kevent(kq, &kev, 1, NULL, 0, NULL) != -1)) { - goto out; - } - start = runtime_get_opaque_time(); - - if (!jobmgr_assumes(jm, runtime_kill(p, SIGTERM) != -1)) { - goto out; + size_t i = 0, ns = 0; + for( i = 0; i < np; i++ ) { + if( p[i] != 0 ) { + EV_SET(&kev, p[i], EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, 0); + + if( jobmgr_assumes(jm, kevent(kq, &kev, 1, NULL, 0, NULL) != -1) ) { + ns++; + } + jobmgr_assumes(jm, runtime_kill(p[i], SIGTERM) != -1); + } } - r = kevent(kq, NULL, 0, &kev, 1, &tts); - - if (!jobmgr_assumes(jm, r == 0 || r == 1)) { - goto out; + size_t nd = 0; + while( (r = kevent(kq, NULL, 0, &kev, 1, &tts)) ) { + int status = 0; + waitpid((pid_t)kev.ident, &status, WNOHANG); + nd++; + + end = runtime_get_opaque_time(); + nanosec = runtime_opaque_time_to_nano(end - start); + jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "PID %u died after %llu nanoseconds.", (pid_t)kev.ident, nanosec); + + for( i = 0; i < np; i++ ) { + p[i] = ( p[i] == (pid_t)kev.ident ) ? 0 : p[i]; + } } - if (r == 0 && jobmgr_assumes(jm, runtime_kill(p, SIGKILL) != -1)) { - jobmgr_assumes(jm, (r = kevent(kq, NULL, 0, &kev, 1, &kts)) == 1); + for( i = 0; i < np; i++ ) { + if( p[i] != 0 ) { + EV_SET(&kev, p[i], EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, 0); + + if( jobmgr_assumes(jm, kevent(kq, &kev, 1, NULL, 0, NULL) != -1) ) { + ns++; + } + jobmgr_assumes(jm, runtime_kill(p[i], SIGKILL) != -1); + } } - end = runtime_get_opaque_time(); - - nanosec = runtime_opaque_time_to_nano(end - start); - - jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "PID %u %s after %llu nanoseconds", p, r == 0 ? "did not die" : "died", nanosec); - if( r == 0 ) { - jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Disregarding PID %u and continuing.", p); + while( (r = kevent(kq, NULL, 0, &kev, 1, &kts)) ) { + int status = 0; + waitpid((pid_t)kev.ident, &status, WNOHANG); + nd++; + + end = runtime_get_opaque_time(); + nanosec = runtime_opaque_time_to_nano(end - start); + jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "PID %u was killed and died after %llu nanoseconds.", (pid_t)kev.ident, nanosec); + + for( i = 0; i < np; i++ ) { + p[i] = ( p[i] == (pid_t)kev.ident ) ? 0 : p[i]; + } } -out: - jobmgr_assumes(jm, runtime_close(kq) != -1); + for( i = 0; i < np; i++ ) { + if( p[i] != 0 ) { + jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Disregarding PID %u and continuing.", p[i]); + } + } } void @@ -5654,7 +5679,8 @@ } kp_cnt = len / sizeof(struct kinfo_proc); - + pid_t *ps = (pid_t *)calloc(sizeof(pid_t), kp_cnt); + for (i = 0; i < kp_cnt; i++) { pid_t p_i = kp[i].kp_proc.p_pid; pid_t pp_i = kp[i].kp_eproc.e_ppid; @@ -5672,17 +5698,21 @@ 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); - if( kill_strays ) { - jobmgr_kill_stray_child(jm, p_i); + int status = 0; + if( (kp[i].kp_proc.p_stat == SZOMB) && waitpid(p_i, &status, WNOHANG) == 0 ) { + jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "Unreaped zombie stray exited with status %i.", WEXITSTATUS(status)); + } else { + ps[i] = p_i; } } } -out: - if (kp_cnt == kp_skipped) { - jobmgr_log(jm, LOG_DEBUG, "No stray processes at shutdown"); + if( (kp_cnt - kp_skipped > 0) && kill_strays ) { + jobmgr_kill_stray_child(jm, ps, kp_cnt - kp_skipped); } + free(ps); +out: free(kp); } -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 17 12:21:48 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 17 Feb 2009 12:21:48 -0800 (PST) Subject: [launchd-changes] [23813] branches/PR-6562592/launchd/src/launchd_core_logic.c Message-ID: <20090217202148.6B947FB2307@beta.macosforge.org> Revision: 23813 http://trac.macosforge.org/projects/launchd/changeset/23813 Author: dsorresso at apple.com Date: 2009-02-17 12:21:46 -0800 (Tue, 17 Feb 2009) Log Message: ----------- Minor tweaks. Modified Paths: -------------- branches/PR-6562592/launchd/src/launchd_core_logic.c Modified: branches/PR-6562592/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6562592/launchd/src/launchd_core_logic.c 2009-02-17 10:11:41 UTC (rev 23812) +++ branches/PR-6562592/launchd/src/launchd_core_logic.c 2009-02-17 20:21:46 UTC (rev 23813) @@ -371,7 +371,7 @@ static bool jobmgr_label_test(jobmgr_t jm, const char *str); static void jobmgr_reap_bulk(jobmgr_t jm, struct kevent *kev); static void jobmgr_log_stray_children(jobmgr_t jm, bool kill_strays); -static void jobmgr_kill_stray_child(jobmgr_t jm, pid_t *p, size_t np); +static void jobmgr_kill_stray_children(jobmgr_t jm, pid_t *p, size_t np); static void jobmgr_remove(jobmgr_t jm); static void jobmgr_dispatch_all(jobmgr_t jm, bool newmounthack); static void jobmgr_dequeue_next_sample(jobmgr_t jm); @@ -5585,7 +5585,7 @@ } void -jobmgr_kill_stray_child(jobmgr_t jm, pid_t *p, size_t np) +jobmgr_kill_stray_children(jobmgr_t jm, pid_t *p, size_t np) { struct timespec tts = { 2, 0 }; /* Wait 2 seconds for stray children to die after being SIGTERM'ed. */ struct timespec kts = { 1, 0 }; /* Wait 1 second for stray children to die after being SIGKILL'ed. */ @@ -5699,16 +5699,21 @@ 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); int status = 0; - if( (kp[i].kp_proc.p_stat == SZOMB) && waitpid(p_i, &status, WNOHANG) == 0 ) { - jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "Unreaped zombie stray exited with status %i.", WEXITSTATUS(status)); + if( (kp[i].kp_proc.p_stat == SZOMB) ) { + if( pp_i == getpid() && waitpid(p_i, &status, WNOHANG) == 0 ) { + jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "Unreaped zombie stray exited with status %i.", WEXITSTATUS(status)); + } + kp_skipped++; } else { ps[i] = p_i; } + } else { + kp_skipped++; } } if( (kp_cnt - kp_skipped > 0) && kill_strays ) { - jobmgr_kill_stray_child(jm, ps, kp_cnt - kp_skipped); + jobmgr_kill_stray_children(jm, ps, kp_cnt - kp_skipped); } free(ps); -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 17 13:00:19 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 17 Feb 2009 13:00:19 -0800 (PST) Subject: [launchd-changes] [23814] branches/PR-6562592/launchd/src/launchd_core_logic.c Message-ID: <20090217210019.BABEFFB405B@beta.macosforge.org> Revision: 23814 http://trac.macosforge.org/projects/launchd/changeset/23814 Author: dsorresso at apple.com Date: 2009-02-17 13:00:17 -0800 (Tue, 17 Feb 2009) Log Message: ----------- More tweaks. Modified Paths: -------------- branches/PR-6562592/launchd/src/launchd_core_logic.c Modified: branches/PR-6562592/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6562592/launchd/src/launchd_core_logic.c 2009-02-17 20:21:46 UTC (rev 23813) +++ branches/PR-6562592/launchd/src/launchd_core_logic.c 2009-02-17 21:00:17 UTC (rev 23814) @@ -5598,23 +5598,24 @@ } start = runtime_get_opaque_time(); - size_t i = 0, ns = 0; + size_t i = 0, n2t = 0; for( i = 0; i < np; i++ ) { if( p[i] != 0 ) { EV_SET(&kev, p[i], EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, 0); if( jobmgr_assumes(jm, kevent(kq, &kev, 1, NULL, 0, NULL) != -1) ) { - ns++; + jobmgr_assumes(jm, runtime_kill(p[i], SIGTERM) != -1); + n2t++; + } else { + jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Disregarding PID %u and continuing.", p[i]); + p[i] = 0; } - jobmgr_assumes(jm, runtime_kill(p[i], SIGTERM) != -1); } } - size_t nd = 0; - while( (r = kevent(kq, NULL, 0, &kev, 1, &tts)) ) { + while( n2t > 0 && (r = kevent(kq, NULL, 0, &kev, 1, &tts)) ) { int status = 0; waitpid((pid_t)kev.ident, &status, WNOHANG); - nd++; end = runtime_get_opaque_time(); nanosec = runtime_opaque_time_to_nano(end - start); @@ -5625,21 +5626,17 @@ } } + size_t n2k = 0; for( i = 0; i < np; i++ ) { if( p[i] != 0 ) { - EV_SET(&kev, p[i], EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, 0); - - if( jobmgr_assumes(jm, kevent(kq, &kev, 1, NULL, 0, NULL) != -1) ) { - ns++; - } jobmgr_assumes(jm, runtime_kill(p[i], SIGKILL) != -1); + n2k++; } } - while( (r = kevent(kq, NULL, 0, &kev, 1, &kts)) ) { + while( n2k > 0 && (r = kevent(kq, NULL, 0, &kev, 1, &kts)) ) { int status = 0; waitpid((pid_t)kev.ident, &status, WNOHANG); - nd++; end = runtime_get_opaque_time(); nanosec = runtime_opaque_time_to_nano(end - start); @@ -5652,7 +5649,7 @@ for( i = 0; i < np; i++ ) { if( p[i] != 0 ) { - jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Disregarding PID %u and continuing.", p[i]); + jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "PID %u did not die after being SIGKILL'ed 1 second ago.", p[i]); } } } @@ -5699,8 +5696,8 @@ 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); int status = 0; - if( (kp[i].kp_proc.p_stat == SZOMB) ) { - if( pp_i == getpid() && waitpid(p_i, &status, WNOHANG) == 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)); } kp_skipped++; -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 17 13:39:00 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 17 Feb 2009 13:39:00 -0800 (PST) Subject: [launchd-changes] [23815] trunk/launchd/src/launchd_core_logic.c Message-ID: <20090217213900.88FEFFB4C12@beta.macosforge.org> Revision: 23815 http://trac.macosforge.org/projects/launchd/changeset/23815 Author: dsorresso at apple.com Date: 2009-02-17 13:38:59 -0800 (Tue, 17 Feb 2009) Log Message: ----------- Remove first per-user launchd hack Forgot to commit this. Modified Paths: -------------- trunk/launchd/src/launchd_core_logic.c Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2009-02-17 21:00:17 UTC (rev 23814) +++ trunk/launchd/src/launchd_core_logic.c 2009-02-17 21:38:59 UTC (rev 23815) @@ -613,7 +613,6 @@ static char **mach_cmd2argv(const char *string); 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 do_first_per_user_launchd_hack(void); 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)); @@ -631,8 +630,6 @@ static size_t total_children; static size_t total_anon_children; static mach_port_t the_exception_server; -static bool did_first_per_user_launchd_BootCache_hack; -#define JOB_BOOTCACHE_HACK_CHECK(j) (unlikely(j->per_user && !did_first_per_user_launchd_BootCache_hack && (j->mach_uid >= 500) && (j->mach_uid != (uid_t)-2))) static job_t workaround_5477111; static pid_t s_update_pid = 0; @@ -3510,10 +3507,6 @@ total_children++; LIST_INSERT_HEAD(&j->mgr->active_jobs[ACTIVE_JOB_HASH(c)], j, pid_hash_sle); - if (JOB_BOOTCACHE_HACK_CHECK(j)) { - did_first_per_user_launchd_BootCache_hack = true; - } - if (likely(!j->legacy_mach_job)) { job_assumes(j, runtime_close(oepair[1]) != -1); } @@ -3543,23 +3536,6 @@ } void -do_first_per_user_launchd_hack(void) -{ - char *bcct_tool[] = { "/usr/sbin/BootCacheControl", "tag", NULL }; - int dummystatus; - pid_t bcp; - - if (launchd_assumes((bcp = vfork()) != -1)) { - if (bcp == 0) { - execve(bcct_tool[0], bcct_tool, environ); - _exit(EXIT_FAILURE); - } else { - launchd_assumes(waitpid(bcp, &dummystatus, 0) != -1); - } - } -} - -void job_start_child(job_t j) { typeof(posix_spawn) *psf; @@ -3572,10 +3548,6 @@ size_t binpref_out_cnt = 0; size_t i; - if (JOB_BOOTCACHE_HACK_CHECK(j)) { - do_first_per_user_launchd_hack(); - } - job_assumes(j, posix_spawnattr_init(&spattr) == 0); job_setup_attributes(j); -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 17 13:42:23 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 17 Feb 2009 13:42:23 -0800 (PST) Subject: [launchd-changes] [23816] tags/launchd-299.2/ Message-ID: <20090217214223.4247AFB4C67@beta.macosforge.org> Revision: 23816 http://trac.macosforge.org/projects/launchd/changeset/23816 Author: dsorresso at apple.com Date: 2009-02-17 13:42:22 -0800 (Tue, 17 Feb 2009) Log Message: ----------- "Tagging launchd-299.2 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- tags/launchd-299.2/ Property changes on: tags/launchd-299.2 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 17 13:45:48 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 17 Feb 2009 13:45:48 -0800 (PST) Subject: [launchd-changes] [23817] branches/PR-6271234/ Message-ID: <20090217214548.C6DA6FB4CF6@beta.macosforge.org> Revision: 23817 http://trac.macosforge.org/projects/launchd/changeset/23817 Author: dsorresso at apple.com Date: 2009-02-17 13:45:48 -0800 (Tue, 17 Feb 2009) Log Message: ----------- "Branch for PR-6271234 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- branches/PR-6271234/ Property changes on: branches/PR-6271234 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 17 13:48:01 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 17 Feb 2009 13:48:01 -0800 (PST) Subject: [launchd-changes] [23818] branches/PR-6271234/launchd/src Message-ID: <20090217214802.03668FB4D3B@beta.macosforge.org> Revision: 23818 http://trac.macosforge.org/projects/launchd/changeset/23818 Author: dsorresso at apple.com Date: 2009-02-17 13:48:01 -0800 (Tue, 17 Feb 2009) Log Message: ----------- Corrected typo in script name. Changed launchd's invocation of script such that it goes through /bin/bash now. Modified Paths: -------------- branches/PR-6271234/launchd/src/launchctl.c branches/PR-6271234/launchd/src/launchd_core_logic.c Modified: branches/PR-6271234/launchd/src/launchctl.c =================================================================== --- branches/PR-6271234/launchd/src/launchctl.c 2009-02-17 21:45:48 UTC (rev 23817) +++ branches/PR-6271234/launchd/src/launchctl.c 2009-02-17 21:48:01 UTC (rev 23818) @@ -1843,7 +1843,7 @@ if( path_check("/etc/rc.deferredinstall") ) { int status = 0; - const char *deferredinstall_tool[] = { _PATH_BSHELL, "/etc/rc.deferredinstall", NULL }; + const char *deferredinstall_tool[] = { _PATH_BSHELL, "/etc/rc.deferred_install", NULL }; if( assumes(fwexec(deferredinstall_tool, &status) != -1) ) { if( WEXITSTATUS(status) == EXIT_SUCCESS ) { if( do_apple_internal_magic ) { Modified: branches/PR-6271234/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6271234/launchd/src/launchd_core_logic.c 2009-02-17 21:45:48 UTC (rev 23817) +++ branches/PR-6271234/launchd/src/launchd_core_logic.c 2009-02-17 21:48:01 UTC (rev 23818) @@ -8619,7 +8619,7 @@ } struct stat sb; - const char *argv[] = { "/etc/rc.deferredinstall", NULL }; + const char *argv[] = { _PATH_BSHELL, "/etc/rc.deferred_install", NULL }; char *try_again = "Will try again at next boot."; int result = ~0; -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 17 13:56:42 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 17 Feb 2009 13:56:42 -0800 (PST) Subject: [launchd-changes] [23819] branches/PR-6271234/launchd/src/launchd_core_logic.c Message-ID: <20090217215642.99757FB53CB@beta.macosforge.org> Revision: 23819 http://trac.macosforge.org/projects/launchd/changeset/23819 Author: dsorresso at apple.com Date: 2009-02-17 13:56:42 -0800 (Tue, 17 Feb 2009) Log Message: ----------- Let's not delete /bin/sh. Modified Paths: -------------- branches/PR-6271234/launchd/src/launchd_core_logic.c Modified: branches/PR-6271234/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6271234/launchd/src/launchd_core_logic.c 2009-02-17 21:48:01 UTC (rev 23818) +++ branches/PR-6271234/launchd/src/launchd_core_logic.c 2009-02-17 21:56:42 UTC (rev 23819) @@ -8658,7 +8658,7 @@ * that the file exists. Outside of someone deliberately messing with us (like if /etc/rc.deferredinstall * is actually a looping sym-link or a mount point for a filesystem) and I/O errors, we should be good. */ - if( !jobmgr_assumes(root_jobmgr, unlink(argv[0]) != -1) ) { + if( !jobmgr_assumes(root_jobmgr, unlink(argv[1]) != -1) ) { jobmgr_log(root_jobmgr, LOG_WARNING | LOG_CONSOLE, "Deferred install script couldn't be removed!"); } } -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 17 13:57:49 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 17 Feb 2009 13:57:49 -0800 (PST) Subject: [launchd-changes] [23820] branches/PR-6271234/launchd/src/launchd_core_logic.c Message-ID: <20090217215749.ACC40FB546E@beta.macosforge.org> Revision: 23820 http://trac.macosforge.org/projects/launchd/changeset/23820 Author: dsorresso at apple.com Date: 2009-02-17 13:57:48 -0800 (Tue, 17 Feb 2009) Log Message: ----------- One more fix. Modified Paths: -------------- branches/PR-6271234/launchd/src/launchd_core_logic.c Modified: branches/PR-6271234/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6271234/launchd/src/launchd_core_logic.c 2009-02-17 21:56:42 UTC (rev 23819) +++ branches/PR-6271234/launchd/src/launchd_core_logic.c 2009-02-17 21:57:48 UTC (rev 23820) @@ -8623,7 +8623,7 @@ char *try_again = "Will try again at next boot."; int result = ~0; - if( unlikely(stat(argv[0], &sb) != -1) ) { + if( unlikely(stat(argv[1], &sb) != -1) ) { jobmgr_log(root_jobmgr, LOG_DEBUG | LOG_CONSOLE, "Going to run deferred install script."); int wstatus; -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 17 14:09:17 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 17 Feb 2009 14:09:17 -0800 (PST) Subject: [launchd-changes] [23821] branches/PR-6271234/launchd/src/launchctl.c Message-ID: <20090217220917.2DDBEFB556B@beta.macosforge.org> Revision: 23821 http://trac.macosforge.org/projects/launchd/changeset/23821 Author: dsorresso at apple.com Date: 2009-02-17 14:09:16 -0800 (Tue, 17 Feb 2009) Log Message: ----------- One more time. Modified Paths: -------------- branches/PR-6271234/launchd/src/launchctl.c Modified: branches/PR-6271234/launchd/src/launchctl.c =================================================================== --- branches/PR-6271234/launchd/src/launchctl.c 2009-02-17 21:57:48 UTC (rev 23820) +++ branches/PR-6271234/launchd/src/launchctl.c 2009-02-17 22:09:16 UTC (rev 23821) @@ -1841,7 +1841,7 @@ assumes(fwexec(rccleanup_tool, NULL) != -1); } - if( path_check("/etc/rc.deferredinstall") ) { + if( path_check("/etc/rc.deferred_install") ) { int status = 0; const char *deferredinstall_tool[] = { _PATH_BSHELL, "/etc/rc.deferred_install", NULL }; if( assumes(fwexec(deferredinstall_tool, &status) != -1) ) { -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Wed Feb 18 11:25:29 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Wed, 18 Feb 2009 11:25:29 -0800 (PST) Subject: [launchd-changes] [23822] branches/PR-6562592/launchd/src/launchd_core_logic.c Message-ID: <20090218192529.AD79CFC99C1@beta.macosforge.org> Revision: 23822 http://trac.macosforge.org/projects/launchd/changeset/23822 Author: dsorresso at apple.com Date: 2009-02-18 11:25:28 -0800 (Wed, 18 Feb 2009) Log Message: ----------- Now we're sending SIGTERM to strays and moving on. No waiting, and no followup SIGKILL. Modified Paths: -------------- branches/PR-6562592/launchd/src/launchd_core_logic.c Modified: branches/PR-6562592/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6562592/launchd/src/launchd_core_logic.c 2009-02-17 22:09:16 UTC (rev 23821) +++ branches/PR-6562592/launchd/src/launchd_core_logic.c 2009-02-18 19:25:28 UTC (rev 23822) @@ -5587,12 +5587,28 @@ void jobmgr_kill_stray_children(jobmgr_t jm, pid_t *p, size_t np) { +#if 1 + /* I maintain that stray processes should be at the mercy of launchd during shutdown, + * but nevertheless, things like diskimages-helper can stick around, and SIGKILLing + * them can result in data loss. So we send SIGTERM to all the strays and don't wait + * for them to exit before moving on. + * + * See rdar://problem/6562592 + */ + size_t i = 0; + for( i = 0; i < np; i++ ) { + if( p[i] != 0 ) { + jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Sending SIGTERM to PID %u and continuing...", p[i]); + jobmgr_assumes(jm, runtime_kill(p[i], SIGTERM) != -1); + } + } +#else struct timespec tts = { 2, 0 }; /* Wait 2 seconds for stray children to die after being SIGTERM'ed. */ struct timespec kts = { 1, 0 }; /* Wait 1 second for stray children to die after being SIGKILL'ed. */ uint64_t start, end, nanosec; struct kevent kev; int r, kq = kqueue(); - + if (!jobmgr_assumes(jm, kq != -1)) { return; } @@ -5652,6 +5668,7 @@ jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "PID %u did not die after being SIGKILL'ed 1 second ago.", p[i]); } } +#endif } void -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 19 14:10:52 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 19 Feb 2009 14:10:52 -0800 (PST) Subject: [launchd-changes] [23823] trunk Message-ID: <20090219221053.2FA43FEB958@beta.macosforge.org> Revision: 23823 http://trac.macosforge.org/projects/launchd/changeset/23823 Author: dsorresso at apple.com Date: 2009-02-19 14:10:52 -0800 (Thu, 19 Feb 2009) Log Message: ----------- QFA: Need to be able to install software at shutdown time to eliminate double reboot Reduce wait time for stray processes (2s delay if stray process does not handle SIGTERM) 10A274: hundreds of failing (ENOENT) opens of /dev/autofs_nowait in launchd at boot Modified Paths: -------------- trunk/launchd/src/launchctl.c trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/launchd_runtime.c Property Changed: ---------------- trunk/ trunk/launchd/src/bootstrap.h trunk/launchd/src/bootstrap_priv.h trunk/launchd/src/launch.h trunk/launchd/src/launch_internal.h trunk/launchd/src/launch_priv.h trunk/launchd/src/protocol_vproc.defs trunk/launchd/src/vproc.h trunk/launchd/src/vproc_internal.h trunk/launchd/src/vproc_priv.h Property changes on: trunk ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 /branches/PR-6271234:23818-23822 /branches/PR-6562592:23812-23822 /branches/PR-6589133:23810-23822 Property changes on: trunk/launchd/src/bootstrap.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5898404/launchd/src/libbootstrap_public.h:23681-23700 /branches/PR-5978442/launchd/src/libbootstrap_public.h:23651-23701 + /branches/PR-5898404/launchd/src/libbootstrap_public.h:23681-23700 /branches/PR-5978442/launchd/src/libbootstrap_public.h:23651-23701 /branches/PR-6271234/launchd/src/bootstrap.h:23818-23822 /branches/PR-6562592/launchd/src/bootstrap.h:23812-23822 /branches/PR-6589133/launchd/src/bootstrap.h:23810-23822 Property changes on: trunk/launchd/src/bootstrap_priv.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5898404/launchd/src/libbootstrap_private.h:23681-23700 /branches/PR-5978442/launchd/src/libbootstrap_private.h:23651-23701 + /branches/PR-5898404/launchd/src/libbootstrap_private.h:23681-23700 /branches/PR-5978442/launchd/src/libbootstrap_private.h:23651-23701 /branches/PR-6271234/launchd/src/bootstrap_priv.h:23818-23822 /branches/PR-6562592/launchd/src/bootstrap_priv.h:23812-23822 /branches/PR-6589133/launchd/src/bootstrap_priv.h:23810-23822 Property changes on: trunk/launchd/src/launch.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5898404/launchd/src/liblaunch_public.h:23681-23700 /branches/PR-5978442/launchd/src/liblaunch_public.h:23651-23701 + /branches/PR-5898404/launchd/src/liblaunch_public.h:23681-23700 /branches/PR-5978442/launchd/src/liblaunch_public.h:23651-23701 /branches/PR-6271234/launchd/src/launch.h:23818-23822 /branches/PR-6562592/launchd/src/launch.h:23812-23822 /branches/PR-6589133/launchd/src/launch.h:23810-23822 Property changes on: trunk/launchd/src/launch_internal.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5898404/launchd/src/liblaunch_internal.h:23681-23700 /branches/PR-5978442/launchd/src/liblaunch_internal.h:23651-23701 + /branches/PR-5898404/launchd/src/liblaunch_internal.h:23681-23700 /branches/PR-5978442/launchd/src/liblaunch_internal.h:23651-23701 /branches/PR-6271234/launchd/src/launch_internal.h:23818-23822 /branches/PR-6562592/launchd/src/launch_internal.h:23812-23822 /branches/PR-6589133/launchd/src/launch_internal.h:23810-23822 Property changes on: trunk/launchd/src/launch_priv.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5898404/launchd/src/liblaunch_private.h:23681-23700 /branches/PR-5978442/launchd/src/liblaunch_private.h:23651-23701 + /branches/PR-5898404/launchd/src/liblaunch_private.h:23681-23700 /branches/PR-5978442/launchd/src/liblaunch_private.h:23651-23701 /branches/PR-6271234/launchd/src/launch_priv.h:23818-23822 /branches/PR-6562592/launchd/src/launch_priv.h:23812-23822 /branches/PR-6589133/launchd/src/launch_priv.h:23810-23822 Modified: trunk/launchd/src/launchctl.c =================================================================== --- trunk/launchd/src/launchctl.c 2009-02-18 19:25:28 UTC (rev 23822) +++ trunk/launchd/src/launchctl.c 2009-02-19 22:10:52 UTC (rev 23823) @@ -1841,9 +1841,9 @@ assumes(fwexec(rccleanup_tool, NULL) != -1); } - if( path_check("/etc/rc.deferredinstall") ) { + if( path_check("/etc/rc.deferred_install") ) { int status = 0; - const char *deferredinstall_tool[] = { _PATH_BSHELL, "/etc/rc.deferredinstall", NULL }; + const char *deferredinstall_tool[] = { _PATH_BSHELL, "/etc/rc.deferred_install", NULL }; if( assumes(fwexec(deferredinstall_tool, &status) != -1) ) { if( WEXITSTATUS(status) == EXIT_SUCCESS ) { if( do_apple_internal_magic ) { Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2009-02-18 19:25:28 UTC (rev 23822) +++ trunk/launchd/src/launchd_core_logic.c 2009-02-19 22:10:52 UTC (rev 23823) @@ -371,7 +371,7 @@ static bool jobmgr_label_test(jobmgr_t jm, const char *str); static void jobmgr_reap_bulk(jobmgr_t jm, struct kevent *kev); static void jobmgr_log_stray_children(jobmgr_t jm, bool kill_strays); -static void jobmgr_kill_stray_child(jobmgr_t jm, pid_t p); +static void jobmgr_kill_stray_children(jobmgr_t jm, pid_t *p, size_t np); static void jobmgr_remove(jobmgr_t jm); static void jobmgr_dispatch_all(jobmgr_t jm, bool newmounthack); static void jobmgr_dequeue_next_sample(jobmgr_t jm); @@ -632,6 +632,7 @@ static mach_port_t the_exception_server; static job_t workaround_5477111; static pid_t s_update_pid = 0; +static int s_no_hang_fd = -1; /* process wide globals */ mach_port_t inherited_bootstrap_port; @@ -3359,6 +3360,17 @@ jobmgr_still_alive_with_check(jm); } break; + case EVFILT_VNODE: + if( kev->ident == (uintptr_t)s_no_hang_fd ) { + int _no_hang_fd = open("/dev/autofs_nowait", O_EVTONLY | O_NONBLOCK); + if( unlikely(_no_hang_fd != -1) ) { + jobmgr_log(root_jobmgr, LOG_DEBUG, "/dev/autofs_nowait has appeared!"); + jobmgr_assumes(root_jobmgr, kevent_mod((uintptr_t)s_no_hang_fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL) != -1); + jobmgr_assumes(root_jobmgr, runtime_close(s_no_hang_fd) != -1); + s_no_hang_fd = _fd(_no_hang_fd); + } + } + break; default: return (void)jobmgr_assumes(jm, false); } @@ -5557,51 +5569,90 @@ } void -jobmgr_kill_stray_child(jobmgr_t jm, pid_t p) +jobmgr_kill_stray_children(jobmgr_t jm, pid_t *p, size_t np) { +#if 1 + /* I maintain that stray processes should be at the mercy of launchd during shutdown, + * but nevertheless, things like diskimages-helper can stick around, and SIGKILLing + * them can result in data loss. So we send SIGTERM to all the strays and don't wait + * for them to exit before moving on. + * + * See rdar://problem/6562592 + */ + size_t i = 0; + for( i = 0; i < np; i++ ) { + if( p[i] != 0 ) { + jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Sending SIGTERM to PID %u and continuing...", p[i]); + jobmgr_assumes(jm, runtime_kill(p[i], SIGTERM) != -1); + } + } +#else struct timespec tts = { 2, 0 }; /* Wait 2 seconds for stray children to die after being SIGTERM'ed. */ struct timespec kts = { 1, 0 }; /* Wait 1 second for stray children to die after being SIGKILL'ed. */ uint64_t start, end, nanosec; struct kevent kev; int r, kq = kqueue(); - + if (!jobmgr_assumes(jm, kq != -1)) { return; } - EV_SET(&kev, p, EVFILT_PROC, EV_ADD, 0, 0, 0); - - if (!jobmgr_assumes(jm, kevent(kq, &kev, 1, NULL, 0, NULL) != -1)) { - goto out; - } - start = runtime_get_opaque_time(); - - if (!jobmgr_assumes(jm, runtime_kill(p, SIGTERM) != -1)) { - goto out; + size_t i = 0, n2t = 0; + for( i = 0; i < np; i++ ) { + if( p[i] != 0 ) { + EV_SET(&kev, p[i], EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, 0); + + if( jobmgr_assumes(jm, kevent(kq, &kev, 1, NULL, 0, NULL) != -1) ) { + jobmgr_assumes(jm, runtime_kill(p[i], SIGTERM) != -1); + n2t++; + } else { + jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Disregarding PID %u and continuing.", p[i]); + p[i] = 0; + } + } } - r = kevent(kq, NULL, 0, &kev, 1, &tts); - - if (!jobmgr_assumes(jm, r == 0 || r == 1)) { - goto out; + while( n2t > 0 && (r = kevent(kq, NULL, 0, &kev, 1, &tts)) ) { + int status = 0; + waitpid((pid_t)kev.ident, &status, WNOHANG); + + end = runtime_get_opaque_time(); + nanosec = runtime_opaque_time_to_nano(end - start); + jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "PID %u died after %llu nanoseconds.", (pid_t)kev.ident, nanosec); + + for( i = 0; i < np; i++ ) { + p[i] = ( p[i] == (pid_t)kev.ident ) ? 0 : p[i]; + } } - if (r == 0 && jobmgr_assumes(jm, runtime_kill(p, SIGKILL) != -1)) { - jobmgr_assumes(jm, (r = kevent(kq, NULL, 0, &kev, 1, &kts)) == 1); + size_t n2k = 0; + for( i = 0; i < np; i++ ) { + if( p[i] != 0 ) { + jobmgr_assumes(jm, runtime_kill(p[i], SIGKILL) != -1); + n2k++; + } } - end = runtime_get_opaque_time(); - - nanosec = runtime_opaque_time_to_nano(end - start); - - jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "PID %u %s after %llu nanoseconds", p, r == 0 ? "did not die" : "died", nanosec); - if( r == 0 ) { - jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Disregarding PID %u and continuing.", p); + while( n2k > 0 && (r = kevent(kq, NULL, 0, &kev, 1, &kts)) ) { + int status = 0; + waitpid((pid_t)kev.ident, &status, WNOHANG); + + end = runtime_get_opaque_time(); + nanosec = runtime_opaque_time_to_nano(end - start); + jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "PID %u was killed and died after %llu nanoseconds.", (pid_t)kev.ident, nanosec); + + for( i = 0; i < np; i++ ) { + p[i] = ( p[i] == (pid_t)kev.ident ) ? 0 : p[i]; + } } -out: - jobmgr_assumes(jm, runtime_close(kq) != -1); + for( i = 0; i < np; i++ ) { + if( p[i] != 0 ) { + jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "PID %u did not die after being SIGKILL'ed 1 second ago.", p[i]); + } + } +#endif } void @@ -5626,7 +5677,8 @@ } kp_cnt = len / sizeof(struct kinfo_proc); - + pid_t *ps = (pid_t *)calloc(sizeof(pid_t), kp_cnt); + for (i = 0; i < kp_cnt; i++) { pid_t p_i = kp[i].kp_proc.p_pid; pid_t pp_i = kp[i].kp_eproc.e_ppid; @@ -5644,17 +5696,26 @@ 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); - if( kill_strays ) { - jobmgr_kill_stray_child(jm, p_i); + 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)); + } + kp_skipped++; + } else { + ps[i] = p_i; } + } else { + kp_skipped++; } } -out: - if (kp_cnt == kp_skipped) { - jobmgr_log(jm, LOG_DEBUG, "No stray processes at shutdown"); + if( (kp_cnt - kp_skipped > 0) && kill_strays ) { + jobmgr_kill_stray_children(jm, ps, kp_cnt - kp_skipped); } + free(ps); +out: free(kp); } @@ -8438,6 +8499,15 @@ SLIST_INIT(&s_curious_jobs); launchd_assert((root_jobmgr = jobmgr_new(NULL, MACH_PORT_NULL, MACH_PORT_NULL, sflag, root_session_type)) != NULL); + + uint32_t fflags = NOTE_ATTRIB | NOTE_LINK | NOTE_REVOKE | NOTE_EXTEND | NOTE_WRITE; + s_no_hang_fd = open("/dev/autofs_nowait", O_EVTONLY | O_NONBLOCK); + if( likely(s_no_hang_fd == -1) ) { + if( jobmgr_assumes(root_jobmgr, (s_no_hang_fd = open("/dev", O_EVTONLY | O_NONBLOCK)) != -1) ) { + jobmgr_assumes(root_jobmgr, kevent_mod((uintptr_t)s_no_hang_fd, EVFILT_VNODE, EV_ADD, fflags, 0, root_jobmgr) != -1); + } + } + s_no_hang_fd = _fd(s_no_hang_fd); } size_t @@ -8619,11 +8689,11 @@ } struct stat sb; - const char *argv[] = { "/etc/rc.deferredinstall", NULL }; + const char *argv[] = { _PATH_BSHELL, "/etc/rc.deferred_install", NULL }; char *try_again = "Will try again at next boot."; int result = ~0; - if( unlikely(stat(argv[0], &sb) != -1) ) { + if( unlikely(stat(argv[1], &sb) != -1) ) { jobmgr_log(root_jobmgr, LOG_DEBUG | LOG_CONSOLE, "Going to run deferred install script."); int wstatus; @@ -8658,7 +8728,7 @@ * that the file exists. Outside of someone deliberately messing with us (like if /etc/rc.deferredinstall * is actually a looping sym-link or a mount point for a filesystem) and I/O errors, we should be good. */ - if( !jobmgr_assumes(root_jobmgr, unlink(argv[0]) != -1) ) { + if( !jobmgr_assumes(root_jobmgr, unlink(argv[1]) != -1) ) { jobmgr_log(root_jobmgr, LOG_WARNING | LOG_CONSOLE, "Deferred install script couldn't be removed!"); } } Modified: trunk/launchd/src/launchd_runtime.c =================================================================== --- trunk/launchd/src/launchd_runtime.c 2009-02-18 19:25:28 UTC (rev 23822) +++ trunk/launchd/src/launchd_runtime.c 2009-02-19 22:10:52 UTC (rev 23823) @@ -1142,16 +1142,6 @@ #endif record_caller_creds(&bufRequest->Head); - - /* - * This is a total hack. We really need a bit in the kernel's proc - * struct to declare our intent. - */ - static int no_hang_fd = -1; - if (unlikely(no_hang_fd == -1)) { - no_hang_fd = _fd(open("/dev/autofs_nowait", 0)); - } - runtime_ktrace(RTKT_LAUNCHD_MACH_IPC|DBG_FUNC_START, bufRequest->Head.msgh_local_port, bufRequest->Head.msgh_id, (long)the_demux); if (the_demux(&bufRequest->Head, &bufReply->Head) == FALSE) { Property changes on: trunk/launchd/src/protocol_vproc.defs ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5092682/launchd/src/protocol_job.defs:23731-23742 /branches/PR-5898404/launchd/src/protocol_job.defs:23681-23700 /branches/PR-5978442/launchd/src/protocol_job.defs:23651-23701 /branches/PR-6132016/launchd/src/protocol_job.defs:23719-23738 + /branches/PR-5092682/launchd/src/protocol_job.defs:23731-23742 /branches/PR-5898404/launchd/src/protocol_job.defs:23681-23700 /branches/PR-5978442/launchd/src/protocol_job.defs:23651-23701 /branches/PR-6132016/launchd/src/protocol_job.defs:23719-23738 /branches/PR-6271234/launchd/src/protocol_vproc.defs:23818-23822 /branches/PR-6562592/launchd/src/protocol_vproc.defs:23812-23822 /branches/PR-6589133/launchd/src/protocol_vproc.defs:23810-23822 Property changes on: trunk/launchd/src/vproc.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5092682/launchd/src/libvproc_public.h:23731-23742 /branches/PR-5898404/launchd/src/libvproc_public.h:23681-23700 /branches/PR-5978442/launchd/src/libvproc_public.h:23651-23701 /branches/PR-6132016/launchd/src/libvproc_public.h:23719-23738 + /branches/PR-5092682/launchd/src/libvproc_public.h:23731-23742 /branches/PR-5898404/launchd/src/libvproc_public.h:23681-23700 /branches/PR-5978442/launchd/src/libvproc_public.h:23651-23701 /branches/PR-6132016/launchd/src/libvproc_public.h:23719-23738 /branches/PR-6271234/launchd/src/vproc.h:23818-23822 /branches/PR-6562592/launchd/src/vproc.h:23812-23822 /branches/PR-6589133/launchd/src/vproc.h:23810-23822 Property changes on: trunk/launchd/src/vproc_internal.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5898404/launchd/src/libvproc_internal.h:23681-23700 /branches/PR-5978442/launchd/src/libvproc_internal.h:23651-23701 + /branches/PR-5898404/launchd/src/libvproc_internal.h:23681-23700 /branches/PR-5978442/launchd/src/libvproc_internal.h:23651-23701 /branches/PR-6271234/launchd/src/vproc_internal.h:23818-23822 /branches/PR-6562592/launchd/src/vproc_internal.h:23812-23822 /branches/PR-6589133/launchd/src/vproc_internal.h:23810-23822 Property changes on: trunk/launchd/src/vproc_priv.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5092682/launchd/src/libvproc_private.h:23731-23742 /branches/PR-5898404/launchd/src/libvproc_private.h:23681-23700 /branches/PR-5978442/launchd/src/libvproc_private.h:23651-23701 /branches/PR-6132016/launchd/src/libvproc_private.h:23719-23738 + /branches/PR-5092682/launchd/src/libvproc_private.h:23731-23742 /branches/PR-5898404/launchd/src/libvproc_private.h:23681-23700 /branches/PR-5978442/launchd/src/libvproc_private.h:23651-23701 /branches/PR-6132016/launchd/src/libvproc_private.h:23719-23738 /branches/PR-6271234/launchd/src/vproc_priv.h:23818-23822 /branches/PR-6562592/launchd/src/vproc_priv.h:23812-23822 /branches/PR-6589133/launchd/src/vproc_priv.h:23810-23822 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 19 14:11:11 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 19 Feb 2009 14:11:11 -0800 (PST) Subject: [launchd-changes] [23824] tags/launchd-300/ Message-ID: <20090219221111.61B40FEB97F@beta.macosforge.org> Revision: 23824 http://trac.macosforge.org/projects/launchd/changeset/23824 Author: dsorresso at apple.com Date: 2009-02-19 14:11:11 -0800 (Thu, 19 Feb 2009) Log Message: ----------- "Tagging launchd-300 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- tags/launchd-300/ Property changes on: tags/launchd-300 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 /branches/PR-6271234:23818-23822 /branches/PR-6562592:23812-23822 /branches/PR-6589133:23810-23822 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Fri Feb 20 18:58:52 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Fri, 20 Feb 2009 18:58:52 -0800 (PST) Subject: [launchd-changes] [23825] trunk/launchd/src/rc.netboot Message-ID: <20090221025852.EDE041015D88@beta.macosforge.org> Revision: 23825 http://trac.macosforge.org/projects/launchd/changeset/23825 Author: dsorresso at apple.com Date: 2009-02-20 18:58:49 -0800 (Fri, 20 Feb 2009) Log Message: ----------- Diskless NetBoot... isn't diskless Modified Paths: -------------- trunk/launchd/src/rc.netboot Modified: trunk/launchd/src/rc.netboot =================================================================== --- trunk/launchd/src/rc.netboot 2009-02-19 22:11:11 UTC (rev 23824) +++ trunk/launchd/src/rc.netboot 2009-02-21 02:58:49 UTC (rev 23825) @@ -107,8 +107,8 @@ case "${mount_from}" in afp:*) fstype=afp - kextload /System/Library/Filesystems/AppleShare/asp_tcp.kext - kextload /System/Library/Filesystems/AppleShare/afpfs.kext + kextutil -v 0 /System/Library/Filesystems/AppleShare/asp_tcp.kext + kextutil -v 0 /System/Library/Filesystems/AppleShare/afpfs.kext ;; nfs:*) fstype=nfs;; *) echo "unknown network filesystem mount from ${mount_from}" -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Fri Feb 20 18:58:57 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Fri, 20 Feb 2009 18:58:57 -0800 (PST) Subject: [launchd-changes] [23826] tags/launchd-300.1/ Message-ID: <20090221025857.966751015DA7@beta.macosforge.org> Revision: 23826 http://trac.macosforge.org/projects/launchd/changeset/23826 Author: dsorresso at apple.com Date: 2009-02-20 18:58:57 -0800 (Fri, 20 Feb 2009) Log Message: ----------- "Tagging launchd-300.1 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- tags/launchd-300.1/ Property changes on: tags/launchd-300.1 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 /branches/PR-6271234:23818-23822 /branches/PR-6562592:23812-23822 /branches/PR-6589133:23810-23822 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Mon Feb 23 13:04:46 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Mon, 23 Feb 2009 13:04:46 -0800 (PST) Subject: [launchd-changes] [23827] branches/PR-6609410/ Message-ID: <20090223210446.1D8D91060965@beta.macosforge.org> Revision: 23827 http://trac.macosforge.org/projects/launchd/changeset/23827 Author: dsorresso at apple.com Date: 2009-02-23 13:04:45 -0800 (Mon, 23 Feb 2009) Log Message: ----------- "Branch for PR-6609410 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- branches/PR-6609410/ Property changes on: branches/PR-6609410 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 /branches/PR-6271234:23818-23822 /branches/PR-6562592:23812-23822 /branches/PR-6589133:23810-23822 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Mon Feb 23 13:07:49 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Mon, 23 Feb 2009 13:07:49 -0800 (PST) Subject: [launchd-changes] [23828] branches/PR-6609410/launchd/src Message-ID: <20090223210749.D104610609E0@beta.macosforge.org> Revision: 23828 http://trac.macosforge.org/projects/launchd/changeset/23828 Author: dsorresso at apple.com Date: 2009-02-23 13:07:49 -0800 (Mon, 23 Feb 2009) Log Message: ----------- Now giving clean jobs that were SIGKILLed 1 second to exit before advancing state of shutdown. Modified Paths: -------------- branches/PR-6609410/launchd/src/launchd.c branches/PR-6609410/launchd/src/launchd_core_logic.c branches/PR-6609410/launchd/src/launchd_runtime.c branches/PR-6609410/launchd/src/launchd_runtime.h Modified: branches/PR-6609410/launchd/src/launchd.c =================================================================== --- branches/PR-6609410/launchd/src/launchd.c 2009-02-23 21:04:45 UTC (rev 23827) +++ branches/PR-6609410/launchd/src/launchd.c 2009-02-23 21:07:49 UTC (rev 23828) @@ -429,7 +429,7 @@ shutdown_in_progress = true; - if (pid1_magic) { + if( pid1_magic || g_log_per_user_shutdown ) { /* * When this changes to a more sustainable API, update this: * http://howto.apple.com/db.cgi?Debugging_Apps_Non-Responsive_At_Shutdown Modified: branches/PR-6609410/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6609410/launchd/src/launchd_core_logic.c 2009-02-23 21:04:45 UTC (rev 23827) +++ branches/PR-6609410/launchd/src/launchd_core_logic.c 2009-02-23 21:07:49 UTC (rev 23828) @@ -126,9 +126,10 @@ * it a SIGTERM, SIGKILL it. Can be overriden in the job plist. */ #define LAUNCHD_MIN_JOB_RUN_TIME 10 -#define LAUNCHD_SAMPLE_TIMEOUT 1 +#define LAUNCHD_SAMPLE_TIMEOUT 2 #define LAUNCHD_DEFAULT_EXIT_TIMEOUT 20 #define LAUNCHD_SIGKILL_TIMER 5 +#define LAUNCHD_CLEAN_KILL_TIMER 1 #define LAUNCHD_JETSAM_PRIORITY_UNSET 0xdead1eebabell #define SHUTDOWN_LOG_DIR "/var/log/shutdown" @@ -522,6 +523,7 @@ needs_kickoff :1, /* The job is to be kept alive continuously, but it must be initially kicked off. */ is_bootstrapper :1, /* The job is a bootstrapper. */ has_console :1, /* The job owns the console. */ + clean_exit_timer_expired :1, /* The job was clean, received SIGKILL and failed to exit after LAUNCHD_CLEAN_KILL_TIMER seconds. */ migratory :1; /* The (anonymous) job called vprocmgr_switch_to_session(). */ mode_t mask; pid_t tracing_pid; @@ -2996,8 +2998,8 @@ j->sent_sigkill = true; - job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, - EV_ADD, NOTE_SECONDS, LAUNCHD_SIGKILL_TIMER, j) != -1); + intptr_t timer = j->clean_kill ? LAUNCHD_CLEAN_KILL_TIMER : LAUNCHD_SIGKILL_TIMER; + job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, timer, j) != -1); job_log(j, LOG_DEBUG, "Sent SIGKILL signal"); } @@ -3212,6 +3214,16 @@ 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 seconds 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; + + jobmgr_do_garbage_collection(j->mgr); + return; + } + /* * This block might be executed up to 3 times for a given (slow) job * - once for the SAMPLE_TIMEOUT timer, at which point sampling is triggered @@ -5399,11 +5411,14 @@ /* If the job is active and we haven't told it to stop yet, stop it. */ job_stop(ji); - /* We may have sent SIGKILL to the job in job_stop(). In this case, - * "clean" jobs should exit immediately, so we shouldn't have to wait - * for them. + /* We may have sent SIGKILL to the job in job_stop(). Clean jobs + * get 1 second to exit. */ - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + if( !ji->clean_kill ) { + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else { + unkilled_cnt += ji->clean_exit_timer_expired ? 1 : 0; + } } else if( ji->stopped ) { /* If the job is active and has been told to stop, disregard it * after we've sent SIGKILL. @@ -5456,11 +5471,14 @@ /* If the job is active and we haven't told it to stop yet, stop it. */ job_stop(ji); - /* We may have sent SIGKILL to the job in job_stop(). In this case, - * "clean" jobs should exit immediately, so we shouldn't have to wait - * for them. + /* We may have sent SIGKILL to the job in job_stop(). Clean jobs + * get 1 second to exit. */ - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + if( !ji->clean_kill ) { + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else { + unkilled_cnt += ji->clean_exit_timer_expired ? 1 : 0; + } } else if( ji->stopped ) { /* If the job is active and has been told to stop, disregard it * after we've sent SIGKILL. @@ -5515,11 +5533,14 @@ /* If the job is active and we haven't told it to stop yet, stop it. */ job_stop(ji); - /* We may have sent SIGKILL to the job in job_stop(). In this case, - * "clean" jobs should exit immediately, so we shouldn't have to wait - * for them. + /* We may have sent SIGKILL to the job in job_stop(). Clean jobs + * get 1 second to exit. */ - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + if( !ji->clean_kill ) { + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else { + unkilled_cnt += ji->clean_exit_timer_expired ? 1 : 0; + } } else if( ji->stopped ) { /* If the job is active and has been told to stop, disregard it * after we've sent SIGKILL. @@ -5558,7 +5579,7 @@ } if( !_jm && SLIST_EMPTY(&jm->submgrs) ) { - jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "Removing."); + jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Removing."); jobmgr_log_stray_children(jm, false); jobmgr_remove(jm); } else { Modified: branches/PR-6609410/launchd/src/launchd_runtime.c =================================================================== --- branches/PR-6609410/launchd/src/launchd_runtime.c 2009-02-23 21:04:45 UTC (rev 23827) +++ branches/PR-6609410/launchd/src/launchd_runtime.c 2009-02-23 21:07:49 UTC (rev 23828) @@ -133,6 +133,7 @@ bool g_flat_mach_namespace = true; bool g_simulate_pid1_crash = false; bool g_use_gmalloc = false; +bool g_log_per_user_shutdown = false; pid_t g_wsp = 0; mach_port_t @@ -1344,8 +1345,7 @@ offset = (void *)*outval; -#if 0 - if( !ourlogfile && !pid1_magic && shutdown_in_progress ) { + if( g_log_per_user_shutdown && !ourlogfile && !pid1_magic && shutdown_in_progress ) { char logfile[NAME_MAX]; snprintf(logfile, sizeof(logfile), "/var/tmp/launchd-%s.shutdown.log", g_username); @@ -1355,7 +1355,6 @@ rename(logfile, logfile1); ourlogfile = fopen(logfile, "a"); } -#endif static int64_t shutdown_start = 0; if( shutdown_start == 0 ) { @@ -1795,6 +1794,10 @@ g_force_old_kill_path = true; } + if( stat("/var/db/.launchd_log_per_user_shutdown", &sb) == 0 ) { + g_log_per_user_shutdown = true; + } + if( !pid1_magic && stat("/var/db/.launchd_no_flat_per_user_namespace", &sb) == 0 ) { g_flat_mach_namespace = false; } Modified: branches/PR-6609410/launchd/src/launchd_runtime.h =================================================================== --- branches/PR-6609410/launchd/src/launchd_runtime.h 2009-02-23 21:04:45 UTC (rev 23827) +++ branches/PR-6609410/launchd/src/launchd_runtime.h 2009-02-23 21:07:49 UTC (rev 23828) @@ -103,6 +103,7 @@ extern char g_username[128]; extern bool g_shutdown_debugging; extern bool g_use_gmalloc; +extern bool g_log_per_user_shutdown; extern pid_t g_wsp; mach_port_t runtime_get_kernel_port(void); -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Tue Feb 24 19:16:41 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Tue, 24 Feb 2009 19:16:41 -0800 (PST) Subject: [launchd-changes] [23829] trunk Message-ID: <20090225031642.588E31081547@beta.macosforge.org> Revision: 23829 http://trac.macosforge.org/projects/launchd/changeset/23829 Author: dsorresso at apple.com Date: 2009-02-24 19:16:40 -0800 (Tue, 24 Feb 2009) Log Message: ----------- 10A278: per-user launchd of logged-out user still around with lots of zombies Modified Paths: -------------- trunk/launchd/src/launchd.c trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/launchd_runtime.c trunk/launchd/src/launchd_runtime.h Property Changed: ---------------- trunk/ trunk/launchd/src/bootstrap.h trunk/launchd/src/bootstrap_priv.h trunk/launchd/src/launch.h trunk/launchd/src/launch_internal.h trunk/launchd/src/launch_priv.h trunk/launchd/src/protocol_vproc.defs trunk/launchd/src/vproc.h trunk/launchd/src/vproc_internal.h trunk/launchd/src/vproc_priv.h Property changes on: trunk ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 /branches/PR-6271234:23818-23822 /branches/PR-6562592:23812-23822 /branches/PR-6589133:23810-23822 + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 /branches/PR-6271234:23818-23822 /branches/PR-6562592:23812-23822 /branches/PR-6589133:23810-23822 /branches/PR-6609410:23828 Property changes on: trunk/launchd/src/bootstrap.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5898404/launchd/src/libbootstrap_public.h:23681-23700 /branches/PR-5978442/launchd/src/libbootstrap_public.h:23651-23701 /branches/PR-6271234/launchd/src/bootstrap.h:23818-23822 /branches/PR-6562592/launchd/src/bootstrap.h:23812-23822 /branches/PR-6589133/launchd/src/bootstrap.h:23810-23822 + /branches/PR-5898404/launchd/src/libbootstrap_public.h:23681-23700 /branches/PR-5978442/launchd/src/libbootstrap_public.h:23651-23701 /branches/PR-6271234/launchd/src/bootstrap.h:23818-23822 /branches/PR-6562592/launchd/src/bootstrap.h:23812-23822 /branches/PR-6589133/launchd/src/bootstrap.h:23810-23822 /branches/PR-6609410/launchd/src/bootstrap.h:23828 Property changes on: trunk/launchd/src/bootstrap_priv.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5898404/launchd/src/libbootstrap_private.h:23681-23700 /branches/PR-5978442/launchd/src/libbootstrap_private.h:23651-23701 /branches/PR-6271234/launchd/src/bootstrap_priv.h:23818-23822 /branches/PR-6562592/launchd/src/bootstrap_priv.h:23812-23822 /branches/PR-6589133/launchd/src/bootstrap_priv.h:23810-23822 + /branches/PR-5898404/launchd/src/libbootstrap_private.h:23681-23700 /branches/PR-5978442/launchd/src/libbootstrap_private.h:23651-23701 /branches/PR-6271234/launchd/src/bootstrap_priv.h:23818-23822 /branches/PR-6562592/launchd/src/bootstrap_priv.h:23812-23822 /branches/PR-6589133/launchd/src/bootstrap_priv.h:23810-23822 /branches/PR-6609410/launchd/src/bootstrap_priv.h:23828 Property changes on: trunk/launchd/src/launch.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5898404/launchd/src/liblaunch_public.h:23681-23700 /branches/PR-5978442/launchd/src/liblaunch_public.h:23651-23701 /branches/PR-6271234/launchd/src/launch.h:23818-23822 /branches/PR-6562592/launchd/src/launch.h:23812-23822 /branches/PR-6589133/launchd/src/launch.h:23810-23822 + /branches/PR-5898404/launchd/src/liblaunch_public.h:23681-23700 /branches/PR-5978442/launchd/src/liblaunch_public.h:23651-23701 /branches/PR-6271234/launchd/src/launch.h:23818-23822 /branches/PR-6562592/launchd/src/launch.h:23812-23822 /branches/PR-6589133/launchd/src/launch.h:23810-23822 /branches/PR-6609410/launchd/src/launch.h:23828 Property changes on: trunk/launchd/src/launch_internal.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5898404/launchd/src/liblaunch_internal.h:23681-23700 /branches/PR-5978442/launchd/src/liblaunch_internal.h:23651-23701 /branches/PR-6271234/launchd/src/launch_internal.h:23818-23822 /branches/PR-6562592/launchd/src/launch_internal.h:23812-23822 /branches/PR-6589133/launchd/src/launch_internal.h:23810-23822 + /branches/PR-5898404/launchd/src/liblaunch_internal.h:23681-23700 /branches/PR-5978442/launchd/src/liblaunch_internal.h:23651-23701 /branches/PR-6271234/launchd/src/launch_internal.h:23818-23822 /branches/PR-6562592/launchd/src/launch_internal.h:23812-23822 /branches/PR-6589133/launchd/src/launch_internal.h:23810-23822 /branches/PR-6609410/launchd/src/launch_internal.h:23828 Property changes on: trunk/launchd/src/launch_priv.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5898404/launchd/src/liblaunch_private.h:23681-23700 /branches/PR-5978442/launchd/src/liblaunch_private.h:23651-23701 /branches/PR-6271234/launchd/src/launch_priv.h:23818-23822 /branches/PR-6562592/launchd/src/launch_priv.h:23812-23822 /branches/PR-6589133/launchd/src/launch_priv.h:23810-23822 + /branches/PR-5898404/launchd/src/liblaunch_private.h:23681-23700 /branches/PR-5978442/launchd/src/liblaunch_private.h:23651-23701 /branches/PR-6271234/launchd/src/launch_priv.h:23818-23822 /branches/PR-6562592/launchd/src/launch_priv.h:23812-23822 /branches/PR-6589133/launchd/src/launch_priv.h:23810-23822 /branches/PR-6609410/launchd/src/launch_priv.h:23828 Modified: trunk/launchd/src/launchd.c =================================================================== --- trunk/launchd/src/launchd.c 2009-02-23 21:07:49 UTC (rev 23828) +++ trunk/launchd/src/launchd.c 2009-02-25 03:16:40 UTC (rev 23829) @@ -429,7 +429,7 @@ shutdown_in_progress = true; - if (pid1_magic) { + if( pid1_magic || g_log_per_user_shutdown ) { /* * When this changes to a more sustainable API, update this: * http://howto.apple.com/db.cgi?Debugging_Apps_Non-Responsive_At_Shutdown Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2009-02-23 21:07:49 UTC (rev 23828) +++ trunk/launchd/src/launchd_core_logic.c 2009-02-25 03:16:40 UTC (rev 23829) @@ -126,9 +126,10 @@ * it a SIGTERM, SIGKILL it. Can be overriden in the job plist. */ #define LAUNCHD_MIN_JOB_RUN_TIME 10 -#define LAUNCHD_SAMPLE_TIMEOUT 1 +#define LAUNCHD_SAMPLE_TIMEOUT 2 #define LAUNCHD_DEFAULT_EXIT_TIMEOUT 20 #define LAUNCHD_SIGKILL_TIMER 5 +#define LAUNCHD_CLEAN_KILL_TIMER 1 #define LAUNCHD_JETSAM_PRIORITY_UNSET 0xdead1eebabell #define SHUTDOWN_LOG_DIR "/var/log/shutdown" @@ -522,6 +523,7 @@ needs_kickoff :1, /* The job is to be kept alive continuously, but it must be initially kicked off. */ is_bootstrapper :1, /* The job is a bootstrapper. */ has_console :1, /* The job owns the console. */ + clean_exit_timer_expired :1, /* The job was clean, received SIGKILL and failed to exit after LAUNCHD_CLEAN_KILL_TIMER seconds. */ migratory :1; /* The (anonymous) job called vprocmgr_switch_to_session(). */ mode_t mask; pid_t tracing_pid; @@ -2996,8 +2998,8 @@ j->sent_sigkill = true; - job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, - EV_ADD, NOTE_SECONDS, LAUNCHD_SIGKILL_TIMER, j) != -1); + intptr_t timer = j->clean_kill ? LAUNCHD_CLEAN_KILL_TIMER : LAUNCHD_SIGKILL_TIMER; + job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, timer, j) != -1); job_log(j, LOG_DEBUG, "Sent SIGKILL signal"); } @@ -3212,6 +3214,16 @@ 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 seconds 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; + + jobmgr_do_garbage_collection(j->mgr); + return; + } + /* * This block might be executed up to 3 times for a given (slow) job * - once for the SAMPLE_TIMEOUT timer, at which point sampling is triggered @@ -5399,11 +5411,14 @@ /* If the job is active and we haven't told it to stop yet, stop it. */ job_stop(ji); - /* We may have sent SIGKILL to the job in job_stop(). In this case, - * "clean" jobs should exit immediately, so we shouldn't have to wait - * for them. + /* We may have sent SIGKILL to the job in job_stop(). Clean jobs + * get 1 second to exit. */ - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + if( !ji->clean_kill ) { + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else { + unkilled_cnt += ji->clean_exit_timer_expired ? 1 : 0; + } } else if( ji->stopped ) { /* If the job is active and has been told to stop, disregard it * after we've sent SIGKILL. @@ -5456,11 +5471,14 @@ /* If the job is active and we haven't told it to stop yet, stop it. */ job_stop(ji); - /* We may have sent SIGKILL to the job in job_stop(). In this case, - * "clean" jobs should exit immediately, so we shouldn't have to wait - * for them. + /* We may have sent SIGKILL to the job in job_stop(). Clean jobs + * get 1 second to exit. */ - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + if( !ji->clean_kill ) { + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else { + unkilled_cnt += ji->clean_exit_timer_expired ? 1 : 0; + } } else if( ji->stopped ) { /* If the job is active and has been told to stop, disregard it * after we've sent SIGKILL. @@ -5515,11 +5533,14 @@ /* If the job is active and we haven't told it to stop yet, stop it. */ job_stop(ji); - /* We may have sent SIGKILL to the job in job_stop(). In this case, - * "clean" jobs should exit immediately, so we shouldn't have to wait - * for them. + /* We may have sent SIGKILL to the job in job_stop(). Clean jobs + * get 1 second to exit. */ - unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + if( !ji->clean_kill ) { + unkilled_cnt += !ji->sent_sigkill ? 1 : 0; + } else { + unkilled_cnt += ji->clean_exit_timer_expired ? 1 : 0; + } } else if( ji->stopped ) { /* If the job is active and has been told to stop, disregard it * after we've sent SIGKILL. @@ -5558,7 +5579,7 @@ } if( !_jm && SLIST_EMPTY(&jm->submgrs) ) { - jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "Removing."); + jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Removing."); jobmgr_log_stray_children(jm, false); jobmgr_remove(jm); } else { Modified: trunk/launchd/src/launchd_runtime.c =================================================================== --- trunk/launchd/src/launchd_runtime.c 2009-02-23 21:07:49 UTC (rev 23828) +++ trunk/launchd/src/launchd_runtime.c 2009-02-25 03:16:40 UTC (rev 23829) @@ -133,6 +133,7 @@ bool g_flat_mach_namespace = true; bool g_simulate_pid1_crash = false; bool g_use_gmalloc = false; +bool g_log_per_user_shutdown = false; pid_t g_wsp = 0; mach_port_t @@ -1344,8 +1345,7 @@ offset = (void *)*outval; -#if 0 - if( !ourlogfile && !pid1_magic && shutdown_in_progress ) { + if( g_log_per_user_shutdown && !ourlogfile && !pid1_magic && shutdown_in_progress ) { char logfile[NAME_MAX]; snprintf(logfile, sizeof(logfile), "/var/tmp/launchd-%s.shutdown.log", g_username); @@ -1355,7 +1355,6 @@ rename(logfile, logfile1); ourlogfile = fopen(logfile, "a"); } -#endif static int64_t shutdown_start = 0; if( shutdown_start == 0 ) { @@ -1795,6 +1794,10 @@ g_force_old_kill_path = true; } + if( stat("/var/db/.launchd_log_per_user_shutdown", &sb) == 0 ) { + g_log_per_user_shutdown = true; + } + if( !pid1_magic && stat("/var/db/.launchd_no_flat_per_user_namespace", &sb) == 0 ) { g_flat_mach_namespace = false; } Modified: trunk/launchd/src/launchd_runtime.h =================================================================== --- trunk/launchd/src/launchd_runtime.h 2009-02-23 21:07:49 UTC (rev 23828) +++ trunk/launchd/src/launchd_runtime.h 2009-02-25 03:16:40 UTC (rev 23829) @@ -103,6 +103,7 @@ extern char g_username[128]; extern bool g_shutdown_debugging; extern bool g_use_gmalloc; +extern bool g_log_per_user_shutdown; extern pid_t g_wsp; mach_port_t runtime_get_kernel_port(void); Property changes on: trunk/launchd/src/protocol_vproc.defs ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5092682/launchd/src/protocol_job.defs:23731-23742 /branches/PR-5898404/launchd/src/protocol_job.defs:23681-23700 /branches/PR-5978442/launchd/src/protocol_job.defs:23651-23701 /branches/PR-6132016/launchd/src/protocol_job.defs:23719-23738 /branches/PR-6271234/launchd/src/protocol_vproc.defs:23818-23822 /branches/PR-6562592/launchd/src/protocol_vproc.defs:23812-23822 /branches/PR-6589133/launchd/src/protocol_vproc.defs:23810-23822 + /branches/PR-5092682/launchd/src/protocol_job.defs:23731-23742 /branches/PR-5898404/launchd/src/protocol_job.defs:23681-23700 /branches/PR-5978442/launchd/src/protocol_job.defs:23651-23701 /branches/PR-6132016/launchd/src/protocol_job.defs:23719-23738 /branches/PR-6271234/launchd/src/protocol_vproc.defs:23818-23822 /branches/PR-6562592/launchd/src/protocol_vproc.defs:23812-23822 /branches/PR-6589133/launchd/src/protocol_vproc.defs:23810-23822 /branches/PR-6609410/launchd/src/protocol_vproc.defs:23828 Property changes on: trunk/launchd/src/vproc.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5092682/launchd/src/libvproc_public.h:23731-23742 /branches/PR-5898404/launchd/src/libvproc_public.h:23681-23700 /branches/PR-5978442/launchd/src/libvproc_public.h:23651-23701 /branches/PR-6132016/launchd/src/libvproc_public.h:23719-23738 /branches/PR-6271234/launchd/src/vproc.h:23818-23822 /branches/PR-6562592/launchd/src/vproc.h:23812-23822 /branches/PR-6589133/launchd/src/vproc.h:23810-23822 + /branches/PR-5092682/launchd/src/libvproc_public.h:23731-23742 /branches/PR-5898404/launchd/src/libvproc_public.h:23681-23700 /branches/PR-5978442/launchd/src/libvproc_public.h:23651-23701 /branches/PR-6132016/launchd/src/libvproc_public.h:23719-23738 /branches/PR-6271234/launchd/src/vproc.h:23818-23822 /branches/PR-6562592/launchd/src/vproc.h:23812-23822 /branches/PR-6589133/launchd/src/vproc.h:23810-23822 /branches/PR-6609410/launchd/src/vproc.h:23828 Property changes on: trunk/launchd/src/vproc_internal.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5898404/launchd/src/libvproc_internal.h:23681-23700 /branches/PR-5978442/launchd/src/libvproc_internal.h:23651-23701 /branches/PR-6271234/launchd/src/vproc_internal.h:23818-23822 /branches/PR-6562592/launchd/src/vproc_internal.h:23812-23822 /branches/PR-6589133/launchd/src/vproc_internal.h:23810-23822 + /branches/PR-5898404/launchd/src/libvproc_internal.h:23681-23700 /branches/PR-5978442/launchd/src/libvproc_internal.h:23651-23701 /branches/PR-6271234/launchd/src/vproc_internal.h:23818-23822 /branches/PR-6562592/launchd/src/vproc_internal.h:23812-23822 /branches/PR-6589133/launchd/src/vproc_internal.h:23810-23822 /branches/PR-6609410/launchd/src/vproc_internal.h:23828 Property changes on: trunk/launchd/src/vproc_priv.h ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-5092682/launchd/src/libvproc_private.h:23731-23742 /branches/PR-5898404/launchd/src/libvproc_private.h:23681-23700 /branches/PR-5978442/launchd/src/libvproc_private.h:23651-23701 /branches/PR-6132016/launchd/src/libvproc_private.h:23719-23738 /branches/PR-6271234/launchd/src/vproc_priv.h:23818-23822 /branches/PR-6562592/launchd/src/vproc_priv.h:23812-23822 /branches/PR-6589133/launchd/src/vproc_priv.h:23810-23822 + /branches/PR-5092682/launchd/src/libvproc_private.h:23731-23742 /branches/PR-5898404/launchd/src/libvproc_private.h:23681-23700 /branches/PR-5978442/launchd/src/libvproc_private.h:23651-23701 /branches/PR-6132016/launchd/src/libvproc_private.h:23719-23738 /branches/PR-6271234/launchd/src/vproc_priv.h:23818-23822 /branches/PR-6562592/launchd/src/vproc_priv.h:23812-23822 /branches/PR-6589133/launchd/src/vproc_priv.h:23810-23822 /branches/PR-6609410/launchd/src/vproc_priv.h:23828 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Wed Feb 25 11:24:55 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Wed, 25 Feb 2009 11:24:55 -0800 (PST) Subject: [launchd-changes] [23830] tags/launchd-301/ Message-ID: <20090225192455.ED7751090275@beta.macosforge.org> Revision: 23830 http://trac.macosforge.org/projects/launchd/changeset/23830 Author: dsorresso at apple.com Date: 2009-02-25 11:24:54 -0800 (Wed, 25 Feb 2009) Log Message: ----------- "Tagging launchd-301 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- tags/launchd-301/ Property changes on: tags/launchd-301 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 /branches/PR-6271234:23818-23822 /branches/PR-6562592:23812-23822 /branches/PR-6589133:23810-23822 /branches/PR-6609410:23828 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Wed Feb 25 12:19:38 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Wed, 25 Feb 2009 12:19:38 -0800 (PST) Subject: [launchd-changes] [23831] branches/PR-6564965/ Message-ID: <20090225201938.D273E1092080@beta.macosforge.org> Revision: 23831 http://trac.macosforge.org/projects/launchd/changeset/23831 Author: dsorresso at apple.com Date: 2009-02-25 12:19:38 -0800 (Wed, 25 Feb 2009) Log Message: ----------- "Branch for PR-6564965 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- branches/PR-6564965/ Property changes on: branches/PR-6564965 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 /branches/PR-6271234:23818-23822 /branches/PR-6562592:23812-23822 /branches/PR-6589133:23810-23822 /branches/PR-6609410:23828 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Wed Feb 25 20:09:33 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Wed, 25 Feb 2009 20:09:33 -0800 (PST) Subject: [launchd-changes] [23832] branches/PR-6564965/launchd/src Message-ID: <20090226040934.4DA2E109BB41@beta.macosforge.org> Revision: 23832 http://trac.macosforge.org/projects/launchd/changeset/23832 Author: dsorresso at apple.com Date: 2009-02-25 20:09:33 -0800 (Wed, 25 Feb 2009) Log Message: ----------- Beginnings of changes. Modified Paths: -------------- branches/PR-6564965/launchd/src/launch_internal.h branches/PR-6564965/launchd/src/launchctl.c branches/PR-6564965/launchd/src/launchd.c branches/PR-6564965/launchd/src/launchd_core_logic.c Modified: branches/PR-6564965/launchd/src/launch_internal.h =================================================================== --- branches/PR-6564965/launchd/src/launch_internal.h 2009-02-25 20:19:38 UTC (rev 23831) +++ branches/PR-6564965/launchd/src/launch_internal.h 2009-02-26 04:09:33 UTC (rev 23832) @@ -22,6 +22,9 @@ #pragma GCC visibility push(default) +#define LAUNCHD_JOB_STATE_DB_PREFIX "/var/db/launchd_job_state_db" +extern char g_job_enabled_db[PATH_MAX]; + size_t launch_data_pack(launch_data_t d, void *where, size_t len, int *fd_where, size_t *fdslotsleft); launch_data_t launch_data_unpack(void *data, size_t data_size, int *fds, size_t fd_cnt, size_t *data_offset, size_t *fdoffset); Modified: branches/PR-6564965/launchd/src/launchctl.c =================================================================== --- branches/PR-6564965/launchd/src/launchctl.c 2009-02-25 20:19:38 UTC (rev 23831) +++ branches/PR-6564965/launchd/src/launchctl.c 2009-02-26 04:09:33 UTC (rev 23832) @@ -257,6 +257,8 @@ static bool rootuser_context; static bool g_shutdown_debugging = false; +char g_job_enabled_db[PATH_MAX]; + int main(int argc, char *const argv[]) { @@ -921,9 +923,17 @@ bool r = false; switch (launch_data_get_type(obj)) { - case LAUNCH_DATA_DICTIONARY: - launch_data_dict_iterate(obj, job_disabled_dict_logic, &r); + case LAUNCH_DATA_DICTIONARY: { + launch_data_t label = NULL; + if( (label = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_LABEL)) && launch_data_get_type(label) == LAUNCH_DATA_STRING ) { + char db_path[PATH_MAX]; + + } else { + launch_data_dict_iterate(obj, job_disabled_dict_logic, &r); + } + break; + } case LAUNCH_DATA_BOOL: r = launch_data_get_bool(obj); break; Modified: branches/PR-6564965/launchd/src/launchd.c =================================================================== --- branches/PR-6564965/launchd/src/launchd.c 2009-02-25 20:19:38 UTC (rev 23831) +++ branches/PR-6564965/launchd/src/launchd.c 2009-02-26 04:09:33 UTC (rev 23832) @@ -116,6 +116,7 @@ bool fake_shutdown_in_progress; bool network_up; char g_username[128] = "__Uninitialized__"; +char g_job_enabled_db[PATH_MAX]; FILE *g_console = NULL; int @@ -187,6 +188,7 @@ strlcpy(g_username, pwent->pw_name, sizeof(g_username) - 1); } + snprintf(g_job_enabled_db, sizeof(g_job_enabled_db), "/var/db/launch_job_state_db/com.apple.launchd.peruser.%u", getuid()); runtime_syslog(LOG_DEBUG, "Per-user launchd for UID %u (%s) has begun.", getuid(), g_username); } @@ -195,12 +197,8 @@ if( g_use_gmalloc ) { runtime_syslog(LOG_NOTICE | LOG_CONSOLE, "*** Using libgmalloc ***"); } - - struct stat sb; - if( stat("/var/db/.launchd_flat_per_user_namespace", &sb) == 0 ) { - runtime_syslog(LOG_NOTICE | LOG_CONSOLE, "Flat per-user Mach namespaces enabled."); - } - /* We just wanted to print status about the per-user namespace. PID 1 doesn't have a flat namespace. */ + + /* PID 1 doesn't have a flat namespace. */ g_flat_mach_namespace = false; } @@ -404,6 +402,12 @@ launchd_assumes(setsid() != -1); launchd_assumes(chdir("/") != -1); launchd_assumes(setlogin("root") != -1); + + strcpy(g_job_enabled_db, "/var/db/launchd_job_state_db/com.apple.launchd"); + struct stat sb; + if( stat(g_job_enabled_db, &sb) == -1 ) { + launchd_assumes(mkdir(g_job_enabled_db, S_IRWXO) != -1); + } } Modified: branches/PR-6564965/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-25 20:19:38 UTC (rev 23831) +++ branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-26 04:09:33 UTC (rev 23832) @@ -7271,6 +7271,15 @@ ji->per_user = true; ji->kill_via_shmem = true; + struct stat sb; + char pu_db[PATH_MAX]; + snprintf(pu_db, sizeof(pu_db), "/var/db/launchd_job_state_db/%s", lbuf); + + if( stat(pu_db, &sb) == -1 && job_assumes(ji, errno == ENOENT) ) { + job_assumes(ji, mkdir(pu_db, S_IRWXO) != -1); + job_assumes(ji, chown(pu_db, which_user, 0) != -1); + } + if ((ms = machservice_new(ji, lbuf, mp, false)) == NULL) { job_remove(ji); ji = NULL; -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 11:09:11 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 11:09:11 -0800 (PST) Subject: [launchd-changes] [23833] branches/PR-6564965/launchd/src Message-ID: <20090226190911.AFFF810ACAA9@beta.macosforge.org> Revision: 23833 http://trac.macosforge.org/projects/launchd/changeset/23833 Author: dsorresso at apple.com Date: 2009-02-26 11:09:11 -0800 (Thu, 26 Feb 2009) Log Message: ----------- More incremental steps. Modified Paths: -------------- branches/PR-6564965/launchd/src/launchctl.c branches/PR-6564965/launchd/src/launchd.c branches/PR-6564965/launchd/src/launchd_core_logic.c branches/PR-6564965/launchd/src/vproc_priv.h Modified: branches/PR-6564965/launchd/src/launchctl.c =================================================================== --- branches/PR-6564965/launchd/src/launchctl.c 2009-02-26 04:09:33 UTC (rev 23832) +++ branches/PR-6564965/launchd/src/launchctl.c 2009-02-26 19:09:11 UTC (rev 23833) @@ -336,6 +336,16 @@ } } + char *db = NULL; + vproc_err_t verr = vproc_swap_string(NULL, VPROC_GSK_JOB_ENABLED_DB, NULL, &db); + if( verr ) { + fprintf(stderr, "Could not get location of job state database.\n"); + g_job_enabled_db[0] = 0; + } else { + strncpy(g_job_enabled_db, db, strlen(db)); + free(db); + } + if (NULL == readline) { fprintf(stderr, "missing library: readline\n"); exit(EXIT_FAILURE); @@ -926,12 +936,24 @@ case LAUNCH_DATA_DICTIONARY: { launch_data_t label = NULL; if( (label = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_LABEL)) && launch_data_get_type(label) == LAUNCH_DATA_STRING ) { - char db_path[PATH_MAX]; + bool disabled = false; + launch_data_t disabled_data = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_DISABLED); + if( disabled_data && launch_data_get_type(disabled_data) == LAUNCH_DATA_BOOL ) { + disabled = launch_data_get_bool(disabled_data); + } + + if( disabled && g_job_enabled_db[0] != 0 ) { + char path[PATH_MAX]; + snprintf(path, sizeof(path), "%s/%s", g_job_enabled_db, launch_data_get_string(label)); + + struct stat sb; + r = stat(path, &sb) == -1; + } } else { launch_data_dict_iterate(obj, job_disabled_dict_logic, &r); } - + break; } case LAUNCH_DATA_BOOL: Modified: branches/PR-6564965/launchd/src/launchd.c =================================================================== --- branches/PR-6564965/launchd/src/launchd.c 2009-02-26 04:09:33 UTC (rev 23832) +++ branches/PR-6564965/launchd/src/launchd.c 2009-02-26 19:09:11 UTC (rev 23833) @@ -188,7 +188,7 @@ strlcpy(g_username, pwent->pw_name, sizeof(g_username) - 1); } - snprintf(g_job_enabled_db, sizeof(g_job_enabled_db), "/var/db/launch_job_state_db/com.apple.launchd.peruser.%u", getuid()); + snprintf(g_job_enabled_db, sizeof(g_job_enabled_db), LAUNCHD_JOB_STATE_DB_PREFIX "/com.apple.launchd.peruser.%u", getuid()); runtime_syslog(LOG_DEBUG, "Per-user launchd for UID %u (%s) has begun.", getuid(), g_username); } @@ -403,7 +403,7 @@ launchd_assumes(chdir("/") != -1); launchd_assumes(setlogin("root") != -1); - strcpy(g_job_enabled_db, "/var/db/launchd_job_state_db/com.apple.launchd"); + strcpy(g_job_enabled_db, LAUNCHD_JOB_STATE_DB_PREFIX "/com.apple.launchd"); struct stat sb; if( stat(g_job_enabled_db, &sb) == -1 ) { launchd_assumes(mkdir(g_job_enabled_db, S_IRWXO) != -1); Modified: branches/PR-6564965/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-26 04:09:33 UTC (rev 23832) +++ branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-26 19:09:11 UTC (rev 23833) @@ -6860,6 +6860,16 @@ launch_data_free(output_obj); break; + case VPROC_GSK_JOB_ENABLED_DB: + if( !g_job_enabled_db || (g_job_enabled_db && !(output_obj = launch_data_new_string(g_job_enabled_db))) ) { + goto out_bad; + } + packed_size = launch_data_pack(output_obj, (void *)*outval, *outvalCnt, NULL, NULL); + if (!job_assumes(j, packed_size != 0)) { + goto out_bad; + } + + launch_data_free(output_obj); case 0: mig_deallocate(*outval, *outvalCnt); *outval = 0; @@ -7273,7 +7283,7 @@ struct stat sb; char pu_db[PATH_MAX]; - snprintf(pu_db, sizeof(pu_db), "/var/db/launchd_job_state_db/%s", lbuf); + snprintf(pu_db, sizeof(pu_db), LAUNCHD_JOB_STATE_DB_PREFIX "/%s", lbuf); if( stat(pu_db, &sb) == -1 && job_assumes(ji, errno == ENOENT) ) { job_assumes(ji, mkdir(pu_db, S_IRWXO) != -1); Modified: branches/PR-6564965/launchd/src/vproc_priv.h =================================================================== --- branches/PR-6564965/launchd/src/vproc_priv.h 2009-02-26 04:09:33 UTC (rev 23832) +++ branches/PR-6564965/launchd/src/vproc_priv.h 2009-02-26 19:09:11 UTC (rev 23833) @@ -64,6 +64,7 @@ VPROC_GSK_SHUTDOWN_DEBUGGING, VPROC_GSK_PERUSER_SUSPEND, VPROC_GSK_PERUSER_RESUME, + VPROC_GSK_JOB_ENABLED_DB, } vproc_gsk_t; typedef unsigned int vproc_flags_t; -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 11:12:16 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 11:12:16 -0800 (PST) Subject: [launchd-changes] [23834] branches/PR-6623625/ Message-ID: <20090226191216.D793110ACE04@beta.macosforge.org> Revision: 23834 http://trac.macosforge.org/projects/launchd/changeset/23834 Author: dsorresso at apple.com Date: 2009-02-26 11:12:16 -0800 (Thu, 26 Feb 2009) Log Message: ----------- "Branch for PR-6623625 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- branches/PR-6623625/ Property changes on: branches/PR-6623625 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 /branches/PR-6271234:23818-23822 /branches/PR-6562592:23812-23822 /branches/PR-6589133:23810-23822 /branches/PR-6609410:23828 -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 15:32:14 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 15:32:14 -0800 (PST) Subject: [launchd-changes] [23835] branches/PR-6564965/launchd/src Message-ID: <20090226233215.4B5EF10BEF1C@beta.macosforge.org> Revision: 23835 http://trac.macosforge.org/projects/launchd/changeset/23835 Author: dsorresso at apple.com Date: 2009-02-26 15:32:14 -0800 (Thu, 26 Feb 2009) Log Message: ----------- Changed to using plists for databases. Modified Paths: -------------- branches/PR-6564965/launchd/src/launch_internal.h branches/PR-6564965/launchd/src/launchctl.c branches/PR-6564965/launchd/src/launchd.c branches/PR-6564965/launchd/src/launchd.h branches/PR-6564965/launchd/src/launchd_core_logic.c Modified: branches/PR-6564965/launchd/src/launch_internal.h =================================================================== --- branches/PR-6564965/launchd/src/launch_internal.h 2009-02-26 19:12:16 UTC (rev 23834) +++ branches/PR-6564965/launchd/src/launch_internal.h 2009-02-26 23:32:14 UTC (rev 23835) @@ -22,9 +22,6 @@ #pragma GCC visibility push(default) -#define LAUNCHD_JOB_STATE_DB_PREFIX "/var/db/launchd_job_state_db" -extern char g_job_enabled_db[PATH_MAX]; - size_t launch_data_pack(launch_data_t d, void *where, size_t len, int *fd_where, size_t *fdslotsleft); launch_data_t launch_data_unpack(void *data, size_t data_size, int *fds, size_t fd_cnt, size_t *data_offset, size_t *fdoffset); Modified: branches/PR-6564965/launchd/src/launchctl.c =================================================================== --- branches/PR-6564965/launchd/src/launchctl.c 2009-02-26 19:12:16 UTC (rev 23834) +++ branches/PR-6564965/launchd/src/launchctl.c 2009-02-26 23:32:14 UTC (rev 23835) @@ -113,6 +113,7 @@ }; static void myCFDictionaryApplyFunction(const void *key, const void *value, void *context); +static void job_override(CFTypeRef key, CFTypeRef val, CFMutableDictionaryRef job); static CFTypeRef CFTypeCreateFromLaunchData(launch_data_t obj); static CFArrayRef CFArrayCreateFromLaunchArray(launch_data_t arr); static CFDictionaryRef CFDictionaryCreateFromLaunchDictionary(launch_data_t dict); @@ -257,7 +258,8 @@ static bool rootuser_context; static bool g_shutdown_debugging = false; -char g_job_enabled_db[PATH_MAX]; +char g_job_overrides_db_path[PATH_MAX]; +CFDictionaryRef g_job_overrides_db = NULL; int main(int argc, char *const argv[]) @@ -340,10 +342,12 @@ vproc_err_t verr = vproc_swap_string(NULL, VPROC_GSK_JOB_ENABLED_DB, NULL, &db); if( verr ) { fprintf(stderr, "Could not get location of job state database.\n"); - g_job_enabled_db[0] = 0; + g_job_overrides_db_path[0] = 0; } else { - strncpy(g_job_enabled_db, db, strlen(db)); + strncpy(g_job_overrides_db_path, db, strlen(db)); free(db); + + g_job_overrides_db = (CFDictionaryRef)CreateMyPropertyListFromFile(g_job_overrides_db_path); } if (NULL == readline) { @@ -702,6 +706,21 @@ } } +void +job_override(CFTypeRef key, CFTypeRef val, CFMutableDictionaryRef job) +{ + if( CFGetTypeID(key) != CFStringGetTypeID() ) { + return; + } + if( CFStringCompare(key, CFSTR(LAUNCH_JOBKEY_LABEL), kCFCompareCaseInsensitive) == 0 ) { + return; + } + + fprintf(stdout, "Overriding %s in %s...\n", CFStringGetCStringPtr(key, kCFStringEncodingUTF8), CFStringGetCStringPtr(CFDictionaryGetValue(job, CFSTR(LAUNCH_JOBKEY_LABEL)), kCFStringEncodingUTF8)); + + CFDictionarySetValue(job, key, val); +} + launch_data_t read_plist_file(const char *file, bool editondisk, bool load) { @@ -713,6 +732,14 @@ return NULL; } + CFStringRef label = CFDictionaryGetValue(plist, CFSTR(LAUNCH_JOBKEY_LABEL)); + if( label && CFGetTypeID(label) == CFStringGetTypeID() ) { + CFDictionaryRef overrides = CFDictionaryGetValue(g_job_overrides_db, label); + if( overrides ) { + CFDictionaryApplyFunction(overrides, (CFDictionaryApplierFunction)job_override, (void *)plist); + } + } + if (editondisk) { if (load) { CFDictionaryRemoveValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED)); @@ -931,38 +958,18 @@ job_disabled_logic(launch_data_t obj) { bool r = false; - + switch (launch_data_get_type(obj)) { - case LAUNCH_DATA_DICTIONARY: { - launch_data_t label = NULL; - if( (label = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_LABEL)) && launch_data_get_type(label) == LAUNCH_DATA_STRING ) { - bool disabled = false; - launch_data_t disabled_data = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_DISABLED); - - if( disabled_data && launch_data_get_type(disabled_data) == LAUNCH_DATA_BOOL ) { - disabled = launch_data_get_bool(disabled_data); - } - - if( disabled && g_job_enabled_db[0] != 0 ) { - char path[PATH_MAX]; - snprintf(path, sizeof(path), "%s/%s", g_job_enabled_db, launch_data_get_string(label)); - - struct stat sb; - r = stat(path, &sb) == -1; - } - } else { + case LAUNCH_DATA_DICTIONARY: launch_data_dict_iterate(obj, job_disabled_dict_logic, &r); - } - - break; + break; + case LAUNCH_DATA_BOOL: + r = launch_data_get_bool(obj); + break; + default: + break; } - case LAUNCH_DATA_BOOL: - r = launch_data_get_bool(obj); - break; - default: - break; - } - + return r; } Modified: branches/PR-6564965/launchd/src/launchd.c =================================================================== --- branches/PR-6564965/launchd/src/launchd.c 2009-02-26 19:12:16 UTC (rev 23834) +++ branches/PR-6564965/launchd/src/launchd.c 2009-02-26 23:32:14 UTC (rev 23835) @@ -116,7 +116,7 @@ bool fake_shutdown_in_progress; bool network_up; char g_username[128] = "__Uninitialized__"; -char g_job_enabled_db[PATH_MAX]; +char g_job_overrides_db_path[PATH_MAX]; FILE *g_console = NULL; int @@ -188,7 +188,7 @@ strlcpy(g_username, pwent->pw_name, sizeof(g_username) - 1); } - snprintf(g_job_enabled_db, sizeof(g_job_enabled_db), LAUNCHD_JOB_STATE_DB_PREFIX "/com.apple.launchd.peruser.%u", getuid()); + snprintf(g_job_overrides_db_path, sizeof(g_job_overrides_db_path), LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/com.apple.launchd.peruser.%u/overrides.plist", getuid()); runtime_syslog(LOG_DEBUG, "Per-user launchd for UID %u (%s) has begun.", getuid(), g_username); } @@ -403,10 +403,10 @@ launchd_assumes(chdir("/") != -1); launchd_assumes(setlogin("root") != -1); - strcpy(g_job_enabled_db, LAUNCHD_JOB_STATE_DB_PREFIX "/com.apple.launchd"); + strcpy(g_job_overrides_db_path, LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/com.apple.launchd/overrides.plist"); struct stat sb; - if( stat(g_job_enabled_db, &sb) == -1 ) { - launchd_assumes(mkdir(g_job_enabled_db, S_IRWXO) != -1); + if( stat(g_job_overrides_db_path, &sb) == -1 && launchd_assumes(errno == ENOENT) ) { + launchd_assumes(mkdir(g_job_overrides_db_path, S_IRWXO) != -1); } } Modified: branches/PR-6564965/launchd/src/launchd.h =================================================================== --- branches/PR-6564965/launchd/src/launchd.h 2009-02-26 19:12:16 UTC (rev 23834) +++ branches/PR-6564965/launchd/src/launchd.h 2009-02-26 23:32:14 UTC (rev 23835) @@ -26,6 +26,8 @@ #include "bootstrap.h" #include "launchd_runtime.h" +#define LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/var/db/launchd_job_overrides" + struct kevent; struct conncb; @@ -35,6 +37,7 @@ extern bool g_force_old_kill_path; extern bool g_simulate_pid1_crash; extern FILE *g_console; +extern char g_job_overrides_db_path[PATH_MAX]; bool init_check_pid(pid_t); Modified: branches/PR-6564965/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-26 19:12:16 UTC (rev 23834) +++ branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-26 23:32:14 UTC (rev 23835) @@ -3216,7 +3216,7 @@ } if( j->clean_kill ) { - job_log(j, LOG_DEBUG | LOG_CONSOLE, "Clean job failed to exit %u seconds after receiving SIGKILL.", LAUNCHD_CLEAN_KILL_TIMER); + job_log(j, LOG_DEBUG | 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; @@ -3241,7 +3241,7 @@ uint64_t td = runtime_get_nanoseconds_since(j->sent_signal_time); td /= NSEC_PER_SEC; - td -= j->exit_timeout; + td -= j->clean_kill ? 0 : j->exit_timeout; job_log(j, LOG_WARNING | LOG_CONSOLE, "Did not die after sending SIGKILL %llu seconds ago...", td); } else if( should_enqueue && (!j->exit_timeout || (LAUNCHD_SAMPLE_TIMEOUT < j->exit_timeout)) ) { @@ -5406,7 +5406,7 @@ continue; } - bool active = job_active(ji); + bool active = ji->p; if( active && !ji->stopped ) { /* If the job is active and we haven't told it to stop yet, stop it. */ job_stop(ji); @@ -5466,7 +5466,7 @@ continue; } - bool active = job_active(ji); + bool active = ji->p; if( active && !ji->stopped ) { /* If the job is active and we haven't told it to stop yet, stop it. */ job_stop(ji); @@ -5528,7 +5528,7 @@ continue; } - bool active = job_active(ji); + bool active = ji->p; if( active && !ji->stopped ) { /* If the job is active and we haven't told it to stop yet, stop it. */ job_stop(ji); @@ -6861,7 +6861,7 @@ launch_data_free(output_obj); break; case VPROC_GSK_JOB_ENABLED_DB: - if( !g_job_enabled_db || (g_job_enabled_db && !(output_obj = launch_data_new_string(g_job_enabled_db))) ) { + if( !(output_obj = launch_data_new_string(g_job_overrides_db_path)) ) { goto out_bad; } packed_size = launch_data_pack(output_obj, (void *)*outval, *outvalCnt, NULL, NULL); @@ -7078,45 +7078,45 @@ g_shutdown_debugging = true; } break; - case VPROC_GSK_PERUSER_SUSPEND: - if( pid1_magic && ldc->euid == 0 ) { - mach_port_t junk = MACH_PORT_NULL; - job_t jpu = jobmgr_lookup_per_user_context_internal(j, (uid_t)inval, false, &junk); - if( jpu ) { - job_t ji = NULL; - LIST_FOREACH( ji, &j->suspended_perusers, suspended_peruser_sle ) { - if( (int64_t)(ji->mach_uid) == inval ) { - job_log(j, LOG_WARNING, "Job tried to suspend per-user launchd for UID %u twice.", ji->mach_uid); - break; - } - } - - if( ji == NULL ) { - jpu->peruser_suspend_count++; - LIST_INSERT_HEAD(&j->suspended_perusers, jpu, suspended_peruser_sle); - job_stop(jpu); - } - } - } - break; - case VPROC_GSK_PERUSER_RESUME: - if( pid1_magic && ldc->euid == 0 ) { - job_t ji = NULL, jt = NULL; - LIST_FOREACH_SAFE( ji, &j->suspended_perusers, suspended_peruser_sle, jt ) { + case VPROC_GSK_PERUSER_SUSPEND: + if( pid1_magic && ldc->euid == 0 ) { + mach_port_t junk = MACH_PORT_NULL; + job_t jpu = jobmgr_lookup_per_user_context_internal(j, (uid_t)inval, false, &junk); + if( jpu ) { + job_t ji = NULL; + LIST_FOREACH( ji, &j->suspended_perusers, suspended_peruser_sle ) { if( (int64_t)(ji->mach_uid) == inval ) { - ji->peruser_suspend_count--; - LIST_REMOVE(ji, suspended_peruser_sle); + job_log(j, LOG_WARNING, "Job tried to suspend per-user launchd for UID %u twice.", ji->mach_uid); break; } } if( ji == NULL ) { - job_log(j, LOG_WARNING, "Job tried to resume per-user launchd for UID %llu that it did not suspend.", inval); - } else if( ji->peruser_suspend_count == 0 ) { - job_dispatch(ji, false); + jpu->peruser_suspend_count++; + LIST_INSERT_HEAD(&j->suspended_perusers, jpu, suspended_peruser_sle); + job_stop(jpu); } } - break; + } + break; + case VPROC_GSK_PERUSER_RESUME: + if( pid1_magic && ldc->euid == 0 ) { + job_t ji = NULL, jt = NULL; + LIST_FOREACH_SAFE( ji, &j->suspended_perusers, suspended_peruser_sle, jt ) { + if( (int64_t)(ji->mach_uid) == inval ) { + ji->peruser_suspend_count--; + LIST_REMOVE(ji, suspended_peruser_sle); + break; + } + } + + if( ji == NULL ) { + job_log(j, LOG_WARNING, "Job tried to resume per-user launchd for UID %llu that it did not suspend.", inval); + } else if( ji->peruser_suspend_count == 0 ) { + job_dispatch(ji, false); + } + } + break; case 0: break; default: @@ -7283,7 +7283,7 @@ struct stat sb; char pu_db[PATH_MAX]; - snprintf(pu_db, sizeof(pu_db), LAUNCHD_JOB_STATE_DB_PREFIX "/%s", lbuf); + snprintf(pu_db, sizeof(pu_db), LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/%s", lbuf); if( stat(pu_db, &sb) == -1 && job_assumes(ji, errno == ENOENT) ) { job_assumes(ji, mkdir(pu_db, S_IRWXO) != -1); -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 15:50:12 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 15:50:12 -0800 (PST) Subject: [launchd-changes] [23836] branches/PR-6564965/launchd/src Message-ID: <20090226235013.2BE0710BF501@beta.macosforge.org> Revision: 23836 http://trac.macosforge.org/projects/launchd/changeset/23836 Author: dsorresso at apple.com Date: 2009-02-26 15:50:12 -0800 (Thu, 26 Feb 2009) Log Message: ----------- Bug fixes. Modified Paths: -------------- branches/PR-6564965/launchd/src/launchctl.c branches/PR-6564965/launchd/src/launchd.c branches/PR-6564965/launchd/src/launchd_core_logic.c branches/PR-6564965/launchd/src/vproc_priv.h Modified: branches/PR-6564965/launchd/src/launchctl.c =================================================================== --- branches/PR-6564965/launchd/src/launchctl.c 2009-02-26 23:32:14 UTC (rev 23835) +++ branches/PR-6564965/launchd/src/launchctl.c 2009-02-26 23:50:12 UTC (rev 23836) @@ -339,7 +339,7 @@ } char *db = NULL; - vproc_err_t verr = vproc_swap_string(NULL, VPROC_GSK_JOB_ENABLED_DB, NULL, &db); + vproc_err_t verr = vproc_swap_string(NULL, VPROC_GSK_JOB_OVERRIDES_DB, NULL, &db); if( verr ) { fprintf(stderr, "Could not get location of job state database.\n"); g_job_overrides_db_path[0] = 0; @@ -733,7 +733,7 @@ } CFStringRef label = CFDictionaryGetValue(plist, CFSTR(LAUNCH_JOBKEY_LABEL)); - if( label && CFGetTypeID(label) == CFStringGetTypeID() ) { + if( g_job_overrides_db && label && CFGetTypeID(label) == CFStringGetTypeID() ) { CFDictionaryRef overrides = CFDictionaryGetValue(g_job_overrides_db, label); if( overrides ) { CFDictionaryApplyFunction(overrides, (CFDictionaryApplierFunction)job_override, (void *)plist); Modified: branches/PR-6564965/launchd/src/launchd.c =================================================================== --- branches/PR-6564965/launchd/src/launchd.c 2009-02-26 23:32:14 UTC (rev 23835) +++ branches/PR-6564965/launchd/src/launchd.c 2009-02-26 23:50:12 UTC (rev 23836) @@ -405,7 +405,7 @@ strcpy(g_job_overrides_db_path, LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/com.apple.launchd/overrides.plist"); struct stat sb; - if( stat(g_job_overrides_db_path, &sb) == -1 && launchd_assumes(errno == ENOENT) ) { + if( stat(dirname(g_job_overrides_db_path), &sb) == -1 && launchd_assumes(errno == ENOENT) ) { launchd_assumes(mkdir(g_job_overrides_db_path, S_IRWXO) != -1); } } Modified: branches/PR-6564965/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-26 23:32:14 UTC (rev 23835) +++ branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-26 23:50:12 UTC (rev 23836) @@ -6860,8 +6860,8 @@ launch_data_free(output_obj); break; - case VPROC_GSK_JOB_ENABLED_DB: - if( !(output_obj = launch_data_new_string(g_job_overrides_db_path)) ) { + case VPROC_GSK_JOB_OVERRIDES_DB: + if( !job_assumes(j, (output_obj = launch_data_new_string(g_job_overrides_db_path)) != NULL) ) { goto out_bad; } packed_size = launch_data_pack(output_obj, (void *)*outval, *outvalCnt, NULL, NULL); Modified: branches/PR-6564965/launchd/src/vproc_priv.h =================================================================== --- branches/PR-6564965/launchd/src/vproc_priv.h 2009-02-26 23:32:14 UTC (rev 23835) +++ branches/PR-6564965/launchd/src/vproc_priv.h 2009-02-26 23:50:12 UTC (rev 23836) @@ -64,7 +64,7 @@ VPROC_GSK_SHUTDOWN_DEBUGGING, VPROC_GSK_PERUSER_SUSPEND, VPROC_GSK_PERUSER_RESUME, - VPROC_GSK_JOB_ENABLED_DB, + VPROC_GSK_JOB_OVERRIDES_DB, } vproc_gsk_t; typedef unsigned int vproc_flags_t; -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 15:51:56 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 15:51:56 -0800 (PST) Subject: [launchd-changes] [23837] branches/PR-6564965/launchd/src/launchd.c Message-ID: <20090226235156.A409D10BF5B4@beta.macosforge.org> Revision: 23837 http://trac.macosforge.org/projects/launchd/changeset/23837 Author: dsorresso at apple.com Date: 2009-02-26 15:51:55 -0800 (Thu, 26 Feb 2009) Log Message: ----------- More bug fixing. Modified Paths: -------------- branches/PR-6564965/launchd/src/launchd.c Modified: branches/PR-6564965/launchd/src/launchd.c =================================================================== --- branches/PR-6564965/launchd/src/launchd.c 2009-02-26 23:50:12 UTC (rev 23836) +++ branches/PR-6564965/launchd/src/launchd.c 2009-02-26 23:51:55 UTC (rev 23837) @@ -406,7 +406,7 @@ strcpy(g_job_overrides_db_path, LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/com.apple.launchd/overrides.plist"); struct stat sb; if( stat(dirname(g_job_overrides_db_path), &sb) == -1 && launchd_assumes(errno == ENOENT) ) { - launchd_assumes(mkdir(g_job_overrides_db_path, S_IRWXO) != -1); + launchd_assumes(mkdir(dirname(g_job_overrides_db_path), S_IRWXO) != -1); } } -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 15:58:23 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 15:58:23 -0800 (PST) Subject: [launchd-changes] [23838] branches/PR-6564965/launchd/src/launchd.c Message-ID: <20090226235823.29BE010BF833@beta.macosforge.org> Revision: 23838 http://trac.macosforge.org/projects/launchd/changeset/23838 Author: dsorresso at apple.com Date: 2009-02-26 15:58:22 -0800 (Thu, 26 Feb 2009) Log Message: ----------- More debugging. Modified Paths: -------------- branches/PR-6564965/launchd/src/launchd.c Modified: branches/PR-6564965/launchd/src/launchd.c =================================================================== --- branches/PR-6564965/launchd/src/launchd.c 2009-02-26 23:51:55 UTC (rev 23837) +++ branches/PR-6564965/launchd/src/launchd.c 2009-02-26 23:58:22 UTC (rev 23838) @@ -403,8 +403,12 @@ launchd_assumes(chdir("/") != -1); launchd_assumes(setlogin("root") != -1); + struct stat sb; + if( stat(LAUNCHD_JOB_OVERRIDES_DB_PREFIX, &sb) == -1 && launchd_assumes(errno == ENOENT) ) { + launchd_assumes(mkdir(LAUNCHD_JOB_OVERRIDES_DB_PREFIX, S_IRWXO) != -1); + } + strcpy(g_job_overrides_db_path, LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/com.apple.launchd/overrides.plist"); - struct stat sb; if( stat(dirname(g_job_overrides_db_path), &sb) == -1 && launchd_assumes(errno == ENOENT) ) { launchd_assumes(mkdir(dirname(g_job_overrides_db_path), S_IRWXO) != -1); } -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 16:28:06 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 16:28:06 -0800 (PST) Subject: [launchd-changes] [23839] branches/PR-6564965/launchd/src Message-ID: <20090227002807.1D67610C05EA@beta.macosforge.org> Revision: 23839 http://trac.macosforge.org/projects/launchd/changeset/23839 Author: dsorresso at apple.com Date: 2009-02-26 16:28:06 -0800 (Thu, 26 Feb 2009) Log Message: ----------- More progress. Modified Paths: -------------- branches/PR-6564965/launchd/src/launch_internal.h branches/PR-6564965/launchd/src/launchctl.c branches/PR-6564965/launchd/src/launchd.c branches/PR-6564965/launchd/src/launchd.h branches/PR-6564965/launchd/src/launchd_core_logic.c branches/PR-6564965/launchd/src/libvproc.c Modified: branches/PR-6564965/launchd/src/launch_internal.h =================================================================== --- branches/PR-6564965/launchd/src/launch_internal.h 2009-02-26 23:58:22 UTC (rev 23838) +++ branches/PR-6564965/launchd/src/launch_internal.h 2009-02-27 00:28:06 UTC (rev 23839) @@ -22,6 +22,8 @@ #pragma GCC visibility push(default) +#define LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/var/db/launchd_job_overrides" + size_t launch_data_pack(launch_data_t d, void *where, size_t len, int *fd_where, size_t *fdslotsleft); launch_data_t launch_data_unpack(void *data, size_t data_size, int *fds, size_t fd_cnt, size_t *data_offset, size_t *fdoffset); Modified: branches/PR-6564965/launchd/src/launchctl.c =================================================================== --- branches/PR-6564965/launchd/src/launchctl.c 2009-02-26 23:58:22 UTC (rev 23838) +++ branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 00:28:06 UTC (rev 23839) @@ -28,6 +28,7 @@ #include "vproc_priv.h" #include "vproc_internal.h" #include "bootstrap_priv.h" +#include "launch_internal.h" #include #include @@ -2979,7 +2980,7 @@ CFTypeRef value = NULL; do { io_registry_entry_t entry = IORegistryEntryFromPath(kIOMasterPortDefault, "IODeviceTree:/options"); - if( assumes(entry == IO_OBJECT_NULL) ) { + if( assumes(entry != IO_OBJECT_NULL) ) { break; } @@ -3581,6 +3582,7 @@ { _PATH_TMP, 0, 0, S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO, S_ISUID|S_ISGID, true }, { _PATH_VARTMP, 0, 0, S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO, S_ISUID|S_ISGID, true }, { "/var/folders", 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, S_ISUID | S_ISGID, true }, + { LAUNCHD_JOB_OVERRIDES_DB_PREFIX, 0, 0, S_IRWXO, S_IRWXG | S_IRWXU, true } }; struct stat sb; size_t i; Modified: branches/PR-6564965/launchd/src/launchd.c =================================================================== --- branches/PR-6564965/launchd/src/launchd.c 2009-02-26 23:58:22 UTC (rev 23838) +++ branches/PR-6564965/launchd/src/launchd.c 2009-02-27 00:28:06 UTC (rev 23839) @@ -80,6 +80,7 @@ #include "vproc_priv.h" #include "vproc_internal.h" #include "launch.h" +#include "launch_internal.h" #include "launchd_runtime.h" #include "launchd_core_logic.h" @@ -188,7 +189,7 @@ strlcpy(g_username, pwent->pw_name, sizeof(g_username) - 1); } - snprintf(g_job_overrides_db_path, sizeof(g_job_overrides_db_path), LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/com.apple.launchd.peruser.%u/overrides.plist", getuid()); + snprintf(g_job_overrides_db_path, sizeof(g_job_overrides_db_path), LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/com.apple.launchd.peruser.%u.overrides.plist", getuid()); runtime_syslog(LOG_DEBUG, "Per-user launchd for UID %u (%s) has begun.", getuid(), g_username); } @@ -403,15 +404,7 @@ launchd_assumes(chdir("/") != -1); launchd_assumes(setlogin("root") != -1); - struct stat sb; - if( stat(LAUNCHD_JOB_OVERRIDES_DB_PREFIX, &sb) == -1 && launchd_assumes(errno == ENOENT) ) { - launchd_assumes(mkdir(LAUNCHD_JOB_OVERRIDES_DB_PREFIX, S_IRWXO) != -1); - } - - strcpy(g_job_overrides_db_path, LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/com.apple.launchd/overrides.plist"); - if( stat(dirname(g_job_overrides_db_path), &sb) == -1 && launchd_assumes(errno == ENOENT) ) { - launchd_assumes(mkdir(dirname(g_job_overrides_db_path), S_IRWXO) != -1); - } + strcpy(g_job_overrides_db_path, LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/com.apple.launchd.overrides.plist"); } Modified: branches/PR-6564965/launchd/src/launchd.h =================================================================== --- branches/PR-6564965/launchd/src/launchd.h 2009-02-26 23:58:22 UTC (rev 23838) +++ branches/PR-6564965/launchd/src/launchd.h 2009-02-27 00:28:06 UTC (rev 23839) @@ -26,8 +26,6 @@ #include "bootstrap.h" #include "launchd_runtime.h" -#define LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/var/db/launchd_job_overrides" - struct kevent; struct conncb; Modified: branches/PR-6564965/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-26 23:58:22 UTC (rev 23838) +++ branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-27 00:28:06 UTC (rev 23839) @@ -7283,11 +7283,12 @@ struct stat sb; char pu_db[PATH_MAX]; - snprintf(pu_db, sizeof(pu_db), LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/%s", lbuf); + snprintf(pu_db, sizeof(pu_db), LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/%s.overrides.plist", lbuf); - if( stat(pu_db, &sb) == -1 && job_assumes(ji, errno == ENOENT) ) { - job_assumes(ji, mkdir(pu_db, S_IRWXO) != -1); - job_assumes(ji, chown(pu_db, which_user, 0) != -1); + if( stat(pu_db, &sb) != -1 ) { + if( !job_assumes(ji, sb.st_uid == which_user) || !job_assumes(ji, sb.st_uid == 0) || !job_assumes(ji, sb.st_mode == S_IRWXU) ) { + job_assumes(ji, remove(pu_db) != -1); + } } if ((ms = machservice_new(ji, lbuf, mp, false)) == NULL) { Modified: branches/PR-6564965/launchd/src/libvproc.c =================================================================== --- branches/PR-6564965/launchd/src/libvproc.c 2009-02-26 23:58:22 UTC (rev 23838) +++ branches/PR-6564965/launchd/src/libvproc.c 2009-02-27 00:28:06 UTC (rev 23839) @@ -823,21 +823,20 @@ /* Once you're in the transaction model, you're in for good. Like the Mafia. */ s_cached_transactions_enabled = 1; break; - case VPROC_GSK_PERUSER_SUSPEND: - { - char peruser_label[NAME_MAX]; - snprintf(peruser_label, NAME_MAX - 1, "com.apple.launchd.peruser.%u", (uid_t)*inval); + case VPROC_GSK_PERUSER_SUSPEND: { + char peruser_label[NAME_MAX]; + snprintf(peruser_label, NAME_MAX - 1, "com.apple.launchd.peruser.%u", (uid_t)*inval); + + vproc_t pu_vp = vprocmgr_lookup_vproc(peruser_label); + if( pu_vp ) { + int status = 0; + kern_return_t kr = vproc_mig_wait2(bootstrap_port, pu_vp->j_port, &status); + vproc_release(pu_vp); - vproc_t pu_vp = vprocmgr_lookup_vproc(peruser_label); - if( pu_vp ) { - int status = 0; - kern_return_t kr = vproc_mig_wait2(bootstrap_port, pu_vp->j_port, &status); - vproc_release(pu_vp); - - syslog(LOG_DEBUG, "%u's suspended launchd exited with status %i (kr = 0x%x).", (uid_t)*inval, status, kr); - } + syslog(LOG_DEBUG, "%u's suspended launchd exited with status %i (kr = 0x%x).", (uid_t)*inval, status, kr); } break; + } default: break; } -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 16:32:41 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 16:32:41 -0800 (PST) Subject: [launchd-changes] [23840] branches/PR-6564965/launchd/src/launchctl.c Message-ID: <20090227003242.343A510C07F4@beta.macosforge.org> Revision: 23840 http://trac.macosforge.org/projects/launchd/changeset/23840 Author: dsorresso at apple.com Date: 2009-02-26 16:32:40 -0800 (Thu, 26 Feb 2009) Log Message: ----------- Wrong permissions. Doh. Modified Paths: -------------- branches/PR-6564965/launchd/src/launchctl.c Modified: branches/PR-6564965/launchd/src/launchctl.c =================================================================== --- branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 00:28:06 UTC (rev 23839) +++ branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 00:32:40 UTC (rev 23840) @@ -1939,7 +1939,6 @@ _vproc_set_global_on_demand(true); - #if !TARGET_OS_EMBEDDED char *load_launchd_items[] = { "load", "-D", "all", "/etc/mach_init.d", NULL }; int load_launchd_items_cnt = 4; @@ -3582,7 +3581,7 @@ { _PATH_TMP, 0, 0, S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO, S_ISUID|S_ISGID, true }, { _PATH_VARTMP, 0, 0, S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO, S_ISUID|S_ISGID, true }, { "/var/folders", 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, S_ISUID | S_ISGID, true }, - { LAUNCHD_JOB_OVERRIDES_DB_PREFIX, 0, 0, S_IRWXO, S_IRWXG | S_IRWXU, true } + { LAUNCHD_JOB_OVERRIDES_DB_PREFIX, 0, 0, S_IRWXU, S_IRWXG | S_IRWXO, true } }; struct stat sb; size_t i; -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 16:43:16 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 16:43:16 -0800 (PST) Subject: [launchd-changes] [23841] branches/PR-6564965/launchd/src/launchd_core_logic.c Message-ID: <20090227004317.1998B10C1179@beta.macosforge.org> Revision: 23841 http://trac.macosforge.org/projects/launchd/changeset/23841 Author: dsorresso at apple.com Date: 2009-02-26 16:43:16 -0800 (Thu, 26 Feb 2009) Log Message: ----------- It's nice to have breaks in cases. Modified Paths: -------------- branches/PR-6564965/launchd/src/launchd_core_logic.c Modified: branches/PR-6564965/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-27 00:32:40 UTC (rev 23840) +++ branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-27 00:43:16 UTC (rev 23841) @@ -6869,7 +6869,8 @@ goto out_bad; } - launch_data_free(output_obj); + launch_data_free(output_obj); + break; case 0: mig_deallocate(*outval, *outvalCnt); *outval = 0; -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 18:34:46 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 18:34:46 -0800 (PST) Subject: [launchd-changes] [23842] branches/PR-6564965/launchd/src/launchctl.c Message-ID: <20090227023447.2B5B410C310A@beta.macosforge.org> Revision: 23842 http://trac.macosforge.org/projects/launchd/changeset/23842 Author: dsorresso at apple.com Date: 2009-02-26 18:34:46 -0800 (Thu, 26 Feb 2009) Log Message: ----------- Adjusted the "-w" option for load and unload to write to the override database. Modified Paths: -------------- branches/PR-6564965/launchd/src/launchctl.c Modified: branches/PR-6564965/launchd/src/launchctl.c =================================================================== --- branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 00:43:16 UTC (rev 23841) +++ branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 02:34:46 UTC (rev 23842) @@ -104,6 +104,7 @@ #define assumes(e) \ (__builtin_expect(!(e), 0) ? _log_launchctl_bug(__rcs_file_version__, __FILE__, __LINE__, #e), false : true) +#define CFTypeCheck(cf, type) (CFGetTypeID(cf) == type ## GetTypeID()) struct load_unload_state { launch_data_t pass0; @@ -259,8 +260,9 @@ static bool rootuser_context; static bool g_shutdown_debugging = false; +static bool g_job_overrides_db_has_changed = false; +static CFDictionaryRef g_job_overrides_db = NULL; char g_job_overrides_db_path[PATH_MAX]; -CFDictionaryRef g_job_overrides_db = NULL; int main(int argc, char *const argv[]) @@ -710,15 +712,13 @@ void job_override(CFTypeRef key, CFTypeRef val, CFMutableDictionaryRef job) { - if( CFGetTypeID(key) != CFStringGetTypeID() ) { + if( !CFTypeCheck(key, CFString) ) { return; } if( CFStringCompare(key, CFSTR(LAUNCH_JOBKEY_LABEL), kCFCompareCaseInsensitive) == 0 ) { return; } - fprintf(stdout, "Overriding %s in %s...\n", CFStringGetCStringPtr(key, kCFStringEncodingUTF8), CFStringGetCStringPtr(CFDictionaryGetValue(job, CFSTR(LAUNCH_JOBKEY_LABEL)), kCFStringEncodingUTF8)); - CFDictionarySetValue(job, key, val); } @@ -734,25 +734,34 @@ } CFStringRef label = CFDictionaryGetValue(plist, CFSTR(LAUNCH_JOBKEY_LABEL)); - if( g_job_overrides_db && label && CFGetTypeID(label) == CFStringGetTypeID() ) { + if( g_job_overrides_db && label && CFTypeCheck(label, CFString) ) { CFDictionaryRef overrides = CFDictionaryGetValue(g_job_overrides_db, label); - if( overrides ) { + if( overrides && CFTypeCheck(label, CFDictionary) ) { CFDictionaryApplyFunction(overrides, (CFDictionaryApplierFunction)job_override, (void *)plist); } } if (editondisk) { - if (load) { - CFDictionaryRemoveValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED)); + if( g_job_overrides_db ) { + CFMutableDictionaryRef job = (CFMutableDictionaryRef)CFDictionaryGetValue(g_job_overrides_db, label); + if( job && CFTypeCheck(job, CFDictionary) ) { + CFDictionarySetValue(job, CFSTR(LAUNCH_JOBKEY_DISABLED), load ? kCFBooleanFalse : kCFBooleanTrue); + g_job_overrides_db_has_changed = true; + } } else { - CFDictionarySetValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED), kCFBooleanTrue); + if (load) { + CFDictionaryRemoveValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED)); + } else { + CFDictionarySetValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED), kCFBooleanTrue); + } + WriteMyPropertyListToFile(plist, file); } - WriteMyPropertyListToFile(plist, file); } r = CF2launch_data(plist); CFRelease(plist); + CFReleaseIfNotNULL(label); return r; } @@ -2296,6 +2305,10 @@ } } + if( g_job_overrides_db ) { + WriteMyPropertyListToFile(g_job_overrides_db, g_job_overrides_db_path); + } + return 0; } @@ -3581,7 +3594,7 @@ { _PATH_TMP, 0, 0, S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO, S_ISUID|S_ISGID, true }, { _PATH_VARTMP, 0, 0, S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO, S_ISUID|S_ISGID, true }, { "/var/folders", 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, S_ISUID | S_ISGID, true }, - { LAUNCHD_JOB_OVERRIDES_DB_PREFIX, 0, 0, S_IRWXU, S_IRWXG | S_IRWXO, true } + { LAUNCHD_JOB_OVERRIDES_DB_PREFIX, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, S_IRWXG | S_IRWXO, true } }; struct stat sb; size_t i; -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 18:41:30 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 18:41:30 -0800 (PST) Subject: [launchd-changes] [23843] branches/PR-6564965/launchd/src/launchctl.c Message-ID: <20090227024130.CA02610C32D5@beta.macosforge.org> Revision: 23843 http://trac.macosforge.org/projects/launchd/changeset/23843 Author: dsorresso at apple.com Date: 2009-02-26 18:41:29 -0800 (Thu, 26 Feb 2009) Log Message: ----------- Bug fixes. Modified Paths: -------------- branches/PR-6564965/launchd/src/launchctl.c Modified: branches/PR-6564965/launchd/src/launchctl.c =================================================================== --- branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 02:34:46 UTC (rev 23842) +++ branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 02:41:29 UTC (rev 23843) @@ -761,7 +761,6 @@ r = CF2launch_data(plist); CFRelease(plist); - CFReleaseIfNotNULL(label); return r; } @@ -2305,7 +2304,7 @@ } } - if( g_job_overrides_db ) { + if( g_job_overrides_db_has_changed ) { WriteMyPropertyListToFile(g_job_overrides_db, g_job_overrides_db_path); } -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 18:56:20 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 18:56:20 -0800 (PST) Subject: [launchd-changes] [23844] branches/PR-6564965/launchd/src/launchctl.c Message-ID: <20090227025620.3873110C3780@beta.macosforge.org> Revision: 23844 http://trac.macosforge.org/projects/launchd/changeset/23844 Author: dsorresso at apple.com Date: 2009-02-26 18:56:19 -0800 (Thu, 26 Feb 2009) Log Message: ----------- Another bug fix. Modified Paths: -------------- branches/PR-6564965/launchd/src/launchctl.c Modified: branches/PR-6564965/launchd/src/launchctl.c =================================================================== --- branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 02:41:29 UTC (rev 23843) +++ branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 02:56:19 UTC (rev 23844) @@ -746,6 +746,7 @@ CFMutableDictionaryRef job = (CFMutableDictionaryRef)CFDictionaryGetValue(g_job_overrides_db, label); if( job && CFTypeCheck(job, CFDictionary) ) { CFDictionarySetValue(job, CFSTR(LAUNCH_JOBKEY_DISABLED), load ? kCFBooleanFalse : kCFBooleanTrue); + CFDictionarySetValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED), load ? kCFBooleanFalse : kCFBooleanTrue); g_job_overrides_db_has_changed = true; } } else { -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 19:04:10 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 19:04:10 -0800 (PST) Subject: [launchd-changes] [23845] branches/PR-6564965/launchd/src/launchctl.c Message-ID: <20090227030410.534CD10C3A06@beta.macosforge.org> Revision: 23845 http://trac.macosforge.org/projects/launchd/changeset/23845 Author: dsorresso at apple.com Date: 2009-02-26 19:04:10 -0800 (Thu, 26 Feb 2009) Log Message: ----------- Permissions bits fixups. Modified Paths: -------------- branches/PR-6564965/launchd/src/launchctl.c Modified: branches/PR-6564965/launchd/src/launchctl.c =================================================================== --- branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 02:56:19 UTC (rev 23844) +++ branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 03:04:10 UTC (rev 23845) @@ -3594,7 +3594,7 @@ { _PATH_TMP, 0, 0, S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO, S_ISUID|S_ISGID, true }, { _PATH_VARTMP, 0, 0, S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO, S_ISUID|S_ISGID, true }, { "/var/folders", 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, S_ISUID | S_ISGID, true }, - { LAUNCHD_JOB_OVERRIDES_DB_PREFIX, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, S_IRWXG | S_IRWXO, true } + { LAUNCHD_JOB_OVERRIDES_DB_PREFIX, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, S_IWGRP | S_IWOTH, true } }; struct stat sb; size_t i; -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 19:28:49 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 19:28:49 -0800 (PST) Subject: [launchd-changes] [23846] branches/PR-6564965/launchd/src Message-ID: <20090227032850.2FF3A10C40B3@beta.macosforge.org> Revision: 23846 http://trac.macosforge.org/projects/launchd/changeset/23846 Author: dsorresso at apple.com Date: 2009-02-26 19:28:49 -0800 (Thu, 26 Feb 2009) Log Message: ----------- Settled on a directory hierarchy of databases for future expandability. We now have /var/db/launchd.db, with subdirectories for the system and per-user launchd's. In those directories are the override databases, and future databases we might wish to add. Modified Paths: -------------- branches/PR-6564965/launchd/src/launch_internal.h branches/PR-6564965/launchd/src/launchctl.c branches/PR-6564965/launchd/src/launchd.c branches/PR-6564965/launchd/src/launchd_core_logic.c Modified: branches/PR-6564965/launchd/src/launch_internal.h =================================================================== --- branches/PR-6564965/launchd/src/launch_internal.h 2009-02-27 03:04:10 UTC (rev 23845) +++ branches/PR-6564965/launchd/src/launch_internal.h 2009-02-27 03:28:49 UTC (rev 23846) @@ -22,7 +22,7 @@ #pragma GCC visibility push(default) -#define LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/var/db/launchd_job_overrides" +#define LAUNCHD_DB_PREFIX "/var/db/launchd.db" size_t launch_data_pack(launch_data_t d, void *where, size_t len, int *fd_where, size_t *fdslotsleft); launch_data_t launch_data_unpack(void *data, size_t data_size, int *fds, size_t fd_cnt, size_t *data_offset, size_t *fdoffset); Modified: branches/PR-6564965/launchd/src/launchctl.c =================================================================== --- branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 03:04:10 UTC (rev 23845) +++ branches/PR-6564965/launchd/src/launchctl.c 2009-02-27 03:28:49 UTC (rev 23846) @@ -261,7 +261,7 @@ static bool g_shutdown_debugging = false; static bool g_job_overrides_db_has_changed = false; -static CFDictionaryRef g_job_overrides_db = NULL; +static CFMutableDictionaryRef g_job_overrides_db = NULL; char g_job_overrides_db_path[PATH_MAX]; int @@ -350,7 +350,10 @@ strncpy(g_job_overrides_db_path, db, strlen(db)); free(db); - g_job_overrides_db = (CFDictionaryRef)CreateMyPropertyListFromFile(g_job_overrides_db_path); + g_job_overrides_db = (CFMutableDictionaryRef)CreateMyPropertyListFromFile(g_job_overrides_db_path); + if( !g_job_overrides_db ) { + g_job_overrides_db = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + } } if (NULL == readline) { @@ -744,11 +747,15 @@ if (editondisk) { if( g_job_overrides_db ) { CFMutableDictionaryRef job = (CFMutableDictionaryRef)CFDictionaryGetValue(g_job_overrides_db, label); - if( job && CFTypeCheck(job, CFDictionary) ) { - CFDictionarySetValue(job, CFSTR(LAUNCH_JOBKEY_DISABLED), load ? kCFBooleanFalse : kCFBooleanTrue); - CFDictionarySetValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED), load ? kCFBooleanFalse : kCFBooleanTrue); - g_job_overrides_db_has_changed = true; + if( !job || !CFTypeCheck(job, CFDictionary) ) { + job = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(g_job_overrides_db, label, job); + CFRelease(job); } + + CFDictionarySetValue(job, CFSTR(LAUNCH_JOBKEY_DISABLED), load ? kCFBooleanFalse : kCFBooleanTrue); + CFDictionarySetValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED), load ? kCFBooleanFalse : kCFBooleanTrue); + g_job_overrides_db_has_changed = true; } else { if (load) { CFDictionaryRemoveValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED)); @@ -3594,7 +3601,8 @@ { _PATH_TMP, 0, 0, S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO, S_ISUID|S_ISGID, true }, { _PATH_VARTMP, 0, 0, S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO, S_ISUID|S_ISGID, true }, { "/var/folders", 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, S_ISUID | S_ISGID, true }, - { LAUNCHD_JOB_OVERRIDES_DB_PREFIX, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, S_IWGRP | S_IWOTH, true } + { LAUNCHD_DB_PREFIX, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, S_IWGRP | S_IWOTH, true }, + { LAUNCHD_DB_PREFIX "/com.apple.launchd", 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, S_IWGRP | S_IWOTH, true } }; struct stat sb; size_t i; Modified: branches/PR-6564965/launchd/src/launchd.c =================================================================== --- branches/PR-6564965/launchd/src/launchd.c 2009-02-27 03:04:10 UTC (rev 23845) +++ branches/PR-6564965/launchd/src/launchd.c 2009-02-27 03:28:49 UTC (rev 23846) @@ -189,7 +189,7 @@ strlcpy(g_username, pwent->pw_name, sizeof(g_username) - 1); } - snprintf(g_job_overrides_db_path, sizeof(g_job_overrides_db_path), LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/com.apple.launchd.peruser.%u.overrides.plist", getuid()); + snprintf(g_job_overrides_db_path, sizeof(g_job_overrides_db_path), LAUNCHD_DB_PREFIX "/com.apple.launchd.peruser.%u/overrides.plist", getuid()); runtime_syslog(LOG_DEBUG, "Per-user launchd for UID %u (%s) has begun.", getuid(), g_username); } @@ -404,7 +404,7 @@ launchd_assumes(chdir("/") != -1); launchd_assumes(setlogin("root") != -1); - strcpy(g_job_overrides_db_path, LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/com.apple.launchd.overrides.plist"); + strcpy(g_job_overrides_db_path, LAUNCHD_DB_PREFIX "/com.apple.launchd/overrides.plist"); } Modified: branches/PR-6564965/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-27 03:04:10 UTC (rev 23845) +++ branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-27 03:28:49 UTC (rev 23846) @@ -7284,12 +7284,18 @@ struct stat sb; char pu_db[PATH_MAX]; - snprintf(pu_db, sizeof(pu_db), LAUNCHD_JOB_OVERRIDES_DB_PREFIX "/%s.overrides.plist", lbuf); + snprintf(pu_db, sizeof(pu_db), LAUNCHD_DB_PREFIX "/%s", lbuf); if( stat(pu_db, &sb) != -1 ) { - if( !job_assumes(ji, sb.st_uid == which_user) || !job_assumes(ji, sb.st_uid == 0) || !job_assumes(ji, sb.st_mode == S_IRWXU) ) { - job_assumes(ji, remove(pu_db) != -1); + if( !job_assumes(ji, sb.st_uid == which_user) ) { + job_assumes(ji, chown(pu_db, which_user, 0) != -1); } + if( !job_assumes(ji, sb.st_gid == 0) ) { + job_assumes(ji, chown(pu_db, which_user, 0) != -1); + } + if( !job_assumes(ji, sb.st_mode == S_IRWXU) ) { + job_assumes(ji, chmod(pu_db, S_IRWXU) != -1); + } } if ((ms = machservice_new(ji, lbuf, mp, false)) == NULL) { -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Thu Feb 26 19:38:46 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Thu, 26 Feb 2009 19:38:46 -0800 (PST) Subject: [launchd-changes] [23847] branches/PR-6564965/launchd/src/launchd_core_logic.c Message-ID: <20090227033847.5D9DF10C440D@beta.macosforge.org> Revision: 23847 http://trac.macosforge.org/projects/launchd/changeset/23847 Author: dsorresso at apple.com Date: 2009-02-26 19:38:46 -0800 (Thu, 26 Feb 2009) Log Message: ----------- Creating per-user database directories. Modified Paths: -------------- branches/PR-6564965/launchd/src/launchd_core_logic.c Modified: branches/PR-6564965/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-27 03:28:49 UTC (rev 23846) +++ branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-27 03:38:46 UTC (rev 23847) @@ -7286,7 +7286,13 @@ char pu_db[PATH_MAX]; snprintf(pu_db, sizeof(pu_db), LAUNCHD_DB_PREFIX "/%s", lbuf); - if( stat(pu_db, &sb) != -1 ) { + int err = -1; + if( (err = stat(pu_db, &sb)) == -1 && job_assumes(ji, errno == ENOENT) ) { + job_assumes(ji, mkdir(pu_db, S_IRWXU) != -1); + job_assumes(ji, (err = stat(pu_db, &sb)) != -1); + } + + if( err != -1 ) { if( !job_assumes(ji, sb.st_uid == which_user) ) { job_assumes(ji, chown(pu_db, which_user, 0) != -1); } -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Fri Feb 27 22:34:35 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Fri, 27 Feb 2009 22:34:35 -0800 (PST) Subject: [launchd-changes] [23848] branches/PR-6564965/launchd/src/launchd_core_logic.c Message-ID: <20090228063436.2F82010DEAFA@beta.macosforge.org> Revision: 23848 http://trac.macosforge.org/projects/launchd/changeset/23848 Author: dsorresso at apple.com Date: 2009-02-27 22:34:34 -0800 (Fri, 27 Feb 2009) Log Message: ----------- Fix for rdar://problem/6623625. Modified Paths: -------------- branches/PR-6564965/launchd/src/launchd_core_logic.c Modified: branches/PR-6564965/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-27 03:38:46 UTC (rev 23847) +++ branches/PR-6564965/launchd/src/launchd_core_logic.c 2009-02-28 06:34:34 UTC (rev 23848) @@ -5492,7 +5492,7 @@ /* If we've killed everyone, move on. */ if( unkilled_cnt == 0 ) { - jm->killed_hopefully_first_jobs = true; + jm->killed_normal_jobs = true; jm = NULL; } @@ -5554,7 +5554,7 @@ /* If we've killed everyone, move on. */ if( unkilled_cnt == 0 ) { - jm->killed_hopefully_first_jobs = true; + jm->killed_hopefully_last_jobs = true; jm = NULL; } @@ -5573,6 +5573,12 @@ jobmgr_do_garbage_collection(jmi); } + if( SLIST_EMPTY(&jm->submgrs) ) { + jobmgr_log(jm, LOG_DEBUG, "No submanagers left."); + } else { + jobmgr_log(jm, LOG_DEBUG, "Still have submanagers."); + } + jobmgr_t _jm = jobmgr_do_hopefully_first_shutdown_phase(jm); if( !_jm ) { _jm = jobmgr_do_normal_shutdown_phase(jm) ? : jobmgr_do_hopefully_last_shutdown_phase(jm); -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Sat Feb 28 13:15:57 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Sat, 28 Feb 2009 13:15:57 -0800 (PST) Subject: [launchd-changes] [23849] trunk/launchd/src Message-ID: <20090228211558.5291C10EA5F1@beta.macosforge.org> Revision: 23849 http://trac.macosforge.org/projects/launchd/changeset/23849 Author: dsorresso at apple.com Date: 2009-02-28 13:15:57 -0800 (Sat, 28 Feb 2009) Log Message: ----------- launchd adoption of audit session objects _vprocmgr_switch_to_session() should return success if you're already in the target session Modified Paths: -------------- trunk/launchd/src/launch_priv.h trunk/launchd/src/launchctl.c trunk/launchd/src/launchd.c trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/launchd_core_logic.h trunk/launchd/src/launchd_mig_types.defs trunk/launchd/src/launchd_runtime.c trunk/launchd/src/launchd_runtime.h trunk/launchd/src/liblaunch.c trunk/launchd/src/libvproc.c trunk/launchd/src/protocol_vproc.defs trunk/launchd/src/vproc_internal.h trunk/launchd/src/vproc_priv.h Modified: trunk/launchd/src/launch_priv.h =================================================================== --- trunk/launchd/src/launch_priv.h 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/launch_priv.h 2009-02-28 21:15:57 UTC (rev 23849) @@ -25,6 +25,7 @@ #include #include #include +#include #pragma GCC visibility push(default) @@ -58,6 +59,7 @@ #define LAUNCH_JOBKEY_SANDBOXFLAGS "SandboxFlags" #define LAUNCH_JOBKEY_SANDBOX_NAMED "Named" #define LAUNCH_JOBKEY_JETSAMPRIORITY "JetsamPriority" +#define LAUNCH_JOBKEY_SECURITYSESSIONUUID "SecuritySessionUUID" #define LAUNCH_JOBKEY_ENTERKERNELDEBUGGERBEFOREKILL "EnterKernelDebuggerBeforeKill" #define LAUNCH_JOBKEY_PERJOBMACHSERVICES "PerJobMachServices" Modified: trunk/launchd/src/launchctl.c =================================================================== --- trunk/launchd/src/launchctl.c 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/launchctl.c 2009-02-28 21:15:57 UTC (rev 23849) @@ -255,6 +255,8 @@ static bool do_apple_internal_magic; static bool system_context; static bool rootuser_context; +static bool bootstrapping_system; +static bool bootstrapping_peruser; static bool g_shutdown_debugging = false; int @@ -860,6 +862,14 @@ if (job_disabled && lus->load) { goto out_bad; } + + if( bootstrapping_system || bootstrapping_peruser ) { + uuid_t uuid; + uuid_clear(uuid); + + launch_data_t uuid_d = launch_data_new_opaque(uuid, sizeof(uuid_t)); + launch_data_dict_insert(thejob, uuid_d, LAUNCH_JOBKEY_SECURITYSESSIONUUID); + } if (delay_to_second_pass(thejob)) { launch_data_array_append(lus->pass2, thejob); @@ -1899,7 +1909,6 @@ _vproc_set_global_on_demand(true); - #if !TARGET_OS_EMBEDDED char *load_launchd_items[] = { "load", "-D", "all", "/etc/mach_init.d", NULL }; int load_launchd_items_cnt = 4; @@ -2031,6 +2040,7 @@ } if (strcasecmp(session_type, "System") == 0) { + bootstrapping_system = true; system_specific_bootstrap(sflag); } else { char *load_launchd_items[] = { "load", "-S", session_type, "-D", "all", NULL, NULL, NULL, NULL, NULL, NULL }; @@ -2104,6 +2114,7 @@ } if (strcasecmp(session_type, VPROCMGR_SESSION_BACKGROUND) == 0) { + bootstrapping_peruser = true; read_launchd_conf(); #if 0 /* XXX PR-6456403 */ assumes(SessionCreate(sessionKeepCurrentBootstrap, 0) == 0); Modified: trunk/launchd/src/launchd.c =================================================================== --- trunk/launchd/src/launchd.c 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/launchd.c 2009-02-28 21:15:57 UTC (rev 23849) @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -116,6 +117,7 @@ bool fake_shutdown_in_progress; bool network_up; char g_username[128] = "__Uninitialized__"; +char g_my_label[128] = "__Uninitialized__"; FILE *g_console = NULL; int @@ -187,6 +189,15 @@ strlcpy(g_username, pwent->pw_name, sizeof(g_username) - 1); } + snprintf(g_my_label, sizeof(g_my_label), "com.apple.launchd.peruser.%u", getuid()); + + auditinfo_addr_t auinfo; + if( launchd_assumes(getaudit_addr(&auinfo, sizeof(auinfo)) != -1) ) { + g_audit_session = auinfo.ai_asid; + runtime_syslog(LOG_DEBUG, "Our audit session ID is %i", g_audit_session); + } + + g_audit_session_port = _audit_session_self(); runtime_syslog(LOG_DEBUG, "Per-user launchd for UID %u (%s) has begun.", getuid(), g_username); } @@ -404,9 +415,30 @@ launchd_assumes(setsid() != -1); launchd_assumes(chdir("/") != -1); launchd_assumes(setlogin("root") != -1); + + strcpy(g_my_label, "com.apple.launchd"); + +#if !TARGET_OS_EMBEDDED + auditinfo_addr_t auinfo = { + .ai_termid = { .at_type = AU_IPv4 }, + .ai_asid = AU_ASSIGN_ASID, + .ai_flags = sessionIsRoot, + }; + + if( !launchd_assumes(setaudit_addr(&auinfo, sizeof(auinfo)) != -1) ) { + runtime_syslog(LOG_WARNING | LOG_CONSOLE, "Could not set audit session! (errno = %d)", errno); + _exit(EXIT_FAILURE); + } + + if( launchd_assumes(getaudit_addr(&auinfo, sizeof(auinfo)) != -1) ) { + g_audit_session = auinfo.ai_asid; + runtime_syslog(LOG_DEBUG, "Our audit session ID is %i", g_audit_session); + } + + g_audit_session_port = _audit_session_self(); +#endif } - int _fd(int fd) { Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/launchd_core_logic.c 2009-02-28 21:15:57 UTC (rev 23849) @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -340,6 +341,7 @@ STAILQ_HEAD(, job_s) pending_samples; mach_port_t jm_port; mach_port_t req_port; + mach_port_t init_audit_session; jobmgr_t parentmgr; int reboot_flags; unsigned int global_on_demand_cnt; @@ -362,7 +364,7 @@ #define jobmgr_assumes(jm, e) \ (unlikely(!(e)) ? jobmgr_log_bug(jm, __LINE__), false : true) -static jobmgr_t jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag, const char *name); +static jobmgr_t jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag, const char *name, mach_port_t session_port); static job_t jobmgr_import2(jobmgr_t jm, launch_data_t pload); static jobmgr_t jobmgr_parent(jobmgr_t jm); static jobmgr_t jobmgr_do_hopefully_first_shutdown_phase(jobmgr_t jm); @@ -397,7 +399,8 @@ struct job_s { kq_callback kqjob_callback; /* MUST be first element of this structure for benefit of launchd's run loop. */ - LIST_ENTRY(job_s) sle; + LIST_ENTRY(job_s) sle; + LIST_ENTRY(job_s) needing_session_sle; LIST_ENTRY(job_s) jetsam_sle; LIST_ENTRY(job_s) pid_hash_sle; LIST_ENTRY(job_s) label_hash_sle; @@ -527,6 +530,8 @@ migratory :1; /* The (anonymous) job called vprocmgr_switch_to_session(). */ mode_t mask; pid_t tracing_pid; + mach_port_t audit_session; + uuid_t expected_audit_uuid; const char label[0]; }; @@ -562,9 +567,6 @@ static bool job_setup_machport(job_t j); static void job_setup_fd(job_t j, int target_fd, const char *path, int flags); static void job_postfork_become_user(job_t j); -#if !TARGET_OS_EMBEDDED -static void job_enable_audit_for_user(job_t j, uid_t u, char *name); -#endif static void job_postfork_test_user(job_t j); static void job_log_pids_with_weird_uids(job_t j); static void job_setup_exception_port(job_t j, task_t target_task); @@ -633,6 +635,13 @@ static size_t total_anon_children; static mach_port_t the_exception_server; static job_t workaround_5477111; +static LIST_HEAD(, job_s) s_needing_sessions; +mach_port_t g_audit_session_port = MACH_PORT_NULL; +#if !TARGET_OS_EMBEDDED +au_asid_t g_audit_session = AU_DEFAUDITSID; +#else +pid_t g_audit_session = 0; +#endif static pid_t s_update_pid = 0; static int s_no_hang_fd = -1; @@ -1143,6 +1152,12 @@ LIST_REMOVE(j, jetsam_sle); j->mgr->jetsam_jobs_cnt--; } + if( j->audit_session != MACH_PORT_NULL ) { + job_assumes(j, mach_port_deallocate(mach_task_self(), j->audit_session) == KERN_SUCCESS); + } + if( !uuid_is_null(j->expected_audit_uuid) ) { + LIST_REMOVE(j, needing_session_sle); + } kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); kevent_mod((uintptr_t)j, EVFILT_PROC, EV_DELETE, 0, 0, NULL); @@ -1468,6 +1483,7 @@ j->ondemand = true; j->checkedin = true; j->jetsam_priority = LAUNCHD_JETSAM_PRIORITY_UNSET; + uuid_clear(j->expected_audit_uuid); if (prog) { j->prog = strdup(prog); @@ -1507,6 +1523,7 @@ LIST_INSERT_HEAD(&jm->jobs, j, sle); LIST_INSERT_HEAD(&label_hash[hash_label(j->label)], j, label_hash_sle); + uuid_clear(j->expected_audit_uuid); job_log(j, LOG_DEBUG, "Conceived"); @@ -1903,6 +1920,14 @@ } } #endif + case 's': + case 'S': + if( strcasecmp(key, LAUNCH_JOBKEY_SECURITYSESSIONUUID) == 0 ) { + size_t tmpsz = launch_data_get_opaque_size(value); + if( job_assumes(j, tmpsz == sizeof(uuid_t)) ) { + memcpy(j->expected_audit_uuid, launch_data_get_opaque(value), sizeof(uuid_t)); + } + } break; default: break; @@ -2203,6 +2228,15 @@ if (likely(j = job_new(jm, label, prog, argv))) { launch_data_dict_iterate(pload, job_import_keys, j); + if( !uuid_is_null(j->expected_audit_uuid) ) { + uuid_string_t uuid_str; + uuid_unparse(j->expected_audit_uuid, uuid_str); + job_log(j, LOG_DEBUG, "Imported job. Waiting for session for UUID %s.", uuid_str); + LIST_INSERT_HEAD(&s_needing_sessions, j, needing_session_sle); + } else { + job_log(j, LOG_DEBUG, "No security session specified."); + j->audit_session = MACH_PORT_NULL; + } } return j; @@ -2894,6 +2928,11 @@ job_t job_dispatch(job_t j, bool kickstart) { + /* Don't dispatch a job if it has no audit session set. */ + if( !uuid_is_null(j->expected_audit_uuid) ) { + return NULL; + } + /* * The whole job removal logic needs to be consolidated. The fact that * a job can be removed from just about anywhere makes it easy to have @@ -2901,7 +2940,7 @@ * used after the deallocation. In particular, during job iteration. * * This is a classic example. The act of dispatching a job may delete it. - */ + */ if (!job_active(j)) { if (job_useless(j)) { job_remove(j); @@ -3903,10 +3942,6 @@ desired_gid = gre->gr_gid; } -#if !TARGET_OS_EMBEDDED - job_enable_audit_for_user(j, desired_uid, loginname); -#endif - if (!job_assumes(j, setlogin(loginname) != -1)) { _exit(EXIT_FAILURE); } @@ -3957,31 +3992,7 @@ setenv("LOGNAME", loginname, 0); } -#if !TARGET_OS_EMBEDDED void -job_enable_audit_for_user(job_t j, uid_t u, char *name) -{ - auditinfo_t auinfo = { - .ai_auid = u, - .ai_asid = j->p, - }; - long au_cond; - - if (!job_assumes(j, auditon(A_GETCOND, &au_cond, sizeof(long)) == 0)) { - _exit(EXIT_FAILURE); - } - - if (au_cond != AUC_NOAUDIT) { - if (!job_assumes(j, au_user_mask(name, &auinfo.ai_mask) == 0)) { - _exit(EXIT_FAILURE); - } else if (!job_assumes(j, setaudit(&auinfo) == 0)) { - _exit(EXIT_FAILURE); - } - } -} -#endif - -void job_setup_attributes(job_t j) { struct limititem *li; @@ -4010,6 +4021,23 @@ } } +#if !TARGET_OS_EMBEDDED + if( unlikely(j->per_user) ) { + auditinfo_addr_t auinfo = { + .ai_termid = { .at_type = AU_IPv4 }, + .ai_auid = j->mach_uid, + .ai_asid = AU_ASSIGN_ASID, + }; + + if( !launchd_assumes(setaudit_addr(&auinfo, sizeof(auinfo)) != -1) ) { + runtime_syslog(LOG_WARNING | LOG_CONSOLE, "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."); + } + } +#endif + if (unlikely(!j->inetcompat && j->session_create)) { launchd_SessionCreate(); } @@ -4242,7 +4270,7 @@ bool log_to_console = pri & LOG_CONSOLE; int _pri = pri & ~LOG_CONSOLE; - struct runtime_syslog_attr attr = { "com.apple.launchd", j->label, j->mgr->name, _pri, getuid(), getpid(), j->p }; + struct runtime_syslog_attr attr = { g_my_label, j->label, j->mgr->name, _pri, getuid(), getpid(), j->p }; char *newmsg; int oldmask = 0; size_t newmsgsz; @@ -4358,7 +4386,7 @@ bool log_to_console = pri & LOG_CONSOLE; int _pri = pri & ~LOG_CONSOLE; - struct runtime_syslog_attr attr = { "com.apple.launchd", "com.apple.launchd", jm->name, _pri, getuid(), getpid(), getpid() }; + struct runtime_syslog_attr attr = { g_my_label, g_my_label, jm->name, _pri, getuid(), getpid(), getpid() }; runtime_vsyslog(&attr, log_to_console, newmsg, ap); } @@ -5492,7 +5520,7 @@ /* If we've killed everyone, move on. */ if( unkilled_cnt == 0 ) { - jm->killed_hopefully_first_jobs = true; + jm->killed_normal_jobs = true; jm = NULL; } @@ -5554,7 +5582,7 @@ /* If we've killed everyone, move on. */ if( unkilled_cnt == 0 ) { - jm->killed_hopefully_first_jobs = true; + jm->killed_hopefully_last_jobs = true; jm = NULL; } @@ -5760,7 +5788,7 @@ } jobmgr_t -jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag, const char *name) +jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag, const char *name, mach_port_t session_port) { mach_msg_size_t mxmsgsz; job_t bootstrapper = NULL; @@ -5859,6 +5887,8 @@ jobmgr_log(jmr, LOG_DEBUG, "Created job manager%s%s", jm ? " with parent: " : ".", jm ? jm->name : ""); if (bootstrapper) { + bootstrapper->audit_session = session_port; + jobmgr_log(jmr, LOG_DEBUG, "Bootstrapping new job manager with audit session %u", session_port); jobmgr_assumes(jmr, job_dispatch(bootstrapper, true) != NULL); } @@ -5909,7 +5939,7 @@ #endif } } - + jm->session_initialized = true; return bootstrapper; @@ -6783,8 +6813,8 @@ kern_return_t job_mig_swap_complex(job_t j, vproc_gsk_t inkey, vproc_gsk_t outkey, - vm_offset_t inval, mach_msg_type_number_t invalCnt, - vm_offset_t *outval, mach_msg_type_number_t *outvalCnt) + vm_offset_t inval, mach_msg_type_number_t invalCnt, + vm_offset_t *outval, mach_msg_type_number_t *outvalCnt) { const char *action; launch_data_t input_obj = NULL, output_obj = NULL; @@ -7118,7 +7148,7 @@ } kern_return_t -job_mig_post_fork_ping(job_t j, task_t child_task) +job_mig_post_fork_ping(job_t j, task_t child_task, mach_port_t *audit_session) { struct machservice *ms; @@ -7155,6 +7185,14 @@ } } + mach_port_t _session = MACH_PORT_NULL; +#if !TARGET_OS_EMBEDDED + if( !j->anonymous && !j->per_user ) { + job_log(j, LOG_DEBUG, "Returning session port %u", j->audit_session); + _session = j->audit_session; + } +#endif + *audit_session = _session; job_assumes(j, launchd_mport_deallocate(child_task) == KERN_SUCCESS); return 0; @@ -7823,6 +7861,51 @@ return kr; } +#if !TARGET_OS_EMBEDDED +kern_return_t +job_mig_set_security_session(job_t j, uuid_t uuid, mach_port_t session) +{ + uuid_string_t uuid_str; + uuid_unparse(uuid, uuid_str); + job_log(j, LOG_DEBUG, "Setting session %u for UUID %s...", session, uuid_str); + + job_t ji = NULL, jt = NULL; + LIST_FOREACH_SAFE( ji, &s_needing_sessions, sle, jt ) { + uuid_string_t uuid_str2; + uuid_unparse(ji->expected_audit_uuid, uuid_str2); + + if( uuid_compare(uuid, ji->expected_audit_uuid) == 0 ) { + uuid_clear(ji->expected_audit_uuid); + if( session != MACH_PORT_NULL ) { + job_log(ji, LOG_DEBUG, "Job should join session with port %u", session); + mach_port_mod_refs(mach_task_self(), session, MACH_PORT_RIGHT_SEND, 1); + } else { + job_log(ji, LOG_DEBUG, "No session to set for job. Using our session."); + } + + ji->audit_session = session; + LIST_REMOVE(ji, needing_session_sle); + job_dispatch(ji, false); + } + } + + /* Each job that the session port was set for holds a reference. At the end of + * the loop, there will be one extra reference belonging to this MiG protocol. + * We need to release it so that the session goes away when all the jobs + * referencing it are unloaded. + */ + mach_port_deallocate(mach_task_self(), session); + + return KERN_SUCCESS; +} +#else +kern_return_t +job_mig_set_security_session(job_t j __attribute__((unused)), uuid_t uuid __attribute__((unused)), mach_port_t session __attribute__((unused))) +{ + return KERN_SUCCESS; +} +#endif + jobmgr_t jobmgr_find_by_name(jobmgr_t jm, const char *where) { @@ -7866,7 +7949,7 @@ } kern_return_t -job_mig_move_subset(job_t j, mach_port_t target_subset, name_t session_type, uint64_t flags) +job_mig_move_subset(job_t j, mach_port_t target_subset, name_t session_type, mach_port_t audit_session, uint64_t flags) { mach_msg_type_number_t l2l_i, l2l_port_cnt = 0; mach_port_array_t l2l_ports = NULL; @@ -7880,50 +7963,7 @@ return BOOTSTRAP_NO_MEMORY; } - if (target_subset == MACH_PORT_NULL) { - job_t j2; - - if (j->mgr->session_initialized) { - job_log(j, LOG_ERR, "Tried to initialize an already setup session!"); - kr = BOOTSTRAP_NOT_PRIVILEGED; - goto out; - } else if (strcmp(session_type, VPROCMGR_SESSION_LOGINWINDOW) == 0) { - jobmgr_t jmi; - - /* - * 5330262 - * - * We're working around LoginWindow and the WindowServer. - * - * In practice, there is only one LoginWindow session. Unfortunately, for certain - * scenarios, the WindowServer spawns loginwindow, and in those cases, it frequently - * spawns a replacement loginwindow session before cleaning up the previous one. - * - * We're going to use the creation of a new LoginWindow context as a clue that the - * previous LoginWindow context is on the way out and therefore we should just - * kick-start the shutdown of it. - */ - - SLIST_FOREACH(jmi, &root_jobmgr->submgrs, sle) { - if (unlikely(jmi->shutting_down)) { - continue; - } else if (strcasecmp(jmi->name, session_type) == 0) { - jobmgr_shutdown(jmi); - break; - } - } - } - - jobmgr_log(j->mgr, LOG_DEBUG, "Renaming to: %s", session_type); - strcpy(j->mgr->name_init, session_type); - - if (job_assumes(j, (j2 = jobmgr_init_session(j->mgr, session_type, false)))) { - job_assumes(j, job_dispatch(j2, true)); - } - - kr = 0; - goto out; - } else if (job_mig_intran2(root_jobmgr, target_subset, ldc->pid)) { + if (job_mig_intran2(root_jobmgr, target_subset, ldc->pid)) { job_log(j, LOG_ERR, "Moving a session to ourself is bogus."); kr = BOOTSTRAP_NOT_PRIVILEGED; @@ -7940,7 +7980,7 @@ launchd_assert(launch_data_array_get_count(out_obj_array) == l2l_port_cnt); - if (!job_assumes(j, (jmr = jobmgr_new(j->mgr, reqport, rcvright, false, session_type)) != NULL)) { + if (!job_assumes(j, (jmr = jobmgr_new(j->mgr, reqport, rcvright, false, session_type, audit_session)) != NULL)) { kr = BOOTSTRAP_NO_MEMORY; goto out; } @@ -8014,7 +8054,7 @@ } kern_return_t -job_mig_init_session(job_t j, name_t session_type) +job_mig_init_session(job_t j, name_t session_type, mach_port_t audit_session) { job_t j2; @@ -8053,6 +8093,7 @@ strcpy(j->mgr->name_init, session_type); if (job_assumes(j, (j2 = jobmgr_init_session(j->mgr, session_type, false)))) { + j2->audit_session = audit_session; job_assumes(j, job_dispatch(j2, true)); kr = BOOTSTRAP_SUCCESS; } @@ -8061,9 +8102,9 @@ } kern_return_t -job_mig_switch_to_session(job_t j, mach_port_t requestor_port, name_t session_name, mach_port_t *new_bsport) +job_mig_switch_to_session(job_t j, mach_port_t requestor_port, name_t session_name, mach_port_t audit_session, mach_port_t *new_bsport) { - job_log(j, LOG_NOTICE, "Job wants to move to %s session.", session_name); + job_log(j, LOG_DEBUG, "Job wants to move to %s session.", session_name); if( !job_assumes(j, pid1_magic == false) ) { job_log(j, LOG_WARNING, "Switching sessions is not allowed in the system Mach bootstrap."); @@ -8077,11 +8118,18 @@ jobmgr_t target_jm = jobmgr_find_by_name(root_jobmgr, session_name); if( target_jm == j->mgr ) { - job_log(j, LOG_WARNING, "Job tried to switch to its current session (%s).", session_name); - return BOOTSTRAP_NOT_PRIVILEGED; + job_log(j, LOG_DEBUG, "Job is already in its desired session (%s).", session_name); + *new_bsport = target_jm->jm_port; + return BOOTSTRAP_SUCCESS; } - target_jm = target_jm ? : jobmgr_new(j->mgr, requestor_port, MACH_PORT_NULL, false, session_name); + if( !target_jm ) { + target_jm = jobmgr_new(j->mgr, requestor_port, MACH_PORT_NULL, false, session_name, audit_session); + if( !target_jm ) { + mach_port_deallocate(mach_task_self(), audit_session); + } + } + if( !job_assumes(j, target_jm != NULL) ) { job_log(j, LOG_WARNING, "Could not find %s session!", session_name); return BOOTSTRAP_NO_MEMORY; @@ -8293,7 +8341,7 @@ return BOOTSTRAP_NO_MEMORY; } - if (!job_assumes(j, (jmr = jobmgr_new(j->mgr, requestorport, MACH_PORT_NULL, false, NULL)) != NULL)) { + if (!job_assumes(j, (jmr = jobmgr_new(j->mgr, requestorport, MACH_PORT_NULL, false, NULL, j->audit_session)) != NULL)) { if (unlikely(requestorport == MACH_PORT_NULL)) { return BOOTSTRAP_NOT_PRIVILEGED; } @@ -8426,7 +8474,7 @@ } kern_return_t -job_mig_spawn(job_t j, vm_offset_t indata, mach_msg_type_number_t indataCnt, pid_t *child_pid, mach_port_t *obsvr_port) +job_mig_spawn(job_t j, vm_offset_t indata, mach_msg_type_number_t indataCnt, mach_port_t audit_session, pid_t *child_pid, mach_port_t *obsvr_port) { launch_data_t input_obj = NULL; size_t data_offset = 0; @@ -8466,7 +8514,7 @@ jobmgr_log(j->mgr, LOG_NOTICE, "%s() can't find its session!", __func__); return 1; } - + jr = jobmgr_import2(target_jm ?: j->mgr, input_obj); if (!job_assumes(j, jr != NULL)) { @@ -8486,6 +8534,8 @@ jr->abandon_pg = true; jr->stall_before_exec = jr->wait4debugger; jr->wait4debugger = false; + jr->audit_session = audit_session; + uuid_clear(jr->expected_audit_uuid); jr = job_dispatch(jr, true); @@ -8518,8 +8568,9 @@ { const char *root_session_type = pid1_magic ? VPROCMGR_SESSION_SYSTEM : VPROCMGR_SESSION_BACKGROUND; SLIST_INIT(&s_curious_jobs); + LIST_INIT(&s_needing_sessions); - launchd_assert((root_jobmgr = jobmgr_new(NULL, MACH_PORT_NULL, MACH_PORT_NULL, sflag, root_session_type)) != NULL); + launchd_assert((root_jobmgr = jobmgr_new(NULL, MACH_PORT_NULL, MACH_PORT_NULL, sflag, root_session_type, MACH_PORT_NULL)) != NULL); uint32_t fflags = NOTE_ATTRIB | NOTE_LINK | NOTE_REVOKE | NOTE_EXTEND | NOTE_WRITE; s_no_hang_fd = open("/dev/autofs_nowait", O_EVTONLY | O_NONBLOCK); Modified: trunk/launchd/src/launchd_core_logic.h =================================================================== --- trunk/launchd/src/launchd_core_logic.h 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/launchd_core_logic.h 2009-02-28 21:15:57 UTC (rev 23849) @@ -29,6 +29,8 @@ extern jobmgr_t root_jobmgr; extern mach_port_t inherited_bootstrap_port; +extern mach_port_t g_audit_session_port; +extern au_asid_t g_audit_session; extern bool g_flat_mach_namespace; void jobmgr_init(bool); Modified: trunk/launchd/src/launchd_mig_types.defs =================================================================== --- trunk/launchd/src/launchd_mig_types.defs 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/launchd_mig_types.defs 2009-02-28 21:15:57 UTC (rev 23849) @@ -36,6 +36,7 @@ type bootstrap_property_array_t = ^array [] of bootstrap_property_t; type bootstrap_status_t = integer_t; type bootstrap_status_array_t = ^array [] of bootstrap_status_t; +type uuid_t = array [16] of MACH_MSG_TYPE_BYTE; type job_t = mach_port_t intran : job_t job_mig_intran(mach_port_t) Modified: trunk/launchd/src/launchd_runtime.c =================================================================== --- trunk/launchd/src/launchd_runtime.c 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/launchd_runtime.c 2009-02-28 21:15:57 UTC (rev 23849) @@ -1239,9 +1239,13 @@ int _pri = pri & ~LOG_CONSOLE; struct runtime_syslog_attr attr = { - "com.apple.launchd", "com.apple.launchd", + g_my_label, + g_my_label, pid1_magic ? "System" : "Background", - _pri, getuid(), getpid(), getpid() + _pri, + getuid(), + getpid(), + getpid() }; va_list ap; @@ -1271,9 +1275,8 @@ vsnprintf(newmsg, sizeof(newmsg), message, args); - if (unlikely(low_level_debug) || echo_to_console) { - fprintf(g_console, "%s %u\t%s %u\t%s\n", attr->from_name, attr->from_pid, - attr->about_name, attr->about_pid, newmsg); + if( g_console && (unlikely(low_level_debug) || echo_to_console) ) { + fprintf(g_console, "%s %u\t%s %u\t%s\n", attr->from_name, attr->from_pid, attr->about_name, attr->about_pid, newmsg); } logmsg_add(attr, saved_errno, newmsg); Modified: trunk/launchd/src/launchd_runtime.h =================================================================== --- trunk/launchd/src/launchd_runtime.h 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/launchd_runtime.h 2009-02-28 21:15:57 UTC (rev 23849) @@ -101,6 +101,7 @@ extern bool pid1_magic; extern bool low_level_debug; extern char g_username[128]; +extern char g_my_label[128]; extern bool g_shutdown_debugging; extern bool g_use_gmalloc; extern bool g_log_per_user_shutdown; Modified: trunk/launchd/src/liblaunch.c =================================================================== --- trunk/launchd/src/liblaunch.c 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/liblaunch.c 2009-02-28 21:15:57 UTC (rev 23849) @@ -40,6 +40,8 @@ #include #include #include +#include +#include #ifdef __LP64__ /* workaround: 5723161 */ @@ -951,6 +953,23 @@ return r; } +extern kern_return_t vproc_mig_set_security_session(mach_port_t, uuid_t, mach_port_t); + +static inline bool +uuid_data_is_null(launch_data_t d) +{ + bool result = false; + if( launch_data_get_type(d) == LAUNCH_DATA_OPAQUE && launch_data_get_opaque_size(d) == sizeof(uuid_t) ) { + uuid_t existing_uuid; + memcpy(existing_uuid, launch_data_get_opaque(d), sizeof(uuid_t)); + + /* A NULL UUID tells us to keep the session inherited from the parent. */ + result = (bool)uuid_is_null(existing_uuid); + } + + return result; +} + launch_data_t launch_msg_internal(launch_data_t d) { @@ -964,6 +983,46 @@ pthread_once(&_lc_once, launch_client_init); +#if !TARGET_OS_EMBEDDED + uuid_t uuid; + launch_data_t uuid_d = NULL; + size_t jobs_that_need_sessions = 0; + if( d && launch_data_get_type(d) == LAUNCH_DATA_DICTIONARY ) { + launch_data_t v = launch_data_dict_lookup(d, LAUNCH_KEY_SUBMITJOB); + + if( v && launch_data_get_type(v) == LAUNCH_DATA_ARRAY ) { + size_t cnt = launch_data_array_get_count(v); + size_t i = 0; + + uuid_generate(uuid); + for( i = 0; i < cnt; i++ ) { + launch_data_t ji = launch_data_array_get_index(v, i); + if( launch_data_get_type(ji) == LAUNCH_DATA_DICTIONARY ) { + launch_data_t existing_v = launch_data_dict_lookup(ji, LAUNCH_JOBKEY_SECURITYSESSIONUUID); + if( !existing_v ) { + /* I really wish these were reference-counted. Sigh... */ + uuid_d = launch_data_new_opaque(uuid, sizeof(uuid)); + launch_data_dict_insert(ji, uuid_d, LAUNCH_JOBKEY_SECURITYSESSIONUUID); + jobs_that_need_sessions++; + } else if( launch_data_get_type(existing_v) == LAUNCH_DATA_OPAQUE ) { + jobs_that_need_sessions += uuid_data_is_null(existing_v) ? 0 : 1; + } + } + } + } else if( v && launch_data_get_type(v) == LAUNCH_DATA_DICTIONARY ) { + launch_data_t existing_v = launch_data_dict_lookup(v, LAUNCH_JOBKEY_SECURITYSESSIONUUID); + if( !existing_v ) { + uuid_generate(uuid); + uuid_d = launch_data_new_opaque(uuid, sizeof(uuid)); + launch_data_dict_insert(v, uuid_d, LAUNCH_JOBKEY_SECURITYSESSIONUUID); + jobs_that_need_sessions++; + } else { + jobs_that_need_sessions += uuid_data_is_null(existing_v) ? 0 : 1; + } + } + } +#endif + if (!_lc) { errno = ENOTCONN; return NULL; @@ -999,8 +1058,28 @@ } } } +out: +#if !TARGET_OS_EMBEDDED + if( !uuid_is_null(uuid) && resp && jobs_that_need_sessions > 0 ) { + mach_port_t session = MACH_PORT_NULL; + if( (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO && launch_data_get_errno(resp) == 0) || launch_data_get_type(resp) == LAUNCH_DATA_ARRAY ) { + session = _audit_session_self(); + } -out: + kern_return_t kr = KERN_FAILURE; + + /* If we can't get our own session, set the sessions for our recently-submitted jobs + * to MACH_PORT_NULL. + */ + kr = vproc_mig_set_security_session(bootstrap_port, uuid, session); + + if( kr != KERN_SUCCESS || session == MACH_PORT_NULL ) { + launch_data_set_errno(resp, EACCES); + _vproc_log_error(LOG_WARNING, "Could not set security session for recently submitted jobs!"); + } + } +#endif + pthread_mutex_unlock(&_lc->mtx); return resp; Modified: trunk/launchd/src/libvproc.c =================================================================== --- trunk/launchd/src/libvproc.c 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/libvproc.c 2009-02-28 21:15:57 UTC (rev 23849) @@ -35,6 +35,7 @@ #include #include #include +#include #if HAVE_QUARANTINE #include @@ -407,13 +408,45 @@ vproc_err_t _vproc_post_fork_ping(void) { - return vproc_mig_post_fork_ping(bootstrap_port, mach_task_self()) == 0 ? NULL : _vproc_post_fork_ping; +#if !TARGET_OS_EMBEDDED + au_asid_t s = AU_DEFAUDITSID; + do { + mach_port_t session = MACH_PORT_NULL; + kern_return_t kr = vproc_mig_post_fork_ping(bootstrap_port, mach_task_self(), &session); + if( kr != KERN_SUCCESS ) { + /* If this happens, our bootstrap port probably got hosed. */ + _vproc_log(LOG_ERR, "Post-fork ping failed!"); + break; + } + + /* If we get back MACH_PORT_NULL, that means we just stick with the session + * we inherited across fork(2). + */ + if( session == MACH_PORT_NULL ) { + s = ~AU_DEFAUDITSID; + break; + } + + s = _audit_session_join(session); + if( s == 0 ) { + _vproc_log_error(LOG_ERR, "Could not join security session!"); + s = AU_DEFAUDITSID; + } else { + _vproc_log(LOG_DEBUG, "Joined session %d.", s); + } + } while( 0 ); + + return s != AU_DEFAUDITSID ? NULL : _vproc_post_fork_ping; +#else + mach_port_t session = MACH_PORT_NULL; + return vproc_mig_post_fork_ping(bootstrap_port, mach_task_self(), &session) ? _vproc_post_fork_ping : NULL; +#endif } vproc_err_t _vprocmgr_init(const char *session_type) { - if (vproc_mig_init_session(bootstrap_port, (char *)session_type) == 0) { + if (vproc_mig_init_session(bootstrap_port, (char *)session_type, _audit_session_self()) == 0) { return NULL; } @@ -457,7 +490,7 @@ mach_port_deallocate(mach_task_self(), bootstrap_port); bootstrap_port = puc; } else { - kr = vproc_mig_move_subset(puc, bootstrap_port, (char *)session_type, flags); + kr = vproc_mig_move_subset(puc, bootstrap_port, (char *)session_type, _audit_session_self(), flags); mach_port_deallocate(mach_task_self(), puc); } @@ -475,11 +508,10 @@ { mach_port_t new_bsport = MACH_PORT_NULL; kern_return_t kr = KERN_FAILURE; - + mach_port_t tnp = MACH_PORT_NULL; task_name_for_pid(mach_task_self(), getpid(), &tnp); - - if( (kr = vproc_mig_switch_to_session(bootstrap_port, tnp, (char *)target_session, &new_bsport)) != KERN_SUCCESS ) { + if( (kr = vproc_mig_switch_to_session(bootstrap_port, tnp, (char *)target_session, _audit_session_self(), &new_bsport)) != KERN_SUCCESS ) { _vproc_log(LOG_NOTICE, "_vprocmgr_switch_to_session(): kr = 0x%x", kr); return (vproc_err_t)_vprocmgr_switch_to_session; } @@ -628,13 +660,13 @@ indata = (vm_offset_t)buf; - kr = vproc_mig_spawn(bootstrap_port, indata, indata_cnt, &p, &obsvr_port); + kr = vproc_mig_spawn(bootstrap_port, indata, indata_cnt, _audit_session_self(), &p, &obsvr_port); if (kr == VPROC_ERR_TRY_PER_USER) { mach_port_t puc; if (vproc_mig_lookup_per_user_context(bootstrap_port, 0, &puc) == 0) { - kr = vproc_mig_spawn(puc, indata, indata_cnt, &p, &obsvr_port); + kr = vproc_mig_spawn(puc, indata, indata_cnt, _audit_session_self(), &p, &obsvr_port); mach_port_deallocate(mach_task_self(), puc); } } Modified: trunk/launchd/src/protocol_vproc.defs =================================================================== --- trunk/launchd/src/protocol_vproc.defs 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/protocol_vproc.defs 2009-02-28 21:15:57 UTC (rev 23849) @@ -83,7 +83,8 @@ routine post_fork_ping( __bs_port : job_t; - __task_port : task_t); + __task_port : task_t; +out __audit_session : mach_port_t); routine info( __bs_port : job_t; @@ -114,6 +115,7 @@ routine spawn( __bs_port : job_t; __indata : pointer_t; + __audit_session : mach_port_t; out __pid : pid_t; out __obsvr_port : mach_port_make_send_t); @@ -147,6 +149,7 @@ __bs_port : job_t; __target_port : mach_port_t; __sessiontype : name_t; + __audit_session : mach_port_t; __sessionflags : uint64_t); routine swap_complex( @@ -188,6 +191,7 @@ __bs_port : job_t; __req_port : mach_port_t; __session_name : name_t; + __audit_session : mach_port_t; out __new_bs_port : mach_port_make_send_t); routine transaction_count_for_pid( @@ -208,8 +212,14 @@ routine init_session( __bs_port : job_t; - __session_name : name_t); + __session_name : name_t; + __audit_session : mach_port_t); +routine set_security_session( + __bs_port : job_t; + __uuid : uuid_t; + __session : mach_port_t); + routine wait2( __bs_port : job_t; __target_port : job_t; Modified: trunk/launchd/src/vproc_internal.h =================================================================== --- trunk/launchd/src/vproc_internal.h 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/vproc_internal.h 2009-02-28 21:15:57 UTC (rev 23849) @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include "launch.h" #include "bootstrap.h" #include "vproc.h" @@ -54,6 +56,14 @@ vproc_err_t _vprocmgr_init(const char *session_type); vproc_err_t _vproc_post_fork_ping(void); +#if !TARGET_OS_EMBEDDED + #define _audit_session_self(v) (mach_port_t)syscall(SYS_audit_session_self) + #define _audit_session_join(s) (au_asid_t)syscall(SYS_audit_session_join, session) +#else + #define _audit_session_self(v) MACH_PORT_NULL + #define _audit_session_join(s) 0 +#endif + #define SPAWN_HAS_PATH 0x0001 #define SPAWN_HAS_WDIR 0x0002 #define SPAWN_HAS_UMASK 0x0004 @@ -65,7 +75,6 @@ kern_return_t _vprocmgr_getsocket(name_t); - struct logmsg_s { union { STAILQ_ENTRY(logmsg_s) sqe; Modified: trunk/launchd/src/vproc_priv.h =================================================================== --- trunk/launchd/src/vproc_priv.h 2009-02-28 06:34:34 UTC (rev 23848) +++ trunk/launchd/src/vproc_priv.h 2009-02-28 21:15:57 UTC (rev 23849) @@ -28,6 +28,7 @@ #include #include #include +#include #ifndef VPROC_HAS_TRANSACTIONS #define VPROC_HAS_TRANSACTIONS @@ -61,6 +62,7 @@ VPROC_GSK_TRANSACTIONS_ENABLED, VPROC_GSK_WEIRD_BOOTSTRAP, VPROC_GSK_WAITFORDEBUGGER, + VPROC_GSK_SECURITYSESSION, VPROC_GSK_SHUTDOWN_DEBUGGING, VPROC_GSK_PERUSER_SUSPEND, VPROC_GSK_PERUSER_RESUME, -------------- next part -------------- An HTML attachment was scrubbed... URL: From source_changes at macosforge.org Sat Feb 28 13:16:59 2009 From: source_changes at macosforge.org (source_changes at macosforge.org) Date: Sat, 28 Feb 2009 13:16:59 -0800 (PST) Subject: [launchd-changes] [23850] tags/launchd-302/ Message-ID: <20090228211659.D0EFD10EA616@beta.macosforge.org> Revision: 23850 http://trac.macosforge.org/projects/launchd/changeset/23850 Author: dsorresso at apple.com Date: 2009-02-28 13:16:59 -0800 (Sat, 28 Feb 2009) Log Message: ----------- "Tagging launchd-302 from https://svn.macosforge.org/repository/launchd/trunk" Added Paths: ----------- tags/launchd-302/ Property changes on: tags/launchd-302 ___________________________________________________________________ Added: svn:ignore + build Added: svn:mergeinfo + /branches/PR-5092682:23731-23742 /branches/PR-5898404:23681-23700 /branches/PR-5978442:23651-23701 /branches/PR-6132016:23719-23738 /branches/PR-6271234:23818-23822 /branches/PR-6562592:23812-23822 /branches/PR-6589133:23810-23822 /branches/PR-6609410:23828 -------------- next part -------------- An HTML attachment was scrubbed... URL: