[launchd-changes] [23823] trunk

source_changes at macosforge.org source_changes at macosforge.org
Thu Feb 19 14:10:52 PST 2009


Revision: 23823
          http://trac.macosforge.org/projects/launchd/changeset/23823
Author:   dsorresso at apple.com
Date:     2009-02-19 14:10:52 -0800 (Thu, 19 Feb 2009)
Log Message:
-----------
<rdar://problem/6271234> QFA: Need to be able to install software at shutdown time to eliminate double reboot
<rdar://problem/6562592> Reduce wait time for stray processes (2s delay if stray process does not handle SIGTERM)
<rdar://problem/6589133> 10A274: hundreds of failing (ENOENT) opens of /dev/autofs_nowait in launchd at boot

Modified Paths:
--------------
    trunk/launchd/src/launchctl.c
    trunk/launchd/src/launchd_core_logic.c
    trunk/launchd/src/launchd_runtime.c

Property Changed:
----------------
    trunk/
    trunk/launchd/src/bootstrap.h
    trunk/launchd/src/bootstrap_priv.h
    trunk/launchd/src/launch.h
    trunk/launchd/src/launch_internal.h
    trunk/launchd/src/launch_priv.h
    trunk/launchd/src/protocol_vproc.defs
    trunk/launchd/src/vproc.h
    trunk/launchd/src/vproc_internal.h
    trunk/launchd/src/vproc_priv.h


Property changes on: trunk
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/PR-5092682:23731-23742
/branches/PR-5898404:23681-23700
/branches/PR-5978442:23651-23701
/branches/PR-6132016:23719-23738
   + /branches/PR-5092682:23731-23742
/branches/PR-5898404:23681-23700
/branches/PR-5978442:23651-23701
/branches/PR-6132016:23719-23738
/branches/PR-6271234:23818-23822
/branches/PR-6562592:23812-23822
/branches/PR-6589133:23810-23822


Property changes on: trunk/launchd/src/bootstrap.h
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/PR-5898404/launchd/src/libbootstrap_public.h:23681-23700
/branches/PR-5978442/launchd/src/libbootstrap_public.h:23651-23701
   + /branches/PR-5898404/launchd/src/libbootstrap_public.h:23681-23700
/branches/PR-5978442/launchd/src/libbootstrap_public.h:23651-23701
/branches/PR-6271234/launchd/src/bootstrap.h:23818-23822
/branches/PR-6562592/launchd/src/bootstrap.h:23812-23822
/branches/PR-6589133/launchd/src/bootstrap.h:23810-23822


Property changes on: trunk/launchd/src/bootstrap_priv.h
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/PR-5898404/launchd/src/libbootstrap_private.h:23681-23700
/branches/PR-5978442/launchd/src/libbootstrap_private.h:23651-23701
   + /branches/PR-5898404/launchd/src/libbootstrap_private.h:23681-23700
/branches/PR-5978442/launchd/src/libbootstrap_private.h:23651-23701
/branches/PR-6271234/launchd/src/bootstrap_priv.h:23818-23822
/branches/PR-6562592/launchd/src/bootstrap_priv.h:23812-23822
/branches/PR-6589133/launchd/src/bootstrap_priv.h:23810-23822


Property changes on: trunk/launchd/src/launch.h
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/PR-5898404/launchd/src/liblaunch_public.h:23681-23700
/branches/PR-5978442/launchd/src/liblaunch_public.h:23651-23701
   + /branches/PR-5898404/launchd/src/liblaunch_public.h:23681-23700
/branches/PR-5978442/launchd/src/liblaunch_public.h:23651-23701
/branches/PR-6271234/launchd/src/launch.h:23818-23822
/branches/PR-6562592/launchd/src/launch.h:23812-23822
/branches/PR-6589133/launchd/src/launch.h:23810-23822


Property changes on: trunk/launchd/src/launch_internal.h
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/PR-5898404/launchd/src/liblaunch_internal.h:23681-23700
/branches/PR-5978442/launchd/src/liblaunch_internal.h:23651-23701
   + /branches/PR-5898404/launchd/src/liblaunch_internal.h:23681-23700
/branches/PR-5978442/launchd/src/liblaunch_internal.h:23651-23701
/branches/PR-6271234/launchd/src/launch_internal.h:23818-23822
/branches/PR-6562592/launchd/src/launch_internal.h:23812-23822
/branches/PR-6589133/launchd/src/launch_internal.h:23810-23822


