diff options
author | Jeff Trawick <trawick@apache.org> | 2009-11-24 00:17:51 +0100 |
---|---|---|
committer | Jeff Trawick <trawick@apache.org> | 2009-11-24 00:17:51 +0100 |
commit | 2e9668a33d7187ef575e17c1a198a515366c0db1 (patch) | |
tree | 0e58bebdbd155b366ae32e4ada3c3b142ce9adfc | |
parent | KeepAlive no longer accepts other than On|Off. (diff) | |
download | apache2-2e9668a33d7187ef575e17c1a198a515366c0db1.tar.xz apache2-2e9668a33d7187ef575e17c1a198a515366c0db1.zip |
Replace AcceptMutex, LockFile, RewriteLock, SSLMutex, SSLStaplingMutex,
and WatchdogMutexPath with a single Mutex directive. Add APIs to
simplify setup and user customization of APR proc and global mutexes.
(See util_mutex.h.) Build-time setting DEFAULT_LOCKFILE is no longer
respected; set DEFAULT_REL_RUNTIMEDIR instead.
Some existing modules, such as mod_ldap and mod_auth_digest gain
configurability for their mutexes.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@883540 13f79535-47bb-0310-9956-ffa450edef68
31 files changed, 627 insertions, 563 deletions
@@ -10,6 +10,12 @@ Changes with Apache 2.3.3 mod_proxy_ftp: NULL pointer dereference on error paths. [Stefan Fritsch <sf fritsch.de>, Joe Orton] + *) Replace AcceptMutex, LockFile, RewriteLock, SSLMutex, SSLStaplingMutex, + and WatchdogMutexPath with a single Mutex directive. Add APIs to + simplify setup and user customization of APR proc and global mutexes. + (See util_mutex.h.) Build-time setting DEFAULT_LOCKFILE is no longer + respected; set DEFAULT_REL_RUNTIMEDIR instead. [Jeff Trawick] + *) http_core: KeepAlive no longer accepts other than On|Off. [Takashi Sato] diff --git a/build/mkconfNW.awk b/build/mkconfNW.awk index b441cfa046..8b79d1dc7c 100644 --- a/build/mkconfNW.awk +++ b/build/mkconfNW.awk @@ -100,8 +100,8 @@ match ($0,/^SSLSessionCache +"shmcb:/) { sub(/^SSLSessionCache/, "#SSLSessionCache") } -match ($0,/^SSLMutex +"file:@exp_runtimedir@\/ssl_mutex"/) { - sub(/"file:@exp_runtimedir@\/ssl_mutex"/, "default") +match ($0,/^Mutex +"file:@rel_runtimedir@"/) { + sub(/"file:@rel_runtimedir@"/, "default") } match ($0,/@@.*@@/) { diff --git a/docs/conf/extra/httpd-mpm.conf.in b/docs/conf/extra/httpd-mpm.conf.in index 5717754548..0987cfca99 100644 --- a/docs/conf/extra/httpd-mpm.conf.in +++ b/docs/conf/extra/httpd-mpm.conf.in @@ -13,20 +13,6 @@ </IfModule> # -# The accept serialization lock file MUST BE STORED ON A LOCAL DISK. -# -<IfModule !mpm_simple_module> -<IfModule !mpm_winnt_module> -<IfModule !mpm_netware_module> -<IfModule !mpm_mpmt_os2_module> -LockFile "@rel_logfiledir@/accept.lock" -</IfModule> -</IfModule> -</IfModule> -</IfModule> - - -# # Only one of the below sections will be relevant on your # installed httpd. Use "apachectl -l" to find out the # active mpm. diff --git a/docs/conf/extra/httpd-ssl.conf.in b/docs/conf/extra/httpd-ssl.conf.in index 809ab827d4..fae4cbeef7 100644 --- a/docs/conf/extra/httpd-ssl.conf.in +++ b/docs/conf/extra/httpd-ssl.conf.in @@ -56,11 +56,6 @@ SSLPassPhraseDialog builtin SSLSessionCache "shmcb:@exp_runtimedir@/ssl_scache(512000)" SSLSessionCacheTimeout 300 -# Semaphore: -# Configure the path to the mutual exclusion semaphore the -# SSL engine uses internally for inter-process synchronization. -SSLMutex "file:@exp_runtimedir@/ssl_mutex" - ## ## SSL Virtual Host Context ## diff --git a/docs/conf/httpd.conf.in b/docs/conf/httpd.conf.in index b5e6319169..6b24798352 100644 --- a/docs/conf/httpd.conf.in +++ b/docs/conf/httpd.conf.in @@ -22,13 +22,23 @@ # configuration, error, and log files are kept. # # Do not add a slash at the end of the directory path. If you point -# ServerRoot at a non-local disk, be sure to point the LockFile directive -# at a local disk. If you wish to share the same ServerRoot for multiple -# httpd daemons, you will need to change at least LockFile and PidFile. +# ServerRoot at a non-local disk, be sure to specify a local disk on the +# Mutex directive, if file-based mutexes are used. If you wish to share the +# same ServerRoot for multiple httpd daemons, you will need to change at +# least PidFile. # ServerRoot "@@ServerRoot@@" # +# Mutex: Allows you to set the mutex mechanism and mutex file directory +# for individual mutexes, or change the global defaults +# +# Uncomment only if mutexes are file-based and the default mutex file +# directory is not appropriate. +# +# Mutex default file:@rel_runtimedir@ + +# # Listen: Allows you to bind Apache to specific IP addresses and/or # ports, instead of the default. See also the <VirtualHost> # directive. diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 5d63e2f7c3..96fe1d147d 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -205,6 +205,7 @@ * 20091011.1 (2.3.3-dev) add debug_level to util_ldap_state_t * 20091031.0 (2.3.3-dev) remove public LDAP referral-related macros * 20091119.0 (2.3.4-dev) dav_error interface uses apr_status_t parm, not errno + * 20091119.1 (2.3.4-dev) ap_mutex_register(), ap_{proc,global}_mutex_create() * */ @@ -213,7 +214,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20091119 #endif -#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 1 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/ap_slotmem.h b/include/ap_slotmem.h index 3d4f0620a9..4d24c01009 100644 --- a/include/ap_slotmem.h +++ b/include/ap_slotmem.h @@ -40,10 +40,6 @@ #include "apr_global_mutex.h" #include "apr_file_io.h" -#ifdef AP_NEED_SET_MUTEX_PERMS -#include "unixd.h" -#endif - #if APR_HAVE_UNISTD_H #include <unistd.h> /* for getpid() */ #endif diff --git a/include/mpm_common.h b/include/mpm_common.h index e5fe358853..40c96ce7b2 100644 --- a/include/mpm_common.h +++ b/include/mpm_common.h @@ -264,20 +264,6 @@ extern const char *ap_pid_fname; const char *ap_mpm_set_pidfile(cmd_parms *cmd, void *dummy, const char *arg); -/** - * The name of lockfile used when Apache needs to lock the accept() call. - */ -extern const char *ap_lock_fname; -const char *ap_mpm_set_lockfile(cmd_parms *cmd, void *dummy, - const char *arg); - -/** - * The system mutex implementation to use for the accept mutex. - */ -extern apr_lockmech_e ap_accept_lock_mech; -const char *ap_mpm_set_accept_lock_mech(cmd_parms *cmd, void *dummy, - const char *arg); - /* * Set the scorboard file. */ @@ -347,6 +333,11 @@ AP_DECLARE_HOOK(apr_status_t, mpm_register_timed_callback, /* get MPM name (e.g., "prefork" or "event") */ AP_DECLARE_HOOK(const char *,mpm_get_name,(void)) +/* mutex type string for accept mutex, if any; MPMs should use the + * same mutex type for ease of configuration + */ +#define ap_accept_mutex_type "mpm-accept" + #ifdef __cplusplus } #endif diff --git a/include/util_ldap.h b/include/util_ldap.h index d4760233bd..a1ebb33a9d 100644 --- a/include/util_ldap.h +++ b/include/util_ldap.h @@ -156,7 +156,6 @@ typedef struct util_ldap_state_t { /* cache ald */ void *util_ldap_cache; - char *lock_file; /* filename for shm lock mutex */ long connectionTimeout; int verify_svr_cert; int debug_level; /* SDK debug level */ diff --git a/include/util_mutex.h b/include/util_mutex.h index 4882d42047..b25247d5c0 100644 --- a/include/util_mutex.h +++ b/include/util_mutex.h @@ -98,6 +98,110 @@ AP_DECLARE(apr_status_t) ap_parse_mutex(const char *arg, apr_pool_t *pool, apr_lockmech_e *mutexmech, const char **mutexfile); +/* private function to process the Mutex directive */ +AP_DECLARE(const char *) ap_set_mutex(cmd_parms *cmd, void *dummy, + const char *typelist, + const char *mechfile); + +/** + * option flags for ap_mutex_register(), ap_global_mutex_create(), and + * ap_proc_mutex_create() + */ +#define AP_MUTEX_ALLOW_NONE 1 /* allow "none" as mutex implementation; + * respected only on ap_mutex_register() + */ +#define AP_MUTEX_DEFAULT_NONE 2 /* default to "none" for this mutex; + * respected only on ap_mutex_register() + */ + +/** + * Register a module's mutex type with core to allow configuration + * with the Mutex directive. This must be called in the pre_config + * hook; otherwise, configuration directives referencing this mutex + * type will be rejected. + * + * The default_dir and default_mech parameters allow a module to set + * defaults for the lock file directory and mechanism. These could + * be based on compile-time settings. These aren't required except + * in special circumstances. + * + * The order of precedence for the choice of mechanism and lock file + * directory is: + * + * 1. Mutex directive specifically for this mutex + * e.g., Mutex mpm-default flock:/tmp/mpmlocks + * 2. Mutex directive for global default + * e.g., Mutex default flock:/tmp/httpdlocks + * 3. Defaults for this mutex provided on the ap_mutex_register() + * 4. Built-in defaults for all mutexes, which are + * APR_LOCK_DEFAULT and DEFAULT_REL_RUNTIMEDIR. + * + * @param pconf The pconf pool + * @param type The type name of the mutex, used as the basename of the + * file associated with the mutex, if any. This must be unique among + * all mutex types (mutex creation accommodates multi-instance mutex + * types); mod_foo might have mutex types "foo-pipe" and "foo-shm" + * @param default_dir Default dir for any lock file required for this + * lock, to override built-in defaults; should be NULL for most + * modules, to respect built-in defaults + * @param default_mech Default mechanism for this lock, to override + * built-in defaults; should be APR_LOCK_DEFAULT for most modules, to + * respect built-in defaults + * or NULL if there are no defaults for this mutex. + * @param options combination of AP_MUTEX_* constants, or 0 for defaults + */ +AP_DECLARE(apr_status_t) ap_mutex_register(apr_pool_t *pconf, + const char *type, + const char *default_dir, + apr_lockmech_e default_mech, + apr_int32_t options); + +/** + * Create an APR global mutex that has been registered previously with + * ap_mutex_register(). Mutex files, permissions, and error logging will + * be handled internally. + * @param mutex The memory address where the newly created mutex will be + * stored. If this mutex is disabled, mutex will be set to NULL on + * output. (That is allowed only if the AP_MUTEX_ALLOW_NONE flag is + * passed to ap_mutex_register().) + * @param type The type name of the mutex, matching the type name passed + * to ap_mutex_register(). + * @param instance_id A unique string to be used in the lock filename IFF + * this mutex type is multi-instance, NULL otherwise. + * @param s server_rec of main server + * @param pconf pool + * @param options combination of AP_MUTEX_* constants, or 0 for defaults + * (currently none are defined for this function) + */ +AP_DECLARE(apr_status_t) ap_global_mutex_create(apr_global_mutex_t **mutex, + const char *type, + const char *instance_id, + server_rec *s, + apr_pool_t *pconf, + apr_int32_t options); + +/** + * Create an APR proc mutex that has been registered previously with + * ap_mutex_register(). Mutex files, permissions, and error logging will + * be handled internally. + * @param mutex The memory address where the newly created mutex will be + * stored. If this mutex is disabled, mutex will be set to NULL on + * output. (That is allowed only if the AP_MUTEX_ALLOW_NONE flag is + * passed to ap_mutex_register().) + * @param type The type name of the mutex, matching the type name passed + * to ap_mutex_register(). + * @param instance_id A unique string to be used in the lock filename IFF + * this mutex type is multi-instance, NULL otherwise. + * @param s server_rec of main server + * @param pconf pool + * @param options combination of AP_MUTEX_* constants, or 0 for defaults + * (currently none are defined for this function) + */ +AP_DECLARE(apr_status_t) ap_proc_mutex_create(apr_proc_mutex_t **mutex, + const char *type, + const char *instance_id, + server_rec *s, apr_pool_t *p, + apr_int32_t options); #ifdef __cplusplus } diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c index 8bc2934ac2..878525cc6a 100644 --- a/modules/aaa/mod_auth_digest.c +++ b/modules/aaa/mod_auth_digest.c @@ -74,6 +74,7 @@ #include "http_protocol.h" #include "apr_uri.h" #include "util_md5.h" +#include "util_mutex.h" #include "apr_shm.h" #include "apr_rmm.h" #include "ap_provider.h" @@ -179,8 +180,8 @@ static unsigned long *opaque_cntr; static apr_time_t *otn_counter; /* one-time-nonce counter */ static apr_global_mutex_t *client_lock = NULL; static apr_global_mutex_t *opaque_lock = NULL; -static const char *client_lock_name; -static const char *opaque_lock_name; +static const char *client_lock_type = "authdigest-client"; +static const char *opaque_lock_type = "authdigest-opaque"; static const char *client_shm_filename; #define DEF_SHMEM_SIZE 1000L /* ~ 12 entries */ @@ -321,12 +322,7 @@ static int initialize_tables(server_rec *s, apr_pool_t *ctx) client_list->tbl_len = num_buckets; client_list->num_entries = 0; - client_lock_name = apr_psprintf(ctx, "%s/authdigest_lock.%"APR_PID_T_FMT, tempdir, - getpid()); - /* FIXME: get the client_lock_name from a directive so we're portable - * to non-process-inheriting operating systems, like Win32. */ - sts = apr_global_mutex_create(&client_lock, client_lock_name, - APR_LOCK_DEFAULT, ctx); + sts = ap_global_mutex_create(&client_lock, client_lock_type, NULL, s, ctx, 0); if (sts != APR_SUCCESS) { log_error_and_cleanup("failed to create lock (client_lock)", sts, s); return !OK; @@ -342,11 +338,7 @@ static int initialize_tables(server_rec *s, apr_pool_t *ctx) } *opaque_cntr = 1UL; - opaque_lock_name = apr_psprintf(ctx, "%s/authdigest_opaque_lock.%"APR_PID_T_FMT, - tempdir, - getpid()); - sts = apr_global_mutex_create(&opaque_lock, opaque_lock_name, - APR_LOCK_DEFAULT, ctx); + sts = ap_global_mutex_create(&opaque_lock, opaque_lock_type, NULL, s, ctx, 0); if (sts != APR_SUCCESS) { log_error_and_cleanup("failed to create lock (opaque_lock)", sts, s); return !OK; @@ -370,6 +362,21 @@ static int initialize_tables(server_rec *s, apr_pool_t *ctx) #endif /* APR_HAS_SHARED_MEMORY */ +static int pre_init(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp) +{ + apr_status_t rv; + + rv = ap_mutex_register(pconf, client_lock_type, NULL, APR_LOCK_DEFAULT, 0); + if (rv == APR_SUCCESS) { + rv = ap_mutex_register(pconf, opaque_lock_type, NULL, APR_LOCK_DEFAULT, + 0); + } + if (rv != APR_SUCCESS) { + return rv; + } + + return OK; +} static int initialize_module(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) @@ -428,12 +435,16 @@ static void initialize_child(apr_pool_t *p, server_rec *s) return; } - sts = apr_global_mutex_child_init(&client_lock, client_lock_name, p); + sts = apr_global_mutex_child_init(&client_lock, + apr_global_mutex_lockfile(client_lock), + p); if (sts != APR_SUCCESS) { log_error_and_cleanup("failed to create lock (client_lock)", sts, s); return; } - sts = apr_global_mutex_child_init(&opaque_lock, opaque_lock_name, p); + sts = apr_global_mutex_child_init(&opaque_lock, + apr_global_mutex_lockfile(opaque_lock), + p); if (sts != APR_SUCCESS) { log_error_and_cleanup("failed to create lock (opaque_lock)", sts, s); return; @@ -2033,6 +2044,7 @@ static void register_hooks(apr_pool_t *p) static const char * const cfgPost[]={ "http_core.c", NULL }; static const char * const parsePre[]={ "mod_proxy.c", NULL }; + ap_hook_pre_config(pre_init, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_config(initialize_module, NULL, cfgPost, APR_HOOK_MIDDLE); ap_hook_child_init(initialize_child, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_read_request(parse_hdr_and_update_nc, parsePre, NULL, APR_HOOK_MIDDLE); diff --git a/modules/core/mod_watchdog.c b/modules/core/mod_watchdog.c index a7f9b621e9..cff5a953ff 100644 --- a/modules/core/mod_watchdog.c +++ b/modules/core/mod_watchdog.c @@ -20,10 +20,7 @@ #include "mod_watchdog.h" #include "ap_provider.h" #include "ap_mpm.h" - -#ifdef AP_NEED_SET_MUTEX_PERMS -#include "unixd.h" -#endif +#include "util_mutex.h" #define AP_WATCHODG_PGROUP "watchdog" #define AP_WATCHODG_PVERSION "parent" @@ -46,7 +43,6 @@ struct ap_watchdog_t { apr_thread_mutex_t *startup; apr_proc_mutex_t *mutex; - const char *mutex_path; const char *name; watchdog_list_t *callbacks; int is_running; @@ -66,11 +62,11 @@ struct wd_server_conf_t server_rec *s; }; -static char *wd_mutex_path = NULL; static wd_server_conf_t *wd_server_conf = NULL; static apr_interval_time_t wd_interval = AP_WD_TM_INTERVAL; static int wd_interval_set = 0; static int mpm_is_forked = AP_MPMQ_NOT_SUPPORTED; +static const char *wd_proc_mutex_type = "wd-proc"; static apr_status_t wd_worker_cleanup(void *data) { @@ -276,7 +272,8 @@ static apr_status_t wd_startup(ap_watchdog_t *w, apr_pool_t *p) if (w->singleton) { /* Initialize singleton mutex in child */ - rc = apr_proc_mutex_child_init(&w->mutex, w->mutex_path, p); + rc = apr_proc_mutex_child_init(&w->mutex, + apr_proc_mutex_lockfile(w->mutex), p); if (rc != APR_SUCCESS) return rc; } @@ -387,38 +384,6 @@ static apr_status_t ap_watchdog_register_callback(ap_watchdog_t *w, return APR_SUCCESS; } -static apr_status_t wd_create_mutex(ap_watchdog_t *w, apr_pool_t *p) -{ - apr_status_t rv; - apr_lockmech_e mech = APR_LOCK_DEFAULT; - const char *mb_path = wd_mutex_path ? wd_mutex_path : "logs"; - - w->mutex_path = ap_server_root_relative(p, - apr_pstrcat(p, mb_path, - "/.wdc-", w->name, ".mutex", NULL)); - - /* TODO: Check the mutex mechanisms */ -#if APR_HAS_FCNTL_SERIALIZE - mech = APR_LOCK_FCNTL; -#else -#if APR_HAS_FLOCK_SERIALIZE - mech = APR_LOCK_FLOCK; -#endif -#endif - rv = apr_proc_mutex_create(&w->mutex, w->mutex_path, mech, p); -#ifdef AP_NEED_SET_MUTEX_PERMS - if (rv == APR_SUCCESS) { - rv = ap_unixd_set_proc_mutex_perms(w->mutex); - if (rv != APR_SUCCESS) { - /* Destroy the mutex early */ - apr_proc_mutex_destroy(w->mutex); - w->mutex = NULL; - } - } -#endif - return rv; -} - /*--------------------------------------------------------------------------*/ /* */ /* Pre config hook. */ @@ -451,6 +416,12 @@ static int wd_pre_config_hook(apr_pool_t *pconf, apr_pool_t *plog, return rv; } } + + if ((rv = ap_mutex_register(pconf, wd_proc_mutex_type, NULL, + APR_LOCK_DEFAULT, 0)) != APR_SUCCESS) { + return rv; + } + return OK; } @@ -557,10 +528,10 @@ static int wd_post_config_hook(apr_pool_t *pconf, apr_pool_t *plog, * Create mutexes for singleton watchdogs */ if (w->singleton) { - rv = wd_create_mutex(w, wd_server_conf->pool); + rv = ap_proc_mutex_create(&w->mutex, wd_proc_mutex_type, + w->name, s, + wd_server_conf->pool, 0); if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, - "Watchdog: Failed to create mutex."); return rv; } } @@ -614,30 +585,6 @@ static void wd_child_init_hook(apr_pool_t *p, server_rec *s) /*--------------------------------------------------------------------------*/ /* */ -/* WatchdogMutexPath directive */ -/* */ -/*--------------------------------------------------------------------------*/ -static const char *wd_cmd_mutex_path(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *errs = ap_check_cmd_context(cmd, GLOBAL_ONLY); - - if (errs != NULL) - return errs; - - if (wd_mutex_path != NULL) - return "Duplicate WatchdogMutexPath directives are not allowed"; - - wd_mutex_path = apr_pstrdup(cmd->pool, arg); - if (wd_mutex_path == NULL) - return "Invalid WatchdogMutexPath name"; - if (wd_mutex_path[strlen(wd_mutex_path) - 1] == '/') - wd_mutex_path[strlen(wd_mutex_path) - 1] = '\0'; - return NULL; -} - -/*--------------------------------------------------------------------------*/ -/* */ /* WatchdogInterval directive */ /* */ /*--------------------------------------------------------------------------*/ @@ -667,13 +614,6 @@ static const char *wd_cmd_watchdog_int(cmd_parms *cmd, void *dummy, static const command_rec wd_directives[] = { AP_INIT_TAKE1( - "WatchdogMutexPath", /* directive name */ - wd_cmd_mutex_path, /* config action routine */ - NULL, /* argument to include in call */ - RSRC_CONF, /* where available */ - "Path where the Watchdog mutexes will be created" - ), - AP_INIT_TAKE1( "WatchdogInterval", /* directive name */ wd_cmd_watchdog_int, /* config action routine */ NULL, /* argument to include in call */ diff --git a/modules/core/mod_watchdog.h b/modules/core/mod_watchdog.h index c02ee28464..8c4cece7f9 100644 --- a/modules/core/mod_watchdog.h +++ b/modules/core/mod_watchdog.h @@ -44,10 +44,6 @@ #include "apr_global_mutex.h" #include "apr_thread_mutex.h" -#ifdef AP_NEED_SET_MUTEX_PERMS -#include "unixd.h" -#endif - #if APR_HAVE_UNISTD_H #include <unistd.h> /* for getpid() */ #endif diff --git a/modules/examples/mod_example_ipc.c b/modules/examples/mod_example_ipc.c index ea1d3830c0..079ccac339 100644 --- a/modules/examples/mod_example_ipc.c +++ b/modules/examples/mod_example_ipc.c @@ -52,13 +52,9 @@ #include "http_config.h" #include "http_log.h" #include "http_protocol.h" +#include "util_mutex.h" #include "ap_config.h" -#if !defined(OS2) && !defined(WIN32) && !defined(NETWARE) -#include "unixd.h" -#define MOD_EXIPC_SET_MUTEX_PERMS /* XXX Apache should define something */ -#endif - #if APR_HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -80,7 +76,7 @@ apr_shm_t *exipc_shm; /* Pointer to shared memory block */ char *shmfilename; /* Shared memory file name, used on some systems */ apr_global_mutex_t *exipc_mutex; /* Lock around shared memory segment access */ -char *mutexfilename; /* Lock file name, used on some systems */ +static const char *exipc_mutex_type = "example-ipc-shm"; /* Data structure for shared memory block */ typedef struct exipc_data { @@ -100,6 +96,18 @@ static apr_status_t shm_cleanup_wrapper(void *unused) { return OK; } +/* + * This routine is called in the parent; we must register our + * mutex type before the config is processed so that users can + * adjust the mutex settings using the Mutex directive. + */ + +static int exipc_pre_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + ap_mutex_register(pconf, exipc_mutex_type, NULL, APR_LOCK_DEFAULT, 0); + return OK; +} /* * This routine is called in the parent, so we'll set up the shared @@ -140,8 +148,8 @@ static int exipc_post_config(apr_pool_t *pconf, apr_pool_t *plog, } /* Kilroy was here */ /* - * Both the shared memory and mutex allocation routines take a - * file name. Depending on system-specific implementation of these + * The shared memory allocation routines take a file name. + * Depending on system-specific implementation of these * routines, that file may or may not actually be created. We'd * like to store those files in the operating system's designated * temporary directory, which APR can point us to. @@ -178,39 +186,11 @@ static int exipc_post_config(apr_pool_t *pconf, apr_pool_t *plog, /* Create global mutex */ - /* - * Create another unique filename to lock upon. Note that - * depending on OS and locking mechanism of choice, the file - * may or may not be actually created. - */ - mutexfilename = apr_psprintf(pconf, "%s/httpd_mutex.%ld", tempdir, - (long int) getpid()); - - rs = apr_global_mutex_create(&exipc_mutex, (const char *) mutexfilename, - APR_LOCK_DEFAULT, pconf); - if (APR_SUCCESS != rs) { - ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, - "Failed to create mutex on file %s", - mutexfilename); - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* - * After the mutex is created, its permissions need to be adjusted - * on unix platforms so that the child processe can acquire - * it. This call takes care of that. The preprocessor define was - * set up early in this source file since Apache doesn't provide - * it. - */ -#ifdef MOD_EXIPC_SET_MUTEX_PERMS - rs = ap_unixd_set_global_mutex_perms(exipc_mutex); + rs = ap_global_mutex_create(&exipc_mutex, exipc_mutex_type, NULL, s, pconf, + 0); if (APR_SUCCESS != rs) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rs, s, - "Parent could not set permissions on Example IPC " - "mutex: check User and Group directives"); return HTTP_INTERNAL_SERVER_ERROR; } -#endif /* MOD_EXIPC_SET_MUTEX_PERMS */ /* * Destroy the shm segment when the configuration pool gets destroyed. This @@ -236,12 +216,12 @@ static void exipc_child_init(apr_pool_t *p, server_rec *s) * the mutex pointer global here. */ rs = apr_global_mutex_child_init(&exipc_mutex, - (const char *) mutexfilename, + apr_global_mutex_lockfile(exipc_mutex), p); if (APR_SUCCESS != rs) { ap_log_error(APLOG_MARK, APLOG_CRIT, rs, s, - "Failed to reopen mutex on file %s", - shmfilename); + "Failed to reopen mutex %s in child", + exipc_mutex_type); /* There's really nothing else we can do here, since This * routine doesn't return a status. If this ever goes wrong, * it will turn Apache into a fork bomb. Let's hope it never @@ -367,6 +347,7 @@ static int exipc_handler(request_rec *r) static void exipc_register_hooks(apr_pool_t *p) { + ap_hook_pre_config(exipc_pre_config, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_config(exipc_post_config, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_child_init(exipc_child_init, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_handler(exipc_handler, NULL, NULL, APR_HOOK_MIDDLE); diff --git a/modules/generators/mod_info.c b/modules/generators/mod_info.c index 273459ffdf..fdcfec3fc6 100644 --- a/modules/generators/mod_info.c +++ b/modules/generators/mod_info.c @@ -528,10 +528,6 @@ static int show_server_settings(request_rec * r) ap_rputs(" -D DEFAULT_SCOREBOARD=\"" DEFAULT_SCOREBOARD "\"\n", r); #endif -#ifdef DEFAULT_LOCKFILE - ap_rputs(" -D DEFAULT_LOCKFILE=\"" DEFAULT_LOCKFILE "\"\n", r); -#endif - #ifdef DEFAULT_ERRORLOG ap_rputs(" -D DEFAULT_ERRORLOG=\"" DEFAULT_ERRORLOG "\"\n", r); #endif diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c index 7bf7213673..8fbe808939 100644 --- a/modules/ldap/util_ldap.c +++ b/modules/ldap/util_ldap.c @@ -28,6 +28,7 @@ #include "http_log.h" #include "http_protocol.h" #include "http_request.h" +#include "util_mutex.h" #include "util_ldap.h" #include "util_ldap_cache.h" @@ -41,10 +42,6 @@ #error mod_ldap requires APR-util to have LDAP support built in #endif -#ifdef AP_NEED_SET_MUTEX_PERMS -#include "unixd.h" -#endif - /* Default define for ldap functions that need a SIZELIMIT but * do not have the define * XXX This should be removed once a supporting #define is @@ -67,6 +64,7 @@ #define AP_LDAP_CHASEREFERRALS_ON 1 module AP_MODULE_DECLARE_DATA ldap_module; +static const char *ldap_cache_lock_type = "ldap-cache"; #define LDAP_CACHE_LOCK() do { \ if (st->util_ldap_cache_lock) \ @@ -2518,6 +2516,20 @@ static apr_status_t util_ldap_cleanup_module(void *data) } +static int util_ldap_pre_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + apr_status_t result; + + result = ap_mutex_register(pconf, ldap_cache_lock_type, NULL, + APR_LOCK_DEFAULT, 0); + if (result != APR_SUCCESS) { + return result; + } + + return OK; +} + static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { @@ -2567,30 +2579,12 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, return DONE; } - -#if APR_HAS_SHARED_MEMORY - if (st->cache_file) { - st->lock_file = apr_pstrcat(st->pool, st->cache_file, ".lck", - NULL); - } -#endif - - result = apr_global_mutex_create(&st->util_ldap_cache_lock, - st->lock_file, APR_LOCK_DEFAULT, - st->pool); + result = ap_global_mutex_create(&st->util_ldap_cache_lock, + ldap_cache_lock_type, NULL, s, p, 0); if (result != APR_SUCCESS) { return result; } -#ifdef AP_NEED_SET_MUTEX_PERMS - result = ap_unixd_set_global_mutex_perms(st->util_ldap_cache_lock); - if (result != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, result, s, - "LDAP cache: failed to set mutex permissions"); - return result; - } -#endif - /* merge config in all vhost */ s_vhost = s->next; while (s_vhost) { @@ -2607,7 +2601,6 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, "for VHOST: %s", st->cache_shm, st->cache_rmm, s_vhost->server_hostname); #endif - st_vhost->lock_file = st->lock_file; s_vhost = s_vhost->next; } #if APR_HAS_SHARED_MEMORY @@ -2684,12 +2677,12 @@ static void util_ldap_child_init(apr_pool_t *p, server_rec *s) if (!st->util_ldap_cache_lock) return; sts = apr_global_mutex_child_init(&st->util_ldap_cache_lock, - st->lock_file, p); + apr_global_mutex_lockfile(st->util_ldap_cache_lock), p); if (sts != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, sts, s, "Failed to initialise global mutex %s in child process %" APR_PID_T_FMT ".", - st->lock_file, getpid()); + ldap_cache_lock_type, getpid()); } } @@ -2795,6 +2788,7 @@ static void util_ldap_register_hooks(apr_pool_t *p) APR_REGISTER_OPTIONAL_FN(uldap_ssl_supported); APR_REGISTER_OPTIONAL_FN(uldap_cache_check_subgroups); + ap_hook_pre_config(util_ldap_pre_config, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_config(util_ldap_post_config,NULL,NULL,APR_HOOK_MIDDLE); ap_hook_handler(util_ldap_handler, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_child_init(util_ldap_child_init, NULL, NULL, APR_HOOK_MIDDLE); diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index 067e7c839e..43e586625f 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -94,15 +94,12 @@ #include "http_log.h" #include "http_protocol.h" #include "http_vhost.h" +#include "util_mutex.h" #include "mod_ssl.h" #include "mod_rewrite.h" -#ifdef AP_NEED_SET_MUTEX_PERMS -#include "unixd.h" -#endif - static ap_dbd_t *(*dbd_acquire)(request_rec*) = NULL; static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL; @@ -382,8 +379,8 @@ static int proxy_available; static int rewrite_rand_init_done = 0; /* Locks/Mutexes */ -static const char *lockname; static apr_global_mutex_t *rewrite_mapr_lock_acquire = NULL; +const char *rewritemap_mutex_type = "rewrite-map"; /* Optional functions imported from mod_ssl when loaded: */ static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *rewrite_ssl_lookup = NULL; @@ -1232,7 +1229,6 @@ static apr_status_t run_rewritemap_programs(server_rec *s, apr_pool_t *p) rewrite_server_conf *conf; apr_hash_index_t *hi; apr_status_t rc; - int lock_warning_issued = 0; conf = ap_get_module_config(s->module_config, &rewrite_module); @@ -1259,13 +1255,6 @@ static apr_status_t run_rewritemap_programs(server_rec *s, apr_pool_t *p) continue; } - if (!lock_warning_issued && (!lockname || !*lockname)) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, - "mod_rewrite: Running external rewrite maps " - "without defining a RewriteLock is DANGEROUS!"); - ++lock_warning_issued; - } - rc = rewritemap_program_child(p, map->argv[0], map->argv, &fpout, &fpin); if (rc != APR_SUCCESS || fpin == NULL || fpout == NULL) { @@ -2646,45 +2635,26 @@ static apr_status_t rewritelock_create(server_rec *s, apr_pool_t *p) { apr_status_t rc; - /* only operate if a lockfile is used */ - if (lockname == NULL || *(lockname) == '\0') { - return APR_SUCCESS; - } - /* create the lockfile */ - rc = apr_global_mutex_create(&rewrite_mapr_lock_acquire, lockname, - APR_LOCK_DEFAULT, p); - if (rc != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s, - "mod_rewrite: Parent could not create RewriteLock " - "file %s", lockname); - return rc; - } - -#ifdef AP_NEED_SET_MUTEX_PERMS - rc = ap_unixd_set_global_mutex_perms(rewrite_mapr_lock_acquire); + /* XXX See if there are any rewrite map programs before creating + * the mutex. + */ + rc = ap_global_mutex_create(&rewrite_mapr_lock_acquire, + rewritemap_mutex_type, NULL, s, p, 0); if (rc != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s, - "mod_rewrite: Parent could not set permissions " - "on RewriteLock; check User and Group directives"); return rc; } -#endif return APR_SUCCESS; } static apr_status_t rewritelock_remove(void *data) { - /* only operate if a lockfile is used */ - if (lockname == NULL || *(lockname) == '\0') { - return APR_SUCCESS; - } - /* destroy the rewritelock */ - apr_global_mutex_destroy (rewrite_mapr_lock_acquire); - rewrite_mapr_lock_acquire = NULL; - lockname = NULL; + if (rewrite_mapr_lock_acquire) { + apr_global_mutex_destroy(rewrite_mapr_lock_acquire); + rewrite_mapr_lock_acquire = NULL; + } return(0); } @@ -3158,23 +3128,6 @@ static const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, const char *a1, return NULL; } -static const char *cmd_rewritelock(cmd_parms *cmd, void *dconf, const char *a1) -{ - const char *error; - - if ((error = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL) - return error; - - /* fixup the path, especially for rewritelock_remove() */ - lockname = ap_server_root_relative(cmd->pool, a1); - - if (!lockname) { - return apr_pstrcat(cmd->pool, "Invalid RewriteLock path ", a1, NULL); - } - - return NULL; -} - static const char *cmd_rewritebase(cmd_parms *cmd, void *in_dconf, const char *a1) { @@ -4279,6 +4232,8 @@ static int pre_config(apr_pool_t *pconf, { APR_OPTIONAL_FN_TYPE(ap_register_rewrite_mapfunc) *map_pfn_register; + ap_mutex_register(pconf, rewritemap_mutex_type, NULL, APR_LOCK_DEFAULT, 0); + /* register int: rewritemap handlers */ map_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_rewrite_mapfunc); if (map_pfn_register) { @@ -4348,9 +4303,9 @@ static void init_child(apr_pool_t *p, server_rec *s) { apr_status_t rv = 0; /* get a rid of gcc warning (REWRITELOG_DISABLED) */ - if (lockname != NULL && *(lockname) != '\0') { + if (rewrite_mapr_lock_acquire) { rv = apr_global_mutex_child_init(&rewrite_mapr_lock_acquire, - lockname, p); + apr_global_mutex_lockfile(rewrite_mapr_lock_acquire), p); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, "mod_rewrite: could not init rewrite_mapr_lock_acquire" @@ -5023,9 +4978,6 @@ static const command_rec command_table[] = { "an URL-applied regexp-pattern and a substitution URL"), AP_INIT_TAKE2( "RewriteMap", cmd_rewritemap, NULL, RSRC_CONF, "a mapname and a filename"), - AP_INIT_TAKE1( "RewriteLock", cmd_rewritelock, NULL, RSRC_CONF, - "the filename of a lockfile used for inter-process " - "synchronization"), #ifndef REWRITELOG_DISABLED AP_INIT_TAKE1( "RewriteLog", cmd_rewritelog, NULL, RSRC_CONF, "the filename of the rewriting logfile"), diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index af79b37710..8ec003395c 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -54,7 +54,6 @@ static const command_rec ssl_config_cmds[] = { /* * Global (main-server) context configuration directives */ - SSL_CMD_SRV(Mutex, TAKE1, AP_ALL_AVAILABLE_MUTEXES_STRING) SSL_CMD_SRV(PassPhraseDialog, TAKE1, "SSL dialog mechanism for the pass phrase query " "('builtin', '|/path/to/pipe_program', " @@ -201,7 +200,6 @@ static const command_rec ssl_config_cmds[] = { /* * OCSP Stapling options */ - SSL_CMD_SRV(StaplingMutex, TAKE1, AP_ALL_AVAILABLE_MUTEXES_STRING) SSL_CMD_SRV(StaplingCache, TAKE1, "SSL Stapling Response Cache storage " "(`dbm:/path/to/file')") @@ -313,6 +311,12 @@ static int ssl_hook_pre_config(apr_pool_t *pconf, /* Register to handle mod_status status page generation */ ssl_scache_status_register(pconf); + /* Register mutex type names so they can be configured with Mutex */ + ap_mutex_register(pconf, ssl_cache_mutex_type, NULL, APR_LOCK_DEFAULT, 0); +#ifdef HAVE_OCSP_STAPLING + ap_mutex_register(pconf, ssl_stapling_mutex_type, NULL, APR_LOCK_DEFAULT, 0); +#endif + return OK; } diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index a346ae466d..d02c38e5be 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -61,9 +61,6 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s) */ mc->sesscache_mode = SSL_SESS_CACHE_OFF; mc->sesscache = NULL; - mc->nMutexMode = SSL_MUTEXMODE_UNSET; - mc->nMutexMech = APR_LOCK_DEFAULT; - mc->szMutexFile = NULL; mc->pMutex = NULL; mc->aRandSeed = apr_array_make(pool, 4, sizeof(ssl_randseed_t)); @@ -74,11 +71,8 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s) mc->szCryptoDevice = NULL; #endif #ifdef HAVE_OCSP_STAPLING - mc->stapling_cache = NULL; - mc->stapling_mutex_mode = SSL_MUTEXMODE_UNSET; - mc->stapling_mutex_mech = APR_LOCK_DEFAULT; - mc->stapling_mutex_file = NULL; - mc->stapling_mutex = NULL; + mc->stapling_cache = NULL; + mc->stapling_mutex = NULL; #endif memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys)); @@ -383,41 +377,6 @@ void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv) * Configuration functions for particular directives */ -const char *ssl_cmd_SSLMutex(cmd_parms *cmd, - void *dcfg, - const char *arg_) -{ - apr_status_t rv; - const char *err; - SSLModConfigRec *mc = myModConfig(cmd->server); - - if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { - return err; - } - - if (ssl_config_global_isfixed(mc)) { - return NULL; - } - - rv = ap_parse_mutex(arg_, cmd->server->process->pool, - &mc->nMutexMech, &mc->szMutexFile); - - if (rv == APR_ENOLOCK) { - mc->nMutexMode = SSL_MUTEXMODE_NONE; - return NULL; - } else if (rv == APR_ENOTIMPL) { - return apr_pstrcat(cmd->pool, "Invalid SSLMutex argument ", arg_, - " (" AP_ALL_AVAILABLE_MUTEXES_STRING ")", NULL); - } else if (rv == APR_BADARG) { - return apr_pstrcat(cmd->pool, "Invalid SSLMutex filepath ", - arg_, NULL); - } - - mc->nMutexMode = SSL_MUTEXMODE_USED; - - return NULL; -} - const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd, void *dcfg, const char *arg) @@ -1546,44 +1505,6 @@ const char *ssl_cmd_SSLStaplingCache(cmd_parms *cmd, return NULL; } -const char *ssl_cmd_SSLStaplingMutex(cmd_parms *cmd, - void *dcfg, - const char *arg_) -{ - apr_status_t rv; - const char *err; - SSLModConfigRec *mc = myModConfig(cmd->server); - - if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { - return err; - } - - if (ssl_config_global_isfixed(mc)) { - return NULL; - } - - rv = ap_parse_mutex(arg_, cmd->server->process->pool, - &mc->stapling_mutex_mech, &mc->stapling_mutex_file); - - if (rv == APR_ENOLOCK) { - mc->stapling_mutex_mode = SSL_MUTEXMODE_NONE; - return NULL; - } - else if (rv == APR_ENOTIMPL) { - return apr_pstrcat(cmd->pool, "Invalid SSLStaplingMutex argument ", - arg_, - " (" AP_ALL_AVAILABLE_MUTEXES_STRING ")", NULL); - } - else if (rv == APR_BADARG) { - return apr_pstrcat(cmd->pool, "Invalid SSLStaplingMutex filepath ", - arg_, NULL); - } - - mc->stapling_mutex_mode = SSL_MUTEXMODE_USED; - - return NULL; -} - const char *ssl_cmd_SSLUseStapling(cmd_parms *cmd, void *dcfg, int flag) { SSLSrvConfigRec *sc = mySrvConfig(cmd->server); diff --git a/modules/ssl/ssl_engine_mutex.c b/modules/ssl/ssl_engine_mutex.c index 7ab416ce93..fccd97991b 100644 --- a/modules/ssl/ssl_engine_mutex.c +++ b/modules/ssl/ssl_engine_mutex.c @@ -30,10 +30,6 @@ #include "ssl_private.h" -#ifdef AP_NEED_SET_MUTEX_PERMS -#include "unixd.h" -#endif - int ssl_mutex_init(server_rec *s, apr_pool_t *p) { SSLModConfigRec *mc = myModConfig(s); @@ -50,35 +46,13 @@ int ssl_mutex_init(server_rec *s, apr_pool_t *p) if (mc->pMutex) { return TRUE; } - else if (mc->nMutexMode == SSL_MUTEXMODE_NONE) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "An SSLMutex is required for the '%s' session cache", - mc->sesscache->name); - return FALSE; - } - if ((rv = apr_global_mutex_create(&mc->pMutex, mc->szMutexFile, - mc->nMutexMech, s->process->pool)) + if ((rv = ap_global_mutex_create(&mc->pMutex, ssl_cache_mutex_type, NULL, + s, s->process->pool, 0)) != APR_SUCCESS) { - if (mc->szMutexFile) - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "Cannot create SSLMutex with file `%s'", - mc->szMutexFile); - else - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "Cannot create SSLMutex"); return FALSE; } -#ifdef AP_NEED_SET_MUTEX_PERMS - rv = ap_unixd_set_global_mutex_perms(mc->pMutex); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "Could not set permissions on ssl_mutex; check User " - "and Group directives"); - return FALSE; - } -#endif return TRUE; } @@ -86,21 +60,24 @@ int ssl_mutex_reinit(server_rec *s, apr_pool_t *p) { SSLModConfigRec *mc = myModConfig(s); apr_status_t rv; + const char *lockfile; - if (mc->nMutexMode == SSL_MUTEXMODE_NONE || !mc->sesscache + if (mc->pMutex == NULL || !mc->sesscache || (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) == 0) { return TRUE; } + lockfile = apr_global_mutex_lockfile(mc->pMutex); if ((rv = apr_global_mutex_child_init(&mc->pMutex, - mc->szMutexFile, p)) != APR_SUCCESS) { - if (mc->szMutexFile) + lockfile, + p)) != APR_SUCCESS) { + if (lockfile) ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "Cannot reinit SSLMutex with file `%s'", - mc->szMutexFile); + "Cannot reinit %s mutex with file `%s'", + ssl_cache_mutex_type, lockfile); else ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, - "Cannot reinit SSLMutex"); + "Cannot reinit %s mutex", ssl_cache_mutex_type); return FALSE; } return TRUE; diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index cf9b9278e5..0bea8508e1 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -39,6 +39,7 @@ #include "util_script.h" #include "util_filter.h" #include "util_ebcdic.h" +#include "util_mutex.h" #include "apr.h" #include "apr_strings.h" #define APR_WANT_STRFUNC @@ -267,15 +268,6 @@ typedef enum { typedef unsigned int ssl_pathcheck_t; /** - * Define the SSL mutex modes - */ -typedef enum { - SSL_MUTEXMODE_UNSET = UNSET, - SSL_MUTEXMODE_NONE = 0, - SSL_MUTEXMODE_USED = 1 -} ssl_mutexmode_t; - -/** * Define the SSL enabled state */ typedef enum { @@ -403,9 +395,6 @@ typedef struct { const ap_socache_provider_t *sesscache; ap_socache_instance_t *sesscache_context; - ssl_mutexmode_t nMutexMode; - apr_lockmech_e nMutexMech; - const char *szMutexFile; apr_global_mutex_t *pMutex; apr_array_header_t *aRandSeed; apr_hash_t *tVHostKeys; @@ -419,9 +408,6 @@ typedef struct { #ifdef HAVE_OCSP_STAPLING const ap_socache_provider_t *stapling_cache; ap_socache_instance_t *stapling_cache_context; - ssl_mutexmode_t stapling_mutex_mode; - apr_lockmech_e stapling_mutex_mech; - const char *stapling_mutex_file; apr_global_mutex_t *stapling_mutex; #endif @@ -566,7 +552,6 @@ void *ssl_config_server_create(apr_pool_t *, server_rec *); void *ssl_config_server_merge(apr_pool_t *, void *, void *); void *ssl_config_perdir_create(apr_pool_t *, char *); void *ssl_config_perdir_merge(apr_pool_t *, void *, void *); -const char *ssl_cmd_SSLMutex(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *); @@ -666,7 +651,6 @@ int ssl_engine_disable(conn_rec *c); /** OCSP Stapling Support */ #ifdef HAVE_OCSP_STAPLING -const char *ssl_cmd_SSLStaplingMutex(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLStaplingCache(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLUseStapling(cmd_parms *, void *, int); const char *ssl_cmd_SSLStaplingResponseTimeSkew(cmd_parms *, void *, const char *); @@ -741,6 +725,10 @@ int ssl_mutex_off(server_rec *); int ssl_stapling_mutex_init(server_rec *, apr_pool_t *); int ssl_stapling_mutex_reinit(server_rec *, apr_pool_t *); +/* mutex type names for Mutex directive */ +#define ssl_cache_mutex_type "ssl-cache" +#define ssl_stapling_mutex_type "ssl-stapling" + /** Logfile Support */ void ssl_die(void); void ssl_log_ssl_error(const char *, int, int, server_rec *); diff --git a/modules/ssl/ssl_util_stapling.c b/modules/ssl/ssl_util_stapling.c index fccd532ec7..5e20614aa4 100644 --- a/modules/ssl/ssl_util_stapling.c +++ b/modules/ssl/ssl_util_stapling.c @@ -32,10 +32,6 @@ #include "ap_mpm.h" #include "apr_thread_mutex.h" -#ifdef AP_NEED_SET_MUTEX_PERMS -#include "unixd.h" -#endif - #ifdef HAVE_OCSP_STAPLING /** @@ -480,36 +476,13 @@ int ssl_stapling_mutex_init(server_rec *s, apr_pool_t *p) if (mc->stapling_mutex || sc->server->stapling_enabled != TRUE) { return TRUE; } - if (mc->stapling_mutex_mode == SSL_MUTEXMODE_NONE - || mc->stapling_mutex_mode == SSL_MUTEXMODE_UNSET) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "An SSLStaplingMutex is required for OCSP Stapling"); - return FALSE; - } - if ((rv = apr_global_mutex_create(&mc->stapling_mutex, - mc->stapling_mutex_file, - mc->stapling_mutex_mech, s->process->pool)) - != APR_SUCCESS) { - if (mc->stapling_mutex_file) - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "Cannot create SSLStaplingMutex with file `%s'", - mc->stapling_mutex_file); - else - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "Cannot create SSLStaplingMutex"); + if ((rv = ap_global_mutex_create(&mc->stapling_mutex, + ssl_stapling_mutex_type, NULL, s, + s->process->pool, 0)) != APR_SUCCESS) { return FALSE; } -#ifdef AP_NEED_SET_MUTEX_PERMS - rv = ap_unixd_set_global_mutex_perms(mc->stapling_mutex); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "Could not set permissions on ssl_mutex; check User " - "and Group directives"); - return FALSE; - } -#endif return TRUE; } @@ -517,21 +490,23 @@ int ssl_stapling_mutex_reinit(server_rec *s, apr_pool_t *p) { SSLModConfigRec *mc = myModConfig(s); apr_status_t rv; + const char *lockfile; if (mc->stapling_mutex == NULL) { return TRUE; } + lockfile = apr_global_mutex_lockfile(mc->stapling_mutex); if ((rv = apr_global_mutex_child_init(&mc->stapling_mutex, - mc->stapling_mutex_file, p)) != APR_SUCCESS) { - if (mc->stapling_mutex_file) { + lockfile, p)) != APR_SUCCESS) { + if (lockfile) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "Cannot reinit SSLMutex with file `%s'", - mc->szMutexFile); + "Cannot reinit %s mutex with file `%s'", + ssl_stapling_mutex_type, lockfile); } else { ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, - "Cannot reinit SSLMutex"); + "Cannot reinit %s mutex", ssl_stapling_mutex_type); } return FALSE; } diff --git a/server/core.c b/server/core.c index 0fdab6c356..cac5b4f373 100644 --- a/server/core.c +++ b/server/core.c @@ -3319,6 +3319,8 @@ AP_INIT_TAKE1("LimitRequestBody", set_limit_req_body, AP_INIT_TAKE1("LimitXMLRequestBody", set_limit_xml_req_body, NULL, OR_ALL, "Limit (in bytes) on maximum size of an XML-based request " "body"), +AP_INIT_TAKE2("Mutex", ap_set_mutex, NULL, RSRC_CONF, + "mutex (or \"default\") and mechanism"), /* System Resource Controls */ #ifdef RLIMIT_CPU @@ -3378,14 +3380,10 @@ AP_INIT_TAKE1("PidFile", ap_mpm_set_pidfile, NULL, RSRC_CONF, "A file for logging the server process ID"), AP_INIT_TAKE1("ScoreBoardFile", ap_mpm_set_scoreboard, NULL, RSRC_CONF, "A file for Apache to maintain runtime process management information"), -AP_INIT_TAKE1("LockFile", ap_mpm_set_lockfile, NULL, RSRC_CONF, - "The lockfile used when Apache needs to lock the accept() call (deprecated)"), AP_INIT_TAKE1("MaxRequestsPerChild", ap_mpm_set_max_requests, NULL, RSRC_CONF, "Maximum number of requests a particular child serves before dying."), AP_INIT_TAKE1("CoreDumpDirectory", ap_mpm_set_coredumpdir, NULL, RSRC_CONF, "The location of the directory Apache changes to before dumping core"), -AP_INIT_TAKE1("AcceptMutex", ap_mpm_set_accept_lock_mech, NULL, RSRC_CONF, - AP_AVAILABLE_MUTEXES_STRING), AP_INIT_TAKE1("MaxMemFree", ap_mpm_set_max_mem_free, NULL, RSRC_CONF, "Maximum number of 1k blocks a particular childs allocator may hold."), AP_INIT_TAKE1("ThreadStackSize", ap_mpm_set_thread_stacksize, NULL, RSRC_CONF, diff --git a/server/main.c b/server/main.c index a3cfe7ed5b..8888a36cf5 100644 --- a/server/main.c +++ b/server/main.c @@ -237,10 +237,6 @@ static void show_compile_settings(void) printf(" -D DEFAULT_SCOREBOARD=\"" DEFAULT_SCOREBOARD "\"\n"); #endif -#ifdef DEFAULT_LOCKFILE - printf(" -D DEFAULT_LOCKFILE=\"" DEFAULT_LOCKFILE "\"\n"); -#endif - #ifdef DEFAULT_ERRORLOG printf(" -D DEFAULT_ERRORLOG=\"" DEFAULT_ERRORLOG "\"\n"); #endif diff --git a/server/mpm/prefork/mpm_default.h b/server/mpm/prefork/mpm_default.h index d548a7ec53..36e72a7a94 100644 --- a/server/mpm/prefork/mpm_default.h +++ b/server/mpm/prefork/mpm_default.h @@ -46,11 +46,6 @@ #define DEFAULT_MIN_FREE_DAEMON 5 #endif -/* File used for accept locking, when we use a file */ -#ifndef DEFAULT_LOCKFILE -#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" -#endif - /* Where the main/parent process's pid is logged */ #ifndef DEFAULT_PIDLOG #define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index 91d8ae81bb..c1e0c1412f 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -41,6 +41,7 @@ #include "http_connection.h" #include "scoreboard.h" #include "ap_mpm.h" +#include "util_mutex.h" #include "unixd.h" #include "mpm_common.h" #include "ap_listen.h" @@ -457,6 +458,7 @@ static void child_main(int child_num_arg) ap_sb_handle_t *sbh; apr_bucket_alloc_t *bucket_alloc; int last_poll_idx = 0; + const char *lockfile; mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this * child initializes @@ -487,11 +489,16 @@ static void child_main(int child_num_arg) /* needs to be done before we switch UIDs so we have permissions */ ap_reopen_scoreboard(pchild, NULL, 0); - status = apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, pchild); + lockfile = apr_proc_mutex_lockfile(accept_mutex); + status = apr_proc_mutex_child_init(&accept_mutex, + lockfile, + pchild); if (status != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, "Couldn't initialize cross-process lock in child " - "(%s) (%d)", ap_lock_fname, ap_accept_lock_mech); + "(%s) (%s)", + lockfile ? lockfile : "none", + apr_proc_mutex_name(accept_mutex)); clean_child_exit(APEXIT_CHILDFATAL); } @@ -908,36 +915,13 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) ap_log_pid(pconf, ap_pid_fname); /* Initialize cross-process accept lock */ - ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT, - ap_server_root_relative(_pconf, ap_lock_fname), - ap_my_pid); - - rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, - ap_accept_lock_mech, _pconf); + rv = ap_proc_mutex_create(&accept_mutex, ap_accept_mutex_type, NULL, s, + _pconf, 0); if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't create accept lock (%s) (%d)", - ap_lock_fname, ap_accept_lock_mech); mpm_state = AP_MPMQ_STOPPING; return DONE; } -#if APR_USE_SYSVSEM_SERIALIZE - if (ap_accept_lock_mech == APR_LOCK_DEFAULT || - ap_accept_lock_mech == APR_LOCK_SYSVSEM) { -#else - if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { -#endif - rv = ap_unixd_set_proc_mutex_perms(accept_mutex); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't set permissions on cross-process lock; " - "check User and Group directives"); - mpm_state = AP_MPMQ_STOPPING; - return DONE; - } - } - if (!is_graceful) { if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { mpm_state = AP_MPMQ_STOPPING; @@ -988,7 +972,7 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, "Server built: %s", ap_get_server_built()); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "AcceptMutex: %s (default: %s)", + "Accept mutex: %s (default: %s)", apr_proc_mutex_name(accept_mutex), apr_proc_mutex_defname()); restart_pending = shutdown_pending = 0; @@ -1284,6 +1268,8 @@ static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp foreground = ap_exists_config_define("FOREGROUND"); } + ap_mutex_register(p, ap_accept_mutex_type, NULL, APR_LOCK_DEFAULT, 0); + /* sigh, want this only the second time around */ retained = ap_retained_data_get(userdata_key); if (!retained) { @@ -1313,7 +1299,6 @@ static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp server_limit = DEFAULT_SERVER_LIMIT; ap_daemons_limit = server_limit; ap_pid_fname = DEFAULT_PIDLOG; - ap_lock_fname = DEFAULT_LOCKFILE; ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; ap_extended_status = 0; ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; diff --git a/server/mpm/worker/mpm_default.h b/server/mpm/worker/mpm_default.h index a48f6725de..422d59a158 100644 --- a/server/mpm/worker/mpm_default.h +++ b/server/mpm/worker/mpm_default.h @@ -50,11 +50,6 @@ #define DEFAULT_THREADS_PER_CHILD 25 #endif -/* File used for accept locking, when we use a file */ -#ifndef DEFAULT_LOCKFILE -#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" -#endif - /* Where the main/parent process's pid is logged */ #ifndef DEFAULT_PIDLOG #define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index aa397475a1..296a75fbcd 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -64,6 +64,7 @@ #include "scoreboard.h" #include "fdqueue.h" #include "mpm_default.h" +#include "util_mutex.h" #include "unixd.h" #include <signal.h> @@ -1172,7 +1173,8 @@ static void child_main(int child_num_arg) /*stuff to do before we switch id's, so we have permissions.*/ ap_reopen_scoreboard(pchild, NULL, 0); - rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, + rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&accept_mutex, + apr_proc_mutex_lockfile(accept_mutex), pchild)); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, @@ -1692,35 +1694,13 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) ap_log_pid(pconf, ap_pid_fname); /* Initialize cross-process accept lock */ - ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT, - ap_server_root_relative(_pconf, ap_lock_fname), - ap_my_pid); - - rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, - ap_accept_lock_mech, _pconf); + rv = ap_proc_mutex_create(&accept_mutex, ap_accept_mutex_type, NULL, s, + _pconf, 0); if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't create accept lock"); mpm_state = AP_MPMQ_STOPPING; return DONE; } -#if APR_USE_SYSVSEM_SERIALIZE - if (ap_accept_lock_mech == APR_LOCK_DEFAULT || - ap_accept_lock_mech == APR_LOCK_SYSVSEM) { -#else - if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { -#endif - rv = ap_unixd_set_proc_mutex_perms(accept_mutex); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't set permissions on cross-process lock; " - "check User and Group directives"); - mpm_state = AP_MPMQ_STOPPING; - return DONE; - } - } - if (!is_graceful) { if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { mpm_state = AP_MPMQ_STOPPING; @@ -1766,7 +1746,7 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, "Server built: %s", ap_get_server_built()); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "AcceptMutex: %s (default: %s)", + "Accept mutex: %s (default: %s)", apr_proc_mutex_name(accept_mutex), apr_proc_mutex_defname()); restart_pending = shutdown_pending = 0; @@ -1957,6 +1937,8 @@ static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog, foreground = ap_exists_config_define("FOREGROUND"); } + ap_mutex_register(pconf, ap_accept_mutex_type, NULL, APR_LOCK_DEFAULT, 0); + /* sigh, want this only the second time around */ retained = ap_retained_data_get(userdata_key); if (!retained) { @@ -1988,7 +1970,6 @@ static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog, threads_per_child = DEFAULT_THREADS_PER_CHILD; max_clients = ap_daemons_limit * threads_per_child; ap_pid_fname = DEFAULT_PIDLOG; - ap_lock_fname = DEFAULT_LOCKFILE; ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; ap_extended_status = 0; ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; diff --git a/server/mpm_common.c b/server/mpm_common.c index ca8d8e54d9..005e90936b 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -253,20 +253,6 @@ const char * ap_mpm_set_scoreboard(cmd_parms *cmd, void *dummy, return NULL; } -const char *ap_lock_fname = NULL; - -const char *ap_mpm_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; - } - - ap_lock_fname = arg; - return NULL; -} - int ap_max_requests_per_child = 0; const char *ap_mpm_set_max_requests(cmd_parms *cmd, void *dummy, @@ -327,35 +313,6 @@ const char * ap_mpm_set_graceful_shutdown(cmd_parms *cmd, void *dummy, return NULL; } -apr_lockmech_e ap_accept_lock_mech = APR_LOCK_DEFAULT; - -const char *ap_mpm_set_accept_lock_mech(cmd_parms *cmd, - void *dummy, - const char *arg) -{ - apr_status_t rv; - const char *lockfile; - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - rv = ap_parse_mutex(arg, cmd->server->process->pool, - &ap_accept_lock_mech, &lockfile); - - if ((rv == APR_ENOTIMPL) || (rv == APR_ENOLOCK)) { - return apr_pstrcat(cmd->pool, "Invalid AcceptMutex argument ", arg, - " (" AP_AVAILABLE_MUTEXES_STRING ")", NULL); - } else if (rv == APR_BADARG) { - return apr_pstrcat(cmd->pool, "Invalid AcceptMutex filepath ", - arg, NULL); - } - - if (lockfile && !ap_lock_fname) - ap_lock_fname = lockfile; - return NULL; -} - apr_uint32_t ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; const char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy, diff --git a/server/util_mutex.c b/server/util_mutex.c index eb24f757d0..29d554a035 100644 --- a/server/util_mutex.c +++ b/server/util_mutex.c @@ -21,6 +21,7 @@ #include "apr.h" +#include "apr_hash.h" #include "apr_strings.h" #include "apr_lib.h" @@ -31,7 +32,12 @@ #include "httpd.h" #include "http_main.h" #include "http_config.h" +#include "http_log.h" #include "util_mutex.h" +#include "unixd.h" +#ifdef HAVE_UNISTD_H +#include <unistd.h> /* getpid() */ +#endif AP_DECLARE(apr_status_t) ap_parse_mutex(const char *arg, apr_pool_t *pool, apr_lockmech_e *mutexmech, @@ -47,16 +53,16 @@ AP_DECLARE(apr_status_t) ap_parse_mutex(const char *arg, apr_pool_t *pool, } } - if (!strcasecmp(meth, "none") || !strcasecmp(meth, "no")) { - return APR_ENOLOCK; - } - /* APR determines temporary filename unless overridden below, * we presume file indicates an mutexfile is a file path * unless the method sets mutexfile=file and NULLs file */ *mutexfile = NULL; + if (!strcasecmp(meth, "none") || !strcasecmp(meth, "no")) { + return APR_ENOLOCK; + } + /* NOTE: previously, 'yes' implied 'sem' */ if (!strcasecmp(meth, "default") || !strcasecmp(meth, "yes")) { *mutexmech = APR_LOCK_DEFAULT; @@ -112,3 +118,330 @@ AP_DECLARE(apr_status_t) ap_parse_mutex(const char *arg, apr_pool_t *pool, return APR_SUCCESS; } + +typedef struct { + apr_int32_t options; + int set; + int none; + apr_lockmech_e mech; + const char *dir; +} mutex_cfg_t; + +/* hash is created the first time a module calls ap_mutex_register(), + * rather than attempting to be the REALLY_REALLY_FIRST pre-config + * hook; it is cleaned up when the associated pool goes away; assume + * pconf is the pool passed to ap_mutex_register() + */ +static apr_hash_t *mxcfg_by_type; + +static apr_status_t cleanup_mx_hash(void *dummy) +{ + mxcfg_by_type = NULL; + return APR_SUCCESS; +} + +static void mx_hash_init(apr_pool_t *p) +{ + mutex_cfg_t *def; + + if (mxcfg_by_type) { + return; + } + + mxcfg_by_type = apr_hash_make(p); + apr_pool_cleanup_register(p, NULL, cleanup_mx_hash, apr_pool_cleanup_null); + + /* initialize default mutex configuration */ + def = apr_pcalloc(p, sizeof *def); + def->mech = APR_LOCK_DEFAULT; + def->dir = DEFAULT_REL_RUNTIMEDIR; + apr_hash_set(mxcfg_by_type, "default", APR_HASH_KEY_STRING, def); +} + +AP_DECLARE(const char *) ap_set_mutex(cmd_parms *cmd, void *dummy, + const char *type, const char *mechdir) +{ + apr_pool_t *p = cmd->pool; + apr_lockmech_e mech; + apr_status_t rv; + const char *mutexdir; + mutex_cfg_t *mxcfg = apr_hash_get(mxcfg_by_type, type, + APR_HASH_KEY_STRING); + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + + if (!mxcfg) { + return apr_psprintf(p, "Mutex type %s is not valid", type); + } + + mxcfg->none = 0; /* in case that was the default */ + + rv = ap_parse_mutex(mechdir, p, &mech, &mutexdir); + if (rv == APR_ENOTIMPL) { + return apr_pstrcat(p, "Invalid Mutex argument ", mechdir, + " (" AP_ALL_AVAILABLE_MUTEXES_STRING ")", NULL); + } + else if (rv == APR_BADARG + || (mutexdir && !ap_is_directory(p, mutexdir))) { + return apr_pstrcat(p, "Invalid Mutex directory in argument ", + mechdir, NULL); + } + + mxcfg->set = 1; + if (rv == APR_ENOLOCK) { /* "none" */ + if (!(mxcfg->options & AP_MUTEX_ALLOW_NONE)) { + return apr_psprintf(p, + "None is not allowed for mutex type %s", + type); + } + mxcfg->none = 1; + } + else { + mxcfg->mech = mech; + if (mutexdir) { /* retain mutex default if not configured */ + mxcfg->dir = mutexdir; + } + } + + return NULL; +} + +AP_DECLARE(apr_status_t) ap_mutex_register(apr_pool_t *pconf, + const char *type, + const char *default_dir, + apr_lockmech_e default_mech, + apr_int32_t options) +{ + mutex_cfg_t *mxcfg = apr_pcalloc(pconf, sizeof *mxcfg); + + if ((options & ~(AP_MUTEX_ALLOW_NONE | AP_MUTEX_DEFAULT_NONE))) { + return APR_EINVAL; + } + + mx_hash_init(pconf); + + mxcfg->options = options; + if (options & AP_MUTEX_DEFAULT_NONE) { + mxcfg->none = 1; + } + mxcfg->dir = default_dir; /* usually NULL */ + mxcfg->mech = default_mech; /* usually APR_LOCK_DEFAULT */ + apr_hash_set(mxcfg_by_type, type, APR_HASH_KEY_STRING, mxcfg); + + return APR_SUCCESS; +} + +static int mutex_needs_file(apr_lockmech_e mech) +{ + if (mech != APR_LOCK_FLOCK + && mech != APR_LOCK_FCNTL +#if APR_USE_FLOCK_SERIALIZE || APR_USE_FCNTL_SERIALIZE + && mech != APR_LOCK_DEFAULT +#endif + ) { + return 0; + } + return 1; +} + +static const char *get_mutex_filename(apr_pool_t *p, mutex_cfg_t *mxcfg, + const char *type, + const char *instance_id) +{ + const char *pid_suffix = ""; + + if (!mutex_needs_file(mxcfg->mech)) { + return NULL; + } + +#if HAVE_UNISTD_H + pid_suffix = apr_psprintf(p, ".%" APR_PID_T_FMT, getpid()); +#endif + + return ap_server_root_relative(p, + apr_pstrcat(p, + mxcfg->dir, + "/", + type, + instance_id ? "-" : "", + instance_id ? instance_id : "", + pid_suffix, + NULL)); +} + +static mutex_cfg_t *mxcfg_lookup(apr_pool_t *p, const char *type) +{ + mutex_cfg_t *defcfg, *mxcfg, *newcfg; + + defcfg = apr_hash_get(mxcfg_by_type, "default", APR_HASH_KEY_STRING); + + /* MUST exist in table, or wasn't registered */ + mxcfg = apr_hash_get(mxcfg_by_type, type, APR_HASH_KEY_STRING); + if (!mxcfg) { + return NULL; + } + + /* order of precedence: + * 1. Mutex directive for this mutex + * 2. Mutex directive for "default" + * 3. Defaults for this mutex from ap_mutex_register() + * 4. Global defaults + */ + + if (mxcfg->set) { + newcfg = mxcfg; + } + else if (defcfg->set) { + newcfg = defcfg; + } + else if (mxcfg->none || mxcfg->mech != APR_LOCK_DEFAULT) { + newcfg = mxcfg; + } + else { + newcfg = defcfg; + } + + if (!newcfg->none && mutex_needs_file(newcfg->mech) && !newcfg->dir) { + /* a file-based mutex mechanism was configured, but + * without a mutex file directory; go back through + * the chain to find the directory, store in new + * mutex cfg structure + */ + newcfg = apr_pmemdup(p, newcfg, sizeof *newcfg); + + /* !true if dir not already set: mxcfg->set && defcfg->dir */ + if (defcfg->set && defcfg->dir) { + newcfg->dir = defcfg->dir; + } + else if (mxcfg->dir) { + newcfg->dir = mxcfg->dir; + } + else { + newcfg->dir = defcfg->dir; + } + } + + return newcfg; +} + +static void log_bad_create_options(server_rec *s, const char *type) +{ + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, + "Invalid options were specified when creating the %s mutex", + type); +} + +static void log_unknown_type(server_rec *s, const char *type) +{ + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, + "Can't create mutex of unknown type %s", type); +} + +static void log_create_failure(apr_status_t rv, server_rec *s, const char *type, + const char *fname) +{ + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't create the %s mutex %s%s%s", type, + fname ? "(file " : "", + fname ? fname : "", + fname ? ")" : ""); +} + +static void log_perms_failure(apr_status_t rv, server_rec *s, const char *type) +{ + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't set permissions on the %s mutex; " + "check User and Group directives", + type); +} + +AP_DECLARE(apr_status_t) ap_global_mutex_create(apr_global_mutex_t **mutex, + const char *type, + const char *instance_id, + server_rec *s, apr_pool_t *p, + apr_int32_t options) +{ + apr_status_t rv; + const char *fname; + mutex_cfg_t *mxcfg = mxcfg_lookup(p, type); + + if (options) { + log_bad_create_options(s, type); + return APR_EINVAL; + } + + if (!mxcfg) { + log_unknown_type(s, type); + return APR_EINVAL; + } + + if (mxcfg->none) { + *mutex = NULL; + return APR_SUCCESS; + } + + fname = get_mutex_filename(p, mxcfg, type, instance_id); + + rv = apr_global_mutex_create(mutex, fname, mxcfg->mech, p); + if (rv != APR_SUCCESS) { + log_create_failure(rv, s, type, fname); + return rv; + } + +#ifdef AP_NEED_SET_MUTEX_PERMS + rv = ap_unixd_set_global_mutex_perms(*mutex); + if (rv != APR_SUCCESS) { + log_perms_failure(rv, s, type); + return rv; + } +#endif + + return APR_SUCCESS; +} + +AP_DECLARE(apr_status_t) ap_proc_mutex_create(apr_proc_mutex_t **mutex, + const char *type, + const char *instance_id, + server_rec *s, apr_pool_t *p, + apr_int32_t options) +{ + apr_status_t rv; + const char *fname; + mutex_cfg_t *mxcfg = mxcfg_lookup(p, type); + + if (options) { + log_bad_create_options(s, type); + return APR_EINVAL; + } + + if (!mxcfg) { + log_unknown_type(s, type); + return APR_EINVAL; + } + + if (mxcfg->none) { + *mutex = NULL; + return APR_SUCCESS; + } + + fname = get_mutex_filename(p, mxcfg, type, instance_id); + + rv = apr_proc_mutex_create(mutex, fname, mxcfg->mech, p); + if (rv != APR_SUCCESS) { + log_create_failure(rv, s, type, fname); + return rv; + } + +#ifdef AP_NEED_SET_MUTEX_PERMS + rv = ap_unixd_set_proc_mutex_perms(*mutex); + if (rv != APR_SUCCESS) { + log_perms_failure(rv, s, type); + return rv; + } +#endif + + return APR_SUCCESS; +} diff --git a/test/make_sni.sh b/test/make_sni.sh index 6d1288acf5..c12ad31cda 100644 --- a/test/make_sni.sh +++ b/test/make_sni.sh @@ -209,8 +209,8 @@ SSLSessionCache none # Note that this SSL configuration is far # from complete - you propably will want -# to configure SSLMutex-es and SSLSession -# Caches at the very least. +# to configure SSLSession Caches at the +# very least. <Directory /> Options None |