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

source_changes at macosforge.org source_changes at macosforge.org
Fri Mar 28 12:47:55 PDT 2008


Revision: 23580
          http://trac.macosforge.org/projects/launchd/changeset/23580
Author:   zarzycki at apple.com
Date:     2008-03-28 12:47:54 -0700 (Fri, 28 Mar 2008)

Log Message:
-----------
Have launchd use the kill-via-shmem trick.

Modified Paths:
--------------
    trunk/launchd/src/launchd.c
    trunk/launchd/src/launchd_core_logic.c
    trunk/launchd/src/launchd_runtime.c
    trunk/launchd/src/launchd_runtime.h
    trunk/launchd/src/libvproc.c
    trunk/launchd/src/libvproc_internal.h
    trunk/launchd/src/libvproc_private.h

Modified: trunk/launchd/src/launchd.c
===================================================================
--- trunk/launchd/src/launchd.c	2008-03-27 22:56:23 UTC (rev 23579)
+++ trunk/launchd/src/launchd.c	2008-03-28 19:47:54 UTC (rev 23580)
@@ -70,6 +70,7 @@
 
 #include "libbootstrap_public.h"
 #include "libvproc_public.h"
+#include "libvproc_private.h"
 #include "libvproc_internal.h"
 #include "liblaunch_public.h"
 
@@ -158,6 +159,10 @@
 
 	if (pid1_magic) {
 		handle_pid1_crashes_separately();
+	} else {
+		/* prime shared memory before the 'bootstrap_port' global is set to zero */
+		_vproc_transaction_begin();
+		_vproc_transaction_end();
 	}
 
 	jobmgr_init(sflag);

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2008-03-27 22:56:23 UTC (rev 23579)
+++ trunk/launchd/src/launchd_core_logic.c	2008-03-28 19:47:54 UTC (rev 23580)
@@ -563,6 +563,7 @@
 INTERNAL_ABI void
 job_stop(job_t j)
 {
+	char extralog[100];
 	int32_t newval = 1;
 
 	if (unlikely(!j->p || j->anonymous)) {
@@ -595,7 +596,13 @@
 						EV_ADD|EV_ONESHOT, NOTE_SECONDS, j->exit_timeout, j) != -1);
 		}
 
-		job_log(j, LOG_DEBUG, "Sent SIGTERM signal");
+		if (j->kill_via_shmem) {
+			snprintf(extralog, sizeof(extralog), ": %d remaining transactions", j->shmem->vp_shmem_transaction_cnt + 1);
+		} else {
+			extralog[0] = '\0';
+		}
+
+		job_log(j, LOG_DEBUG, "Sent SIGTERM signal%s", extralog);
 	}
 }
 
@@ -803,7 +810,7 @@
 	}
 
 	if (jm->parentmgr) {
-		runtime_del_ref();
+		runtime_del_weak_ref();
 		SLIST_REMOVE(&jm->parentmgr->submgrs, jm, jobmgr_s, sle);
 	} else if (pid1_magic) {
 		jobmgr_log(jm, LOG_DEBUG, "About to call: sync()");
@@ -959,7 +966,7 @@
 		free(j->j_binpref);
 	}
 	if (j->start_interval) {
-		runtime_del_ref();
+		runtime_del_weak_ref();
 		job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1);
 	}
 	if (j->poll_for_vfs_changes) {
@@ -1664,7 +1671,7 @@
 			} else if (unlikely(value > UINT32_MAX)) {
 				job_log(j, LOG_WARNING, "%s is too large. Ignoring.", LAUNCH_JOBKEY_STARTINTERVAL);
 			} else {
-				runtime_add_ref();
+				runtime_add_weak_ref();
 				j->start_interval = value;
 
 				job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, value, j) != -1);
@@ -2230,7 +2237,7 @@
 	job_log(j, LOG_DEBUG, "Reaping");
 
 	if (j->shmem) {
-		job_assumes(j, munmap(j->shmem, getpagesize()) == 0);
+		job_assumes(j, vm_deallocate(mach_task_self(), (vm_address_t)j->shmem, getpagesize()) == 0);
 		j->shmem = NULL;
 	}
 
@@ -3791,7 +3798,7 @@
 	
 	calendarinterval_setalarm(j, ci);
 
-	runtime_add_ref();
+	runtime_add_weak_ref();
 
 	return true;
 }
@@ -3804,7 +3811,7 @@
 
 	free(ci);
 
-	runtime_del_ref();
+	runtime_del_weak_ref();
 }
 
 void
@@ -3862,7 +3869,7 @@
 
 	SLIST_INSERT_HEAD(&j->sockets, sg, sle);
 
-	runtime_add_ref();
+	runtime_add_weak_ref();
 
 	return true;
 }