Property changes on: trunk/launchd/src/launch_priv.h
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/PR-5898404/launchd/src/liblaunch_private.h:23681-23700
/branches/PR-5978442/launchd/src/liblaunch_private.h:23651-23701
   + /branches/PR-5898404/launchd/src/liblaunch_private.h:23681-23700
/branches/PR-5978442/launchd/src/liblaunch_private.h:23651-23701
/branches/PR-6271234/launchd/src/launch_priv.h:23818-23822
/branches/PR-6562592/launchd/src/launch_priv.h:23812-23822
/branches/PR-6589133/launchd/src/launch_priv.h:23810-23822

Modified: trunk/launchd/src/launchctl.c
===================================================================
--- trunk/launchd/src/launchctl.c	2009-02-18 19:25:28 UTC (rev 23822)
+++ trunk/launchd/src/launchctl.c	2009-02-19 22:10:52 UTC (rev 23823)
@@ -1841,9 +1841,9 @@
 		assumes(fwexec(rccleanup_tool, NULL) != -1);
 	}
 
-	if( path_check("/etc/rc.deferredinstall") ) {
+	if( path_check("/etc/rc.deferred_install") ) {
 		int status = 0;
-		const char *deferredinstall_tool[] = { _PATH_BSHELL, "/etc/rc.deferredinstall", NULL };
+		const char *deferredinstall_tool[] = { _PATH_BSHELL, "/etc/rc.deferred_install", NULL };
 		if( assumes(fwexec(deferredinstall_tool, &status) != -1) ) {
 			if( WEXITSTATUS(status) == EXIT_SUCCESS ) {
 				if( do_apple_internal_magic ) {

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2009-02-18 19:25:28 UTC (rev 23822)
+++ trunk/launchd/src/launchd_core_logic.c	2009-02-19 22:10:52 UTC (rev 23823)
@@ -371,7 +371,7 @@
 static bool jobmgr_label_test(jobmgr_t jm, const char *str);
 static void jobmgr_reap_bulk(jobmgr_t jm, struct kevent *kev);
 static void jobmgr_log_stray_children(jobmgr_t jm, bool kill_strays);
-static void jobmgr_kill_stray_child(jobmgr_t jm, pid_t p);
+static void jobmgr_kill_stray_children(jobmgr_t jm, pid_t *p, size_t np);
 static void jobmgr_remove(jobmgr_t jm);
 static void jobmgr_dispatch_all(jobmgr_t jm, bool newmounthack);
 static void jobmgr_dequeue_next_sample(jobmgr_t jm);
@@ -632,6 +632,7 @@
 static mach_port_t the_exception_server;
 static job_t workaround_5477111;
 static pid_t s_update_pid = 0;
+static int s_no_hang_fd = -1;
 
 /* process wide globals */
 mach_port_t inherited_bootstrap_port;
@@ -3359,6 +3360,17 @@
 			jobmgr_still_alive_with_check(jm);
 		}
 		break;
+	case EVFILT_VNODE:
+		if( kev->ident == (uintptr_t)s_no_hang_fd ) {
+			int _no_hang_fd = open("/dev/autofs_nowait", O_EVTONLY | O_NONBLOCK);
+			if( unlikely(_no_hang_fd != -1) ) {
+				jobmgr_log(root_jobmgr, LOG_DEBUG, "/dev/autofs_nowait has appeared!");
+				jobmgr_assumes(root_jobmgr, kevent_mod((uintptr_t)s_no_hang_fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL) != -1);
+				jobmgr_assumes(root_jobmgr, runtime_close(s_no_hang_fd) != -1);
+				s_no_hang_fd = _fd(_no_hang_fd);
+			}
+		}
+		break;
 	default:
 		return (void)jobmgr_assumes(jm, false);
 	}
@@ -5557,51 +5569,90 @@
 }
 
 void
-jobmgr_kill_stray_child(jobmgr_t jm, pid_t p)
+jobmgr_kill_stray_children(jobmgr_t jm, pid_t *p, size_t np)
 {
+#if 1
+	/* I maintain that stray processes should be at the mercy of launchd during shutdown,
+	 * but nevertheless, things like diskimages-helper can stick around, and SIGKILLing 
+	 * them can result in data loss. So we send SIGTERM to all the strays and don't wait
+	 * for them to exit before moving on.
+	 * 
+	 * See rdar://problem/6562592
+	 */
+	size_t i = 0;
+	for( i = 0; i < np; i++ ) {
+		if( p[i] != 0 ) {
+			jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Sending SIGTERM to PID %u and continuing...", p[i]);
+			jobmgr_assumes(jm, runtime_kill(p[i], SIGTERM) != -1);
+		}
+	}
+#else
 	struct timespec tts = { 2, 0 }; /* Wait 2 seconds for stray children to die after being SIGTERM'ed. */
 	struct timespec kts = { 1, 0 }; /* Wait 1 second for stray children to die after being SIGKILL'ed. */
 	uint64_t start, end, nanosec;
 	struct kevent kev;
 	int r, kq = kqueue();
-
+	
 	if (!jobmgr_assumes(jm, kq != -1)) {
 		return;
 	}
 
-	EV_SET(&kev, p, EVFILT_PROC, EV_ADD, 0, 0, 0);
-
-	if (!jobmgr_assumes(jm, kevent(kq, &kev, 1, NULL, 0, NULL) != -1)) {
-		goto out;
-	}
-
 	start = runtime_get_opaque_time();
-
-	if (!jobmgr_assumes(jm, runtime_kill(p, SIGTERM) != -1)) {
-		goto out;
+	size_t i = 0, n2t = 0;
+	for( i = 0; i < np; i++ ) {
+		if( p[i] != 0 ) {
+			EV_SET(&kev, p[i], EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, 0);
+			
+			if( jobmgr_assumes(jm, kevent(kq, &kev, 1, NULL, 0, NULL) != -1) ) {
+				jobmgr_assumes(jm, runtime_kill(p[i], SIGTERM) != -1);
+				n2t++;
+			} else {
+				jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Disregarding PID %u and continuing.", p[i]);
+				p[i] = 0;
+			}
+		}
 	}
 
-	r = kevent(kq, NULL, 0, &kev, 1, &tts);
-
-	if (!jobmgr_assumes(jm, r == 0 || r == 1)) {
-		goto out;
+	while( n2t > 0 && (r = kevent(kq, NULL, 0, &kev, 1, &tts)) ) {
+		int status = 0;
+		waitpid((pid_t)kev.ident, &status, WNOHANG);
+		
+		end = runtime_get_opaque_time();
+		nanosec = runtime_opaque_time_to_nano(end - start);
+		jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "PID %u died after %llu nanoseconds.", (pid_t)kev.ident, nanosec);
+		
+		for( i = 0; i < np; i++ ) {
+			p[i] = ( p[i] == (pid_t)kev.ident ) ? 0 : p[i];
+		}
 	}
 
-	if (r == 0 && jobmgr_assumes(jm, runtime_kill(p, SIGKILL) != -1)) {
-		jobmgr_assumes(jm, (r = kevent(kq, NULL, 0, &kev, 1, &kts)) == 1);
+	size_t n2k = 0;
+	for( i = 0; i < np; i++ ) {
+		if( p[i] != 0 ) {
+			jobmgr_assumes(jm, runtime_kill(p[i], SIGKILL) != -1);
+			n2k++;
+		}
 	}
 
-	end = runtime_get_opaque_time();
-
-	nanosec = runtime_opaque_time_to_nano(end - start);
-
-	jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "PID %u %s after %llu nanoseconds", p, r == 0 ? "did not die" : "died", nanosec);
-	if( r == 0 ) {
-		jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Disregarding PID %u and continuing.", p);
+	while( n2k > 0 && (r = kevent(kq, NULL, 0, &kev, 1, &kts)) ) {
+		int status = 0;
+		waitpid((pid_t)kev.ident, &status, WNOHANG);
+		
+		end = runtime_get_opaque_time();
+		nanosec = runtime_opaque_time_to_nano(end - start);
+		jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "PID %u was killed and died after %llu nanoseconds.", (pid_t)kev.ident, nanosec);
+		
+		for( i = 0; i < np; i++ ) {
+			p[i] = ( p[i] == (pid_t)kev.ident ) ? 0 : p[i];
+		}
 	}
 	
-out:
-	jobmgr_assumes(jm, runtime_close(kq) != -1);
+	for( i = 0; i < np; i++ ) {
+		if( p[i] != 0 ) {
+			jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "PID %u did not die after being SIGKILL'ed 1 second ago.", p[i]);
+		}
+	}
+#endif
 }
 
 void
@@ -5626,7 +5677,8 @@
 	}
 
 	kp_cnt = len / sizeof(struct kinfo_proc);
-
+	pid_t *ps = (pid_t *)calloc(sizeof(pid_t), kp_cnt);
+	
 	for (i = 0; i < kp_cnt; i++) {
 		pid_t p_i = kp[i].kp_proc.p_pid;
 		pid_t pp_i = kp[i].kp_eproc.e_ppid;
@@ -5644,17 +5696,26 @@
 		if( !j || (j && j->anonymous) ) {
 			jobmgr_log(jm, LOG_WARNING | LOG_CONSOLE, "Stray %s %s at shutdown: PID %u PPID %u PGID %u %s", z, j ? "anonymous job" : "process", p_i, pp_i, pg_i, n);
 			
-			if( kill_strays ) {
-				jobmgr_kill_stray_child(jm, p_i);
+			int status = 0;
+			if( pp_i == getpid() && !jobmgr_assumes(jm, kp[i].kp_proc.p_stat != SZOMB) ) {
+				if( jobmgr_assumes(jm, waitpid(p_i, &status, WNOHANG) == 0) ) {
+					jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "Unreaped zombie stray exited with status %i.", WEXITSTATUS(status));
+				}
+				kp_skipped++;
+			} else {
+				ps[i] = p_i;
 			}
+		} else {
+			kp_skipped++;
 		}
 	}
 
-out:
-	if (kp_cnt == kp_skipped) {
-		jobmgr_log(jm, LOG_DEBUG, "No stray processes at shutdown");
+	if( (kp_cnt - kp_skipped > 0) && kill_strays ) {
+		jobmgr_kill_stray_children(jm, ps, kp_cnt - kp_skipped);
 	}
 
+	free(ps);
+out:
 	free(kp);
 }
 
@@ -8438,6 +8499,15 @@
 	SLIST_INIT(&s_curious_jobs);
 	
 	launchd_assert((root_jobmgr = jobmgr_new(NULL, MACH_PORT_NULL, MACH_PORT_NULL, sflag, root_session_type)) != NULL);
+	
+	uint32_t fflags = NOTE_ATTRIB | NOTE_LINK | NOTE_REVOKE | NOTE_EXTEND | NOTE_WRITE;
+	s_no_hang_fd = open("/dev/autofs_nowait", O_EVTONLY | O_NONBLOCK);
+	if( likely(s_no_hang_fd == -1) ) {
+		if( jobmgr_assumes(root_jobmgr, (s_no_hang_fd = open("/dev", O_EVTONLY | O_NONBLOCK)) != -1) ) {
+			jobmgr_assumes(root_jobmgr, kevent_mod((uintptr_t)s_no_hang_fd, EVFILT_VNODE, EV_ADD, fflags, 0, root_jobmgr) != -1);
+		}
+	}
+	s_no_hang_fd = _fd(s_no_hang_fd);
 }
 
 size_t
