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

source_changes at macosforge.org source_changes at macosforge.org
Thu Apr 9 18:56:53 PDT 2009


Revision: 23889
          http://trac.macosforge.org/projects/launchd/changeset/23889
Author:   dsorresso at apple.com
Date:     2009-04-09 18:56:53 -0700 (Thu, 09 Apr 2009)
Log Message:
-----------
<rdar://problem/6754652> Tweak per-user suspend and resume

Modified Paths:
--------------
    trunk/launchd/src/launchd_core_logic.c
    trunk/launchd/src/libvproc.c

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2009-04-09 18:05:32 UTC (rev 23888)
+++ trunk/launchd/src/launchd_core_logic.c	2009-04-10 01:56:53 UTC (rev 23889)
@@ -399,6 +399,11 @@
 #define AUTO_PICK_LEGACY_LABEL (const char *)(~0)
 #define AUTO_PICK_ANONYMOUS_LABEL (const char *)(~1)
 
+struct suspended_peruser {
+	LIST_ENTRY(suspended_peruser) sle;
+	job_t j;
+};
+
 struct job_s {
 	kq_callback kqjob_callback;	/* MUST be first element of this structure for benefit of launchd's run loop. */
 	LIST_ENTRY(job_s) sle;
@@ -407,10 +412,9 @@
 	LIST_ENTRY(job_s) pid_hash_sle;
 	LIST_ENTRY(job_s) label_hash_sle;
 	LIST_ENTRY(job_s) global_env_sle;
-	LIST_ENTRY(job_s) suspended_peruser_sle;
 	STAILQ_ENTRY(job_s) pending_samples_sle;
 	SLIST_ENTRY(job_s) curious_jobs_sle;
-	LIST_HEAD(, job_s) suspended_perusers;
+	LIST_HEAD(, suspended_peruser) suspended_perusers;
 	LIST_HEAD(, waiting_for_exit) exit_watchers;
 	SLIST_HEAD(, socketgroup) sockets;
 	SLIST_HEAD(, calendarinterval) cal_intervals;
@@ -2732,14 +2736,15 @@
 		}
 	}
 		
-	job_t ji = NULL;
-	while( (ji = LIST_FIRST(&j->suspended_perusers)) ) {
-		job_log(j, LOG_ERR, "Job exited before resuming per-user launchd for UID %u. Will forcibly resume.", ji->mach_uid);
-		ji->peruser_suspend_count--;
-		if( ji->peruser_suspend_count == 0 ) {
-			LIST_REMOVE(ji, suspended_peruser_sle);
+	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);
+		spi->j->peruser_suspend_count--;
+		if( spi->j->peruser_suspend_count == 0 ) {
+			job_dispatch(spi->j, false);
 		}
-		job_dispatch(ji, false);
+		LIST_REMOVE(spi, sle);
+		free(spi);
 	}
 	
 	struct waiting_for_exit *w4e = NULL;
@@ -7148,42 +7153,56 @@
 		}
 		break;
 	case VPROC_GSK_PERUSER_SUSPEND:
-		if( pid1_magic && ldc->euid == 0 ) {
+		if( job_assumes(j, pid1_magic && ldc->euid == 0) ) {
 			mach_port_t junk = MACH_PORT_NULL;
 			job_t jpu = jobmgr_lookup_per_user_context_internal(j, (uid_t)inval, false, &junk);
-			if( jpu ) {
-				job_t ji = NULL;
-				LIST_FOREACH( ji, &j->suspended_perusers, suspended_peruser_sle ) {
-					if( (int64_t)(ji->mach_uid) == inval ) {
-						job_log(j, LOG_WARNING, "Job tried to suspend per-user launchd for UID %u twice.", ji->mach_uid);
+			if( job_assumes(j, jpu != NULL) ) {
+				struct suspended_peruser *spi = NULL;
+				LIST_FOREACH( spi, &j->suspended_perusers, sle ) {
+					if( (int64_t)(spi->j->mach_uid) == inval ) {
+						job_log(j, LOG_WARNING, "Job tried to suspend per-user launchd for UID %lli twice.", inval);
 						break;
 					}
 				}
-				
-				if( ji == NULL ) {
-					jpu->peruser_suspend_count++;
-					LIST_INSERT_HEAD(&j->suspended_perusers, jpu, suspended_peruser_sle);					
-					job_stop(jpu);
+
+				if( spi == NULL ) {
+					job_log(j, LOG_INFO, "Job is suspending the per-user launchd for UID %lli.", inval);
+					spi = (struct suspended_peruser *)calloc(sizeof(struct suspended_peruser), 1);
+					if( job_assumes(j, spi != NULL) ) {
+						spi->j = jpu;
+						spi->j->peruser_suspend_count++;
+						LIST_INSERT_HEAD(&j->suspended_perusers, spi, sle);
+						job_stop(spi->j);
+					} else {
+						kr = BOOTSTRAP_NO_MEMORY;
+					}
 				}
 			}
+		} else {
+			kr = 1;
 		}
 		break;
 	case VPROC_GSK_PERUSER_RESUME:
-		if( pid1_magic && ldc->euid == 0 ) {
-			job_t ji = NULL, jt = NULL;
-			LIST_FOREACH_SAFE( ji, &j->suspended_perusers, suspended_peruser_sle, jt ) {
-				if( (int64_t)(ji->mach_uid) == inval ) {
-					ji->peruser_suspend_count--;
-					LIST_REMOVE(ji, suspended_peruser_sle);
+		if( job_assumes(j, pid1_magic == true) ) {
+			struct suspended_peruser *spi = NULL, *spt = NULL;
+			LIST_FOREACH_SAFE( spi, &j->suspended_perusers, sle, spt ) {
+				if( (int64_t)(spi->j->mach_uid) == inval ) {
+					spi->j->peruser_suspend_count--;
+					LIST_REMOVE(spi, sle);
+					job_log(j, LOG_INFO, "Job is resuming the per-user launchd for UID %lli.", inval);
 					break;
 				}
 			}
 			
-			if( ji == NULL ) {
-				job_log(j, LOG_WARNING, "Job tried to resume per-user launchd for UID %llu that it did not suspend.", inval);
-			} else if( ji->peruser_suspend_count == 0 ) {
-				job_dispatch(ji, false);
+			if( !job_assumes(j, spi != NULL) ) {
+				job_log(j, LOG_WARNING, "Job tried to resume per-user launchd for UID %lli that it did not suspend.", inval);
+				kr = BOOTSTRAP_NOT_PRIVILEGED;
+			} else if( spi->j->peruser_suspend_count == 0 ) {
+				job_dispatch(spi->j, false);
+				free(spi);
 			}
+		} else {
+			kr = 1;
 		}
 		break;
 	case 0:
@@ -8437,7 +8456,7 @@
 	}
 
 	char name[NAME_MAX];
-	snprintf(name, sizeof(name), "bootstrap_subset(%u)->%s[%i]", MACH_PORT_INDEX(requestorport), j->anonymous ? j->prog : j->label, j->p);
+	snprintf(name, sizeof(name), "%s[%i].subset.%i", j->anonymous ? j->prog : j->label, j->p, MACH_PORT_INDEX(requestorport));
 
 	if (!job_assumes(j, (jmr = jobmgr_new(j->mgr, requestorport, MACH_PORT_NULL, false, name, j->audit_session)) != NULL)) {
 		if (unlikely(requestorport == MACH_PORT_NULL)) {

Modified: trunk/launchd/src/libvproc.c
===================================================================
--- trunk/launchd/src/libvproc.c	2009-04-09 18:05:32 UTC (rev 23888)
+++ trunk/launchd/src/libvproc.c	2009-04-10 01:56:53 UTC (rev 23889)
@@ -842,8 +842,9 @@
 		break;
 	}
 
+	kern_return_t kr = KERN_FAILURE;
 	mach_port_t mp = vp ? vp->j_port : bootstrap_port;
-	if (vproc_mig_swap_integer(mp, inval ? key : 0, outval ? key : 0, inval ? *inval : 0, outval ? outval : &dummyval) == 0) {
+	if ((kr = vproc_mig_swap_integer(mp, inval ? key : 0, outval ? key : 0, inval ? *inval : 0, outval ? outval : &dummyval)) == 0) {
 		switch (key) {
 		case VPROC_GSK_MGR_PID:
 			cached_pid = outval ? *outval : dummyval;
@@ -862,10 +863,8 @@
 			vproc_t pu_vp = vprocmgr_lookup_vproc(peruser_label);
 			if( pu_vp ) {
 				int status = 0;
-				kern_return_t kr = vproc_mig_wait2(bootstrap_port, pu_vp->j_port, &status);
+				kr = vproc_mig_wait2(bootstrap_port, pu_vp->j_port, &status);
 				vproc_release(pu_vp);
-				
-				syslog(LOG_DEBUG, "%u's suspended launchd exited with status %i (kr = 0x%x).", (uid_t)*inval, status, kr);
 			}
 			break;
 		}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/launchd-changes/attachments/20090409/ce047748/attachment-0001.html>


More information about the launchd-changes mailing list