@@ -3893,7 +3900,7 @@
 	free(sg->fds);
 	free(sg);
 
-	runtime_del_ref();
+	runtime_del_weak_ref();
 }
 
 void
@@ -4729,7 +4736,7 @@
 	}
 
 	if (jmr->parentmgr) {
-		runtime_add_ref();
+		runtime_add_weak_ref();
 	}
 
 	return jmr;
@@ -5169,9 +5176,9 @@
 	}
 
 	if (add) {
-		runtime_add_ref();
+		runtime_add_weak_ref();
 	} else {
-		runtime_del_ref();
+		runtime_del_weak_ref();
 	}
 }
 
@@ -5437,6 +5444,7 @@
 job_mig_setup_shmem(job_t j, mach_port_t *shmem_port)
 {
 	memory_object_size_t size_of_page, size_of_page_orig;
+	vm_address_t vm_addr;
 	kern_return_t kr;
 
 	if (!launchd_assumes(j != NULL)) {
@@ -5444,6 +5452,7 @@
 	}
 
 	if (unlikely(j->anonymous)) {
+		job_log(j, LOG_ERR, "Anonymous job tried to setup shared memory");
 		return BOOTSTRAP_NOT_PRIVILEGED;
 	}
 
@@ -5454,17 +5463,25 @@
 
 	size_of_page_orig = size_of_page = getpagesize();
 
-	if (!job_assumes(j, j->shmem = mmap(NULL, size_of_page, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0))) {
-		return BOOTSTRAP_NO_MEMORY;
+	kr = vm_allocate(mach_task_self(), &vm_addr, size_of_page, true);
+
+	if (!job_assumes(j, kr == 0)) {
+		return kr;
 	}
 
+	j->shmem = (typeof(j->shmem))vm_addr;
+	j->shmem->vp_shmem_standby_timeout = j->timeout;
+
 	kr = mach_make_memory_entry_64(mach_task_self(), &size_of_page,
-			(memory_object_offset_t)((long)j->shmem), VM_PROT_DEFAULT, shmem_port, 0);
+			(memory_object_offset_t)vm_addr, VM_PROT_READ|VM_PROT_WRITE, shmem_port, 0);
 
 	if (job_assumes(j, kr == 0)) {
 		job_assumes(j, size_of_page == size_of_page_orig);
 	}
 
+	/* no need to inherit this in child processes */
+	job_assumes(j, vm_inherit(mach_task_self(), (vm_address_t)j->shmem, size_of_page_orig, VM_INHERIT_NONE) == 0);
+
 	return kr;
 }
 
@@ -5776,7 +5793,7 @@
 			kr = 1;
 		} else if (inval) {
 			if (j->start_interval == 0) {
-				runtime_add_ref();
+				runtime_add_weak_ref();
 			} else {
 				/* Workaround 5225889 */
 				job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, j) != -1);
@@ -5786,7 +5803,7 @@
 		} else if (j->start_interval) {
 			job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1);
 			if (j->start_interval != 0) {
-				runtime_del_ref();
+				runtime_del_weak_ref();
 			}
 			j->start_interval = 0;
 		}
@@ -6014,6 +6031,7 @@
 
 		ji->mach_uid = which_user;
 		ji->per_user = true;
+		ji->kill_via_shmem = true;
 
 		if ((ms = machservice_new(ji, lbuf, up_cont, false)) == NULL) {
 			job_remove(ji);

Modified: trunk/launchd/src/launchd_runtime.c
===================================================================
--- trunk/launchd/src/launchd_runtime.c	2008-03-27 22:56:23 UTC (rev 23579)
+++ trunk/launchd/src/launchd_runtime.c	2008-03-28 19:47:54 UTC (rev 23580)
@@ -69,6 +69,8 @@
 #include "launch.h"
 #include "launchd.h"
 #include "launchd_core_logic.h"
+#include "libvproc_public.h"
+#include "libvproc_private.h"
 #include "libvproc_internal.h"
 #include "job_reply.h"
 
@@ -99,6 +101,7 @@
 static mach_msg_timeout_t runtime_idle_timeout;
 static struct ldcred ldc;
 static size_t runtime_busy_cnt;
+static size_t runtime_standby_cnt;
 
 
 static STAILQ_HEAD(, logmsg_s) logmsg_queue = STAILQ_HEAD_INITIALIZER(logmsg_queue);
@@ -989,6 +992,7 @@
 	mig_callback the_demux;
 	mach_msg_timeout_t to;
 	mach_msg_return_t mr;
+	size_t busy_cnt;
 
 	options = MACH_RCV_MSG|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) |
 		MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0);
