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

source_changes at macosforge.org source_changes at macosforge.org
Wed Jul 11 15:11:37 PDT 2007


Revision: 23304
          http://trac.macosforge.org/projects/launchd/changeset/23304
Author:   zarzycki at apple.com
Date:     2007-07-11 15:11:37 -0700 (Wed, 11 Jul 2007)

Log Message:
-----------
<rdar://problem/5194957> launchctl unload should block until unload is complete

Modified Paths:
--------------
    trunk/launchd/src/launchctl.c
    trunk/launchd/src/launchd_core_logic.c
    trunk/launchd/src/libvproc_private.h
    trunk/launchd/src/protocol_job.defs
    trunk/launchd/src/protocol_job_reply.defs

Modified: trunk/launchd/src/launchctl.c
===================================================================
--- trunk/launchd/src/launchctl.c	2007-07-11 18:10:33 UTC (rev 23303)
+++ trunk/launchd/src/launchctl.c	2007-07-11 22:11:37 UTC (rev 23304)
@@ -440,11 +440,8 @@
 void
 unloadjob(launch_data_t job)
 {
-	launch_data_t resp, tmp, tmps, msg;
-	int e;
+	launch_data_t tmps;
 
-	msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
-	tmp = launch_data_alloc(LAUNCH_DATA_STRING);
 	tmps = launch_data_dict_lookup(job, LAUNCH_JOBKEY_LABEL);
 
 	if (!tmps) {
@@ -452,20 +449,7 @@
 		return;
 	}
 
-	launch_data_set_string(tmp, launch_data_get_string(tmps));
-	launch_data_dict_insert(msg, tmp, LAUNCH_KEY_REMOVEJOB);
-	resp = launch_msg(msg);
-	launch_data_free(msg);
-	if (!resp) {
-		fprintf(stderr, "%s: Error: launch_msg(): %s\n", getprogname(), strerror(errno));
-		return;
-	}
-	if (LAUNCH_DATA_ERRNO == launch_data_get_type(resp)) {
-		if ((e = launch_data_get_errno(resp))) {
-			fprintf(stderr, "%s\n", strerror(e));
-		}
-	}
-	launch_data_free(resp);
+	assumes(_vproc_send_signal_by_label(launch_data_get_string(tmps), VPROC_MAGIC_UNLOAD_SIGNAL) == NULL);
 }
 
 launch_data_t

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2007-07-11 18:10:33 UTC (rev 23303)
+++ trunk/launchd/src/launchd_core_logic.c	2007-07-11 22:11:37 UTC (rev 23304)
@@ -105,8 +105,14 @@
 
 extern char **environ;
 
-mach_port_t inherited_bootstrap_port;
+struct waiting_for_removal {
+	SLIST_ENTRY(waiting_for_removal) sle;
+	mach_port_t reply_port;
+};
 
