static apr_status_t create_process_manager(server_rec * main_server, apr_pool_t * configpool) { apr_status_t rv; g_process_manager = (apr_proc_t *) apr_pcalloc(configpool, sizeof(*g_process_manager)); rv = apr_proc_fork(g_process_manager, configpool); if (rv == APR_INCHILD) { /* I am the child */ g_pm_pid = getpid(); ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server, "mod_fcgid: Process manager %" APR_PID_T_FMT " started", getpid()); if ((rv = init_signal(main_server)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server, "mod_fcgid: can't install signal handler, exiting now"); exit(DAEMON_STARTUP_ERROR); } /* If running as root, switch to configured user. * * When running children via suexec, only the effective uid is * switched, so that the PM can return to euid 0 to kill child * processes. * * When running children as the configured user, the real uid * is switched. */ if (ap_unixd_config.suexec_enabled) { if (getuid() != 0) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, main_server, "mod_fcgid: current user is not root while suexec is enabled, exiting now"); exit(DAEMON_STARTUP_ERROR); } suexec_setup_child(); } else ap_unixd_setup_child(); apr_file_pipe_timeout_set(g_pm_read_pipe, apr_time_from_sec(g_wakeup_timeout)); apr_file_close(g_ap_write_pipe); apr_file_close(g_ap_read_pipe); /* Initialize spawn controler */ spawn_control_init(main_server, configpool); pm_main(main_server, configpool); ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server, "mod_fcgid: Process manager %" APR_PID_T_FMT " stopped", getpid()); exit(0); } else if (rv != APR_INPARENT) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server, "mod_fcgid: Create process manager error"); exit(1); } /* I am the parent I will send the stop signal in procmgr_stop_procmgr() */ apr_pool_note_subprocess(configpool, g_process_manager, APR_KILL_ONLY_ONCE); apr_proc_other_child_register(g_process_manager, fcgid_maint, g_process_manager, NULL, configpool); return APR_SUCCESS; }
static int mod_mapcache_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { apr_status_t rc; mapcache_server_cfg* cfg = ap_get_module_config(s->module_config, &mapcache_module); apr_lockmech_e lock_type = APR_LOCK_DEFAULT; server_rec *sconf; if(!cfg) { ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, "configuration not found in server context"); return 1; } #if APR_HAS_PROC_PTHREAD_SERIALIZE lock_type = APR_LOCK_PROC_PTHREAD; #endif rc = apr_global_mutex_create(&cfg->mutex,cfg->mutex_name,lock_type,p); if(rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s, "Could not create global parent mutex %s", cfg->mutex_name); return rc; } #ifdef AP_NEED_SET_MUTEX_PERMS rc = unixd_set_global_mutex_perms(cfg->mutex); if(rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s, "Could not set permissions on global parent mutex %s", cfg->mutex_name); return rc; } #endif apr_pool_cleanup_register(p,cfg->mutex, (void*)apr_global_mutex_destroy, apr_pool_cleanup_null); #ifndef DISABLE_VERSION_STRING ap_add_version_component(p, MAPCACHE_USERAGENT); #endif for (sconf = s->next; sconf; sconf = sconf->next) { mapcache_server_cfg* config = ap_get_module_config(sconf->module_config, &mapcache_module); config->mutex = cfg->mutex; } #if APR_HAS_FORK /* fork a child process to let it accomplish post-configuration tasks with the uid of the runtime user */ apr_proc_t proc; apr_status_t rv; rv = apr_proc_fork(&proc, ptemp); if (rv == APR_INCHILD) { #define ap_unixd_setup_child unixd_setup_child ap_unixd_setup_child(); mapcache_context *ctx = (mapcache_context*)apache_server_context_create(s,p); for (sconf = s; sconf; sconf = sconf->next) { mapcache_server_cfg* config = ap_get_module_config(sconf->module_config, &mapcache_module); if(config->aliases) { apr_hash_index_t *entry = apr_hash_first(ptemp,config->aliases); /* loop through the configured configurations */ while (entry) { const char *alias; apr_ssize_t aliaslen; mapcache_cfg *c; apr_hash_this(entry,(const void**)&alias,&aliaslen,(void**)&c); mapcache_configuration_post_config(ctx, c); if(GC_HAS_ERROR(ctx)) { ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EGENERAL, s, "post config for %s failed: %s", alias, ctx->get_error_message(ctx)); exit(APR_EGENERAL); } entry = apr_hash_next(entry); } } } exit(0); } else if (rv == APR_INPARENT) { apr_exit_why_e exitwhy; int exitcode; apr_proc_wait(&proc,&exitcode,&exitwhy,APR_WAIT); if(exitwhy != APR_PROC_EXIT) { ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EGENERAL, s, "mapcache post-config child terminated abnormally"); return APR_EGENERAL; } else { if(exitcode != 0) { return APR_EGENERAL; } } return OK; } else { ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EGENERAL, s, "failed to fork mapcache post-config child"); return APR_EGENERAL; } #else /* APR_HAS_FORK */ mapcache_context *ctx = (mapcache_context*)apache_server_context_create(s,p); for (sconf = s; sconf; sconf = sconf->next) { mapcache_server_cfg* config = ap_get_module_config(sconf->module_config, &mapcache_module); if(config->aliases) { apr_hash_index_t *entry = apr_hash_first(ptemp,config->aliases); /* loop through the configured configurations */ while (entry) { const char *alias; apr_ssize_t aliaslen; mapcache_cfg *c; apr_hash_this(entry,(const void**)&alias,&aliaslen,(void**)&c); mapcache_configuration_post_config(ctx, c); if(GC_HAS_ERROR(ctx)) { ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EGENERAL, s, "post config for %s failed: %s", alias, ctx->get_error_message(ctx)); return APR_EGENERAL; } entry = apr_hash_next(entry); } } } return OK; #endif }