[launchd-changes] [23161] trunk/launchd/src
source_changes at macosforge.org
source_changes at macosforge.org
Tue Mar 20 16:59:20 PDT 2007
Revision: 23161
http://trac.macosforge.org/projects/launchd/changeset/23161
Author: zarzycki at apple.com
Date: 2007-03-20 16:59:19 -0700 (Tue, 20 Mar 2007)
Log Message:
-----------
<rdar://problem/5075018> Switch to bootstrap_register2 prevents using accessibility with test framework builds
Modified Paths:
--------------
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_unix_ipc.c
trunk/launchd/src/libvproc.c
trunk/launchd/src/libvproc_internal.h
trunk/launchd/src/protocol_job.defs
Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c 2007-03-20 16:48:48 UTC (rev 23160)
+++ trunk/launchd/src/launchd_core_logic.c 2007-03-20 23:59:19 UTC (rev 23161)
@@ -206,7 +206,6 @@
mach_port_t jm_port;
mach_port_t req_port;
jobmgr_t parentmgr;
- job_t anonj;
int reboot_flags;
unsigned int global_on_demand_cnt;
unsigned int sent_stop_to_hopeful_jobs:1, shutting_down:1;
@@ -219,6 +218,7 @@
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 void jobmgr_reap_bulk(jobmgr_t jm, struct kevent *kev);
static bool jobmgr_is_idle(jobmgr_t jm);
static void jobmgr_log_stray_children(jobmgr_t jm);
static void jobmgr_remove(jobmgr_t jm);
@@ -315,6 +315,7 @@
static void job_callback_proc(job_t j, int flags, int fflags);
static void job_callback_timer(job_t j, void *ident);
static void job_callback_read(job_t j, int ident);
+static job_t job_new_anonymous(jobmgr_t jm, pid_t anonpid);
static job_t job_new(jobmgr_t jm, const char *label, const char *prog, const char *const *argv);
static job_t job_new_spawn(job_t j, const char *label, const char *path, const char *workingdir, const char *const *argv, const char *const *env, mode_t *u_mask, bool w4d);
static job_t job_new_via_mach_init(job_t j, const char *cmd, uid_t uid, bool ond);
@@ -417,14 +418,17 @@
void
job_stop(job_t j)
{
- if (j->p) {
- job_assumes(j, kill(j->p, SIGTERM) != -1);
- job_assumes(j, gettimeofday(&j->sent_sigterm_time, NULL) != -1);
- if (j->exit_timeout) {
- job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER,
- EV_ADD|EV_ONESHOT, NOTE_SECONDS, j->exit_timeout, j) != -1);
- }
+ if (!j->p || j->anonymous) {
+ return;
}
+
+ job_assumes(j, kill(j->p, SIGTERM) != -1);
+ job_assumes(j, gettimeofday(&j->sent_sigterm_time, NULL) != -1);
+
+ if (j->exit_timeout) {
+ job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER,
+ EV_ADD|EV_ONESHOT, NOTE_SECONDS, j->exit_timeout, j) != -1);
+ }
}
launch_data_t
@@ -577,16 +581,9 @@
}
}
- /* We should have one job left and it should be the anonymous job */
- ji = SLIST_FIRST(&jm->jobs);
- if (!(jobmgr_assumes(jm, ji != NULL) && jobmgr_assumes(jm, ji == jm->anonj)
- && jobmgr_assumes(jm, SLIST_NEXT(ji, sle) == NULL))) {
- SLIST_FOREACH(ji, &jm->jobs, sle) {
- job_log(ji, LOG_ERR, "Still remaining at removal.");
- }
- }
-
while ((ji = SLIST_FIRST(&jm->jobs))) {
+ /* We should only have anonymous jobs left */
+ job_assumes(ji, ji->anonymous);
job_remove(ji);
}
@@ -624,7 +621,7 @@
struct machservice *ms;
struct semaphoreitem *si;
- if (j->p) {
+ if (j->p && !j->anonymous) {
job_log(j, LOG_DEBUG, "Removal pended until the job exits.");
if (!j->removal_pending) {
@@ -917,19 +914,28 @@
}
job_t
-jobmgr_get_anonymous(jobmgr_t jm)
+job_new_anonymous(jobmgr_t jm, pid_t anonpid)
{
- char newlabel[1000], *procname = "unknown";
- job_t jr;
+ int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, anonpid };
+ char newlabel[1000];
+ struct kinfo_proc kp;
+ size_t len = sizeof(kp);
+ job_t jr = NULL;
- if (jm->anonj) {
- return jm->anonj;
+ if (!jobmgr_assumes(jm, sysctl(mib, 4, &kp, &len, NULL, 0) != -1)) {
+ return NULL;
}
- snprintf(newlabel, sizeof(newlabel), "%u.anonymous", MACH_PORT_INDEX(jm->jm_port));
+ snprintf(newlabel, sizeof(newlabel), "anonymous-%u.%s", anonpid, kp.kp_proc.p_comm);
- if ((jr = job_new(jm, newlabel, procname, NULL))) {
+ if (jobmgr_assumes(jm, (jr = job_new(jm, newlabel, kp.kp_proc.p_comm, NULL)) != NULL)) {
+ total_children++;
jr->anonymous = true;
+ jr->p = anonpid;
+ /* anonymous process reaping is messy */
+ SLIST_INSERT_HEAD(&jm->active_jobs[ACTIVE_JOB_HASH(jr->p)], jr, hash_sle);
+ job_assumes(jr, kevent_mod(jr->p, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, root_jobmgr) != -1);
+ job_log(jr, LOG_DEBUG, "Created anonymously.");
}
return jr;
@@ -1552,7 +1558,7 @@
return ji;
}
}
- return jm->anonj;
+ return job_new_anonymous(jm, ldc.pid);
}
SLIST_FOREACH(jmi, &jm->submgrs, sle) {
@@ -1577,8 +1583,20 @@
{
job_t jr = job_mig_intran2(root_jobmgr, p);
- launchd_assumes(jr != NULL);
+ if (!jobmgr_assumes(root_jobmgr, jr != NULL)) {
+ int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, 0 };
+ struct kinfo_proc kp;
+ struct ldcred ldc;
+ size_t len = sizeof(kp);
+ runtime_get_caller_creds(&ldc);
+ mib[3] = ldc.pid;
+
+ if (jobmgr_assumes(root_jobmgr, sysctl(mib, 4, &kp, &len, NULL, 0) != -1)) {
+ jobmgr_log(root_jobmgr, LOG_ERR, "%s() was confused by PID %u: %s", __func__, ldc.pid, kp.kp_proc.p_comm);
+ }
+ }
+
return jr;
}
@@ -1647,7 +1665,7 @@
{
struct timeval tve, tvd;
struct rusage ru;
- int status;
+ int status = 0;
job_log(j, LOG_DEBUG, "Reaping");
@@ -1672,7 +1690,7 @@
j->forkfd = 0;
}
- if (!job_assumes(j, wait4(j->p, &status, 0, &ru) != -1)) {
+ if (!j->anonymous && !job_assumes(j, wait4(j->p, &status, 0, &ru) != -1)) {
/*
* wait4() then kill() is still racy.
* Then again, we never should have got here in the first place...
@@ -1681,7 +1699,6 @@
job_log(j, LOG_DEBUG, "Working around 5020256");
}
- status = 0;
memset(&ru, 0, sizeof(ru));
}
@@ -1828,6 +1845,10 @@
void
job_kill(job_t j)
{
+ if (!j->p || j->anonymous) {
+ return;
+ }
+
job_assumes(j, kill(j->p, SIGKILL) != -1);
j->sent_sigkill = true;
@@ -1851,10 +1872,11 @@
job_assumes(j, (flags & EV_ONESHOT));
job_assumes(j, (flags & EV_EOF));
job_reap(j);
- job_dispatch(j, false);
- if (launchd_assumes(root_jobmgr != NULL)) {
- root_jobmgr = jobmgr_do_garbage_collection(root_jobmgr);
+ if (j->anonymous) {
+ job_remove(j);
+ } else {
+ job_dispatch(j, false);
}
}
}
@@ -1897,11 +1919,39 @@
}
void
+jobmgr_reap_bulk(jobmgr_t jm, struct kevent *kev)
+{
+ jobmgr_t jmi;
+ job_t ji;
+
+ SLIST_FOREACH(jmi, &jm->submgrs, sle) {
+ jobmgr_reap_bulk(jmi, kev);
+ }
+
+ SLIST_FOREACH(ji, &jm->active_jobs[ACTIVE_JOB_HASH(kev->ident)], hash_sle) {
+ if (ji->p != (pid_t)kev->ident) {
+ continue;
+ }
+
+ kev->udata = ji;
+ job_callback(ji, kev);
+
+ break;
+ }
+}
+
+void
jobmgr_callback(void *obj, struct kevent *kev)
{
jobmgr_t jm = obj;
switch (kev->filter) {
+ case EVFILT_PROC:
+ jobmgr_reap_bulk(jm, kev);
+ if (launchd_assumes(root_jobmgr != NULL)) {
+ root_jobmgr = jobmgr_do_garbage_collection(root_jobmgr);
+ }
+ break;
case EVFILT_SIGNAL:
switch (kev->ident) {
case SIGTERM:
@@ -3398,7 +3448,7 @@
}
SLIST_FOREACH(ji, &jm->jobs, sle) {
- if (ji->p) {
+ if (ji->p && !ji->anonymous) {
return false;
}
}
@@ -3506,8 +3556,6 @@
mxmsgsz = job_mig_protocol_vproc_subsystem.maxsize;
}
- jobmgr_assumes(jmr, (jmr->anonj = jobmgr_get_anonymous(jmr)) != NULL);
-
if (!jm) {
jobmgr_assumes(jmr, kevent_mod(SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, jmr) != -1);
jobmgr_assumes(jmr, kevent_mod(0, EVFILT_FS, EV_ADD|EV_CLEAR, VQ_MOUNT|VQ_UNMOUNT|VQ_UPDATE, 0, jmr) != -1);
@@ -4654,18 +4702,22 @@
kern_return_t
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;
+ mach_msg_type_number_t l2l_i, l2l_name_cnt = 0, l2l_port_cnt = 0, l2l_pid_cnt = 0;
name_array_t l2l_names = NULL;
+ pid_array_t l2l_pids = NULL;
mach_port_array_t l2l_ports = NULL;
mach_port_t reqport, rcvright;
kern_return_t kr;
jobmgr_t jmr;
+ job_t j2;
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);
+ job_assumes(j, (j2 = job_mig_intran2(root_jobmgr, target_subset)) != NULL);
+ j = j2;
+ jobmgr_log(j->mgr, LOG_DEBUG, "Renaming to: %s", session_type);
strcpy(j->mgr->name, session_type);
job_assumes(j, launchd_mport_deallocate(target_subset) == KERN_SUCCESS);
@@ -4677,7 +4729,9 @@
}
kr = _vproc_grab_subset(target_subset, &reqport,
- &rcvright, &l2l_names, &l2l_name_cnt, &l2l_ports, &l2l_port_cnt);
+ &rcvright, &l2l_names, &l2l_name_cnt,
+ &l2l_pids, &l2l_pid_cnt,
+ &l2l_ports, &l2l_port_cnt);
if (job_assumes(j, kr == 0)) {
job_assumes(j, launchd_mport_deallocate(target_subset) == KERN_SUCCESS);
@@ -4686,6 +4740,7 @@
}
launchd_assert(l2l_name_cnt == l2l_port_cnt);
+ launchd_assert(l2l_name_cnt == l2l_pid_cnt);
if ((jmr = jobmgr_new(j->mgr, reqport, rcvright, false, session_type)) == NULL) {
kr = BOOTSTRAP_NO_MEMORY;
@@ -4694,8 +4749,20 @@
for (l2l_i = 0; l2l_i < l2l_name_cnt; l2l_i++) {
struct machservice *ms;
+ job_t j_for_service;
- if ((ms = machservice_new(jmr->anonj, l2l_names[l2l_i], &l2l_ports[l2l_i], false))) {
+ SLIST_FOREACH(j_for_service, &jmr->jobs, sle) {
+ if (j_for_service->p == l2l_pids[l2l_i]) {
+ break;
+ }
+ }
+
+ if (!j_for_service) {
+ j_for_service = job_new_anonymous(jmr, l2l_pids[l2l_i]);
+ jobmgr_assumes(jmr, j_for_service != NULL);
+ }
+
+ if ((ms = machservice_new(j_for_service, l2l_names[l2l_i], &l2l_ports[l2l_i], false))) {
machservice_request_notifications(ms);
}
}
@@ -4709,6 +4776,9 @@
if (l2l_ports) {
mig_deallocate((vm_address_t)l2l_ports, l2l_port_cnt * sizeof(l2l_ports[0]));
}
+ if (l2l_pids) {
+ mig_deallocate((vm_address_t)l2l_pids, l2l_pid_cnt * sizeof(l2l_pids[0]));
+ }
return kr;
}
@@ -4716,13 +4786,16 @@
kern_return_t
job_mig_take_subset(job_t j, mach_port_t *reqport, mach_port_t *rcvright,
name_array_t *servicenamesp, unsigned int *servicenames_cnt,
+ pid_array_t *pidsp, unsigned int *pids_cnt,
mach_port_array_t *portsp, unsigned int *ports_cnt)
{
name_array_t service_names = NULL;
mach_port_array_t ports = NULL;
+ pid_array_t pids = NULL;
unsigned int cnt = 0, cnt2 = 0;
struct machservice *ms;
jobmgr_t jm;
+ job_t ji;
if (!launchd_assumes(j != NULL)) {
return BOOTSTRAP_NO_MEMORY;
@@ -4743,8 +4816,13 @@
job_log(j, LOG_DEBUG, "Transferring sub-bootstrap to the per session launchd.");
- SLIST_FOREACH(ms, &j->machservices, sle) {
- cnt++;
+ SLIST_FOREACH(ji, &j->mgr->jobs, sle) {
+ if (!ji->anonymous) {
+ continue;
+ }
+ SLIST_FOREACH(ms, &ji->machservices, sle) {
+ cnt++;
+ }
}
mig_allocate((vm_address_t *)&service_names, cnt * sizeof(service_names[0]));
@@ -4757,19 +4835,31 @@
goto out_bad;
}
- SLIST_FOREACH(ms, &j->machservices, sle) {
- strlcpy(service_names[cnt2], machservice_name(ms), sizeof(service_names[0]));
- ports[cnt2] = machservice_port(ms);
- /* Increment the send right by one so we can shutdown the jobmgr cleanly */
- jobmgr_assumes(jm, (errno = mach_port_mod_refs(mach_task_self(), ports[cnt2], MACH_PORT_RIGHT_SEND, 1)) == 0);
- cnt2++;
+ mig_allocate((vm_address_t *)&pids, cnt * sizeof(pids[0]));
+ if (!launchd_assumes(pids != NULL)) {
+ goto out_bad;
}
+ SLIST_FOREACH(ji, &j->mgr->jobs, sle) {
+ if (!ji->anonymous) {
+ continue;
+ }
+ SLIST_FOREACH(ms, &ji->machservices, sle) {
+ strlcpy(service_names[cnt2], machservice_name(ms), sizeof(service_names[0]));
+ ports[cnt2] = machservice_port(ms);
+ pids[cnt2] = ms->job->p;
+ /* Increment the send right by one so we can shutdown the jobmgr cleanly */
+ jobmgr_assumes(jm, (errno = mach_port_mod_refs(mach_task_self(), ports[cnt2], MACH_PORT_RIGHT_SEND, 1)) == 0);
+ cnt2++;
+ }
+ }
+
launchd_assumes(cnt == cnt2);
*servicenamesp = service_names;
*portsp = ports;
- *servicenames_cnt = *ports_cnt = cnt;
+ *pidsp = pids;
+ *servicenames_cnt = *ports_cnt = *pids_cnt = cnt;
*reqport = jm->req_port;
*rcvright = jm->jm_port;
@@ -4785,6 +4875,9 @@
if (service_names) {
mig_deallocate((vm_address_t)service_names, cnt * sizeof(service_names[0]));
}
+ if (pids) {
+ mig_deallocate((vm_address_t)pids, cnt * sizeof(pids[0]));
+ }
if (ports) {
mig_deallocate((vm_address_t)ports, cnt * sizeof(ports[0]));
}
Modified: trunk/launchd/src/launchd_core_logic.h
===================================================================
--- trunk/launchd/src/launchd_core_logic.h 2007-03-20 16:48:48 UTC (rev 23160)
+++ trunk/launchd/src/launchd_core_logic.h 2007-03-20 23:59:19 UTC (rev 23161)
@@ -31,7 +31,6 @@
void jobmgr_init(bool);
jobmgr_t jobmgr_shutdown(jobmgr_t jm);
void jobmgr_dispatch_all_semaphores(jobmgr_t jm);
-job_t jobmgr_get_anonymous(jobmgr_t jm);
job_t jobmgr_find(jobmgr_t jm, const char *label);
jobmgr_t jobmgr_delete_anything_with_port(jobmgr_t jm, mach_port_t port);
bool jobmgr_ack_port_destruction(jobmgr_t jm, mach_port_t p);
Modified: trunk/launchd/src/launchd_mig_types.defs
===================================================================
--- trunk/launchd/src/launchd_mig_types.defs 2007-03-20 16:48:48 UTC (rev 23160)
+++ trunk/launchd/src/launchd_mig_types.defs 2007-03-20 23:59:19 UTC (rev 23161)
@@ -24,6 +24,7 @@
*/
type pid_t = integer_t;
+type pid_array_t = ^array [] of pid_t;
type uid_t = integer_t;
type gid_t = integer_t;
type vproc_gsk_t = integer_t;
Modified: trunk/launchd/src/launchd_unix_ipc.c
===================================================================
--- trunk/launchd/src/launchd_unix_ipc.c 2007-03-20 16:48:48 UTC (rev 23160)
+++ trunk/launchd/src/launchd_unix_ipc.c 2007-03-20 23:59:19 UTC (rev 23161)
@@ -184,7 +184,7 @@
c->kqconn_callback = ipc_callback;
c->conn = launchd_fdopen(fd);
- c->j = j ? j : jobmgr_get_anonymous(root_jobmgr);
+ c->j = j;
SLIST_INSERT_HEAD(&connections, c, sle);
kevent_mod(fd, EVFILT_READ, EV_ADD, 0, 0, &c->kqconn_callback);
}
@@ -340,11 +340,11 @@
return;
}
- job_log(rmc->c->j, LOG_DEBUG, "Unix IPC request: %s", cmd);
+ //job_log(rmc->c->j, LOG_DEBUG, "Unix IPC request: %s", cmd);
if (data == NULL) {
if (!strcmp(cmd, LAUNCH_KEY_CHECKIN)) {
- if (!job_is_anonymous(rmc->c->j)) {
+ if (rmc->c->j) {
resp = job_export(rmc->c->j);
job_checkin(rmc->c->j);
} else {
Modified: trunk/launchd/src/libvproc.c
===================================================================
--- trunk/launchd/src/libvproc.c 2007-03-20 16:48:48 UTC (rev 23160)
+++ trunk/launchd/src/libvproc.c 2007-03-20 23:59:19 UTC (rev 23161)
@@ -41,9 +41,10 @@
kern_return_t
_vproc_grab_subset(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright,
name_array_t *service_names, mach_msg_type_number_t *service_namesCnt,
+ pid_array_t *pids, mach_msg_type_number_t *pidCnt,
mach_port_array_t *ports, mach_msg_type_number_t *portCnt)
{
- return vproc_mig_take_subset(bp, reqport, rcvright, service_names, service_namesCnt, ports, portCnt);
+ return vproc_mig_take_subset(bp, reqport, rcvright, service_names, service_namesCnt, pids, pidCnt, ports, portCnt);
}
vproc_err_t
Modified: trunk/launchd/src/libvproc_internal.h
===================================================================
--- trunk/launchd/src/libvproc_internal.h 2007-03-20 16:48:48 UTC (rev 23160)
+++ trunk/launchd/src/libvproc_internal.h 2007-03-20 23:59:19 UTC (rev 23161)
@@ -26,6 +26,7 @@
typedef char * _internal_string_t;
typedef char * logmsg_t;
+typedef pid_t * pid_array_t;
typedef mach_port_t vproc_mig_t;
typedef integer_t binpref_t[8];
@@ -46,6 +47,7 @@
kern_return_t
_vproc_grab_subset(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright,
name_array_t *service_names, mach_msg_type_number_t *service_namesCnt,
+ pid_array_t *pids, mach_msg_type_number_t *pidCnt,
mach_port_array_t *ports, mach_msg_type_number_t *portCnt);
kern_return_t _vprocmgr_getsocket(name_t);
Modified: trunk/launchd/src/protocol_job.defs
===================================================================
--- trunk/launchd/src/protocol_job.defs 2007-03-20 16:48:48 UTC (rev 23160)
+++ trunk/launchd/src/protocol_job.defs 2007-03-20 23:59:19 UTC (rev 23161)
@@ -96,6 +96,7 @@
out __bs_reqport : mach_port_move_send_t;
out __bs_rcvright : mach_port_move_receive_t;
out __service_names : name_array_t, dealloc;
+ out __service_pids : pid_array_t, dealloc;
out __service_ports : mach_port_move_send_array_t, dealloc);
routine getsocket(
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20070320/b4be4de1/attachment.html
More information about the launchd-changes
mailing list