+static bool waiting4removal_new(job_t j, mach_port_t rp);
+static void waiting4removal_delete(job_t j, struct waiting_for_removal *w4r);
+
 struct mspolicy {
 	SLIST_ENTRY(mspolicy) sle;
 	unsigned int		allow:1, per_pid:1;
@@ -308,6 +314,7 @@
 	SLIST_HEAD(, mspolicy) mspolicies;
 	SLIST_HEAD(, machservice) machservices;
 	SLIST_HEAD(, semaphoreitem) semaphores;
+	SLIST_HEAD(, waiting_for_removal) removal_watchers;
 #if DO_RUSAGE_SUMMATION
 	struct rusage ru;
 #endif
@@ -447,6 +454,7 @@
 static jobmgr_t background_jobmgr;
 
 /* process wide globals */
+mach_port_t inherited_bootstrap_port;
 jobmgr_t root_jobmgr;
 
 void
@@ -711,6 +719,7 @@
 void
 job_remove(job_t j)
 {
+	struct waiting_for_removal *w4r;
 	struct calendarinterval *ci;
 	struct semaphoreitem *si;
 	struct socketgroup *sg;
@@ -778,6 +787,9 @@
 	while ((si = SLIST_FIRST(&j->semaphores))) {
 		semaphoreitem_delete(j, si);
 	}
+	while ((w4r = SLIST_FIRST(&j->removal_watchers))) {
+		waiting4removal_delete(j, w4r);
+	}
 
 	if (j->prog) {
 		free(j->prog);
@@ -4769,7 +4781,7 @@
 }
 
 kern_return_t
-job_mig_send_signal(job_t j, name_t targetlabel, int sig)
+job_mig_send_signal(job_t j, mach_port_t srp, name_t targetlabel, int sig)
 {
 	struct ldcred ldc;
 	job_t otherj;
@@ -4788,7 +4800,24 @@
 		return BOOTSTRAP_UNKNOWN_SERVICE;
 	}
 
-	if (otherj->p) {
+	if (sig == VPROC_MAGIC_UNLOAD_SIGNAL) {
+		bool do_block = otherj->p;
+
+		if (otherj->anonymous) {
+			return BOOTSTRAP_NOT_PRIVILEGED;
+		}
+
+		job_remove(otherj);
+
+		if (do_block) {
+			job_log(j, LOG_DEBUG, "Blocking MIG return of job_remove(): %s", otherj->label);
+			/* this is messy. We shouldn't access 'otherj' after job_remove(), but we check otherj->p first... */
+			job_assumes(otherj, waiting4removal_new(otherj, srp));
+			return MIG_NO_REPLY;
+		} else {
+			return 0;
+		}
+	} else if (otherj->p) {
 		job_assumes(j, kill(otherj->p, sig) != -1);
 	}
 
@@ -6134,3 +6163,29 @@
 
 	free(msp);
 }
+
+bool
+waiting4removal_new(job_t j, mach_port_t rp)
+{
+	struct waiting_for_removal *w4r;
+
+	if (!job_assumes(j, (w4r = malloc(sizeof(struct waiting_for_removal))) != NULL)) {
+		return false;
+	}
+
+	w4r->reply_port = rp;
+
+	SLIST_INSERT_HEAD(&j->removal_watchers, w4r, sle);
+
+	return true;
+}
+
+void
+waiting4removal_delete(job_t j, struct waiting_for_removal *w4r)
+{
+	job_assumes(j, job_mig_send_signal_reply(w4r->reply_port, 0) == 0);
+
+	SLIST_REMOVE(&j->removal_watchers, w4r, waiting_for_removal, sle);
+
+	free(w4r);
+}

Modified: trunk/launchd/src/libvproc_private.h
===================================================================
--- trunk/launchd/src/libvproc_private.h	2007-07-11 18:10:33 UTC (rev 23303)
+++ trunk/launchd/src/libvproc_private.h	2007-07-11 22:11:37 UTC (rev 23304)
@@ -31,6 +31,9 @@
 
 #pragma GCC visibility push(default)
 
+/* DO NOT use this. This is a hack for launchctl */
+#define VPROC_MAGIC_UNLOAD_SIGNAL 0x4141504C
+
 typedef enum {
 	VPROC_GSK_LAST_EXIT_STATUS = 1,
 	VPROC_GSK_GLOBAL_ON_DEMAND,

Modified: trunk/launchd/src/protocol_job.defs
===================================================================
--- trunk/launchd/src/protocol_job.defs	2007-07-11 18:10:33 UTC (rev 23303)
+++ trunk/launchd/src/protocol_job.defs	2007-07-11 22:11:37 UTC (rev 23304)
@@ -70,6 +70,7 @@
 
 routine send_signal(
 		__bs_port	: job_t;
+	sreplyport	__rport	: mach_port_make_send_once_t;
 		__label		: name_t;
 		__signal	: integer_t);
 

Modified: trunk/launchd/src/protocol_job_reply.defs
===================================================================
--- trunk/launchd/src/protocol_job_reply.defs	2007-07-11 18:10:33 UTC (rev 23303)
+++ trunk/launchd/src/protocol_job_reply.defs	2007-07-11 22:11:37 UTC (rev 23304)
@@ -37,7 +37,9 @@
 
 skip; /* look_up */
 
-skip; /* send_signal */
+simpleroutine job_mig_send_signal_reply(
+		__r_port	: mach_port_move_send_once_t;
+		__result	: kern_return_t, RetCode);
 
 skip; /* parent */
 

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


More information about the launchd-changes mailing list