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

source_changes at macosforge.org source_changes at macosforge.org
Fri Apr 10 15:06:39 PDT 2009


Revision: 23892
          http://trac.macosforge.org/projects/launchd/changeset/23892
Author:   dsorresso at apple.com
Date:     2009-04-10 15:06:38 -0700 (Fri, 10 Apr 2009)
Log Message:
-----------
<rdar://problem/6757199> ResetAtClose should handle the case of a failed exec(2)

Modified Paths:
--------------
    trunk/launchd/src/launch.h
    trunk/launchd/src/launch_priv.h
    trunk/launchd/src/launchd_core_logic.c

Modified: trunk/launchd/src/launch.h
===================================================================
--- trunk/launchd/src/launch.h	2009-04-10 07:43:38 UTC (rev 23891)
+++ trunk/launchd/src/launch.h	2009-04-10 22:06:38 UTC (rev 23892)
@@ -110,6 +110,7 @@
 
 #define LAUNCH_JOBKEY_MACH_RESETATCLOSE				"ResetAtClose"
 #define LAUNCH_JOBKEY_MACH_HIDEUNTILCHECKIN			"HideUntilCheckIn"
+#define LAUNCH_JOBKEY_MACH_DRAINMESSAGESONCRASH		"DrainMessagesOnCrash"
 
 #define LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT		"SuccessfulExit"
 #define LAUNCH_JOBKEY_KEEPALIVE_NETWORKSTATE		"NetworkState"

Modified: trunk/launchd/src/launch_priv.h
===================================================================
--- trunk/launchd/src/launch_priv.h	2009-04-10 07:43:38 UTC (rev 23891)
+++ trunk/launchd/src/launch_priv.h	2009-04-10 22:06:38 UTC (rev 23892)
@@ -75,7 +75,6 @@
 #define LAUNCH_JOBKEY_MACH_TASKSPECIALPORT				"TaskSpecialPort"
 #define LAUNCH_JOBKEY_MACH_HOSTSPECIALPORT				"HostSpecialPort"
 #define LAUNCH_JOBKEY_MACH_ENTERKERNELDEBUGGERONCLOSE	"EnterKernelDebuggerOnClose"
-#define LAUNCH_JOBKEY_MACH_DRAINMESSAGESONCRASH			"DrainMessagesOnCrash"
 
 typedef struct _launch *launch_t;
 

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2009-04-10 07:43:38 UTC (rev 23891)
+++ trunk/launchd/src/launchd_core_logic.c	2009-04-10 22:06:38 UTC (rev 23892)
@@ -168,18 +168,21 @@
 	job_t				job;
 	unsigned int		gen_num;
 	mach_port_name_t	port;
-	unsigned int		isActive				:1,
-						reset					:1,
-						recv					:1,
-						hide					:1,
-						kUNCServer				:1,
-						per_user_hack			:1,
-						debug_on_close			:1,
-						per_pid					:1,
-						delete_on_destruction	:1,
-						drain_one				:1,
-						drain_all				:1,
-						special_port_num		:22;
+	unsigned int		isActive					:1,
+						reset						:1,
+						recv						:1,
+						hide						:1,
+						kUNCServer					:1,
+						per_user_hack				:1,
+						debug_on_close				:1,
+						per_pid						:1,
+						delete_on_destruction		:1,
+						drain_one_on_crash			:1,
+						drain_all_on_crash			:1,
+						/* Don't let the size of this field to get too small. It has to be large enough
+						 * to represent the reasonable range of special port numbers.
+						 */
+						special_port_num			:20;
 	
 	const char		name[0];
 };
@@ -534,6 +537,7 @@
 			has_console					:1, /* The job owns the console. */
 			clean_exit_timer_expired	:1, /* The job was clean, received SIGKILL and failed to exit after LAUNCHD_CLEAN_KILL_TIMER seconds. */
 			embedded_special_privileges	:1, /* The job runs as a non-root user on embedded but has select privileges of the root user. */
+			did_exec					:1, /* The job exec(2)ed successfully. */
 			migratory					:1; /* The (anonymous) job called vprocmgr_switch_to_session(). */
 	mode_t mask;
 	pid_t tracing_pid;
@@ -2728,14 +2732,18 @@
 	j->reaped = true;
 	
 	struct machservice *msi = NULL;
