⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perchild.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 5 页
字号:
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0,                              ap_server_conf,                             "long lost child came home! (pid %ld)",                              (long)pid.pid);            }            /* Don't perform idle maintenance when a child dies,             * only do it when there's a timeout.  Remember only a             * finite number of children can die, and it's pretty             * pathological for a lot to die suddenly.             */            continue;        }        else if (remaining_children_to_start) {            /* we hit a 1 second timeout in which none of the previous             * generation of children needed to be reaped... so assume             * they're all done, and pick up the slack if any is left.             */            remaining_children_to_start = \                startup_children(remaining_children_to_start);            /* In any event we really shouldn't do the code below because             * few of the servers we just started are in the IDLE state             * yet, so we'd mistakenly create an extra server.             */            continue;        }        perform_child_maintenance();    }}int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s){    int remaining_children_to_start;    int i;    apr_status_t rv;    apr_size_t one = 1;    ap_listen_rec *lr;    apr_socket_t *sock = NULL;    int fd;    ap_log_pid(pconf, ap_pid_fname);    first_server_limit = server_limit;    first_thread_limit = thread_limit;    if (changed_limit_at_restart) {        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,                     "WARNING: Attempt to change ServerLimit or ThreadLimit "                     "ignored during restart");        changed_limit_at_restart = 0;    }    ap_server_conf = s;    if ((ap_accept_lock_mech == APR_LOCK_SYSVSEM) ||         (ap_accept_lock_mech == APR_LOCK_POSIXSEM)) {        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,                     "Server configured for an accept lock mechanism that "                     "cannot be used with perchild.  Falling back to FCNTL.");        ap_accept_lock_mech = APR_LOCK_FCNTL;    }    /* Initialize cross-process accept lock */    ap_lock_fname = apr_psprintf(_pconf, "%s.%u",                                 ap_server_root_relative(_pconf, ap_lock_fname),                                 my_pid);    rv = SAFE_ACCEPT(apr_proc_mutex_create(&process_accept_mutex,                                     ap_lock_fname, ap_accept_lock_mech,                                     _pconf));    if (rv != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,                     "Couldn't create cross-process lock");        return 1;    }    if (!is_graceful) {        if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {            return 1;        }    }    /* Initialize the child table */    if (!is_graceful) {        for (i = 0; i < server_limit; i++) {            ap_child_table[i].pid = 0;        }    }    /* We need to put the new listeners at the end of the ap_listeners     * list.  If we don't, then the pool will be cleared before the     * open_logs phase is called for the second time, and ap_listeners     * will have only invalid data.  If that happens, then the sockets     * that we opened using make_sock() will be lost, and the server     * won't start.     */    for (lr = ap_listeners ; lr->next != NULL; lr = lr->next) {        continue;    }    apr_os_file_get(&fd, pipe_of_death_in);    apr_os_sock_put(&sock, &fd, pconf);    lr->next = apr_palloc(pconf, sizeof(*lr));    lr->next->sd = sock;    lr->next->active = 1;    lr->next->accept_func = check_pipe_of_death;    lr->next->next = NULL;    lr = lr->next;    num_listensocks++;    set_signals();    /* If we're doing a graceful_restart then we're going to see a lot     * of children exiting immediately when we get into the main loop     * below (because we just sent them AP_SIG_GRACEFUL).  This happens      * pretty rapidly... and for each one that exits we'll start a new one      * until we reach at least daemons_min_free.  But we may be permitted to     * start more than that, so we'll just keep track of how many we're     * supposed to start up without the 1 second penalty between each fork.     */    remaining_children_to_start = num_daemons;    if (!is_graceful) {        remaining_children_to_start = \            startup_children(remaining_children_to_start);    }    else {        /* give the system some time to recover before kicking into         * exponential mode */        hold_off_on_exponential_spawning = 10;    }    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,                 "%s configured -- resuming normal operations",                 ap_get_server_version());    ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,                 "Server built: %s", ap_get_server_built());#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,		"AcceptMutex: %s (default: %s)",		apr_proc_mutex_name(process_accept_mutex),		apr_proc_mutex_defname());#endif    restart_pending = shutdown_pending = 0;    server_main_loop(remaining_children_to_start);    if (shutdown_pending) {        /* Time to gracefully shut down:         * Kill child processes, tell them to call child_exit, etc...         */        if (unixd_killpg(getpgrp(), SIGTERM) < 0) {            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,                         "killpg SIGTERM");        }        ap_reclaim_child_processes(1);      /* Start with SIGTERM */        if (!child_fatal) {            /* cleanup pid file on normal shutdown */            const char *pidfile = NULL;            pidfile = ap_server_root_relative (pconf, ap_pid_fname);            if (pidfile != NULL && unlink(pidfile) == 0) {                ap_log_error(APLOG_MARK, APLOG_INFO, 0,                             ap_server_conf,                             "removed PID file %s (pid=%ld)",                             pidfile, (long)getpid());            }                ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,                         ap_server_conf, "caught SIGTERM, shutting down");        }        return 1;    }    /* we've been told to restart */    apr_signal(SIGHUP, SIG_IGN);    if (one_process) {        /* not worth thinking about */        return 1;    }    if (is_graceful) {        char char_of_death = '!';        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,                     ap_server_conf, AP_SIG_GRACEFUL_STRING " received.  "                     "Doing graceful restart");        /* This is mostly for debugging... so that we know what is still         * gracefully dealing with existing request.         */            for (i = 0; i < num_daemons; ++i) {            if (ap_child_table[i].pid) {                ap_child_table[i].status = SERVER_DYING;            }         }        /* give the children the signal to die */        for (i = 0; i < num_daemons;) {            if ((rv = apr_file_write(pipe_of_death_out, &char_of_death,                                     &one)) != APR_SUCCESS) {                if (APR_STATUS_IS_EINTR(rv)) continue;                ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf,                             "write pipe_of_death");            }            i++;        }    }    else {        /* Kill 'em all.  Since the child acts the same on the parents SIGTERM          * and a SIGHUP, we may as well use the same signal, because some user         * pthreads are stealing signals from us left and right.         */        if (unixd_killpg(getpgrp(), SIGTERM) < 0) {            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,                         "killpg SIGTERM");        }        ap_reclaim_child_processes(1);      /* Start with SIGTERM */        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,                     ap_server_conf, "SIGHUP received.  Attempting to restart");    }    return 0;}/* This really should be a post_config hook, but the error log is already * redirected by that point, so we need to do this in the open_logs phase. */static int perchild_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s){    apr_status_t rv;    pconf = p;    ap_server_conf = s;    if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {        ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0,                     NULL, "no listening sockets available, shutting down");        return DONE;    }    ap_log_pid(pconf, ap_pid_fname);    if ((rv = ap_mpm_pod_open(pconf, &pod))) {        ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL,                "Could not open pipe-of-death.");        return DONE;    }    if ((rv = apr_file_pipe_create(&pipe_of_death_in, &pipe_of_death_out,                                   pconf)) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_ERR, rv,                     (const server_rec*) ap_server_conf,                     "apr_file_pipe_create (pipe_of_death)");        exit(1);    }    if ((rv = apr_file_pipe_timeout_set(pipe_of_death_in, 0)) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_ERR, rv,                     (const server_rec*) ap_server_conf,                     "apr_file_pipe_timeout_set (pipe_of_death)");        exit(1);    }    return OK;}static int perchild_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp){    static int restart_num = 0;    int no_detach, debug, foreground;    ap_directive_t *pdir;    int i;    int tmp_server_limit = DEFAULT_SERVER_LIMIT;    int tmp_thread_limit = DEFAULT_THREAD_LIMIT;    apr_status_t rv;    debug = ap_exists_config_define("DEBUG");    if (debug) {        foreground = one_process = 1;        no_detach = 0;    }    else {        one_process = ap_exists_config_define("ONE_PROCESS");        no_detach = ap_exists_config_define("NO_DETACH");        foreground = ap_exists_config_define("FOREGROUND");    }    /* sigh, want this only the second time around */    if (restart_num++ == 1) {        is_graceful = 0;        if (!one_process && !foreground) {            rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND                                           : APR_PROC_DETACH_DAEMONIZE);            if (rv != APR_SUCCESS) {                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,                             "apr_proc_detach failed");                return HTTP_INTERNAL_SERVER_ERROR;            }                          }        my_pid = getpid();    }    unixd_pre_config(ptemp);    ap_listen_pre_config();    num_daemons = DEFAULT_NUM_DAEMON;    threads_to_start = DEFAULT_START_THREAD;    min_spare_threads = DEFAULT_MIN_SPARE_THREAD;    max_spare_threads = DEFAULT_MAX_SPARE_THREAD;    max_threads = thread_limit;    ap_pid_fname = DEFAULT_PIDLOG;    ap_lock_fname = DEFAULT_LOCKFILE;    ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;    curr_child_num = 0;#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE	ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED;#endif    apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));    /* we need to know ServerLimit and ThreadLimit before we start processing     * the tree because we need to already have allocated child_info_table     */    for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) {        if (!strcasecmp(pdir->directive, "ServerLimit")) {            if (atoi(pdir->args) > tmp_server_limit) {                tmp_server_limit = atoi(pdir->args);                if (tmp_server_limit > MAX_SERVER_LIMIT) {                    tmp_server_limit = MAX_SERVER_LIMIT;                }            }        }        else if (!strcasecmp(pdir->directive, "ThreadLimit")) {            if (atoi(pdir->args) > tmp_thread_limit) {                tmp_thread_limit = atoi(pdir->args);                if (tmp_thread_limit > MAX_THREAD_LIMIT) {                    tmp_thread_limit = MAX_THREAD_LIMIT;                }            }        }    }    child_info_table = (child_info_t *)apr_pcalloc(p, tmp_server_limit * sizeof(child_info_t));    for (i = 0; i < tmp_server_limit; i++) {        child_info_table[i].uid = -1;        child_info_table[i].gid = -1;        child_info_table[i].input = -1;        child_info_table[i].output = -1;    }    return OK;}static int pass_request(request_rec *r){    int rv;    apr_socket_t *thesock = ap_get_module_config(r->connection->conn_config, &core_module);    struct msghdr msg;    struct cmsghdr *cmsg;    int sfd;    struct iovec iov[2];    conn_rec *c = r->connection;    apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc);    apr_bucket_brigade *sockbb;    char request_body[HUGE_STRING_LEN] = "\0";    apr_size_t l = sizeof(request_body);    perchild_header h;    apr_bucket *sockbuck;    perchild_server_conf *sconf = (perchild_server_conf *)                            ap_get_module_config(r->server->module_config,                                                  &mpm_perchild_module);    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,                  "passing request to another child.  Vhost: %s, child %d %d",                 apr_table_get(r->headers_in, "Host"), child_num, sconf->output);    ap_get_brigade(r->connection->input_filters, bb, AP_MODE_EXHAUSTIVE, APR_NONBLOCK_READ,                   0);    for (sockbuck = APR_BRIGADE_FIRST(bb); sockbuck != APR_BRIGADE_SENTINEL(bb);         sockbuck = APR_BUCKET_NEXT(sockbuck)) {        if (APR_BUCKET_IS_SOCKET(sockbuck)) {            break;        }    }        if (!sockbuck) {    }    sockbb = apr_brigade_split(bb, sockbuck);     if (apr_brigade_flatten(bb, request_body, &l) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,                      "Unable to flatten brigade, declining request");        return DECLINED;    }    apr_os_sock_get(&sfd, thesock);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -