[launchd-changes] [22876] trunk/launchd/src

source_changes at macosforge.org source_changes at macosforge.org
Sat Sep 23 17:59:30 PDT 2006


Revision: 22876
          http://trac.macosforge.org/projects/launchd/changeset/22876
Author:   zarzycki at apple.com
Date:     2006-09-23 17:59:30 -0700 (Sat, 23 Sep 2006)

Log Message:
-----------
Structural and semantic reorganization:

This change is fairly large, but it gets things going in the right direction. About November/December of 2005, I noticed that Mach bootstraps and launchd jobs had a lot in common from a data structure perspective, so I merged them. Almost one year later, I'm thankful for the learning experience. Suffice it for me to say, they aren't the same.

With this change, we now create "anonymous" jobs on the fly when the PID is not found in launchd's object graph.

What this means, is we'll be able to easily undo the merger of the bootstrap and job data structures, but not go back to the mess I was trying to solve at the end of 2005.

Modified Paths:
--------------
    trunk/launchd/src/launchd_core_logic.c
    trunk/launchd/src/launchd_core_logic.h
    trunk/launchd/src/launchd_mach_ipc.c

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2006-09-23 22:23:38 UTC (rev 22875)
+++ trunk/launchd/src/launchd_core_logic.c	2006-09-24 00:59:30 UTC (rev 22876)
@@ -214,7 +214,7 @@
 	unsigned int start_interval;
 	unsigned int checkedin:1, firstborn:1, debug:1, inetcompat:1, inetcompat_wait:1,
 		ondemand:1, session_create:1, low_pri_io:1, no_init_groups:1, priv_port_has_senders:1,
-		importing_global_env:1, importing_hard_limits:1, setmask:1, legacy_mach_job:1, runatload:1, __pad0:1;
+		importing_global_env:1, importing_hard_limits:1, setmask:1, legacy_mach_job:1, runatload:1, anonymous:1;
 	mode_t mask;
 	unsigned int globargv:1, wait4debugger:1, transfer_bstrap:1, unload_at_exit:1, force_ppc:1, stall_before_exec:1, __pad:26;
 	char label[0];
@@ -459,7 +459,7 @@
 
 	job_log(j, LOG_DEBUG, "Removed");
 