@@ -996,6 +1000,7 @@
 	tmp_options = options;
 
 	for (;;) {
+		busy_cnt = runtime_busy_cnt + runtime_standby_cnt;
 		to = MACH_MSG_TIMEOUT_NONE;
 
 		if (unlikely(msg_size != max_msg_size)) {
@@ -1007,11 +1012,11 @@
 			}
 		}
 
-		if ((tmp_options & MACH_RCV_MSG) && (runtime_idle_callback || (runtime_busy_cnt == 0))) {
+		if ((tmp_options & MACH_RCV_MSG) && (runtime_idle_callback || (busy_cnt == 0))) {
 			tmp_options |= MACH_RCV_TIMEOUT;
 
 			if (!(tmp_options & MACH_SEND_TIMEOUT)) {
-				to = runtime_busy_cnt ? runtime_idle_timeout : (RUNTIME_ADVISABLE_IDLE_TIMEOUT * 1000);
+				to = busy_cnt ? runtime_idle_timeout : (_vproc_standby_timeout() * 1000);
 			}
 		}
 
@@ -1033,7 +1038,7 @@
 			continue;
 		case MACH_RCV_TIMED_OUT:
 			if (to != MACH_MSG_TIMEOUT_NONE) {
-				if (runtime_busy_cnt == 0) {
+				if (busy_cnt == 0) {
 					launchd_shutdown();
 				} else if (runtime_idle_callback) {
 					runtime_idle_callback();
@@ -1477,15 +1482,39 @@
 INTERNAL_ABI void
 runtime_add_ref(void)
 {
+	if (!pid1_magic) {
+		_vproc_transaction_begin();
+	}
 	runtime_busy_cnt++;
 }
 
 INTERNAL_ABI void
 runtime_del_ref(void)
 {
+	if (!pid1_magic) {
+		_vproc_transaction_end();
+	}
 	runtime_busy_cnt--;
 }
 
+INTERNAL_ABI void
+runtime_add_weak_ref(void)
+{
+	if (!pid1_magic) {
+		_vproc_standby_begin();
+	}
+	runtime_standby_cnt++;
+}
+
+INTERNAL_ABI void
+runtime_del_weak_ref(void)
+{
+	if (!pid1_magic) {
+		_vproc_standby_end();
+	}
+	runtime_standby_cnt--;
+}
+
 kern_return_t
 catch_mach_exception_raise(mach_port_t exception_port __attribute__((unused)), mach_port_t thread, mach_port_t task,
 		exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt)

Modified: trunk/launchd/src/launchd_runtime.h
===================================================================
--- trunk/launchd/src/launchd_runtime.h	2008-03-27 22:56:23 UTC (rev 23579)
+++ trunk/launchd/src/launchd_runtime.h	2008-03-28 19:47:54 UTC (rev 23580)
@@ -111,6 +111,8 @@
 
 INTERNAL_ABI void runtime_add_ref(void);
 INTERNAL_ABI void runtime_del_ref(void);
+INTERNAL_ABI void runtime_add_weak_ref(void);
+INTERNAL_ABI void runtime_del_weak_ref(void);
 
 INTERNAL_ABI void launchd_runtime_init(void);
 INTERNAL_ABI void launchd_runtime_init2(void);

Modified: trunk/launchd/src/libvproc.c
===================================================================
--- trunk/launchd/src/libvproc.c	2008-03-27 22:56:23 UTC (rev 23579)
+++ trunk/launchd/src/libvproc.c	2008-03-28 19:47:54 UTC (rev 23580)
@@ -33,6 +33,7 @@
 #include <syslog.h>
 #include <pthread.h>
 #include <signal.h>
+#include <assert.h>
 #if HAVE_QUARANTINE
 #include <quarantine.h>
 #endif
@@ -65,16 +66,12 @@
 
 	kr = vproc_mig_setup_shmem(bootstrap_port, &shmem_port);
 
-	if (unlikely(kr)) {
-		abort();
-	}
+	assert(kr == 0);
 
-	kr = vm_map_64(mach_task_self(), &vm_addr, getpagesize(), 0, true, shmem_port, 0, false,
+	kr = vm_map(mach_task_self(), &vm_addr, getpagesize(), 0, true, shmem_port, 0, false,
 			VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE);
 
-	if (unlikely(kr)) {
-		abort();
-	}
+	assert(kr == 0);
 
 	vproc_shmem = (struct vproc_shmem_s *)vm_addr;
 }
@@ -84,13 +81,13 @@
 {
 	vproc_transaction_t vpt = (vproc_transaction_t)vproc_shmem_init; /* we need a "random" variable that is testable */
 
-	_basic_vproc_transaction_begin();
+	_vproc_transaction_begin();
 
 	return vpt;
 }
 
 void
-_basic_vproc_transaction_begin(void)
+_vproc_transaction_begin(void)
 {
 	typeof(vproc_shmem->vp_shmem_transaction_cnt) newval;
 
@@ -115,13 +112,25 @@
 }
 
 size_t
-_basic_vproc_transaction_count(void)
+_vproc_transaction_count(void)
 {
 	return likely(vproc_shmem) ? vproc_shmem->vp_shmem_transaction_cnt : INT32_MAX;
 }
 
+size_t
+_vproc_standby_count(void)
+{
+	return likely(vproc_shmem) ? vproc_shmem->vp_shmem_standby_cnt : INT32_MAX;
+}
+
+size_t
+_vproc_standby_timeout(void)
+{
+	return likely(vproc_shmem) ? vproc_shmem->vp_shmem_standby_timeout : 0;
+}
+
 void
-_basic_vproc_transaction_try_exit(int status)
+_vproc_transaction_try_exit(int status)
 {
 	typeof(vproc_shmem->vp_shmem_transaction_cnt) newval;
 
@@ -146,11 +155,11 @@
 		abort();
 	}
 
-	_basic_vproc_transaction_end();
+	_vproc_transaction_end();
 }
 
 void
-_basic_vproc_transaction_end(void)
+_vproc_transaction_end(void)
 {
 	typeof(vproc_shmem->vp_shmem_transaction_cnt) newval;
 
@@ -171,12 +180,21 @@
 vproc_standby_begin(vproc_t vp __attribute__((unused)))
 {
 	vproc_standby_t vpsb = (vproc_standby_t)vproc_shmem_init; /* we need a "random" variable that is testable */
+
+	_vproc_standby_begin();
+
+	return vpsb;
+}
+
+void
+_vproc_standby_begin(void)
+{
 	typeof(vproc_shmem->vp_shmem_standby_cnt) newval;
 
 	if (unlikely(vproc_shmem == NULL)) {
 		int po_r = pthread_once(&shmem_inited, vproc_shmem_init);
 		if (po_r != 0 || vproc_shmem == NULL) {
-			return NULL;
+			return;
 		}
 	}
 
@@ -186,20 +204,24 @@
 		__crashreporter_info__ = "Unbalanced: vproc_standby_begin()";
 		abort();
 	}
-
-	return vpsb;
 }
 
 void
 vproc_standby_end(vproc_t vp __attribute__((unused)), vproc_standby_t vpt)
 {
-	typeof(vproc_shmem->vp_shmem_standby_cnt) newval;
-
 	if (unlikely(vpt != (vproc_standby_t)vproc_shmem_init)) {
 		__crashreporter_info__ = "Bogus standby handle passed to vproc_standby_end() ";
 		abort();
 	}
 
+	_vproc_standby_end();
+}
+
+void
+_vproc_standby_end(void)
+{
+	typeof(vproc_shmem->vp_shmem_standby_cnt) newval;
+
 	newval = __sync_sub_and_fetch(&vproc_shmem->vp_shmem_standby_cnt, 1);
 
 	if (unlikely(newval < 0)) {

Modified: trunk/launchd/src/libvproc_internal.h
===================================================================
--- trunk/launchd/src/libvproc_internal.h	2008-03-27 22:56:23 UTC (rev 23579)
+++ trunk/launchd/src/libvproc_internal.h	2008-03-28 19:47:54 UTC (rev 23580)
@@ -38,6 +38,7 @@
 struct vproc_shmem_s {
 	int32_t vp_shmem_transaction_cnt;
 	int32_t vp_shmem_standby_cnt;
+	uint32_t vp_shmem_standby_timeout;
 	int32_t vp_shmem_flags;
 };
 

Modified: trunk/launchd/src/libvproc_private.h
===================================================================
--- trunk/launchd/src/libvproc_private.h	2008-03-27 22:56:23 UTC (rev 23579)
+++ trunk/launchd/src/libvproc_private.h	2008-03-28 19:47:54 UTC (rev 23580)
@@ -76,12 +76,17 @@
 
 vproc_err_t _vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type);
 
-void _basic_vproc_transaction_begin(void);
-void _basic_vproc_transaction_end(void);
-size_t _basic_vproc_transaction_count(void);
-void _basic_vproc_transaction_try_exit(int status);
+void _vproc_standby_begin(void);
+void _vproc_standby_end(void);
+size_t _vproc_standby_count(void);
+size_t _vproc_standby_timeout(void);
 
+void _vproc_transaction_try_exit(int status);
+void _vproc_transaction_begin(void);
+void _vproc_transaction_end(void);
+size_t _vproc_transaction_count(void);
 
+
 #pragma GCC visibility pop
 
 __END_DECLS

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


More information about the launchd-changes mailing list