Projects
Browse Source     Search     Timeline     Wiki

Changeset 23580

Show
Ignore:
Timestamp:
2008-03-28 12:47:54 (6 months ago)
Author:
zarzycki@…
Message:

Have launchd use the kill-via-shmem trick.

Location:
trunk/launchd/src
Files:
7 modified

Legend:

Unmodified
Added
Removed
  • trunk/launchd/src/launchd.c

    r23553 r23580  
    7171#include "libbootstrap_public.h" 
    7272#include "libvproc_public.h" 
     73#include "libvproc_private.h" 
    7374#include "libvproc_internal.h" 
    7475#include "liblaunch_public.h" 
     
    159160        if (pid1_magic) { 
    160161                handle_pid1_crashes_separately(); 
     162        } else { 
     163                /* prime shared memory before the 'bootstrap_port' global is set to zero */ 
     164                _vproc_transaction_begin(); 
     165                _vproc_transaction_end(); 
    161166        } 
    162167 
  • trunk/launchd/src/launchd_core_logic.c

    r23577 r23580  
    564564job_stop(job_t j) 
    565565{ 
     566        char extralog[100]; 
    566567        int32_t newval = 1; 
    567568 
     
    596597                } 
    597598 
    598                 job_log(j, LOG_DEBUG, "Sent SIGTERM signal"); 
     599                if (j->kill_via_shmem) { 
     600                        snprintf(extralog, sizeof(extralog), ": %d remaining transactions", j->shmem->vp_shmem_transaction_cnt + 1); 
     601                } else { 
     602                        extralog[0] = '\0'; 
     603                } 
     604 
     605                job_log(j, LOG_DEBUG, "Sent SIGTERM signal%s", extralog); 
    599606        } 
    600607} 
     
    804811 
    805812        if (jm->parentmgr) { 
    806                 runtime_del_ref(); 
     813                runtime_del_weak_ref(); 
    807814                SLIST_REMOVE(&jm->parentmgr->submgrs, jm, jobmgr_s, sle); 
    808815        } else if (pid1_magic) { 
     
    960967        } 
    961968        if (j->start_interval) { 
    962                 runtime_del_ref(); 
     969                runtime_del_weak_ref(); 
    963970                job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1); 
    964971        } 
     
    16651672                                job_log(j, LOG_WARNING, "%s is too large. Ignoring.", LAUNCH_JOBKEY_STARTINTERVAL); 
    16661673                        } else { 
    1667                                 runtime_add_ref(); 
     1674                                runtime_add_weak_ref(); 
    16681675                                j->start_interval = value; 
    16691676 
     
    22312238 
    22322239        if (j->shmem) { 
    2233                 job_assumes(j, munmap(j->shmem, getpagesize()) == 0); 
     2240                job_assumes(j, vm_deallocate(mach_task_self(), (vm_address_t)j->shmem, getpagesize()) == 0); 
    22342241                j->shmem = NULL; 
    22352242        } 
     
    37923799        calendarinterval_setalarm(j, ci); 
    37933800 
    3794         runtime_add_ref(); 
     3801        runtime_add_weak_ref(); 
    37953802 
    37963803        return true; 
     
    38053812        free(ci); 
    38063813 
    3807         runtime_del_ref(); 
     3814        runtime_del_weak_ref(); 
    38083815} 
    38093816 
     
    38633870        SLIST_INSERT_HEAD(&j->sockets, sg, sle); 
    38643871 
    3865         runtime_add_ref(); 
     3872        runtime_add_weak_ref(); 
    38663873 
    38673874        return true; 
     
    38943901        free(sg); 
    38953902 
    3896         runtime_del_ref(); 
     3903        runtime_del_weak_ref(); 
    38973904} 
    38983905 
     
    47304737 
    47314738        if (jmr->parentmgr) { 
    4732                 runtime_add_ref(); 
     4739                runtime_add_weak_ref(); 
    47334740        } 
    47344741 
     
    51705177 
    51715178        if (add) { 
    5172                 runtime_add_ref(); 
     5179                runtime_add_weak_ref(); 
    51735180        } else { 
    5174                 runtime_del_ref(); 
     5181                runtime_del_weak_ref(); 
    51755182        } 
    51765183} 
     
    54385445{ 
    54395446        memory_object_size_t size_of_page, size_of_page_orig; 
     5447        vm_address_t vm_addr; 
    54405448        kern_return_t kr; 
    54415449 
     
    54455453 
    54465454        if (unlikely(j->anonymous)) { 
     5455                job_log(j, LOG_ERR, "Anonymous job tried to setup shared memory"); 
    54475456                return BOOTSTRAP_NOT_PRIVILEGED; 
    54485457        } 
     
    54555464        size_of_page_orig = size_of_page = getpagesize(); 
    54565465 
    5457         if (!job_assumes(j, j->shmem = mmap(NULL, size_of_page, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0))) { 
    5458                 return BOOTSTRAP_NO_MEMORY; 
    5459         } 
     5466        kr = vm_allocate(mach_task_self(), &vm_addr, size_of_page, true); 
     5467 
     5468        if (!job_assumes(j, kr == 0)) { 
     5469                return kr; 
     5470        } 
     5471 
     5472        j->shmem = (typeof(j->shmem))vm_addr; 
     5473        j->shmem->vp_shmem_standby_timeout = j->timeout; 
    54605474 
    54615475        kr = mach_make_memory_entry_64(mach_task_self(), &size_of_page, 
    5462                         (memory_object_offset_t)((long)j->shmem), VM_PROT_DEFAULT, shmem_port, 0); 
     5476                        (memory_object_offset_t)vm_addr, VM_PROT_READ|VM_PROT_WRITE, shmem_port, 0); 
    54635477 
    54645478        if (job_assumes(j, kr == 0)) { 
    54655479                job_assumes(j, size_of_page == size_of_page_orig); 
    54665480        } 
     5481 
     5482        /* no need to inherit this in child processes */ 
     5483        job_assumes(j, vm_inherit(mach_task_self(), (vm_address_t)j->shmem, size_of_page_orig, VM_INHERIT_NONE) == 0); 
    54675484 
    54685485        return kr; 
     
    57775794                } else if (inval) { 
    57785795                        if (j->start_interval == 0) { 
    5779                                 runtime_add_ref(); 
     5796                                runtime_add_weak_ref(); 
    57805797                        } else { 
    57815798                                /* Workaround 5225889 */ 
     
    57875804                        job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1); 
    57885805                        if (j->start_interval != 0) { 
    5789                                 runtime_del_ref(); 
     5806                                runtime_del_weak_ref(); 
    57905807                        } 
    57915808                        j->start_interval = 0; 
     
    60156032                ji->mach_uid = which_user; 
    60166033                ji->per_user = true; 
     6034                ji->kill_via_shmem = true; 
    60176035 
    60186036                if ((ms = machservice_new(ji, lbuf, up_cont, false)) == NULL) { 
  • trunk/launchd/src/launchd_runtime.c

    r23563 r23580  
    7070#include "launchd.h" 
    7171#include "launchd_core_logic.h" 
     72#include "libvproc_public.h" 
     73#include "libvproc_private.h" 
    7274#include "libvproc_internal.h" 
    7375#include "job_reply.h" 
     
    100102static struct ldcred ldc; 
    101103static size_t runtime_busy_cnt; 
     104static size_t runtime_standby_cnt; 
    102105 
    103106 
     
    990993        mach_msg_timeout_t to; 
    991994        mach_msg_return_t mr; 
     995        size_t busy_cnt; 
    992996 
    993997        options = MACH_RCV_MSG|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | 
     
    9971001 
    9981002        for (;;) { 
     1003                busy_cnt = runtime_busy_cnt + runtime_standby_cnt; 
    9991004                to = MACH_MSG_TIMEOUT_NONE; 
    10001005 
     
    10081013                } 
    10091014 
    1010                 if ((tmp_options & MACH_RCV_MSG) && (runtime_idle_callback || (runtime_busy_cnt == 0))) { 
     1015                if ((tmp_options & MACH_RCV_MSG) && (runtime_idle_callback || (busy_cnt == 0))) { 
    10111016                        tmp_options |= MACH_RCV_TIMEOUT; 
    10121017 
    10131018                        if (!(tmp_options & MACH_SEND_TIMEOUT)) { 
    1014                                 to = runtime_busy_cnt ? runtime_idle_timeout : (RUNTIME_ADVISABLE_IDLE_TIMEOUT * 1000); 
     1019                                to = busy_cnt ? runtime_idle_timeout : (_vproc_standby_timeout() * 1000); 
    10151020                        } 
    10161021                } 
     
    10341039                case MACH_RCV_TIMED_OUT: 
    10351040                        if (to != MACH_MSG_TIMEOUT_NONE) { 
    1036                                 if (runtime_busy_cnt == 0) { 
     1041                                if (busy_cnt == 0) { 
    10371042                                        launchd_shutdown(); 
    10381043                                } else if (runtime_idle_callback) { 
     
    14781483runtime_add_ref(void) 
    14791484{ 
     1485        if (!pid1_magic) { 
     1486                _vproc_transaction_begin(); 
     1487        } 
    14801488        runtime_busy_cnt++; 
    14811489} 
     
    14841492runtime_del_ref(void) 
    14851493{ 
     1494        if (!pid1_magic) { 
     1495                _vproc_transaction_end(); 
     1496        } 
    14861497        runtime_busy_cnt--; 
     1498} 
     1499 
     1500INTERNAL_ABI void 
     1501runtime_add_weak_ref(void) 
     1502{ 
     1503        if (!pid1_magic) { 
     1504                _vproc_standby_begin(); 
     1505        } 
     1506        runtime_standby_cnt++; 
     1507} 
     1508 
     1509INTERNAL_ABI void 
     1510runtime_del_weak_ref(void) 
     1511{ 
     1512        if (!pid1_magic) { 
     1513                _vproc_standby_end(); 
     1514        } 
     1515        runtime_standby_cnt--; 
    14871516} 
    14881517 
  • trunk/launchd/src/launchd_runtime.h

    r23542 r23580  
    112112INTERNAL_ABI void runtime_add_ref(void); 
    113113INTERNAL_ABI void runtime_del_ref(void); 
     114INTERNAL_ABI void runtime_add_weak_ref(void); 
     115INTERNAL_ABI void runtime_del_weak_ref(void); 
    114116 
    115117INTERNAL_ABI void launchd_runtime_init(void); 
  • trunk/launchd/src/libvproc.c

    r23578 r23580  
    3434#include <pthread.h> 
    3535#include <signal.h> 
     36#include <assert.h> 
    3637#if HAVE_QUARANTINE 
    3738#include <quarantine.h> 
     
    6667        kr = vproc_mig_setup_shmem(bootstrap_port, &shmem_port); 
    6768 
    68         if (unlikely(kr)) { 
    69                 abort(); 
    70         } 
    71  
    72         kr = vm_map_64(mach_task_self(), &vm_addr, getpagesize(), 0, true, shmem_port, 0, false, 
     69        assert(kr == 0); 
     70 
     71        kr = vm_map(mach_task_self(), &vm_addr, getpagesize(), 0, true, shmem_port, 0, false, 
    7372                        VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); 
    7473 
    75         if (unlikely(kr)) { 
    76                 abort(); 
    77         } 
     74        assert(kr == 0); 
    7875 
    7976        vproc_shmem = (struct vproc_shmem_s *)vm_addr; 
     
    8582        vproc_transaction_t vpt = (vproc_transaction_t)vproc_shmem_init; /* we need a "random" variable that is testable */ 
    8683 
    87         _basic_vproc_transaction_begin(); 
     84        _vproc_transaction_begin(); 
    8885 
    8986        return vpt; 
     
    9188 
    9289void 
    93 _basic_vproc_transaction_begin(void) 
     90_vproc_transaction_begin(void) 
    9491{ 
    9592        typeof(vproc_shmem->vp_shmem_transaction_cnt) newval; 
     
    116113 
    117114size_t 
    118 _basic_vproc_transaction_count(void) 
     115_vproc_transaction_count(void) 
    119116{ 
    120117        return likely(vproc_shmem) ? vproc_shmem->vp_shmem_transaction_cnt : INT32_MAX; 
    121118} 
    122119 
    123 void 
    124 _basic_vproc_transaction_try_exit(int status) 
     120size_t 
     121_vproc_standby_count(void) 
     122{ 
     123        return likely(vproc_shmem) ? vproc_shmem->vp_shmem_standby_cnt : INT32_MAX; 
     124} 
     125 
     126size_t 
     127_vproc_standby_timeout(void) 
     128{ 
     129        return likely(vproc_shmem) ? vproc_shmem->vp_shmem_standby_timeout : 0; 
     130} 
     131 
     132void 
     133_vproc_transaction_try_exit(int status) 
    125134{ 
    126135        typeof(vproc_shmem->vp_shmem_transaction_cnt) newval; 
     
    147156        } 
    148157 
    149         _basic_vproc_transaction_end(); 
    150 } 
    151  
    152 void 
    153 _basic_vproc_transaction_end(void) 
     158        _vproc_transaction_end(); 
     159} 
     160 
     161void 
     162_vproc_transaction_end(void) 
    154163{ 
    155164        typeof(vproc_shmem->vp_shmem_transaction_cnt) newval; 
     
    172181{ 
    173182        vproc_standby_t vpsb = (vproc_standby_t)vproc_shmem_init; /* we need a "random" variable that is testable */ 
     183 
     184        _vproc_standby_begin(); 
     185 
     186        return vpsb; 
     187} 
     188 
     189void 
     190_vproc_standby_begin(void) 
     191{ 
    174192        typeof(vproc_shmem->vp_shmem_standby_cnt) newval; 
    175193 
     
    177195                int po_r = pthread_once(&shmem_inited, vproc_shmem_init); 
    178196                if (po_r != 0 || vproc_shmem == NULL) { 
    179                         return NULL; 
     197                        return; 
    180198                } 
    181199        } 
     
    187205                abort(); 
    188206        } 
    189  
    190         return vpsb; 
    191207} 
    192208 
     
    194210vproc_standby_end(vproc_t vp __attribute__((unused)), vproc_standby_t vpt) 
    195211{ 
    196         typeof(vproc_shmem->vp_shmem_standby_cnt) newval; 
    197  
    198212        if (unlikely(vpt != (vproc_standby_t)vproc_shmem_init)) { 
    199213                __crashreporter_info__ = "Bogus standby handle passed to vproc_standby_end() "; 
    200214                abort(); 
    201215        } 
     216 
     217        _vproc_standby_end(); 
     218} 
     219 
     220void 
     221_vproc_standby_end(void) 
     222{ 
     223        typeof(vproc_shmem->vp_shmem_standby_cnt) newval; 
    202224 
    203225        newval = __sync_sub_and_fetch(&vproc_shmem->vp_shmem_standby_cnt, 1); 
  • trunk/launchd/src/libvproc_internal.h

    r23574 r23580  
    3939        int32_t vp_shmem_transaction_cnt; 
    4040        int32_t vp_shmem_standby_cnt; 
     41        uint32_t vp_shmem_standby_timeout; 
    4142        int32_t vp_shmem_flags; 
    4243}; 
  • trunk/launchd/src/libvproc_private.h

    r23578 r23580  
    7777vproc_err_t _vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type); 
    7878 
    79 void _basic_vproc_transaction_begin(void); 
    80 void _basic_vproc_transaction_end(void); 
    81 size_t _basic_vproc_transaction_count(void); 
    82 void _basic_vproc_transaction_try_exit(int status); 
     79void _vproc_standby_begin(void); 
     80void _vproc_standby_end(void); 
     81size_t _vproc_standby_count(void); 
     82size_t _vproc_standby_timeout(void); 
     83 
     84void _vproc_transaction_try_exit(int status); 
     85void _vproc_transaction_begin(void); 
     86void _vproc_transaction_end(void); 
     87size_t _vproc_transaction_count(void); 
    8388 
    8489