-	if (j->p) {
+	if (j->p && !j->anonymous) {
 		if (kevent_mod(j->p, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, &kqsimple_zombie_reaper) == -1) {
 			job_reap(j);
 		} else {
@@ -700,6 +700,36 @@
 	return jr;
 }
 
+job_t
+job_new_anonymous(job_t p, pid_t who)
+{
+	int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, who };
+	char newlabel[1000], *procname = "unknown";
+	struct kinfo_proc kp;
+	size_t kplen = sizeof(kp);
+	job_t jr;
+
+	if (who) {
+		if (sysctl(mib, 4, &kp, &kplen, NULL, 0) == -1) {
+			return NULL;
+		}
+		procname = kp.kp_proc.p_comm;
+	}
+
+	sprintf(newlabel, "anonymous-%u.%s", who, procname);
+
+	jr = job_new(p, newlabel, procname, NULL, NULL, MACH_PORT_NULL);
+
+	if (!jr) {
+		return NULL;
+	}
+
+	jr->anonymous = true;
+	jr->p = who;
+
+	return jr;
+}
+
 job_t 
 job_new(job_t p, const char *label, const char *prog, const char *const *argv, const char *stdinpath, mach_port_t reqport)
 {
@@ -2648,25 +2678,30 @@
 }
 
 void
-job_foreach_service(job_t j, void (*bs_iter)(struct machservice *, void *), void *context, bool include_subjobs)
+job_foreach_service(job_t j, void (*bs_iter)(struct machservice *, void *), void *context, bool only_anonymous)
 {
 	struct machservice *ms;
 	job_t ji;
 
 	j = job_get_bs(j);
 
-	if (include_subjobs) {
-		SLIST_FOREACH(ji, &j->jobs, sle) {
-			if (ji->req_port)
-				continue;
+	SLIST_FOREACH(ji, &j->jobs, sle) {
+		if (ji->req_port) {
+			continue;
+		} else if (only_anonymous && !ji->anonymous) {
+			continue;
+		}
 
-			SLIST_FOREACH(ms, &ji->machservices, sle)
-				bs_iter(ms, context);
+		SLIST_FOREACH(ms, &ji->machservices, sle) {
+			bs_iter(ms, context);
 		}
 	}
 
-	SLIST_FOREACH(ms, &j->machservices, sle)
-		bs_iter(ms, context);
+	if (!job_assumes(j, SLIST_EMPTY(&j->machservices))) {
+		SLIST_FOREACH(ms, &j->machservices, sle) {
+			bs_iter(ms, context);
+		}
+	}
 }
 
 job_t 
@@ -2737,18 +2772,22 @@
 	}
 
 	SLIST_FOREACH_SAFE(ms, &j->machservices, sle, next_ms) {
-		if (ms->port == port)
+		if (ms->port == port) {
 			machservice_delete(ms);
+		}
 	}
 
 	if (j->req_port == port) {
 		if (j == root_job) {
 			launchd_shutdown();
 		} else {
-			job_remove(j);
+			return job_remove(j);
 		}
 	}
 
+	if (j->anonymous && SLIST_EMPTY(&j->machservices)) {
+		job_remove(j);
+	}
 }
 
 struct machservice *

Modified: trunk/launchd/src/launchd_core_logic.h
===================================================================
--- trunk/launchd/src/launchd_core_logic.h	2006-09-23 22:23:38 UTC (rev 22875)
+++ trunk/launchd/src/launchd_core_logic.h	2006-09-24 00:59:30 UTC (rev 22876)
@@ -50,6 +50,7 @@
 job_t job_new_spawn(const char *label, const char *path, const char *workingdir, const char *const *argv, const char *const *env, mode_t *u_mask, bool w4d, bool fppc);
 job_t job_new_via_mach_init(job_t jbs, const char *cmd, uid_t uid, bool ond);
 job_t job_new_bootstrap(job_t p, mach_port_t requestorport, mach_port_t checkin_port);
+job_t job_new_anonymous(job_t p, pid_t who);
 launch_data_t job_export(job_t j);
 launch_data_t job_export_all(void);
 void job_dispatch(job_t j, bool kickstart);
@@ -70,7 +71,7 @@
 job_t job_parent(job_t j);
 void job_uncork_fork(job_t j);
 struct machservice *job_lookup_service(job_t jbs, const char *name, bool check_parent);
-void job_foreach_service(job_t jbs, void (*bs_iter)(struct machservice *, void *), void *context, bool include_subjobs);
+void job_foreach_service(job_t jbs, void (*bs_iter)(struct machservice *, void *), void *context, bool only_anonymous);
 void job_log(job_t j, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4)));
 void job_log_error(job_t j, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4)));
 void job_log_bug(job_t j, const char *rcs_rev, const char *path, unsigned int line, const char *test);

Modified: trunk/launchd/src/launchd_mach_ipc.c
===================================================================
--- trunk/launchd/src/launchd_mach_ipc.c	2006-09-23 22:23:38 UTC (rev 22875)
+++ trunk/launchd/src/launchd_mach_ipc.c	2006-09-24 00:59:30 UTC (rev 22876)
@@ -87,6 +87,7 @@
 {
 	mach_msg_type_number_t l2l_i;
 	auditinfo_t inherited_audit;
+	job_t root_anon_job;
 
 	getaudit(&inherited_audit);
 	inherited_asid = inherited_audit.ai_asid;
@@ -104,14 +105,18 @@
 	/* cut off the Libc cache, we don't want to deadlock against ourself */
 	bootstrap_port = MACH_PORT_NULL;
 
-	if (l2l_names == NULL)
+	if (l2l_names == NULL) {
 		return;
+	}
 
+	launchd_assert(root_anon_job = job_new_anonymous(root_job, 0));
+
 	for (l2l_i = 0; l2l_i < l2l_cnt; l2l_i++) {
 		struct machservice *ms;
 
-		if ((ms = machservice_new(root_job, l2l_names[l2l_i], l2l_ports + l2l_i)))
+		if ((ms = machservice_new(root_anon_job, l2l_names[l2l_i], l2l_ports + l2l_i))) {
 			machservice_watch(ms);
+		}
 	}
 }
 
