[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