mpm_common.c revision f8aafb8bd93472f7da5a7c158958ee09e4176c8e
ad9437836f5d94b44d40ee702a0455a637c30322Lennart Poettering/* Licensed to the Apache Software Foundation (ASF) under one or more
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * contributor license agreements. See the NOTICE file distributed with
12b42c76672a66c2d4ea7212c14f8f1b5a62b78dTom Gundersen * this work for additional information regarding copyright ownership.
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * The ASF licenses this file to You under the Apache License, Version 2.0
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * (the "License"); you may not use this file except in compliance with
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * the License. You may obtain a copy of the License at
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * Unless required by applicable law or agreed to in writing, software
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * distributed under the License is distributed on an "AS IS" BASIS,
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * See the License for the specific language governing permissions and
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * limitations under the License.
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen/* The purpose of this file is to store the code that MOST mpm's will need
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * this does not mean a function only goes into this file if every MPM needs
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * it. It means that if a function is needed by more than one MPM, and
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * future maintenance would be served by making the code common, then the
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * function belongs here.
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * This is going in src/main because it is not platform specific, it is
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * specific to multi-process servers, but NOT to Unix. Which is why it
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen * does not belong in src/os/unix
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek APR_HOOK_LINK(mpm_get_child_pid)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek APR_HOOK_LINK(mpm_register_timed_callback)
12b42c76672a66c2d4ea7212c14f8f1b5a62b78dTom GundersenAP_IMPLEMENT_HOOK_RUN_ALL(int, fatal_exception,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (ap_exception_info_t *ei), (ei), OK, DECLINED)
57e27ec0ada6775d85a5201cd25e989d92d0a1afZbigniew Jędrzejewski-Szmek APR_HOOK_LINK(mpm_get_child_pid)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekAP_IMPLEMENT_HOOK_RUN_ALL(int, monitor,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (apr_pool_t *p), (p), OK, DECLINED)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekAP_IMPLEMENT_HOOK_RUN_ALL(int, drop_privileges,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (apr_pool_t * pchild, server_rec * s),
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekAP_IMPLEMENT_HOOK_RUN_FIRST(int, mpm,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (apr_pool_t *pconf, apr_pool_t *plog, server_rec *s),
a22e1850c36e52cb9d593b99be59b6ba7639d80aLennart PoetteringAP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_query,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (query_code, result), APR_ENOTIMPL)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekAP_IMPLEMENT_HOOK_RUN_FIRST(pid_t, mpm_get_child_pid,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekAP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_note_child_killed,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekAP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_register_timed_callback,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton),
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekAP_IMPLEMENT_HOOK_RUN_FIRST(const char *, mpm_get_name,
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen/* number of calls to wait_or_timeout between writable probes */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int wait_or_timeout_counter;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekvoid ap_wait_or_timeout(apr_exit_why_e *status, int *exitcode, apr_proc_t *ret,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (wait_or_timeout_counter == INTERVAL_OF_WRITABLE_PROBES) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek rv = apr_proc_wait_all_procs(ret, exitcode, status, APR_NOWAIT, p);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (APR_STATUS_IS_CHILD_DONE(rv)) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#if defined(TCP_NODELAY) && !defined(MPE) && !defined(TPF)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekvoid ap_sock_disable_nagle(apr_socket_t *s)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* The Nagle algorithm says that we should delay sending partial
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * packets in hopes of getting more data. We don't want to do
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * this; we are not telnet. There are bad interactions between
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * persistent connections and Nagle's algorithm that have very severe
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * performance penalties. (Failing to disable Nagle is not much of a
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * problem with simple HTTP.)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * In spite of these problems, failure here is not a shooting offense.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_status_t status = apr_socket_opt_set(s, APR_TCP_NODELAY, 1);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_log_error(APLOG_MARK, APLOG_WARNING, status, ap_server_conf,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "apr_socket_opt_set: (TCP_NODELAY)");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekAP_DECLARE(uid_t) ap_uname2id(const char *name)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "%s: bad user name %s", ap_server_argv0, name);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekAP_DECLARE(gid_t) ap_gname2id(const char *name)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "%s: bad group name %s", ap_server_argv0, name);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekint initgroups(const char *name, gid_t basegid)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#if defined(QNX) || defined(MPE) || defined(BEOS) || defined(_OSD_POSIX) || defined(TPF) || defined(__TANDEM) || defined(OS2) || defined(WIN32) || defined(NETWARE)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* QNX, MPE and BeOS do not appear to support supplementary groups. */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#else /* ndef QNX */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek while (index < NGROUPS_MAX && ((g = getgrent()) != NULL)) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (names = g->gr_mem; *names != NULL; ++names) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#endif /* def QNX */
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek#endif /* def NEED_INITGROUPS */
e88d8021ba34be32ef5ace32e7243da798b0d1c5Zbigniew Jędrzejewski-Szmek/* standard mpm configuration handling */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekconst char *ap_mpm_set_pidfile(cmd_parms *cmd, void *dummy,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return "PidFile directive not allowed in <VirtualHost>";
d0d6a4cd70477970812bff0a37e70f66208d7c14Tom Gundersenconst char * ap_mpm_set_scoreboard(cmd_parms *cmd, void *dummy,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekconst char *ap_lock_fname = NULL;
113bfde15f9393fa8bc22cbd839c0bc64e733ee2Tom Gundersenconst char *ap_mpm_set_lockfile(cmd_parms *cmd, void *dummy,
113bfde15f9393fa8bc22cbd839c0bc64e733ee2Tom Gundersen const char *arg)
113bfde15f9393fa8bc22cbd839c0bc64e733ee2Tom Gundersen const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekint ap_max_requests_per_child = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekconst char *ap_mpm_set_max_requests(cmd_parms *cmd, void *dummy,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rautaconst char *ap_mpm_set_coredumpdir(cmd_parms *cmd, void *dummy,
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta const char *arg)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek fname = ap_server_root_relative(cmd->pool, arg);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return apr_pstrcat(cmd->pool, "Invalid CoreDumpDirectory path ",
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if ((rv = apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool)) != APR_SUCCESS) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (finfo.filetype != APR_DIR) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_cpystrn(ap_coredump_dir, fname, sizeof(ap_coredump_dir));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekint ap_graceful_shutdown_timeout = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekconst char * ap_mpm_set_graceful_shutdown(cmd_parms *cmd, void *dummy,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_graceful_shutdown_timeout = atoi(arg);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekapr_lockmech_e ap_accept_lock_mech = APR_LOCK_DEFAULT;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekconst char *ap_mpm_set_accept_lock_mech(cmd_parms *cmd,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek rv = ap_parse_mutex(arg, cmd->server->process->pool,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek &ap_accept_lock_mech, &lockfile);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if ((rv == APR_ENOTIMPL) || (rv == APR_ENOLOCK)) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return apr_pstrcat(cmd->pool, "Invalid AcceptMutex argument ", arg,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek " (" AP_AVAILABLE_MUTEXES_STRING ")", NULL);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return apr_pstrcat(cmd->pool, "Invalid AcceptMutex filepath ",
2972cba11712c3bfbe9fa07d1f3c3c4330127733Nick Owensapr_uint32_t ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED;
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poetteringconst char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy,
4046d8361c55c80ab8577aea52523b9e6eab0d0cLennart Poettering const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
e2bccc9d9974eb1290653ecfa3ccfd03c313842bDavid Herrmann return apr_pstrcat(cmd->pool, "Invalid MaxMemFree value: ",
505c5f6de1a5c0afb238a46db94fe3571902cc9dBenedikt Morbach ap_max_mem_free = (apr_uint32_t)value * 1024;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekapr_size_t ap_thread_stacksize = 0; /* use system default */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekconst char *ap_mpm_set_thread_stacksize(cmd_parms *cmd, void *dummy,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1f0d9695125bf8e66d0e53e37d454755a84899bbLennart Poettering return apr_pstrcat(cmd->pool, "Invalid ThreadStackSize value: ",
1f0d9695125bf8e66d0e53e37d454755a84899bbLennart PoetteringAP_DECLARE(int) ap_mpm_run(apr_pool_t *pconf, apr_pool_t *plog, server_rec *server_conf)
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan EngelhardtAP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek return ap_run_mpm_query(query_code, result);
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-SzmekAP_DECLARE(pid_t) ap_mpm_get_child_pid(int childnum)
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek return ap_run_mpm_get_child_pid(childnum);
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-SzmekAP_DECLARE(apr_status_t) ap_mpm_note_child_killed(int childnum)
ebf9808112d7ed049f461e3ae8aad82b2d65f901Zbigniew Jędrzejewski-Szmek return ap_run_mpm_note_child_killed(childnum);
941d0aa8f4426b306e246b096175a28676259055Susant SahaniAP_DECLARE(apr_status_t) ap_mpm_register_timed_callback(apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton)
44de7fb14f0fb5b8fe0f829f128c2c3e64114c0cSusant Sahani return ap_run_mpm_register_timed_callback(t, cbfn, baton);