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

📄 perchild.c

📁 Apache V2.0.15 Alpha For Linuxhttpd-2_0_15-alpha.tar.Z
💻 C
📖 第 1 页 / 共 4 页
字号:
    iov.iov_len = 0;    msg.msg_name = NULL;    msg.msg_namelen = 0;    msg.msg_iov = &iov;    msg.msg_iovlen = 1;    cmsg = apr_palloc(r->pool, sizeof(*cmsg) + sizeof(sfd));    cmsg->cmsg_len = sizeof(*cmsg) + sizeof(int);    cmsg->cmsg_level = SOL_SOCKET;    cmsg->cmsg_type = SCM_RIGHTS;    memcpy(CMSG_DATA(cmsg), &sfd, sizeof(sfd));    msg.msg_control = (caddr_t)cmsg;    msg.msg_controllen = cmsg->cmsg_len;    msg.msg_flags=0;    if (sendmsg(sconf->sd2, &msg, 0) == -1) {        apr_pool_destroy(r->pool);        return -1;    }    write(sconf->sd2, foo, len);       while (ap_get_brigade(r->input_filters, bb, AP_MODE_NONBLOCKING) == APR_SUCCESS) {        apr_bucket *e;        APR_BRIGADE_FOREACH(e, bb) {            const char *str;            apr_bucket_read(e, &str, &len, APR_NONBLOCK_READ);            write(sconf->sd2, str, len);        }    }    apr_pool_destroy(r->pool);    return 1;}static char *make_perchild_socket(const char *fullsockname, int sd[2]){    socketpair(PF_UNIX, SOCK_STREAM, 0, sd);    return NULL;}static void perchild_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s){    int i;    server_rec *sr;    perchild_server_conf *sconf;    int def_sd[2];        def_sd[0] = -1;    def_sd[1] = -1;    for (sr = s; sr; sr = sr->next) {        sconf = (perchild_server_conf *)ap_get_module_config(sr->module_config,                                                      &mpm_perchild_module);        if (sconf->sd == -1) {            sconf->fullsockname = apr_pstrcat(sr->process->pool,                                              sconf->sockname, ".DEFAULT", NULL);            if (def_sd[0] == -1) {                if (!make_perchild_socket(sconf->fullsockname, def_sd)) {                    /* log error */                }            }            sconf->sd = def_sd[0];            sconf->sd2 = def_sd[1];        }    }    for (i = 0; i < num_daemons; i++) {        if (child_info_table[i].uid == -1) {            child_info_table[i].sd = def_sd[0];        }    }}static int perchild_post_read(request_rec *r){    ap_filter_t *f = r->connection->input_filters;    int thread_num = r->connection->id % HARD_THREAD_LIMIT;    perchild_server_conf *sconf = (perchild_server_conf *)                            ap_get_module_config(r->server->module_config,                                                  &mpm_perchild_module);    while (f) {        if (!strcmp("PERCHILD_BUFFER", f->frec->name)) {            ap_remove_output_filter(f);            break;        }        f = f->next;    }    if (thread_socket_table[thread_num] != -1) {        apr_socket_t *csd = NULL;        apr_os_sock_put(&csd, &thread_socket_table[thread_num],                              r->connection->pool);        ap_sock_disable_nagle(csd);        r->connection->client_socket = csd;        return OK;    }    else {        if (sconf->sd != child_info_table[child_num].sd) {            if (pass_request(r) == -1) {                ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0,                             ap_server_conf, "Could not pass request to proper "                             "child, request will not be honored.");            }            longjmp(jmpbuffer, 1);         }        return OK;    }    return OK;}static apr_status_t perchild_buffer(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode){    apr_bucket *e;    apr_status_t rv;    char *buffer = NULL;    const char *str;    apr_size_t len;    if ((rv = ap_get_brigade(f->next, b, mode)) != APR_SUCCESS) {        return rv;    }    apr_pool_userdata_get((void **)&buffer, "PERCHILD_BUFFER", f->c->pool);    APR_BRIGADE_FOREACH(e, b) {        if (e->length != 0) {            apr_bucket_read(e, &str, &len, APR_NONBLOCK_READ);                   if (buffer == NULL) {                buffer = apr_pstrndup(f->c->pool, str, len);            }            else {               buffer = apr_pstrcat(f->c->pool, buffer,                                     apr_pstrndup(f->c->pool, str, len), NULL);            }         }    }    apr_pool_userdata_set(buffer, "PERCHILD_BUFFER", apr_pool_cleanup_null, f->c->pool);        return APR_SUCCESS;}static int perchild_pre_connection(conn_rec *c){    ap_add_input_filter("PERCHILD_BUFFER", NULL, NULL, c);    return OK;}static void perchild_hooks(apr_pool_t *p){    one_process = 0;    ap_hook_pre_config(perchild_pre_config, NULL, NULL, APR_HOOK_MIDDLE);     ap_hook_post_config(perchild_post_config, NULL, NULL, APR_HOOK_MIDDLE);     ap_hook_pre_connection(perchild_pre_connection,NULL,NULL, APR_HOOK_MIDDLE);    /* This must be run absolutely first.  If this request isn't for this     * server then we need to forward it to the proper child.  No sense     * tying up this server running more post_read request hooks if it is     * just going to be forwarded along.     */    ap_hook_post_read_request(perchild_post_read, NULL, NULL, APR_HOOK_REALLY_FIRST);    ap_register_input_filter("PERCHILD_BUFFER", perchild_buffer, AP_FTYPE_CONTENT);}static const char *set_pidfile(cmd_parms *cmd, void *dummy, const char *arg) {    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    if (cmd->server->is_virtual) {	return "PidFile directive not allowed in <VirtualHost>";    }    ap_pid_fname = arg;    return NULL;}static const char *set_scoreboard(cmd_parms *cmd, void *dummy, const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    ap_scoreboard_fname = arg;    return NULL;}static const char *set_lockfile(cmd_parms *cmd, void *dummy, const char *arg) {    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    lock_fname = arg;    return NULL;}static const char *set_num_daemons (cmd_parms *cmd, void *dummy, const char *arg) {    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    num_daemons = atoi(arg);    if (num_daemons > HARD_SERVER_LIMIT) {       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                     "WARNING: NumServers of %d exceeds compile time limit "                    "of %d servers,", num_daemons, HARD_SERVER_LIMIT);       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                     " lowering NumServers to %d.  To increase, please "                    "see the", HARD_SERVER_LIMIT);       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                     " HARD_SERVER_LIMIT define in %s.",                    AP_MPM_HARD_LIMITS_FILE);       num_daemons = HARD_SERVER_LIMIT;    }     else if (num_daemons < 1) {	ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                      "WARNING: Require NumServers > 0, setting to 1");	num_daemons = 1;    }    return NULL;}static const char *set_threads_to_start (cmd_parms *cmd, void *dummy, const char *arg) {    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    threads_to_start = atoi(arg);    if (threads_to_start > HARD_THREAD_LIMIT) {        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                      "WARNING: StartThreads of %d exceeds compile time"                     " limit of %d threads,", threads_to_start,                     HARD_THREAD_LIMIT);        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                      " lowering StartThreads to %d. To increase, please"                     " see the", HARD_THREAD_LIMIT);        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                      " HARD_THREAD_LIMIT define in %s.",                     AP_MPM_HARD_LIMITS_FILE);    }    else if (threads_to_start < 1) {	ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                      "WARNING: Require StartThreads > 0, setting to 1");	threads_to_start = 1;    }    return NULL;}static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    min_spare_threads = atoi(arg);    if (min_spare_threads <= 0) {       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                     "WARNING: detected MinSpareThreads set to non-positive.");       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                     "Resetting to 1 to avoid almost certain Apache failure.");       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                     "Please read the documentation.");       min_spare_threads = 1;    }           return NULL;}static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    max_spare_threads = atoi(arg);    if (max_spare_threads >= HARD_THREAD_LIMIT) {       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                     "WARNING: detected MinSpareThreads set higher than");       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                     "HARD_THREAD_LIMIT. Resetting to %d", HARD_THREAD_LIMIT);       max_spare_threads = HARD_THREAD_LIMIT;    }    return NULL;}static const char *set_max_threads(cmd_parms *cmd, void *dummy, const char *arg){    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    max_threads = atoi(arg);    if (max_threads > HARD_THREAD_LIMIT) {       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                     "WARNING: detected MaxThreadsPerChild set higher than");       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,                     "HARD_THREAD_LIMIT. Resetting to %d", HARD_THREAD_LIMIT);       max_threads = HARD_THREAD_LIMIT;    }    return NULL;}static const char *set_max_requests(cmd_parms *cmd, void *dummy, const char *arg) {    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    max_requests_per_child = atoi(arg);    return NULL;}static const char *set_coredumpdir (cmd_parms *cmd, void *dummy,				    const char *arg) {    apr_finfo_t finfo;    const char *fname;    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    if (err != NULL) {        return err;    }    fname = ap_server_root_relative(cmd->pool, arg);    if ((apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool) != APR_SUCCESS)         || (finfo.filetype != APR_DIR)) {	return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, 			  " does not exist or is not a directory", NULL);    }    apr_cpystrn(ap_coredump_dir, fname, sizeof(ap_coredump_dir));    return NULL;}static const char *set_child_per_uid(cmd_parms *cmd, void *dummy, const char *u,                                     const char *g, const char *num){    int i;    int max_this_time = atoi(num) + curr_child_num;    for (i = curr_child_num; i < max_this_time; i++, curr_child_num++); {        child_info_t *ug = &child_info_table[i - 1];        if (i > num_daemons) {            return "Trying to use more child ID's than NumServers.  Increase "                   "NumServers in your config file.";        }            ug->uid = atoi(u);        ug->gid = atoi(g);     }    return NULL;}static const char *assign_childuid(cmd_parms *cmd, void *dummy, const char *uid,                                   const char *gid){    int i;    int u = atoi(uid);    int g = atoi(gid);    const char *errstr;    int socks[2];    perchild_server_conf *sconf = (perchild_server_conf *)                            ap_get_module_config(cmd->server->module_config,                                                  &mpm_perchild_module);    sconf->fullsockname = apr_pstrcat(cmd->pool, sconf->sockname, ".", uid, ":", gid, NULL);    if ((errstr = make_perchild_socket(sconf->fullsockname, socks))) {        return errstr;    }    sconf->sd = socks[0];     sconf->sd2 = socks[1];    for (i = 0; i < num_daemons; i++) {        if (u == child_info_table[i].uid && g == child_info_table[i].gid) {            child_info_table[i].sd = sconf->sd;        }    }    return NULL;}static const command_rec perchild_cmds[] = {UNIX_DAEMON_COMMANDSLISTEN_COMMANDSAP_INIT_TAKE1("PidFile", set_pidfile, NULL, RSRC_CONF,              "A file for logging the server process ID"),AP_INIT_TAKE1("ScoreBoardFile", set_scoreboard, NULL, RSRC_CONF,              "A file for Apache to maintain runtime process management information"),AP_INIT_TAKE1("LockFile", set_lockfile, NULL, RSRC_CONF,              "The lockfile used when Apache needs to lock the accept() call"),AP_INIT_TAKE1("NumServers", set_num_daemons, NULL, RSRC_CONF,              "Number of children alive at the same time"),AP_INIT_TAKE1("StartThreads", set_threads_to_start, NULL, RSRC_CONF,              "Number of threads each child creates"),AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,              "Minimum number of idle threads per child, to handle request spikes"),AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,              "Maximum number of idle threads per child"),AP_INIT_TAKE1("MaxThreadsPerChild", set_max_threads, NULL, RSRC_CONF,              "Maximum number of threads per child"),AP_INIT_TAKE1("MaxRequestsPerChild", set_max_requests, NULL, RSRC_CONF,              "Maximum number of requests a particular child serves before dying."),AP_INIT_TAKE1("CoreDumpDirectory", set_coredumpdir, NULL, RSRC_CONF,              "The location of the directory Apache changes to before dumping core"),AP_INIT_TAKE3("ChildperUserID", set_child_per_uid, NULL, RSRC_CONF,              "Specify a User and Group for a specific child process."),AP_INIT_TAKE2("AssignUserID", assign_childuid, NULL, RSRC_CONF,              "Tie a virtual host to a specific child process."),{ NULL }};static void *perchild_create_config(apr_pool_t *p, server_rec *s){    perchild_server_conf *c =    (perchild_server_conf *) apr_pcalloc(p, sizeof(perchild_server_conf));    c->sd = -1;    return c;}module AP_MODULE_DECLARE_DATA mpm_perchild_module = {    MPM20_MODULE_STUFF,    NULL,                       /* hook to run before apache parses args */    NULL,			/* create per-directory config structure */    NULL,			/* merge per-directory config structures */    perchild_create_config,	/* create per-server config structure */    NULL,			/* merge per-server config structures */    perchild_cmds,		/* command apr_table_t */    perchild_hooks 		/* register_hooks */};

⌨️ 快捷键说明

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