@@ -8619,11 +8689,11 @@
 	}
 	
 	struct stat sb;
-	const char *argv[] = { "/etc/rc.deferredinstall", NULL };
+	const char *argv[] = { _PATH_BSHELL, "/etc/rc.deferred_install", NULL };
 	char *try_again = "Will try again at next boot.";
 	int result = ~0;
 	
-	if( unlikely(stat(argv[0], &sb) != -1) ) {
+	if( unlikely(stat(argv[1], &sb) != -1) ) {
 		jobmgr_log(root_jobmgr, LOG_DEBUG | LOG_CONSOLE, "Going to run deferred install script.");
 		
 		int wstatus;
@@ -8658,7 +8728,7 @@
 		 * that the file exists. Outside of someone deliberately messing with us (like if /etc/rc.deferredinstall
 		 * is actually a looping sym-link or a mount point for a filesystem) and I/O errors, we should be good.
 		 */
-		if( !jobmgr_assumes(root_jobmgr, unlink(argv[0]) != -1) ) {
+		if( !jobmgr_assumes(root_jobmgr, unlink(argv[1]) != -1) ) {
 			jobmgr_log(root_jobmgr, LOG_WARNING | LOG_CONSOLE, "Deferred install script couldn't be removed!");
 		}
 	}

Modified: trunk/launchd/src/launchd_runtime.c
===================================================================
--- trunk/launchd/src/launchd_runtime.c	2009-02-18 19:25:28 UTC (rev 23822)
+++ trunk/launchd/src/launchd_runtime.c	2009-02-19 22:10:52 UTC (rev 23823)
@@ -1142,16 +1142,6 @@
 #endif
 
 		record_caller_creds(&bufRequest->Head);
-
-		/*
-		 * This is a total hack. We really need a bit in the kernel's proc
-		 * struct to declare our intent.
-		 */
-		static int no_hang_fd = -1;
-		if (unlikely(no_hang_fd == -1)) {
-			no_hang_fd = _fd(open("/dev/autofs_nowait", 0));
-		}
-
 		runtime_ktrace(RTKT_LAUNCHD_MACH_IPC|DBG_FUNC_START, bufRequest->Head.msgh_local_port, bufRequest->Head.msgh_id, (long)the_demux);
 
 		if (the_demux(&bufRequest->Head, &bufReply->Head) == FALSE) {


Property changes on: trunk/launchd/src/protocol_vproc.defs
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/PR-5092682/launchd/src/protocol_job.defs:23731-23742
/branches/PR-5898404/launchd/src/protocol_job.defs:23681-23700
/branches/PR-5978442/launchd/src/protocol_job.defs:23651-23701
/branches/PR-6132016/launchd/src/protocol_job.defs:23719-23738
   + /branches/PR-5092682/launchd/src/protocol_job.defs:23731-23742
/branches/PR-5898404/launchd/src/protocol_job.defs:23681-23700
/branches/PR-5978442/launchd/src/protocol_job.defs:23651-23701
/branches/PR-6132016/launchd/src/protocol_job.defs:23719-23738
/branches/PR-6271234/launchd/src/protocol_vproc.defs:23818-23822
/branches/PR-6562592/launchd/src/protocol_vproc.defs:23812-23822
/branches/PR-6589133/launchd/src/protocol_vproc.defs:23810-23822


Property changes on: trunk/launchd/src/vproc.h
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/PR-5092682/launchd/src/libvproc_public.h:23731-23742
/branches/PR-5898404/launchd/src/libvproc_public.h:23681-23700
/branches/PR-5978442/launchd/src/libvproc_public.h:23651-23701
/branches/PR-6132016/launchd/src/libvproc_public.h:23719-23738
   + /branches/PR-5092682/launchd/src/libvproc_public.h:23731-23742
/branches/PR-5898404/launchd/src/libvproc_public.h:23681-23700
/branches/PR-5978442/launchd/src/libvproc_public.h:23651-23701
/branches/PR-6132016/launchd/src/libvproc_public.h:23719-23738
/branches/PR-6271234/launchd/src/vproc.h:23818-23822
/branches/PR-6562592/launchd/src/vproc.h:23812-23822
/branches/PR-6589133/launchd/src/vproc.h:23810-23822


Property changes on: trunk/launchd/src/vproc_internal.h
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/PR-5898404/launchd/src/libvproc_internal.h:23681-23700
/branches/PR-5978442/launchd/src/libvproc_internal.h:23651-23701
   + /branches/PR-5898404/launchd/src/libvproc_internal.h:23681-23700
/branches/PR-5978442/launchd/src/libvproc_internal.h:23651-23701
/branches/PR-6271234/launchd/src/vproc_internal.h:23818-23822
/branches/PR-6562592/launchd/src/vproc_internal.h:23812-23822
/branches/PR-6589133/launchd/src/vproc_internal.h:23810-23822


Property changes on: trunk/launchd/src/vproc_priv.h
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/PR-5092682/launchd/src/libvproc_private.h:23731-23742
/branches/PR-5898404/launchd/src/libvproc_private.h:23681-23700
/branches/PR-5978442/launchd/src/libvproc_private.h:23651-23701
/branches/PR-6132016/launchd/src/libvproc_private.h:23719-23738
   + /branches/PR-5092682/launchd/src/libvproc_private.h:23731-23742
/branches/PR-5898404/launchd/src/libvproc_private.h:23681-23700
/branches/PR-5978442/launchd/src/libvproc_private.h:23651-23701
/branches/PR-6132016/launchd/src/libvproc_private.h:23719-23738
/branches/PR-6271234/launchd/src/vproc_priv.h:23818-23822
/branches/PR-6562592/launchd/src/vproc_priv.h:23812-23822
/branches/PR-6589133/launchd/src/vproc_priv.h:23810-23822
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/launchd-changes/attachments/20090219/b1ce8828/attachment-0001.html>


More information about the launchd-changes mailing list