[launchd-changes] [23853] trunk/launchd/src
source_changes at macosforge.org
source_changes at macosforge.org
Mon Mar 9 17:16:40 PDT 2009
Revision: 23853
http://trac.macosforge.org/projects/launchd/changeset/23853
Author: dsorresso at apple.com
Date: 2009-03-09 17:16:39 -0700 (Mon, 09 Mar 2009)
Log Message:
-----------
<rdar://problem/6501491>
<rdar://problem/6527009>
<rdar://problem/6268510>
<rdar://problem/6565238> MNT: Attempting to unmount volumes one by one fails without an error
Modified Paths:
--------------
trunk/launchd/src/launch_priv.h
trunk/launchd/src/launchctl.c
trunk/launchd/src/launchd_core_logic.c
trunk/launchd/src/libbootstrap.c
Modified: trunk/launchd/src/launch_priv.h
===================================================================
--- trunk/launchd/src/launch_priv.h 2009-03-03 05:21:24 UTC (rev 23852)
+++ trunk/launchd/src/launch_priv.h 2009-03-10 00:16:39 UTC (rev 23853)
@@ -61,6 +61,8 @@
#define LAUNCH_JOBKEY_JETSAMPRIORITY "JetsamPriority"
#define LAUNCH_JOBKEY_SECURITYSESSIONUUID "SecuritySessionUUID"
+#define LAUNCH_JOBKEY_EMBEDDEDSHUTDOWNAUTHORITY "EmbeddedShutdownAuthority"
+
#define LAUNCH_JOBKEY_ENTERKERNELDEBUGGERBEFOREKILL "EnterKernelDebuggerBeforeKill"
#define LAUNCH_JOBKEY_PERJOBMACHSERVICES "PerJobMachServices"
#define LAUNCH_JOBKEY_SERVICEIPC "ServiceIPC"
Modified: trunk/launchd/src/launchctl.c
===================================================================
--- trunk/launchd/src/launchctl.c 2009-03-03 05:21:24 UTC (rev 23852)
+++ trunk/launchd/src/launchctl.c 2009-03-10 00:16:39 UTC (rev 23853)
@@ -270,8 +270,8 @@
#if 0
static bool g_job_cache_db_has_changed = false;
static launch_data_t g_job_cache_db = NULL;
-#endif
static char g_job_cache_db_path[PATH_MAX];
+#endif
int
main(int argc, char *const argv[])
@@ -325,7 +325,7 @@
int64_t manager_uid = -1, manager_pid = -1;
if( vproc_swap_integer(NULL, VPROC_GSK_MGR_UID, NULL, &manager_uid) == NULL ) {
if( vproc_swap_integer(NULL, VPROC_GSK_MGR_PID, NULL, &manager_pid) == NULL ) {
- if( manager_uid || manager_uid == 1 ) {
+ if( manager_uid || manager_pid == 1 ) {
fprintf(stderr, "Running in the root user's per-user context is not supported outside of the root user's bootstrap.\n");
exit(EXIT_FAILURE);
}
@@ -350,32 +350,6 @@
}
}
- char *db = NULL;
- 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 overrides database.\n");
- g_job_overrides_db_path[0] = 0;
- } else {
- strncpy(g_job_overrides_db_path, db, strlen(db));
- free(db);
-
- 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);
- }
- }
-
- verr = vproc_swap_string(NULL, VPROC_GSK_JOB_CACHE_DB, NULL, &db);
- if( verr ) {
- fprintf(stderr, "Could not get location of job cache database.\n");
- g_job_cache_db_path[0] = 0;
- } else {
- strncpy(g_job_cache_db_path, db, strlen(db));
- free(db);
-
- /* Create our launch_data_t from the file... */
- }
-
if (NULL == readline) {
fprintf(stderr, "missing library: readline\n");
exit(EXIT_FAILURE);
@@ -2120,7 +2094,7 @@
char *load_launchd_items[] = { "load", "-S", session_type, "-D", "all", NULL, NULL, NULL, NULL, NULL, NULL };
int the_argc = 5;
- char *load_launchd_items_user[] = { "load", "-S", session_type, "-D", "user", NULL };
+ char *load_launchd_items_user[] = { "load", "-S", VPROCMGR_SESSION_BACKGROUND, "-D", "user", NULL };
int the_argc_user = 0;
if (is_safeboot()) {
@@ -2137,35 +2111,17 @@
if (strcasecmp(session_type, VPROCMGR_SESSION_LOGINWINDOW) == 0) {
load_launchd_items[the_argc] = "/etc/mach_init_per_login_session.d";
the_argc += 1;
- } else {
- #if 0
- /* If we're a per-user launchd initializing our Background session,
- * don't forget about the user's launchd jobs that may be specified as
- * LimitLoadToSessionType = Background. <rdar://problem/5279345> We also
- * must keep in mind that we need to load the user jobs last, since the
- * jobs in the local sessions may be responsible for mounting the home
- * 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
- * bootstrapping the Aqua or StandardIO sessions. This way, we can
- * safely assume that the home directory is present. Yes it's a hack,
- * but it satisfies the user expectation in 99% of cases.
- */
- if( 0 ) {
- the_argc_user = 5;
- }
- #endif
}
} else if (strcasecmp(session_type, VPROCMGR_SESSION_AQUA) == 0) {
load_launchd_items[5] = "/etc/mach_init_per_user.d";
the_argc += 1;
- /* If we're bootstrapping the Aqua session, bootstrap the user's Background
- * agents.
+ /* For now, we'll just load user Background agents when
+ * bootstrapping the Aqua session. This way, we can
+ * safely assume that the home directory is present. If
+ * we try reading the user's Background agents when we're
+ * actually bootstrapping the Background session, we run the
+ * risk of deadlocking against mount_url. But this fix should
+ * satisfy <rdar://problem/5279345>.
*/
the_argc_user = 5;
@@ -2180,11 +2136,6 @@
* problem.
*/
read_environment_dot_plist();
- } else if (strcasecmp(session_type, VPROCMGR_SESSION_AQUA) == 0) {
- /* If we're bootstrapping the StandardIO session, bootstrap the user's Background
- * agents.
- */
- the_argc_user = 5;
}
if (strcasecmp(session_type, VPROCMGR_SESSION_BACKGROUND) == 0) {
@@ -2198,13 +2149,10 @@
int retval = load_and_unload_cmd(the_argc, load_launchd_items);
if( retval == 0 && the_argc_user != 0 ) {
optind = 1;
- pid_t p = getpid();
- if( sysctlbyname("vfs.generic.noremotehang", NULL, NULL, &p, sizeof(p)) == 0 ) {
- int64_t junk = 0;
- vproc_err_t err = vproc_swap_integer(NULL, VPROC_GSK_WEIRD_BOOTSTRAP, &junk, NULL);
- if( !err ) {
- retval = load_and_unload_cmd(the_argc_user, load_launchd_items_user);
- }
+ int64_t junk = 0;
+ vproc_err_t err = vproc_swap_integer(NULL, VPROC_GSK_WEIRD_BOOTSTRAP, &junk, NULL);
+ if( !err ) {
+ retval = load_and_unload_cmd(the_argc_user, load_launchd_items_user);
}
}
@@ -2278,6 +2226,28 @@
return 1;
}
+ int dbfd = -1;
+ char *db = NULL;
+ 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 overrides database.\n");
+ g_job_overrides_db_path[0] = 0;
+ } else {
+ strncpy(g_job_overrides_db_path, db, strlen(db));
+ free(db);
+
+ /* If we can't create or lock the overrides database, we'll fall back to writing to the
+ * plist file directly.
+ */
+ assumes((dbfd = open(db, O_RDONLY | O_EXLOCK | O_CREAT, S_IRUSR | S_IWUSR)) != -1);
+ if( dbfd != -1 ) {
+ 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);
+ }
+ }
+ }
+
/* I wish I didn't need to do three passes, but I need to load mDNSResponder and use it too.
* And loading legacy mach init jobs is extra fun.
*
@@ -2345,7 +2315,9 @@
if( g_job_overrides_db_has_changed ) {
WriteMyPropertyListToFile(g_job_overrides_db, g_job_overrides_db_path);
}
-
+
+ flock(dbfd, LOCK_UN);
+ close(dbfd);
return 0;
}
@@ -3029,7 +3001,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;
}
Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c 2009-03-03 05:21:24 UTC (rev 23852)
+++ trunk/launchd/src/launchd_core_logic.c 2009-03-10 00:16:39 UTC (rev 23853)
@@ -527,6 +527,7 @@
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. */
+ embedded_shutdown_auth :1, /* The job is allowed to call reboot2() on embedded. */
migratory :1; /* The (anonymous) job called vprocmgr_switch_to_session(). */
mode_t mask;
pid_t tracing_pid;
@@ -642,6 +643,7 @@
#else
pid_t g_audit_session = 0;
#endif
+static bool s_embedded_shutdown_right_claimed = false;
static pid_t s_update_pid = 0;
static int s_no_hang_fd = -1;
@@ -1686,6 +1688,9 @@
} else if (strcasecmp(key, LAUNCH_JOBKEY_ENTERKERNELDEBUGGERBEFOREKILL) == 0) {
j->debug_before_kill = value;
found_key = true;
+ } else if( !s_embedded_shutdown_right_claimed && strcasecmp(key, LAUNCH_JOBKEY_EMBEDDEDSHUTDOWNAUTHORITY) == 0 ) {
+ j->embedded_shutdown_auth = true;
+ s_embedded_shutdown_right_claimed = true;
}
break;
case 'w':
@@ -3512,6 +3517,8 @@
switch (c = runtime_fork(j->weird_bootstrap ? j->j_port : j->mgr->jm_port)) {
case -1:
job_log_error(j, LOG_ERR, "fork() failed, will try again in one second");
+ job_assumes(j, kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_ADD|EV_ONESHOT, NOTE_SECONDS, 1, j) != -1);
+
job_assumes(j, runtime_close(execspair[0]) == 0);
job_assumes(j, runtime_close(execspair[1]) == 0);
if (sipc) {
@@ -7242,7 +7249,11 @@
return BOOTSTRAP_NOT_PRIVILEGED;
}
- if (unlikely(ldc->euid)) {
+#if !TARGET_OS_EMBEDDED
+ if( unlikely(ldc->euid) ) {
+#else
+ if( unlikely(ldc->euid) && !j->embedded_shutdown_auth ) {
+#endif
return BOOTSTRAP_NOT_PRIVILEGED;
}
Modified: trunk/launchd/src/libbootstrap.c
===================================================================
--- trunk/launchd/src/libbootstrap.c 2009-03-03 05:21:24 UTC (rev 23852)
+++ trunk/launchd/src/libbootstrap.c 2009-03-10 00:16:39 UTC (rev 23853)
@@ -179,21 +179,21 @@
static mach_port_t prev_bp;
static mach_port_t prev_sp;
static name_t prev_name;
- static bool privileged_server_okay;
audit_token_t au_tok;
bool per_pid_lookup = flags & BOOTSTRAP_PER_PID_SERVICE;
+ bool privileged_server_lookup = flags & BOOTSTRAP_PRIVILEGED_SERVER;
kern_return_t kr = 0;
mach_port_t puc;
-
+
pthread_mutex_lock(&bslu2_lock);
-
- if (per_pid_lookup) {
+
+ if (per_pid_lookup || privileged_server_lookup) {
goto skip_cache;
}
-
+
if (prev_sp) {
if ((bp == prev_bp) && (strncmp(prev_name, service_name, sizeof(name_t)) == 0)
- && (mach_port_mod_refs(mach_task_self(), prev_sp, MACH_PORT_RIGHT_SEND, 1) == 0)) {
+ && (mach_port_mod_refs(mach_task_self(), prev_sp, MACH_PORT_RIGHT_SEND, 1) == 0)) {
*sp = prev_sp;
goto out;
} else {
@@ -201,49 +201,45 @@
prev_sp = 0;
}
}
-
+
skip_cache:
- privileged_server_okay = false;
if ((kr = vproc_mig_look_up2(bp, (char *)service_name, sp, &au_tok, target_pid, flags)) != VPROC_ERR_TRY_PER_USER) {
goto out;
}
-
+
if ((kr = vproc_mig_lookup_per_user_context(bp, 0, &puc)) != 0) {
goto out;
}
-
+
kr = vproc_mig_look_up2(puc, (char *)service_name, sp, &au_tok, target_pid, flags);
mach_port_deallocate(mach_task_self(), puc);
-
+
out:
- if (!per_pid_lookup && kr == 0 && prev_sp == 0 && mach_port_mod_refs(mach_task_self(), *sp, MACH_PORT_RIGHT_SEND, 1) == 0) {
+ if (!(per_pid_lookup || privileged_server_lookup) && kr == 0 && prev_sp == 0 && mach_port_mod_refs(mach_task_self(), *sp, MACH_PORT_RIGHT_SEND, 1) == 0) {
/* We're going to hold on to a send right as a MRU cache */
prev_bp = bp;
prev_sp = *sp;
strlcpy(prev_name, service_name, sizeof(name_t));
}
-
- if ((kr == 0) && (flags & BOOTSTRAP_PRIVILEGED_SERVER) && !privileged_server_okay) {
+
+ if ((kr == 0) && privileged_server_lookup) {
uid_t server_euid;
-
+
/*
* The audit token magic is dependent on the per-user launchd
* forwarding MIG requests to the root launchd when it cannot
* find the answer locally.
*/
-
+
/* This API should be in Libsystem, but is not */
//audit_token_to_au32(au_tok, NULL, &server_euid, NULL, NULL, NULL, NULL, NULL, NULL);
server_euid = au_tok.val[1];
-
+
if (server_euid) {
mach_port_deallocate(mach_task_self(), *sp);
kr = BOOTSTRAP_NOT_PRIVILEGED;
- } else {
- privileged_server_okay = true;
}
-
}
/* If performance becomes a problem, we should restructure this. */
pthread_mutex_unlock(&bslu2_lock);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/launchd-changes/attachments/20090309/81873ee4/attachment-0001.html>
More information about the launchd-changes
mailing list