Revision: 23906 http://trac.macosforge.org/projects/launchd/changeset/23906 Author: dsorresso@apple.com Date: 2009-04-23 13:28:24 -0700 (Thu, 23 Apr 2009) Log Message: ----------- <rdar://problem/6803005> LEAK: 10A333: Finder leaking memory and hangs after running FinderOpsPlus tool Fixes for bstree subcommand. Modified Paths: -------------- trunk/launchd/src/bootstrap_priv.h trunk/launchd/src/launchctl.c trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/launchd_runtime.c trunk/launchd/src/libbootstrap.c trunk/launchd/src/protocol_vproc.defs trunk/launchd/src/vproc_internal.h Modified: trunk/launchd/src/bootstrap_priv.h =================================================================== --- trunk/launchd/src/bootstrap_priv.h 2009-04-22 20:18:51 UTC (rev 23905) +++ trunk/launchd/src/bootstrap_priv.h 2009-04-23 20:28:24 UTC (rev 23906) @@ -27,13 +27,16 @@ #pragma GCC visibility push(default) -#define BOOTSTRAP_PER_PID_SERVICE 1 << 0 -#define BOOTSTRAP_ALLOW_LOOKUP 1 << 1 -#define BOOTSTRAP_DENY_JOB_CREATION 1 << 2 -#define BOOTSTRAP_PRIVILEGED_SERVER 1 << 3 +#define BOOTSTRAP_PER_PID_SERVICE 1 << 0 +#define BOOTSTRAP_ALLOW_LOOKUP 1 << 1 +#define BOOTSTRAP_DENY_JOB_CREATION 1 << 2 +#define BOOTSTRAP_PRIVILEGED_SERVER 1 << 3 +#define BOOTSTRAP_FORCE_LOCAL 1 << 4 -#define BOOTSTRAP_PROPERTY_SUBSET 1 << 0 -#define BOOTSTRAP_PROPERTY_PERUSER 1 << 1 +#define BOOTSTRAP_PROPERTY_EXPLICITSUBSET 1 << 0 /* Created via bootstrap_subset(). */ +#define BOOTSTRAP_PROPERTY_IMPLICITSUBSET 1 << 1 /* Created via _vprocmgr_switch_to_session(). */ +#define BOOTSTRAP_PROPERTY_MOVEDSUBSET 1 << 2 /* Created via _vprocmgr_move_subset_to_user(). */ +#define BOOTSTRAP_PROPERTY_PERUSER 1 << 3 /* A per-user launchd's root bootstrap. */ kern_return_t bootstrap_register2(mach_port_t bp, name_t service_name, mach_port_t sp, uint64_t flags); Modified: trunk/launchd/src/launchctl.c =================================================================== --- trunk/launchd/src/launchctl.c 2009-04-22 20:18:51 UTC (rev 23905) +++ trunk/launchd/src/launchctl.c 2009-04-23 20:28:24 UTC (rev 23906) @@ -209,7 +209,7 @@ static int umask_cmd(int argc, char *const argv[]); static int getrusage_cmd(int argc, char *const argv[]); static int bsexec_cmd(int argc, char *const argv[]); -static int _bslist_cmd(mach_port_t bport, unsigned int depth, bool show_job); +static int _bslist_cmd(mach_port_t bport, unsigned int depth, bool show_job, bool local_only); static int bslist_cmd(int argc, char *const argv[]); static int _bstree_cmd(mach_port_t bsport, unsigned int depth, bool show_jobs); static int bstree_cmd(int argc __attribute__((unused)), char * const argv[] __attribute__((unused))); @@ -3325,7 +3325,7 @@ } int -_bslist_cmd(mach_port_t bport, unsigned int depth, bool show_job) +_bslist_cmd(mach_port_t bport, unsigned int depth, bool show_job, bool local_only) { kern_return_t result; name_array_t service_names; @@ -3339,7 +3339,9 @@ return 1; } - result = bootstrap_info(bport, &service_names, &service_cnt, &service_jobs, &service_jobs_cnt, &service_actives, &service_active_cnt); + uint64_t flags = 0; + flags |= local_only ? BOOTSTRAP_FORCE_LOCAL : 0; + result = bootstrap_info(bport, &service_names, &service_cnt, &service_jobs, &service_jobs_cnt, &service_actives, &service_active_cnt, flags); if (result != BOOTSTRAP_SUCCESS) { fprintf(stderr, "bootstrap_info(): %d\n", result); return 1; @@ -3380,7 +3382,7 @@ return 1; } - return _bslist_cmd(bport, 0, show_jobs); + return _bslist_cmd(bport, 0, show_jobs, false); } int @@ -3408,10 +3410,20 @@ } unsigned int i = 0; - _bslist_cmd(bsport, depth, show_jobs); + _bslist_cmd(bsport, depth, show_jobs, true); for( i = 0; i < cnt; i++ ) { - char *type = ( child_props[i] & BOOTSTRAP_PROPERTY_PERUSER ) ? "Per-user" : "Subset"; + char *type = NULL; + if( child_props[i] & BOOTSTRAP_PROPERTY_PERUSER ) { + type = "Per-user"; + } else if( child_props[i] & BOOTSTRAP_PROPERTY_EXPLICITSUBSET ) { + type = "Explicit Subset"; + } else if( child_props[i] & BOOTSTRAP_PROPERTY_IMPLICITSUBSET ) { + type = "Implicit Subset"; + } else if( child_props[i] & BOOTSTRAP_PROPERTY_MOVEDSUBSET ) { + type = "Moved Subset"; + } + fprintf(stdout, "%*s%s (%s)/\n", depth, "", child_names[i], type); if( child_ports[i] != MACH_PORT_NULL ) { _bstree_cmd(child_ports[i], depth + 4, show_jobs); Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2009-04-22 20:18:51 UTC (rev 23905) +++ trunk/launchd/src/launchd_core_logic.c 2009-04-23 20:28:24 UTC (rev 23906) @@ -360,9 +360,9 @@ killed_hopefully_first_jobs :1, killed_normal_jobs :1, killed_hopefully_last_jobs :1, - killed_stray_jobs :1, - created_via_subset :1; + killed_stray_jobs :1; char sample_log_file[PATH_MAX]; + uint32_t properties; union { const char name[0]; char name_init[0]; @@ -5344,13 +5344,13 @@ jobmgr_t jm_to_insert = j->mgr; if( g_flat_mach_namespace ) { - jm_to_insert = j->mgr->created_via_subset ? j->mgr : root_jobmgr; + jm_to_insert = (j->mgr->properties & BOOTSTRAP_PROPERTY_EXPLICITSUBSET) ? j->mgr : root_jobmgr; } LIST_INSERT_HEAD(&jm_to_insert->ms_hash[hash_ms(ms->name)], ms, name_hash_sle); LIST_INSERT_HEAD(&port_hash[HASH_PORT(ms->port)], ms, port_hash_sle); - job_log(j, LOG_DEBUG, "Mach service added%s: %s", j->mgr->created_via_subset ? " to private namespace" : "", name); + job_log(j, LOG_DEBUG, "Mach service added%s: %s", (j->mgr->properties & BOOTSTRAP_PROPERTY_EXPLICITSUBSET) ? " to private namespace" : "", name); return ms; out_bad2: @@ -5900,6 +5900,10 @@ if (bootstrapper) { bootstrapper->audit_session = session_port; + if( session_port != MACH_PORT_NULL ) { + mach_port_mod_refs(mach_task_self(), session_port, MACH_PORT_RIGHT_SEND, 1); + } + jobmgr_log(jmr, LOG_DEBUG, "Bootstrapping new job manager with audit session %u", session_port); jobmgr_assumes(jmr, job_dispatch(bootstrapper, true) != NULL); } @@ -6029,7 +6033,7 @@ return NULL; } - jobmgr_t jm_to_search = ( g_flat_mach_namespace && !jm->created_via_subset ) ? root_jobmgr : jm; + jobmgr_t jm_to_search = ( g_flat_mach_namespace && !(jm->properties & BOOTSTRAP_PROPERTY_EXPLICITSUBSET) ) ? root_jobmgr : jm; LIST_FOREACH(ms, &jm_to_search->ms_hash[hash_ms(name)], name_hash_sle) { if (!ms->per_pid && strcmp(name, ms->name) == 0) { return ms; @@ -7706,7 +7710,8 @@ kern_return_t job_mig_info(job_t j, name_array_t *servicenamesp, unsigned int *servicenames_cnt, name_array_t *servicejobsp, unsigned int *servicejobs_cnt, - bootstrap_status_array_t *serviceactivesp, unsigned int *serviceactives_cnt) + bootstrap_status_array_t *serviceactivesp, unsigned int *serviceactives_cnt, + uint64_t flags) { name_array_t service_names = NULL; name_array_t service_jobs = NULL; @@ -7718,7 +7723,15 @@ return BOOTSTRAP_NO_MEMORY; } - jm = (g_flat_mach_namespace && !j->mgr->created_via_subset) ? root_jobmgr : j->mgr; + if( g_flat_mach_namespace ) { + if( (j->mgr->properties & BOOTSTRAP_PROPERTY_EXPLICITSUBSET) || (flags & BOOTSTRAP_FORCE_LOCAL) ) { + jm = j->mgr; + } else { + jm = root_jobmgr; + } + } else { + jm = j->mgr; + } unsigned int i = 0; struct machservice *msi = NULL; @@ -7808,7 +7821,7 @@ jobmgr_t jmr = j->mgr; jobmgr_t jmi = NULL; SLIST_FOREACH( jmi, &jmr->submgrs, sle ) { - cnt += g_flat_mach_namespace ? ( jmi->created_via_subset ? 1 : 0 ) : 1; + cnt++; } /* Find our per-user launchds if we're PID 1. */ @@ -7846,40 +7859,36 @@ unsigned int cnt2 = 0; SLIST_FOREACH( jmi, &jmr->submgrs, sle ) { - if( (g_flat_mach_namespace && jmi->created_via_subset) || !g_flat_mach_namespace ) { - if( jobmgr_assumes(jmi, launchd_mport_make_send(jmi->jm_port)) == KERN_SUCCESS ) { - _child_ports[cnt2] = jmi->jm_port; - } else { - _child_ports[cnt2] = MACH_PORT_NULL; - } - - strlcpy(_child_names[cnt2], jmi->name, sizeof(_child_names[0])); - _child_properties[cnt2] |= BOOTSTRAP_PROPERTY_SUBSET; - - cnt2++; + if( jobmgr_assumes(jmi, launchd_mport_make_send(jmi->jm_port) == KERN_SUCCESS) ) { + _child_ports[cnt2] = jmi->jm_port; + } else { + _child_ports[cnt2] = MACH_PORT_NULL; } + + strlcpy(_child_names[cnt2], jmi->name, sizeof(_child_names[0])); + _child_properties[cnt2] = jmi->properties; + + cnt2++; } - if( pid1_magic ) { - LIST_FOREACH( ji, &jmr->jobs, sle ) { - if( ji->per_user ) { - if( job_assumes(ji, SLIST_FIRST(&ji->machservices)->per_user_hack == true) ) { - mach_port_t port = machservice_port(SLIST_FIRST(&ji->machservices)); - - if( job_assumes(ji, launchd_mport_copy_send(port)) == KERN_SUCCESS ) { - _child_ports[cnt2] = port; - } else { - _child_ports[cnt2] = MACH_PORT_NULL; - } + if( pid1_magic ) LIST_FOREACH( ji, &jmr->jobs, sle ) { + if( ji->per_user ) { + if( job_assumes(ji, SLIST_FIRST(&ji->machservices)->per_user_hack == true) ) { + mach_port_t port = machservice_port(SLIST_FIRST(&ji->machservices)); + + if( job_assumes(ji, launchd_mport_copy_send(port) == KERN_SUCCESS) ) { + _child_ports[cnt2] = port; } else { _child_ports[cnt2] = MACH_PORT_NULL; } - - strlcpy(_child_names[cnt2], ji->label, sizeof(_child_names[0])); - _child_properties[cnt2] |= BOOTSTRAP_PROPERTY_PERUSER; - - cnt2++; + } else { + _child_ports[cnt2] = MACH_PORT_NULL; } + + strlcpy(_child_names[cnt2], ji->label, sizeof(_child_names[0])); + _child_properties[cnt2] |= BOOTSTRAP_PROPERTY_PERUSER; + + cnt2++; } } @@ -8113,6 +8122,8 @@ goto out; } + jmr->properties |= BOOTSTRAP_PROPERTY_MOVEDSUBSET; + /* This is a hack. We should be doing this in jobmgr_new(), but since we're in the middle of * processing an IPC request, we'll do this action before the new job manager can get any IPC * requests. This serialization is guaranteed since we are single-threaded in that respect. @@ -8255,6 +8266,8 @@ target_jm = jobmgr_new(j->mgr, requestor_port, MACH_PORT_NULL, false, session_name, audit_session); if( !target_jm ) { mach_port_deallocate(mach_task_self(), audit_session); + } else { + target_jm->properties |= BOOTSTRAP_PROPERTY_IMPLICITSUBSET; } } @@ -8480,7 +8493,7 @@ } *subsetportp = jmr->jm_port; - jmr->created_via_subset = true; + jmr->properties |= BOOTSTRAP_PROPERTY_EXPLICITSUBSET; job_log(j, LOG_DEBUG, "Job created a subset named \"%s\"", jmr->name); return BOOTSTRAP_SUCCESS; Modified: trunk/launchd/src/launchd_runtime.c =================================================================== --- trunk/launchd/src/launchd_runtime.c 2009-04-22 20:18:51 UTC (rev 23905) +++ trunk/launchd/src/launchd_runtime.c 2009-04-23 20:28:24 UTC (rev 23906) @@ -1124,7 +1124,9 @@ } continue; default: - launchd_assumes(mr == MACH_MSG_SUCCESS); + if( !launchd_assumes(mr == MACH_MSG_SUCCESS) ) { + runtime_syslog(LOG_ERR, "mach_msg(): %u: %s", mr, mach_error_string(mr)); + } continue; } Modified: trunk/launchd/src/libbootstrap.c =================================================================== --- trunk/launchd/src/libbootstrap.c 2009-04-22 20:18:51 UTC (rev 23905) +++ trunk/launchd/src/libbootstrap.c 2009-04-23 20:28:24 UTC (rev 23906) @@ -269,9 +269,10 @@ bootstrap_info(mach_port_t bp, name_array_t *service_names, mach_msg_type_number_t *service_namesCnt, name_array_t *service_jobs, mach_msg_type_number_t *service_jobsCnt, - bootstrap_status_array_t *service_active, mach_msg_type_number_t *service_activeCnt) + bootstrap_status_array_t *service_active, mach_msg_type_number_t *service_activeCnt, + uint64_t flags) { - return vproc_mig_info(bp, service_names, service_namesCnt, service_jobs, service_jobsCnt, service_active, service_activeCnt); + return vproc_mig_info(bp, service_names, service_namesCnt, service_jobs, service_jobsCnt, service_active, service_activeCnt, flags); } const char * Modified: trunk/launchd/src/protocol_vproc.defs =================================================================== --- trunk/launchd/src/protocol_vproc.defs 2009-04-22 20:18:51 UTC (rev 23905) +++ trunk/launchd/src/protocol_vproc.defs 2009-04-23 20:28:24 UTC (rev 23906) @@ -90,7 +90,8 @@ __bs_port : job_t; out __service_names : name_array_t, dealloc; out __service_jobs : name_array_t, dealloc; -out __service_active : bootstrap_status_array_t, dealloc); +out __service_active : bootstrap_status_array_t, dealloc; + __flags : uint64_t); routine subset( __bs_port : job_t; Modified: trunk/launchd/src/vproc_internal.h =================================================================== --- trunk/launchd/src/vproc_internal.h 2009-04-22 20:18:51 UTC (rev 23905) +++ trunk/launchd/src/vproc_internal.h 2009-04-23 20:28:24 UTC (rev 23906) @@ -118,7 +118,8 @@ name_array_t *service_jobs, mach_msg_type_number_t *service_jobsCnt, bootstrap_status_array_t *service_active, - mach_msg_type_number_t *service_activeCnt); + mach_msg_type_number_t *service_activeCnt, + uint64_t flags); #pragma GCC visibility pop
participants (1)
-
source_changes@macosforge.org