@@ -201,8 +206,15 @@
 	j2 = job_find_by_pid(j, ldc.pid, false);
 
 	if (!j2) {
-		job_log(j, LOG_NOTICE, "PID %u not managed by launchd", ldc.pid);
-		return BOOTSTRAP_NOT_PRIVILEGED;
+		if (ldc.uid == getuid() && ldc.euid == geteuid()) {
+			j2 = job_new_anonymous(j, ldc.pid);
+			if (!j2) {
+				return BOOTSTRAP_NO_MEMORY;
+			}
+		} else {
+			job_log(j, LOG_NOTICE, "PID %u not managed by launchd", ldc.pid);
+			return BOOTSTRAP_NOT_PRIVILEGED;
+		}
 	}
 
 	*unprivportp = job_get_bsport(j2);
@@ -258,10 +270,14 @@
 
 	audit_token_to_launchd_cred(au_tok, &ldc);
 
-	j2 = job_find_by_pid(root_job, ldc.pid, true);
-
-	if (j2 && job_get_bs(j2) == j) {
-		j = j2;
+	if (j == job_get_bs(j)) {
+		j2 = job_find_by_pid(j, ldc.pid, false);
+		if (!j2) {
+			j2 = job_new_anonymous(j, ldc.pid);
+		}
+		if (j2) {
+			j = j2;
+		}
 	}
 
 	job_log(j, LOG_NOTICE, "bootstrap_register() is deprecated. PID: %u Service: %s", ldc.pid, servicename);
@@ -388,7 +404,7 @@
 	unsigned int cnt = 0;
 
 	for (ji = j; ji; ji = job_parent(ji))
-		job_foreach_service(ji, x_bootstrap_info_countservices, &cnt, true);
+		job_foreach_service(ji, x_bootstrap_info_countservices, &cnt, false);
 
 	result = vm_allocate(mach_task_self(), (vm_address_t *)&info_resp.service_names, cnt * sizeof(info_resp.service_names[0]), true);
 	if (!launchd_assumes(result == KERN_SUCCESS))
@@ -399,7 +415,7 @@
 		goto out_bad;
 
 	for (ji = j; ji; ji = job_parent(ji))
-		job_foreach_service(ji, x_bootstrap_info_copyservices, &info_resp, true);
+		job_foreach_service(ji, x_bootstrap_info_copyservices, &info_resp, false);
 
 	launchd_assumes(info_resp.i == cnt);
 
@@ -436,7 +452,7 @@
 
 	job_log(j, LOG_DEBUG, "Transferring sub-bootstrap to the per session launchd.");
 
-	job_foreach_service(j, x_bootstrap_info_countservices, &cnt, false);
+	job_foreach_service(j, x_bootstrap_info_countservices, &cnt, true);
 
 	result = vm_allocate(mach_task_self(), (vm_address_t *)&info_resp.service_names, cnt * sizeof(info_resp.service_names[0]), true);
 	if (!launchd_assumes(result == KERN_SUCCESS))
@@ -446,7 +462,7 @@
 	if (!launchd_assumes(result == KERN_SUCCESS))
 		goto out_bad;
 
-	job_foreach_service(j, x_bootstrap_info_copyservices, &info_resp, false);
+	job_foreach_service(j, x_bootstrap_info_copyservices, &info_resp, true);
 
 	launchd_assumes(info_resp.i == cnt);
 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20060923/ad3be5fe/attachment.html


More information about the launchd-changes mailing list