From 356184055f4a12ef82280ba481830f3b9574adfb Mon Sep 17 00:00:00 2001 From: Aaron Bannert Date: Fri, 15 Feb 2002 20:48:19 +0000 Subject: [PATCH] Implement new ScoreBoardFile directive logic. This affects how we create the scoreboard's shared memory segment. We now have the best of both worlds: if config specifies ScoreBoardFile create name-based shared memory, errors are fatal else /* we get to choose */ create anonymous shared memory if ENOTIMPL create name-based shared memory from DEFAULT_SCOREBOARD else errors are fatal This gives us the flexibility to have anonymous shared memory (on platforms that support it) as well as name-based shared memory when third-party programs want access to our scoreboard. The ap_scoreboard_fname static variable is now owned by the scoreboard.c file, and no longer by the MPMs. The MPMs MUST NOT set ap_scoreboard_fname to a default, since that will override the default creation logic and only allow name-based segments. Submitted by: Aaron Bannert Reviewed by: Justin Erenkrantz git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93434 13f79535-47bb-0310-9956-ffa450edef68 --- include/scoreboard.h | 6 ++ server/mpm/beos/beos.c | 3 - server/mpm/beos/mpm_default.h | 5 -- .../mpm/experimental/perchild/mpm_default.h | 5 -- server/mpm/experimental/perchild/perchild.c | 1 - server/mpm/netware/mpm_default.h | 5 -- server/mpm/netware/mpm_netware.c | 1 - server/mpm/perchild/mpm_default.h | 5 -- server/mpm/perchild/perchild.c | 1 - server/mpm/prefork/mpm_default.h | 5 -- server/mpm/prefork/prefork.c | 1 - server/mpm/worker/mpm_default.h | 5 -- server/mpm/worker/worker.c | 1 - server/scoreboard.c | 70 ++++++++++++------- 14 files changed, 52 insertions(+), 62 deletions(-) diff --git a/include/scoreboard.h b/include/scoreboard.h index a58dd72e7a..6001caf078 100644 --- a/include/scoreboard.h +++ b/include/scoreboard.h @@ -58,6 +58,7 @@ #ifndef APACHE_SCOREBOARD_H #define APACHE_SCOREBOARD_H + #ifdef __cplusplus extern "C" { #endif @@ -75,6 +76,11 @@ extern "C" { #include "apr_portable.h" #include "apr_shm.h" +/* Scoreboard file, if there is one */ +#ifndef DEFAULT_SCOREBOARD +#define DEFAULT_SCOREBOARD "logs/apache_runtime_status" +#endif + /* Scoreboard info on a process is, for now, kept very brief --- * just status value and pid (the latter so that the caretaker process * can properly update the scoreboard when a process dies). We may want diff --git a/server/mpm/beos/beos.c b/server/mpm/beos/beos.c index d9fc492ff5..c58a5786f4 100644 --- a/server/mpm/beos/beos.c +++ b/server/mpm/beos/beos.c @@ -762,8 +762,6 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) pconf = _pconf; ap_server_conf = s; - ap_scoreboard_fname = DEFAULT_SCOREBOARD; - /* Increase the available pool of fd's. This code from * Joe Kloss */ @@ -1032,7 +1030,6 @@ static int beos_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptem ap_thread_limit = HARD_THREAD_LIMIT; ap_pid_fname = DEFAULT_PIDLOG; ap_max_requests_per_thread = DEFAULT_MAX_REQUESTS_PER_THREAD; - ap_scoreboard_fname = DEFAULT_SCOREBOARD; apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); diff --git a/server/mpm/beos/mpm_default.h b/server/mpm/beos/mpm_default.h index 043f77f691..42e7c27b4b 100644 --- a/server/mpm/beos/mpm_default.h +++ b/server/mpm/beos/mpm_default.h @@ -101,11 +101,6 @@ #define DEFAULT_PIDLOG "logs/httpd.pid" #endif -/* Scoreboard file, if there is one */ -#ifndef DEFAULT_SCOREBOARD -#define DEFAULT_SCOREBOARD "logs/apache_runtime_status" -#endif - /* * Interval, in microseconds, between scoreboard maintenance. */ diff --git a/server/mpm/experimental/perchild/mpm_default.h b/server/mpm/experimental/perchild/mpm_default.h index 46fb097701..065040e63d 100644 --- a/server/mpm/experimental/perchild/mpm_default.h +++ b/server/mpm/experimental/perchild/mpm_default.h @@ -91,11 +91,6 @@ #define DEFAULT_LOCKFILE "logs/accept.lock" #endif -/* Scoreboard file, if there is one */ -#ifndef DEFAULT_SCOREBOARD -#define DEFAULT_SCOREBOARD "logs/apache_runtime_status" -#endif - /* Where the main/parent process's pid is logged */ #ifndef DEFAULT_PIDLOG #define DEFAULT_PIDLOG "logs/httpd.pid" diff --git a/server/mpm/experimental/perchild/perchild.c b/server/mpm/experimental/perchild/perchild.c index 225b27332c..1ea2675b4f 100644 --- a/server/mpm/experimental/perchild/perchild.c +++ b/server/mpm/experimental/perchild/perchild.c @@ -1493,7 +1493,6 @@ static int perchild_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptem max_spare_threads = DEFAULT_MAX_SPARE_THREAD; max_threads = thread_limit; ap_pid_fname = DEFAULT_PIDLOG; - ap_scoreboard_fname = DEFAULT_SCOREBOARD; ap_lock_fname = DEFAULT_LOCKFILE; max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; curr_child_num = 0; diff --git a/server/mpm/netware/mpm_default.h b/server/mpm/netware/mpm_default.h index 8be5919321..ebada94fd8 100644 --- a/server/mpm/netware/mpm_default.h +++ b/server/mpm/netware/mpm_default.h @@ -122,11 +122,6 @@ #endif */ -/* Scoreboard file, if there is one */ -#ifndef DEFAULT_SCOREBOARD -#define DEFAULT_SCOREBOARD "logs/apache_runtime_status" -#endif - /* Where the main/parent process's pid is logged */ /*#ifndef DEFAULT_PIDLOG #define DEFAULT_PIDLOG "logs/httpd.pid" diff --git a/server/mpm/netware/mpm_netware.c b/server/mpm/netware/mpm_netware.c index 7ef5f3e7b0..31e7a5e64e 100644 --- a/server/mpm/netware/mpm_netware.c +++ b/server/mpm/netware/mpm_netware.c @@ -971,7 +971,6 @@ static int netware_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp ap_threads_min_free = DEFAULT_MIN_FREE_THREADS; ap_threads_max_free = DEFAULT_MAX_FREE_THREADS; ap_threads_limit = HARD_THREAD_LIMIT; - ap_scoreboard_fname = DEFAULT_SCOREBOARD; ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; ap_extended_status = 0; diff --git a/server/mpm/perchild/mpm_default.h b/server/mpm/perchild/mpm_default.h index 46fb097701..065040e63d 100644 --- a/server/mpm/perchild/mpm_default.h +++ b/server/mpm/perchild/mpm_default.h @@ -91,11 +91,6 @@ #define DEFAULT_LOCKFILE "logs/accept.lock" #endif -/* Scoreboard file, if there is one */ -#ifndef DEFAULT_SCOREBOARD -#define DEFAULT_SCOREBOARD "logs/apache_runtime_status" -#endif - /* Where the main/parent process's pid is logged */ #ifndef DEFAULT_PIDLOG #define DEFAULT_PIDLOG "logs/httpd.pid" diff --git a/server/mpm/perchild/perchild.c b/server/mpm/perchild/perchild.c index 225b27332c..1ea2675b4f 100644 --- a/server/mpm/perchild/perchild.c +++ b/server/mpm/perchild/perchild.c @@ -1493,7 +1493,6 @@ static int perchild_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptem max_spare_threads = DEFAULT_MAX_SPARE_THREAD; max_threads = thread_limit; ap_pid_fname = DEFAULT_PIDLOG; - ap_scoreboard_fname = DEFAULT_SCOREBOARD; ap_lock_fname = DEFAULT_LOCKFILE; max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; curr_child_num = 0; diff --git a/server/mpm/prefork/mpm_default.h b/server/mpm/prefork/mpm_default.h index 3854a2bc23..2ba0867c51 100644 --- a/server/mpm/prefork/mpm_default.h +++ b/server/mpm/prefork/mpm_default.h @@ -85,11 +85,6 @@ #define DEFAULT_LOCKFILE "logs/accept.lock" #endif -/* Scoreboard file, if there is one */ -#ifndef DEFAULT_SCOREBOARD -#define DEFAULT_SCOREBOARD "logs/apache_runtime_status" -#endif - /* Where the main/parent process's pid is logged */ #ifndef DEFAULT_PIDLOG #define DEFAULT_PIDLOG "logs/httpd.pid" diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index f7c510d9d1..d76098c249 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -1254,7 +1254,6 @@ static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp ap_daemons_max_free = DEFAULT_MAX_FREE_DAEMON; ap_daemons_limit = server_limit; ap_pid_fname = DEFAULT_PIDLOG; - ap_scoreboard_fname = DEFAULT_SCOREBOARD; ap_lock_fname = DEFAULT_LOCKFILE; ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; ap_extended_status = 0; diff --git a/server/mpm/worker/mpm_default.h b/server/mpm/worker/mpm_default.h index 4b9ea3acb2..c3993c4607 100644 --- a/server/mpm/worker/mpm_default.h +++ b/server/mpm/worker/mpm_default.h @@ -89,11 +89,6 @@ #define DEFAULT_LOCKFILE "logs/accept.lock" #endif -/* Scoreboard file, if there is one */ -#ifndef DEFAULT_SCOREBOARD -#define DEFAULT_SCOREBOARD "logs/apache_runtime_status" -#endif - /* Where the main/parent process's pid is logged */ #ifndef DEFAULT_PIDLOG #define DEFAULT_PIDLOG "logs/httpd.pid" diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index f571fb63cc..1750862df9 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -1582,7 +1582,6 @@ static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog, ap_daemons_limit = server_limit; ap_threads_per_child = DEFAULT_THREADS_PER_CHILD; ap_pid_fname = DEFAULT_PIDLOG; - ap_scoreboard_fname = DEFAULT_SCOREBOARD; ap_lock_fname = DEFAULT_LOCKFILE; ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; ap_extended_status = 0; diff --git a/server/scoreboard.c b/server/scoreboard.c index 8eb8e1a241..744fd42905 100644 --- a/server/scoreboard.c +++ b/server/scoreboard.c @@ -161,6 +161,31 @@ void ap_init_scoreboard(void *shared_score) ap_assert(more_storage == (char*)shared_score + scoreboard_size); } +/** + * Create a name-based scoreboard in the given pool using the + * given filename. + */ +static apr_status_t create_namebased_scoreboard(apr_pool_t *pool, + const char *fname) +{ +#if APR_HAS_SHARED_MEMORY + apr_status_t rv; + + /* The shared memory file must not exist before we create the + * segment. */ + apr_file_remove(fname, pool); /* ignore errors */ + + rv = apr_shm_create(&ap_scoreboard_shm, scoreboard_size, fname, pool); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "unable to create scoreboard " + "(name-based shared memory failure)"); + return rv; + } +#endif /* APR_HAS_SHARED_MEMORY */ + return APR_SUCCESS; +} + /* ToDo: This function should be made to handle setting up * a scoreboard shared between processes using any IPC technique, * not just a shared memory segment @@ -183,35 +208,32 @@ static apr_status_t open_scoreboard(apr_pool_t *pconf) return rv; } -#ifndef WIN32 - rv = apr_shm_create(&ap_scoreboard_shm, scoreboard_size, fname, - global_pool); - if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "Fatal error: could not create scoreboard " - "(using anonymous shared memory)"); - return rv; + /* The config says to create a name-based shmem */ + if (ap_scoreboard_fname) { + /* make sure it's an absolute pathname */ + fname = ap_server_root_relative(pconf, ap_scoreboard_fname); + + return create_namebased_scoreboard(global_pool, fname); } - if (rv == APR_ENOTIMPL) { -#else - { -#endif - if (ap_scoreboard_fname) { - fname = ap_server_root_relative(global_pool, ap_scoreboard_fname); - /* make sure the file doesn't exist before trying - * to create the segment. */ - apr_file_remove(fname, global_pool); - } - rv = apr_shm_create(&ap_scoreboard_shm, scoreboard_size, fname, - global_pool); - if (rv != APR_SUCCESS) { + else { /* config didn't specify, we get to choose shmem type */ + rv = apr_shm_create(&ap_scoreboard_shm, scoreboard_size, NULL, + global_pool); /* anonymous shared memory */ + if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "Fatal error: could not open(create) scoreboard"); + "Unable to create scoreboard " + "(anonymous shared memory failure)"); return rv; } + /* Make up a filename and do name-based shmem */ + else if (rv == APR_ENOTIMPL) { + /* Make sure it's an absolute pathname */ + ap_scoreboard_fname = DEFAULT_SCOREBOARD; + fname = ap_server_root_relative(pconf, ap_scoreboard_fname); + + return create_namebased_scoreboard(global_pool, fname); + } } - /* everything will be cleared shortly */ -#endif +#endif /* APR_HAS_SHARED_MEMORY */ return APR_SUCCESS; } -- 2.40.0