-	if( j->crashed ) {
+	if( j->crashed || !(j->did_exec || j->anonymous) ) {
 		SLIST_FOREACH( msi, &j->machservices, sle ) {
-			if( !msi->isActive && (msi->drain_one || msi->drain_all) ) {
+			if( j->crashed && !msi->isActive && (msi->drain_one_on_crash || msi->drain_all_on_crash) ) {
 				machservice_drain_port(msi);
 			}
+			
+			if( !j->did_exec && msi->reset && job_assumes(j, !msi->isActive) ) {
+				machservice_resetport(j, msi);
+			}
 		}
 	}
-		
+	
 	struct suspended_peruser *spi = NULL;
 	while( (spi = LIST_FIRST(&j->suspended_perusers)) ) {
 		job_log(j, LOG_ERR, "Job exited before resuming per-user launchd for UID %u. Will forcibly resume.", spi->j->mach_uid);
@@ -3270,6 +3278,7 @@
 				LIST_INSERT_HEAD(&label_hash[hash_label(j->label)], j, label_hash_sle);
 			}
 		} else {
+			j->did_exec = true;
 			job_log(j, LOG_DEBUG, "Program changed");
 		}
 	}
@@ -3627,6 +3636,7 @@
 		
 		job_log(j, LOG_DEBUG, "Started as PID: %u", c);
 		
+		j->did_exec = false;
 		j->checkedin = false;
 		j->start_pending = false;
 		j->reaped = false;
@@ -3677,7 +3687,7 @@
 				SLIST_REMOVE(&j->env, ei, envitem, sle);
 			}
 		}
-		
+			
 		if (likely(!j->stall_before_exec)) {
 			job_uncork_fork(j);
 		}
@@ -3778,7 +3788,7 @@
 
 	errno = psf(NULL, file2exec, NULL, &spattr, (char *const*)argv, environ);
 	job_log_error(j, LOG_ERR, "posix_spawn(\"%s\", ...)", file2exec);
-
+	
 #if HAVE_SANDBOX
 out_bad:
 #endif
@@ -5464,9 +5474,9 @@
 		if( strcasecmp(key, LAUNCH_JOBKEY_MACH_DRAINMESSAGESONCRASH) == 0 ) {
 			const char *option = launch_data_get_string(obj);
 			if( strcasecmp(option, "One") == 0 ) {
-				ms->drain_one = true;
+				ms->drain_one_on_crash = true;
 			} else if( strcasecmp(option, "All") == 0 ) {
-				ms->drain_all = true;
+				ms->drain_all_on_crash = true;
 			}
 		}
 		break;
@@ -6061,14 +6071,13 @@
 void
 machservice_drain_port(struct machservice *ms)
 {
-	if (!job_assumes(ms->job, ms->job->crashed == true)) {
-		return;
-	}
+	bool drain_one = ms->drain_one_on_crash;
+	bool drain_all = ms->drain_all_on_crash;
 	
-	if( ms->drain_one == false && ms->drain_all == false ) {
+	if( !job_assumes(ms->job, (drain_one || drain_all) == true) ) {
 		return;
 	}
-	
+
 	job_log(ms->job, LOG_INFO, "Draining %s...", ms->name);
 	
 	char req_buff[sizeof(union __RequestUnion__catch_mach_exc_subsystem) * 2];
@@ -6103,7 +6112,7 @@
 					break;
 			}
 		}
-	} while( ms->drain_all && mr != MACH_RCV_TIMED_OUT );
+	} while( drain_all && mr != MACH_RCV_TIMED_OUT );
 }
 
 void
@@ -6257,7 +6266,7 @@
 	 * ReceiveRight(N - 1)Returned
 	 */
 	
-	if( ms->drain_one || ms->drain_all ) {
+	if( ms->drain_one_on_crash || ms->drain_all_on_crash ) {
 		if( j->crashed && j->reaped ) {
 			job_log(j, LOG_DEBUG, "Job has crashed. Draining port...");
 			machservice_drain_port(ms);
@@ -6267,7 +6276,6 @@
 	}
 	
 	ms->isActive = false;
-
 	if (ms->delete_on_destruction) {
 		machservice_delete(j, ms, false);
 	} else if (ms->reset) {
@@ -7588,6 +7596,7 @@
 		}
 	}
 
+	
 	return BOOTSTRAP_SUCCESS;
 }
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/launchd-changes/attachments/20090410/ecc308b9/attachment.html>


More information about the launchd-changes mailing list