Beispiel #1
0
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;
}
Beispiel #2
0
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
}