Changeset 23574
- Timestamp:
- 03/27/08 14:18:33 (8 months ago)
- Location:
- trunk/launchd/src
- Files:
-
- 10 modified
-
Makefile.am (modified) (2 diffs)
-
Makefile.in (modified) (2 diffs)
-
launchd.plist.5 (modified) (1 diff)
-
launchd_core_logic.c (modified) (9 diffs)
-
liblaunch_public.h (modified) (1 diff)
-
libvproc.c (modified) (2 diffs)
-
libvproc_internal.h (modified) (1 diff)
-
libvproc_private.h (modified) (1 diff)
-
libvproc_public.h (modified) (7 diffs)
-
protocol_job.defs (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/launchd/src/Makefile.am
r23536 r23574 1 1 CWARN = -Wall -Wextra -Waggregate-return -Wfloat-equal -Wshadow -Wpacked -Wmissing-prototypes -Wmissing-declarations -Werror # gcc4.2: -Wstrict-overflow=4 # -Wpadded -Wconversion -Wstrict-aliasing=2 2 CTUNE = -fvisibility=hidden # gcc4.2: -fdiagnostics-show-option # -fstrict-aliasing2 CTUNE = -fvisibility=hidden -freorder-blocks # gcc4.2: -fdiagnostics-show-option # -fstrict-aliasing 3 3 CMISC = -isysroot $(SDKROOT) -F$(SDKROOT)/System/Library/PrivateFrameworks -D__MigTypeCheck=1 -Dmig_external=__private_extern__ -D_DARWIN_USE_64_BIT_INODE=1 4 4 AM_CFLAGS = $(CTUNE) $(CMISC) $(CWARN) … … 58 58 endif 59 59 60 launchd_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) -freorder-blocks60 launchd_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) 61 61 launchd_LDFLAGS = $(AM_LDFLAGS) -lbsm 62 62 launchd_SOURCES = launchd.c launchd_core_logic.c launchd_unix_ipc.c protocol_vprocServer.c notifyServer.c launchd_internalUser.c launchd_internalServer.c job_replyUser.c launchd_runtime.c launchd_runtime_kill.c job_forwardUser.c mach_excServer.c -
trunk/launchd/src/Makefile.in
r23536 r23574 244 244 top_srcdir = @top_srcdir@ 245 245 CWARN = -Wall -Wextra -Waggregate-return -Wfloat-equal -Wshadow -Wpacked -Wmissing-prototypes -Wmissing-declarations -Werror # gcc4.2: -Wstrict-overflow=4 # -Wpadded -Wconversion -Wstrict-aliasing=2 246 CTUNE = -fvisibility=hidden # gcc4.2: -fdiagnostics-show-option # -fstrict-aliasing246 CTUNE = -fvisibility=hidden -freorder-blocks # gcc4.2: -fdiagnostics-show-option # -fstrict-aliasing 247 247 CMISC = -isysroot $(SDKROOT) -F$(SDKROOT)/System/Library/PrivateFrameworks -D__MigTypeCheck=1 -Dmig_external=__private_extern__ -D_DARWIN_USE_64_BIT_INODE=1 248 248 AM_CFLAGS = $(CTUNE) $(CMISC) $(CWARN) … … 263 263 @DO_EMBEDDED_MAGIC_FALSE@@LIBS_ONLY_FALSE@SystemStarter_LDFLAGS = $(AM_LDFLAGS) -framework CoreFoundation -framework IOKit 264 264 @DO_EMBEDDED_MAGIC_FALSE@@LIBS_ONLY_FALSE@SystemStarter_SOURCES = StartupItems.c IPC.c SystemStarter.c 265 @LIBS_ONLY_FALSE@launchd_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) -freorder-blocks265 @LIBS_ONLY_FALSE@launchd_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) 266 266 @LIBS_ONLY_FALSE@launchd_LDFLAGS = $(AM_LDFLAGS) -lbsm 267 267 @LIBS_ONLY_FALSE@launchd_SOURCES = launchd.c launchd_core_logic.c launchd_unix_ipc.c protocol_vprocServer.c notifyServer.c launchd_internalUser.c launchd_internalServer.c job_replyUser.c launchd_runtime.c launchd_runtime_kill.c job_forwardUser.c mach_excServer.c -
trunk/launchd/src/launchd.plist.5
r23532 r23574 124 124 .Xr glob 3 125 125 mechanism to update the program arguments before invocation. 126 .It Sy EnableTransactions <boolean> 127 This flag instructs 128 .Nm launchd 129 that the job promises to use 130 .Xr vproc_transaction_begin 3 131 and 132 .Xr vproc_transaction_end 3 133 to track outstanding transactions that need to be reconciled before the process can safely terminate. If no outstanding transactions are in progress, then 134 .Nm launchd 135 is free to send the SIGKILL signal. 126 136 .It Sy OnDemand <boolean> 127 137 This key was used in Mac OS X 10.4 to control whether a job was kept alive or not. The default was true. -
trunk/launchd/src/launchd_core_logic.c
r23573 r23574 51 51 #include <sys/mount.h> 52 52 #include <sys/pipe.h> 53 #include <sys/mman.h> 53 54 #include <net/if.h> 54 55 #include <netinet/in.h> … … 361 362 char *stderrpath; 362 363 char *alt_exc_handler; 364 struct vproc_shmem_s *shmem; 363 365 struct machservice *lastlookup; 364 366 unsigned int lastlookup_gennum; … … 385 387 uint32_t min_run_time; 386 388 uint32_t start_interval; 387 unsigned shortcheckedin:1, anonymous:1, debug:1, inetcompat:1, inetcompat_wait:1,389 bool checkedin:1, anonymous:1, debug:1, inetcompat:1, inetcompat_wait:1, 388 390 ondemand:1, session_create:1, low_pri_io:1, no_init_groups:1, priv_port_has_senders:1, 389 391 importing_global_env:1, importing_hard_limits:1, setmask:1, legacy_mach_job:1, start_pending:1, … … 392 394 legacy_LS_job:1, sent_sigkill:1, debug_before_kill:1, weird_bootstrap:1, start_on_mount:1, 393 395 per_user:1, hopefully_exits_first:1, deny_unknown_mslookups:1, unload_at_mig_return:1, abandon_pg:1, 394 poll_for_vfs_changes:1, deny_job_creation:1, __junk:11;396 poll_for_vfs_changes:1, deny_job_creation:1, kill_via_shmem:1, sent_kill_via_shmem:1; 395 397 mode_t mask; 396 398 const char label[0]; … … 562 564 job_stop(job_t j) 563 565 { 566 int32_t newval = 1; 567 564 568 if (unlikely(!j->p || j->anonymous)) { 565 569 return; 566 570 } 567 571 568 job_assumes(j, runtime_kill(j->p, SIGTERM) != -1); 572 if (j->kill_via_shmem) { 573 if (j->shmem) { 574 if (!j->sent_kill_via_shmem) { 575 j->shmem->vp_shmem_flags |= VPROC_SHMEM_EXITING; 576 newval = __sync_sub_and_fetch(&j->shmem->vp_shmem_transaction_cnt, 1); 577 j->sent_kill_via_shmem = true; 578 } else { 579 newval = j->shmem->vp_shmem_transaction_cnt; 580 } 581 } else { 582 newval = -1; 583 } 584 } 585 569 586 j->sent_sigterm_time = runtime_get_opaque_time(); 570 587 571 if (j->exit_timeout) { 572 job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, 573 EV_ADD|EV_ONESHOT, NOTE_SECONDS, j->exit_timeout, j) != -1); 574 } 575 576 job_log(j, LOG_DEBUG, "Sent SIGTERM signal"); 588 if (newval < 0) { 589 job_kill(j); 590 } else { 591 job_assumes(j, runtime_kill(j->p, SIGTERM) != -1); 592 593 if (j->exit_timeout) { 594 job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, 595 EV_ADD|EV_ONESHOT, NOTE_SECONDS, j->exit_timeout, j) != -1); 596 } 597 598 job_log(j, LOG_DEBUG, "Sent SIGTERM signal"); 599 } 577 600 } 578 601 … … 1453 1476 if (strcasecmp(key, LAUNCH_JOBKEY_ENABLEGLOBBING) == 0) { 1454 1477 j->globargv = value; 1478 found_key = true; 1479 } else if (strcasecmp(key, LAUNCH_JOBKEY_ENABLETRANSACTIONS) == 0) { 1480 j->kill_via_shmem = value; 1455 1481 found_key = true; 1456 1482 } else if (strcasecmp(key, LAUNCH_JOBKEY_ENTERKERNELDEBUGGERBEFOREKILL) == 0) { … … 2204 2230 job_log(j, LOG_DEBUG, "Reaping"); 2205 2231 2232 if (j->shmem) { 2233 job_assumes(j, munmap(j->shmem, getpagesize()) == 0); 2234 } 2235 2206 2236 if (unlikely(j->weird_bootstrap)) { 2207 2237 mach_msg_size_t mxmsgsz = sizeof(union __RequestUnion__job_mig_protocol_vproc_subsystem); … … 2336 2366 j->last_exit_status = status; 2337 2367 j->sent_sigkill = false; 2368 j->sent_kill_via_shmem = false; 2338 2369 j->p = 0; 2339 2370 … … 5403 5434 5404 5435 kern_return_t 5436 job_mig_setup_shmem(job_t j, mach_port_t *shmem_port) 5437 { 5438 memory_object_size_t size_of_page, size_of_page_orig; 5439 kern_return_t kr; 5440 5441 if (!launchd_assumes(j != NULL)) { 5442 return BOOTSTRAP_NO_MEMORY; 5443 } 5444 5445 if (unlikely(j->anonymous)) { 5446 return BOOTSTRAP_NOT_PRIVILEGED; 5447 } 5448 5449 size_of_page_orig = size_of_page = getpagesize(); 5450 5451 if (!job_assumes(j, j->shmem = mmap(NULL, size_of_page, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0))) { 5452 return BOOTSTRAP_NO_MEMORY; 5453 } 5454 5455 kr = mach_make_memory_entry_64(mach_task_self(), &size_of_page, 5456 (memory_object_offset_t)((long)j->shmem), VM_PROT_DEFAULT, shmem_port, 0); 5457 5458 if (job_assumes(j, kr == 0)) { 5459 job_assumes(j, size_of_page == size_of_page_orig); 5460 } 5461 5462 return kr; 5463 } 5464 5465 kern_return_t 5405 5466 job_mig_create_server(job_t j, cmd_t server_cmd, uid_t server_uid, boolean_t on_demand, mach_port_t *server_portp) 5406 5467 { -
trunk/launchd/src/liblaunch_public.h
r23488 r23574 102 102 #define LAUNCH_JOBKEY_ABANDONPROCESSGROUP "AbandonProcessGroup" 103 103 #define LAUNCH_JOBKEY_POLICIES "Policies" 104 #define LAUNCH_JOBKEY_ENABLETRANSACTIONS "EnableTransactions" 104 105 105 106 #define LAUNCH_JOBPOLICY_DENYCREATINGOTHERJOBS "DenyCreatingOtherJobs" -
trunk/launchd/src/libvproc.c
r23563 r23574 33 33 #include <syslog.h> 34 34 #include <pthread.h> 35 #include <signal.h> 35 36 #if HAVE_QUARANTINE 36 37 #include <quarantine.h> … … 45 46 #include "reboot2.h" 46 47 48 #define likely(x) __builtin_expect((bool)(x), true) 49 #define unlikely(x) __builtin_expect((bool)(x), false) 50 47 51 static mach_port_t get_root_bootstrap_port(void); 48 52 53 const char *__crashreporter_info__; /* this should get merged with other versions of the symbol */ 54 49 55 static int64_t cached_pid = -1; 56 static struct vproc_shmem_s *vproc_shmem; 57 58 static void 59 vproc_shmem_init(void) 60 { 61 vm_address_t vm_addr = 0; 62 mach_port_t shmem_port; 63 kern_return_t kr; 64 65 kr = vproc_mig_setup_shmem(bootstrap_port, &shmem_port); 66 67 if (unlikely(kr)) { 68 abort(); 69 } 70 71 kr = vm_map_64(mach_task_self(), &vm_addr, getpagesize(), 0, true, shmem_port, 0, false, 72 VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); 73 74 if (unlikely(kr)) { 75 abort(); 76 } 77 78 vproc_shmem = (struct vproc_shmem_s *)vm_addr; 79 } 80 81 vproc_transaction_t 82 vproc_transaction_begin(vproc_t vp __attribute__((unused))) 83 { 84 vproc_transaction_t vpt = (vproc_transaction_t)vproc_shmem_init; /* we need a "random" variable that is testable */ 85 86 _basic_vproc_transaction_begin(); 87 88 return vpt; 89 } 90 91 void 92 _basic_vproc_transaction_begin(void) 93 { 94 int64_t newval; 95 96 if (unlikely(vproc_shmem == NULL)) { 97 vproc_shmem_init(); 98 if (vproc_shmem == NULL) { 99 return; 100 } 101 } 102 103 newval = __sync_add_and_fetch(&vproc_shmem->vp_shmem_transaction_cnt, 1); 104 105 if (unlikely(newval < 1)) { 106 if (vproc_shmem->vp_shmem_flags & VPROC_SHMEM_EXITING) { 107 raise(SIGKILL); 108 __crashreporter_info__ = "raise(SIGKILL) failed"; 109 } else { 110 __crashreporter_info__ = "Unbalanced: vproc_transaction_begin()"; 111 } 112 abort(); 113 } 114 } 115 116 void 117 vproc_transaction_end(vproc_t vp __attribute__((unused)), vproc_transaction_t vpt) 118 { 119 if (unlikely(vpt != (vproc_transaction_t)vproc_shmem_init)) { 120 __crashreporter_info__ = "Bogus transaction handle passed to vproc_transaction_end() "; 121 abort(); 122 } 123 124 _basic_vproc_transaction_end(); 125 } 126 127 void 128 _basic_vproc_transaction_end(void) 129 { 130 int32_t newval = __sync_sub_and_fetch(&vproc_shmem->vp_shmem_transaction_cnt, 1); 131 132 if (unlikely(newval < 0)) { 133 if (vproc_shmem->vp_shmem_flags & VPROC_SHMEM_EXITING) { 134 raise(SIGKILL); 135 __crashreporter_info__ = "raise(SIGKILL) failed"; 136 } else { 137 __crashreporter_info__ = "Unbalanced: vproc_transaction_end()"; 138 } 139 abort(); 140 } 141 } 142 143 vproc_standby_t 144 vproc_standby_begin(vproc_t vp __attribute__((unused))) 145 { 146 vproc_standby_t vpsb = (vproc_standby_t)vproc_shmem_init; /* we need a "random" variable that is testable */ 147 int64_t newval; 148 149 if (unlikely(vproc_shmem == NULL)) { 150 vproc_shmem_init(); 151 if (vproc_shmem == NULL) { 152 return NULL; 153 } 154 } 155 156 newval = __sync_add_and_fetch(&vproc_shmem->vp_shmem_standby_cnt, 1); 157 158 if (unlikely(newval < 1)) { 159 __crashreporter_info__ = "Unbalanced: vproc_standby_begin()"; 160 abort(); 161 } 162 163 return vpsb; 164 } 165 166 void 167 vproc_standby_end(vproc_t vp __attribute__((unused)), vproc_standby_t vpt) 168 { 169 int32_t newval; 170 171 if (unlikely(vpt != (vproc_standby_t)vproc_shmem_init)) { 172 __crashreporter_info__ = "Bogus standby handle passed to vproc_standby_end() "; 173 abort(); 174 } 175 176 newval = __sync_sub_and_fetch(&vproc_shmem->vp_shmem_standby_cnt, 1); 177 178 if (unlikely(newval < 0)) { 179 __crashreporter_info__ = "Unbalanced: vproc_standby_end()"; 180 abort(); 181 } 182 } 50 183 51 184 kern_return_t -
trunk/launchd/src/libvproc_internal.h
r23563 r23574 33 33 typedef pid_t * pid_array_t; 34 34 typedef mach_port_t vproc_mig_t; 35 36 #define VPROC_SHMEM_EXITING 0x1 37 38 struct vproc_shmem_s { 39 int32_t vp_shmem_transaction_cnt; 40 int32_t vp_shmem_standby_cnt; 41 int32_t vp_shmem_flags; 42 }; 35 43 36 44 #ifdef protocol_vproc_MSG_COUNT -
trunk/launchd/src/libvproc_private.h
r23533 r23574 77 77 vproc_err_t _vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type); 78 78 79 void _basic_vproc_transaction_begin(void); 80 void _basic_vproc_transaction_end(void); 81 79 82 #pragma GCC visibility pop 80 83 -
trunk/launchd/src/libvproc_public.h
r23535 r23574 68 68 * launchd jobs should update their property lists accordingly. 69 69 * 70 * LaunchServices uses private methods to coordinate whether GUI applications71 * have opted into this design.70 * We plan to have LaunchServices use private methods to coordinate 71 * whether GUI applications have opted into this design. 72 72 */ 73 73 … … 81 81 82 82 /*! 83 * @function vproc_transaction_prepare 83 * @function vproc_transaction_begin 84 * 85 * @param virtual_proc 86 * This is meant for future API improvements. Pass NULL for now. 84 87 * 85 88 * @result 86 * Returns an opaque handle to be passed to vproc_transaction_ complete().89 * Returns an opaque handle to be passed to vproc_transaction_end(). 87 90 * 88 91 * @abstract … … 90 93 */ 91 94 vproc_transaction_t 92 vproc_transaction_ prepare(void);95 vproc_transaction_begin(vproc_t virtual_proc); 93 96 94 97 /*! 95 * @function vproc_transaction_complete 98 * @function vproc_transaction_end 99 * 100 * @param virtual_proc 101 * This is meant for future API improvements. Pass NULL for now. 96 102 * 97 103 * @param handle 98 * The handle previously created with vproc_transaction_ prepare().104 * The handle previously created with vproc_transaction_begin(). 99 105 * 100 106 * @abstract … … 105 111 */ 106 112 void 107 vproc_transaction_ complete(vproc_transaction_t handle);113 vproc_transaction_end(vproc_t virtual_proc, vproc_transaction_t handle); 108 114 109 115 /*! … … 116 122 117 123 /*! 118 * @function vproc_standby_prepare 124 * @function vproc_standby_begin 125 * 126 * @param virtual_proc 127 * This is meant for future API improvements. Pass NULL for now. 119 128 * 120 129 * @result 121 * Returns an opaque handle to be passed to vproc_standby_ complete().130 * Returns an opaque handle to be passed to vproc_standby_end(). 122 131 * 123 132 * @abstract … … 126 135 */ 127 136 vproc_standby_t 128 vproc_standby_ prepare(void);137 vproc_standby_begin(vproc_t virtual_proc); 129 138 130 139 /*! 131 * @function vproc_standby_complete 140 * @function vproc_standby_end 141 * 142 * @param virtual_proc 143 * This is meant for future API improvements. Pass NULL for now. 132 144 * 133 145 * @param handle 134 * The handle previously created with vproc_standby_ prepare().146 * The handle previously created with vproc_standby_begin(). 135 147 * 136 148 * @abstract … … 141 153 */ 142 154 void 143 vproc_standby_ complete(vproc_standby_t handle);155 vproc_standby_end(vproc_t virtual_proc, vproc_standby_t handle); 144 156 145 157 #pragma GCC visibility pop -
trunk/launchd/src/protocol_job.defs
r23539 r23574 96 96 out __subset_port : mach_port_make_send_t); 97 97 98 skip; /* create_service prior to 10.6 */ 98 routine setup_shmem( 99 __bs_port : job_t; 100 out __shmem_port : mach_port_move_send_t); 99 101 100 102 routine take_subset(

