[launchd-changes] [23130] trunk/launchd/src
source_changes at macosforge.org
source_changes at macosforge.org
Sun Mar 4 15:38:22 PST 2007
Revision: 23130
http://trac.macosforge.org/projects/launchd/changeset/23130
Author: zarzycki at apple.com
Date: 2007-03-04 15:38:21 -0800 (Sun, 04 Mar 2007)
Log Message:
-----------
<rdar://problem/4465956> launchd should be able to bootstrap itself
Modified Paths:
--------------
trunk/launchd/src/launchctl.c
trunk/launchd/src/launchd_core_logic.c
trunk/launchd/src/liblaunch.c
trunk/launchd/src/libvproc.c
trunk/launchd/src/libvproc_internal.h
trunk/launchd/src/protocol_job.defs
Modified: trunk/launchd/src/launchctl.c
===================================================================
--- trunk/launchd/src/launchctl.c 2007-03-04 17:34:05 UTC (rev 23129)
+++ trunk/launchd/src/launchctl.c 2007-03-04 23:38:21 UTC (rev 23130)
@@ -250,8 +250,9 @@
}
}
- if (i > 0)
+ if (i > 0) {
demux_cmd(i, argv2);
+ }
free(l);
}
@@ -1243,7 +1244,7 @@
}
static void
-very_pid2_specific_bootstrap(bool sflag)
+system_specific_bootstrap(bool sflag)
{
int hnmib[] = { CTL_KERN, KERN_HOSTNAME };
struct group *tfp_gr;
@@ -1340,7 +1341,7 @@
_vproc_set_global_on_demand(true);
- char *load_launchd_items[] = { "load", "-D", "all", "/etc/mach_init.d", NULL, NULL };
+ char *load_launchd_items[] = { "load", "-D", "all", "/etc/mach_init.d", NULL };
if (is_safeboot()) {
load_launchd_items[2] = "system";
@@ -1387,18 +1388,61 @@
}
int
-bootstrap_cmd(int argc, char *const argv[] __attribute__((unused)))
+bootstrap_cmd(int argc, char *const argv[])
{
- if (getuid() == 0) {
- very_pid2_specific_bootstrap(argc == 2);
+ char *session_type = NULL;
+ bool sflag = false;
+ int ch;
+
+ while ((ch = getopt(argc, argv, "sS:")) != -1) {
+ switch (ch) {
+ case 's':
+ sflag = true;
+ break;
+ case 'S':
+ session_type = optarg;
+ break;
+ case '?':
+ default:
+ break;
+ }
+ }
+
+ optind = 1;
+ optreset = 1;
+
+ if (!session_type) {
+ fprintf(stderr, "usage: %s bootstrap [-s] -S <session-type>\n", getprogname());
+ return 1;
+ }
+
+ if (strcasecmp(session_type, "System") == 0) {
+ system_specific_bootstrap(sflag);
} else {
- char *load_launchd_items[] = { "load", "-D", "all", "-S", "Background", NULL };
+ char *load_launchd_items[] = { "load", "-S", session_type, "-D", "all", NULL, NULL, NULL, NULL };
+ int the_argc = 5;
if (is_safeboot()) {
- load_launchd_items[2] = "system";
+ load_launchd_items[4] = "system";
}
- assumes(load_and_unload_cmd(5, load_launchd_items) == 0);
+ if (strcasecmp(session_type, "Background") == 0 || strcasecmp(session_type, "LoginWindow") == 0) {
+ load_launchd_items[4] = "system";
+ if (!is_safeboot()) {
+ load_launchd_items[5] = "-D";
+ load_launchd_items[6] = "local";
+ the_argc += 2;
+ }
+ if (strcasecmp(session_type, "LoginWindow") == 0) {
+ load_launchd_items[the_argc] = "/etc/mach_init_per_login_session.d";
+ the_argc += 1;
+ }
+ } else if (strcasecmp(session_type, "Aqua") == 0) {
+ load_launchd_items[5] = "/etc/mach_init_per_user.d";
+ the_argc += 1;
+ }
+
+ assumes(load_and_unload_cmd(the_argc, load_launchd_items) == 0);
}
return 0;
@@ -1416,8 +1460,9 @@
memset(&lus, 0, sizeof(lus));
- if (!strcmp(argv[0], "load"))
+ if (strcmp(argv[0], "load") == 0) {
lus.load = true;
+ }
while ((ch = getopt(argc, argv, "wFS:D:")) != -1) {
switch (ch) {
@@ -1431,20 +1476,20 @@
lus.session_type = optarg;
break;
case 'D':
- if (strcasecmp(optarg, "all") == 0) {
- es |= NSAllDomainsMask;
- } else if (strcasecmp(optarg, "user") == 0) {
- es |= NSUserDomainMask;
- } else if (strcasecmp(optarg, "local") == 0) {
- es |= NSLocalDomainMask;
- } else if (strcasecmp(optarg, "network") == 0) {
- es |= NSNetworkDomainMask;
- } else if (strcasecmp(optarg, "system") == 0) {
- es |= NSSystemDomainMask;
- } else {
+ if (strcasecmp(optarg, "all") == 0) {
+ es |= NSAllDomainsMask;
+ } else if (strcasecmp(optarg, "user") == 0) {
+ es |= NSUserDomainMask;
+ } else if (strcasecmp(optarg, "local") == 0) {
+ es |= NSLocalDomainMask;
+ } else if (strcasecmp(optarg, "network") == 0) {
+ es |= NSNetworkDomainMask;
+ } else if (strcasecmp(optarg, "system") == 0) {
+ es |= NSSystemDomainMask;
+ } else {
badopts = true;
- }
- break;
+ }
+ break;
case '?':
default:
badopts = true;
@@ -1454,11 +1499,13 @@
argc -= optind;
argv += optind;
- if (lus.session_type == NULL)
+ if (lus.session_type == NULL) {
es &= ~NSUserDomainMask;
+ }
- if (argc == 0 && es == 0)
+ if (argc == 0 && es == 0) {
badopts = true;
+ }
if (badopts) {
fprintf(stderr, "usage: %s load [-wF] [-D <user|local|network|system|all>] paths...\n", getprogname());
@@ -1497,8 +1544,9 @@
}
}
- for (i = 0; i < (size_t)argc; i++)
+ for (i = 0; i < (size_t)argc; i++) {
readpath(argv[i], &lus);
+ }
if (launch_data_array_get_count(lus.pass0) == 0 &&
launch_data_array_get_count(lus.pass1) == 0 &&
Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c 2007-03-04 17:34:05 UTC (rev 23129)
+++ trunk/launchd/src/launchd_core_logic.c 2007-03-04 23:38:21 UTC (rev 23130)
@@ -211,7 +211,7 @@
#define jobmgr_assumes(jm, e) \
(__builtin_expect(!(e), 0) ? jobmgr_log_bug(jm, __rcs_file_version__, __FILE__, __LINE__, #e), false : true)
-static jobmgr_t jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag);
+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_parent(jobmgr_t jm);
static jobmgr_t jobmgr_do_garbage_collection(jobmgr_t jm);
static bool jobmgr_is_idle(jobmgr_t jm);
@@ -272,7 +272,7 @@
mode_t mask;
unsigned int globargv:1, wait4debugger:1, unload_at_exit:1, stall_before_exec:1, only_once:1,
currently_ignored:1, forced_peers_to_demand_mode:1, setnice:1, hopefully_exits_last:1, removal_pending:1,
- wait4pipe_eof:1, sent_sigkill:1, debug_before_kill:1, weird_per_user_bootstrap:1;
+ wait4pipe_eof:1, sent_sigkill:1, debug_before_kill:1, weird_bootstrap:1;
char label[0];
};
@@ -1649,7 +1649,7 @@
job_log(j, LOG_DEBUG, "Reaping");
- if (j->weird_per_user_bootstrap) {
+ if (j->weird_bootstrap) {
mach_msg_size_t mxmsgsz = sizeof(union __RequestUnion__job_mig_protocol_vproc_subsystem);
if (job_mig_protocol_vproc_subsystem.maxsize > mxmsgsz) {
@@ -1657,7 +1657,7 @@
}
job_assumes(j, runtime_add_mport(j->mgr->jm_port, protocol_vproc_server, mxmsgsz) == KERN_SUCCESS);
- j->weird_per_user_bootstrap = false;
+ j->weird_bootstrap = false;
}
if (j->log_redirect_fd && (!j->wait4pipe_eof || j->mgr->shutting_down)) {
@@ -1996,7 +1996,7 @@
time(&j->start_time);
- switch (c = runtime_fork(j->weird_per_user_bootstrap ? j->j_port : j->mgr->jm_port)) {
+ 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, close(execspair[0]) == 0);
@@ -3397,15 +3397,15 @@
}
jobmgr_t
-jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag)
+jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag, const char *name)
{
- const char *bootstrap_tool[] = { "/bin/launchctl", "bootstrap", NULL, NULL };
+ const char *bootstrap_tool[] = { "/bin/launchctl", "bootstrap", "-S", name, NULL, NULL };
mach_msg_size_t mxmsgsz;
job_t bootstrapper = NULL;
jobmgr_t jmr;
if (sflag) {
- bootstrap_tool[2] = "-s";
+ bootstrap_tool[4] = "-s";
}
launchd_assert(offsetof(struct jobmgr_s, kqjobmgr_callback) == 0);
@@ -3415,7 +3415,7 @@
return NULL;
}
- jmr = calloc(1, sizeof(struct jobmgr_s) + 30);
+ jmr = calloc(1, sizeof(struct jobmgr_s) + (name ? (strlen(name) + 1) : 128));
if (jmr == NULL) {
return NULL;
@@ -3423,7 +3423,7 @@
TAILQ_INIT(&jmr->jobs);
jmr->kqjobmgr_callback = jobmgr_callback;
- strcpy(jmr->name, "In-utero");
+ strcpy(jmr->name, name ? name : "Under construction");
jmr->req_port = requestorport;
@@ -3468,7 +3468,9 @@
goto out_bad;
}
- sprintf(jmr->name, "%u", MACH_PORT_INDEX(jmr->jm_port));
+ if (!name) {
+ sprintf(jmr->name, "%u", MACH_PORT_INDEX(jmr->jm_port));
+ }
/* Sigh... at the moment, MIG has maxsize == sizeof(reply union) */
mxmsgsz = sizeof(union __RequestUnion__job_mig_protocol_vproc_subsystem);
@@ -3478,17 +3480,20 @@
jobmgr_assumes(jmr, (jmr->anonj = jobmgr_get_anonymous(jmr)) != NULL);
- bootstrapper = job_new(jmr, "com.apple.launchctld", NULL, bootstrap_tool);
-
if (!jm) {
jobmgr_assumes(jmr, kevent_mod(SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, jmr) != -1);
}
- if (!jm && getuid() != 0) {
- /* per-user bootstrap context is messy */
- bootstrapper->weird_per_user_bootstrap = true;
- jobmgr_assumes(jmr, job_setup_machport(bootstrapper));
- } else {
+ if (name) {
+ /* no name implies: bootstrap_subset() where creating a "bootstrapper" makes no sense */
+ bootstrapper = job_new(jmr, "com.apple.launchctld", NULL, bootstrap_tool);
+ if (jm || getuid()) {
+ bootstrapper->weird_bootstrap = true;
+ jobmgr_assumes(jmr, job_setup_machport(bootstrapper));
+ }
+ }
+
+ if (!bootstrapper || !bootstrapper->weird_bootstrap) {
if (!jobmgr_assumes(jmr, runtime_add_mport(jmr->jm_port, protocol_vproc_server, mxmsgsz) == KERN_SUCCESS)) {
goto out_bad;
}
@@ -3496,7 +3501,7 @@
jobmgr_log(jmr, LOG_DEBUG, "Created job manager%s%s", jm ? " with parent: " : ".", jm ? jm->name : "");
- if (!jm && jobmgr_assumes(jmr, bootstrapper != NULL)) {
+ if (bootstrapper) {
jobmgr_assumes(jmr, job_dispatch(bootstrapper, true) != NULL);
}
@@ -4586,7 +4591,7 @@
}
kern_return_t
-job_mig_move_subset_to_user(job_t j, mach_port_t target_subset)
+job_mig_move_subset(job_t j, mach_port_t target_subset, name_t session_type)
{
mach_msg_type_number_t l2l_i, l2l_name_cnt = 0, l2l_port_cnt = 0;
name_array_t l2l_names = NULL;
@@ -4596,9 +4601,17 @@
jobmgr_t jmr;
if (getuid() == 0) {
+ const char *bootstrap_tool[] = { "/bin/launchctl", "bootstrap", "-S", session_type, NULL };
+ job_t bootstrapper;
+
j = job_mig_intran2(root_jobmgr, target_subset);
+ strcpy(j->mgr->name, session_type);
job_assumes(j, launchd_mport_deallocate(target_subset) == KERN_SUCCESS);
- strcpy(j->mgr->name, "Aqua");
+
+ bootstrapper = job_new(j->mgr, "com.apple.launchctld", NULL, bootstrap_tool);
+ if (job_assumes(j, bootstrapper != NULL)) {
+ job_dispatch(bootstrapper, true);
+ }
return 0;
}
@@ -4613,13 +4626,11 @@
launchd_assert(l2l_name_cnt == l2l_port_cnt);
- if ((jmr = jobmgr_new(j->mgr, reqport, rcvright, false)) == NULL) {
+ if ((jmr = jobmgr_new(j->mgr, reqport, rcvright, false, session_type)) == NULL) {
kr = BOOTSTRAP_NO_MEMORY;
goto out;
}
- strcpy(jmr->name, "Aqua");
-
for (l2l_i = 0; l2l_i < l2l_name_cnt; l2l_i++) {
struct machservice *ms;
@@ -4742,7 +4753,7 @@
return BOOTSTRAP_NO_MEMORY;
}
- if ((jmr = jobmgr_new(j->mgr, requestorport, MACH_PORT_NULL, false)) == NULL) {
+ if ((jmr = jobmgr_new(j->mgr, requestorport, MACH_PORT_NULL, false, NULL)) == NULL) {
if (requestorport == MACH_PORT_NULL) {
return BOOTSTRAP_NOT_PRIVILEGED;
}
@@ -4917,5 +4928,5 @@
void
jobmgr_init(bool sflag)
{
- launchd_assert((root_jobmgr = jobmgr_new(NULL, MACH_PORT_NULL, MACH_PORT_NULL, sflag)) != NULL);
+ launchd_assert((root_jobmgr = jobmgr_new(NULL, MACH_PORT_NULL, MACH_PORT_NULL, sflag, getpid() == 1 ? "System" : "Background")) != NULL);
}
Modified: trunk/launchd/src/liblaunch.c
===================================================================
--- trunk/launchd/src/liblaunch.c 2007-03-04 17:34:05 UTC (rev 23129)
+++ trunk/launchd/src/liblaunch.c 2007-03-04 23:38:21 UTC (rev 23130)
@@ -1160,101 +1160,28 @@
return r;
}
-static pid_t
-fexecv_as_user(const char *login, uid_t u, gid_t g, char *const argv[])
-{
- int i, dtsz;
- pid_t p;
-
- if ((p = fork()) != 0)
- return p;
-
- chdir("/");
-
- seteuid(0);
- setegid(0);
- setgid(g);
- initgroups(login, g);
- setuid(u);
-
- dtsz = getdtablesize();
-
- for (i = STDERR_FILENO + 1; i < dtsz; i++)
- close(i);
-
- execv(argv[0], argv);
- _exit(EXIT_FAILURE);
-}
-
void
-load_launchd_jobs_at_loginwindow_prompt(int flags, ...)
+load_launchd_jobs_at_loginwindow_prompt(int flags __attribute__((unused)), ...)
{
- char *largv[] = { "/bin/launchctl", "load", "-S", "LoginWindow",
- "-D", "system", "-D", "local", "/etc/mach_init_per_login_session.d", NULL };
- int wstatus;
- pid_t p;
-
- if (flags & LOAD_ONLY_SAFEMODE_LAUNCHAGENTS) {
- largv[5] = "system";
- }
-
- if (__vproc_tag_loginwindow_context()) {
- return;
- }
-
- if ((p = fexecv_as_user("root", 0, 0, largv)) == -1) {
- return;
- }
-
- if (waitpid(p, &wstatus, 0) != p) {
- return;
- }
+ _vproc_move_subset_to_user("LoginWindow");
}
pid_t
-create_and_switch_to_per_session_launchd(const char *login, int flags, ...)
+create_and_switch_to_per_session_launchd(const char *login __attribute__((unused)), int flags __attribute__((unused)), ...)
{
- char *largv[] = { "/bin/launchctl", "load", "-S", "Aqua", "-D", "all", "/etc/mach_init_per_user.d", NULL };
mach_port_t bezel_ui_server;
- struct passwd *pwe;
struct stat sb;
- int wstatus;
- pid_t p;
- uid_t u;
- gid_t g;
- if (_vproc_move_subset_to_user()) {
+ if (_vproc_move_subset_to_user("Aqua")) {
return -1;
}
- if ((pwe = getpwnam(login)) == NULL)
- return -1;
-
- u = pwe->pw_uid;
- g = pwe->pw_gid;
-
- if (flags & LOAD_ONLY_SAFEMODE_LAUNCHAGENTS) {
- largv[5] = "system";
- }
-
- if ((p = fexecv_as_user(login, u, g, largv)) == -1) {
- return -1;
- }
-
- if (waitpid(p, &wstatus, 0) != p) {
- return -1;
- }
-
- if (!(WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0)) {
- return -1;
- }
-
#define BEZEL_UI_PATH "/System/Library/LoginPlugins/BezelServices.loginPlugin/Contents/Resources/BezelUI/BezelUIServer"
#define BEZEL_UI_PLIST "/System/Library/LaunchAgents/com.apple.BezelUIServer.plist"
#define BEZEL_UI_SERVICE "BezelUI"
if (!(stat(BEZEL_UI_PLIST, &sb) == 0 && S_ISREG(sb.st_mode))) {
- if (bootstrap_create_server(bootstrap_port, BEZEL_UI_PATH, u, true, &bezel_ui_server) == BOOTSTRAP_SUCCESS) {
+ if (bootstrap_create_server(bootstrap_port, BEZEL_UI_PATH, 0, true, &bezel_ui_server) == BOOTSTRAP_SUCCESS) {
mach_port_t srv;
if (bootstrap_create_service(bezel_ui_server, BEZEL_UI_SERVICE, &srv) == BOOTSTRAP_SUCCESS) {
Modified: trunk/launchd/src/libvproc.c
===================================================================
--- trunk/launchd/src/libvproc.c 2007-03-04 17:34:05 UTC (rev 23129)
+++ trunk/launchd/src/libvproc.c 2007-03-04 23:38:21 UTC (rev 23130)
@@ -47,7 +47,7 @@
}
vproc_err_t
-_vproc_move_subset_to_user(void)
+_vproc_move_subset_to_user(char *session_type)
{
kern_return_t kr = 1;
mach_port_t puc = 0, which_port = bootstrap_port;
@@ -56,7 +56,7 @@
which_port = puc;
}
- kr = vproc_mig_move_subset_to_user(which_port, bootstrap_port);
+ kr = vproc_mig_move_subset(which_port, bootstrap_port, session_type);
if (puc) {
mach_port_deallocate(mach_task_self(), puc);
Modified: trunk/launchd/src/libvproc_internal.h
===================================================================
--- trunk/launchd/src/libvproc_internal.h 2007-03-04 17:34:05 UTC (rev 23129)
+++ trunk/launchd/src/libvproc_internal.h 2007-03-04 23:38:21 UTC (rev 23130)
@@ -57,7 +57,7 @@
kern_return_t _vprocmgr_getsocket(name_t);
-vproc_err_t _vproc_move_subset_to_user(void);
+vproc_err_t _vproc_move_subset_to_user(char *session_type);
void _vproc_logv(int pri, int err, const char *msg, va_list ap);
Modified: trunk/launchd/src/protocol_job.defs
===================================================================
--- trunk/launchd/src/protocol_job.defs 2007-03-04 17:34:05 UTC (rev 23129)
+++ trunk/launchd/src/protocol_job.defs 2007-03-04 23:38:21 UTC (rev 23130)
@@ -142,6 +142,7 @@
__wu : uid_t;
out __u_cont : mach_port_t);
-routine move_subset_to_user(
+routine move_subset(
__bs_port : job_t;
- __target_port : mach_port_t);
+ __target_port : mach_port_t;
+ __sessiontype : name_t);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20070304/b9186eeb/attachment.html
More information about the launchd-changes
mailing list