diff options
author | Daniel Earl Poirier <poirier@apache.org> | 2009-08-26 20:29:49 +0200 |
---|---|---|
committer | Daniel Earl Poirier <poirier@apache.org> | 2009-08-26 20:29:49 +0200 |
commit | 1bc6da5bb44a67db371a19244c65a3d511b477d6 (patch) | |
tree | e7366c4bf591492b688d1ae9cb389b0a63c9e714 | |
parent | Bring back OS/2 support. (diff) | |
download | apache2-1bc6da5bb44a67db371a19244c65a3d511b477d6.tar.xz apache2-1bc6da5bb44a67db371a19244c65a3d511b477d6.zip |
Fix shm, rmm, and lock problems.
PR: 16057
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@808150 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | modules/aaa/mod_auth_digest.c | 117 |
2 files changed, 86 insertions, 34 deletions
@@ -2,6 +2,9 @@ Changes with Apache 2.3.3 + *) mod_auth_digest: Fix usage of shared memory and re-enable it. + PR 16057 [Dan Poirier] + *) Preserve Port information over internal redirects PR 35999 [Jonas Ringh <jonas.ringh cixit.se>] diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c index 6dfbea615f..b3a1251a7a 100644 --- a/modules/aaa/mod_auth_digest.c +++ b/modules/aaa/mod_auth_digest.c @@ -80,11 +80,9 @@ #include "mod_auth.h" -/* Disable shmem until pools/init gets sorted out - * remove following two lines when fixed - */ -#undef APR_HAS_SHARED_MEMORY -#define APR_HAS_SHARED_MEMORY 0 +#if APR_HAVE_UNISTD_H +#include <unistd.h> +#endif /* struct to hold the configuration info */ @@ -181,8 +179,9 @@ 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 char client_lock_name[L_tmpnam]; -static char opaque_lock_name[L_tmpnam]; +static const char *client_lock_name; +static const char *opaque_lock_name; +static const char *client_shm_filename; #define DEF_SHMEM_SIZE 1000L /* ~ 12 entries */ #define DEF_NUM_BUCKETS 15L @@ -204,6 +203,11 @@ static apr_status_t cleanup_tables(void *not_used) "Digest: cleaning up shared memory"); fflush(stderr); + if (client_rmm) { + apr_rmm_destroy(client_rmm); + client_rmm = NULL; + } + if (client_shm) { apr_shm_destroy(client_shm); client_shm = NULL; @@ -259,24 +263,56 @@ static void log_error_and_cleanup(char *msg, apr_status_t sts, server_rec *s) #if APR_HAS_SHARED_MEMORY -static void initialize_tables(server_rec *s, apr_pool_t *ctx) +static int initialize_tables(server_rec *s, apr_pool_t *ctx) { unsigned long idx; apr_status_t sts; + const char *tempdir; /* set up client list */ - sts = apr_shm_create(&client_shm, shmem_size, tmpnam(NULL), ctx); + sts = apr_temp_dir_get(&tempdir, ctx); + if (APR_SUCCESS != sts) { + ap_log_error(APLOG_MARK, APLOG_ERR, sts, s, + "Failed to find temporary directory"); + log_error_and_cleanup("failed to find temp dir", sts, s); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* Create the shared memory segment */ + + /* + * Create a unique filename using our pid. This information is + * stashed in the global variable so the children inherit it. + */ + client_shm_filename = apr_psprintf(ctx, "%s/authdigest_shm.%"APR_PID_T_FMT, tempdir, + getpid()); + + /* Now create that segment */ + sts = apr_shm_create(&client_shm, shmem_size, + client_shm_filename, ctx); + if (APR_SUCCESS != sts) { + ap_log_error(APLOG_MARK, APLOG_ERR, sts, s, + "Failed to create shared memory segment on file %s", + client_shm_filename); + log_error_and_cleanup("failed to initialize shm", sts, s); + return HTTP_INTERNAL_SERVER_ERROR; + } + + sts = apr_rmm_init(&client_rmm, + NULL, /* no lock, we'll do the locking ourselves */ + apr_shm_baseaddr_get(client_shm), + shmem_size, ctx); if (sts != APR_SUCCESS) { - log_error_and_cleanup("failed to create shared memory segments", sts, s); - return; + log_error_and_cleanup("failed to initialize rmm", sts, s); + return !OK; } - client_list = apr_rmm_malloc(client_rmm, sizeof(*client_list) + - sizeof(client_entry*)*num_buckets); + client_list = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(*client_list) + + sizeof(client_entry*)*num_buckets)); if (!client_list) { log_error_and_cleanup("failed to allocate shared memory", -1, s); - return; + return !OK; } client_list->table = (client_entry**) (client_list + 1); for (idx = 0; idx < num_buckets; idx++) { @@ -285,50 +321,51 @@ static void initialize_tables(server_rec *s, apr_pool_t *ctx) client_list->tbl_len = num_buckets; client_list->num_entries = 0; - tmpnam(client_lock_name); + 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); if (sts != APR_SUCCESS) { log_error_and_cleanup("failed to create lock (client_lock)", sts, s); - return; + return !OK; } /* setup opaque */ - opaque_cntr = apr_rmm_malloc(client_rmm, sizeof(*opaque_cntr)); + opaque_cntr = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(*opaque_cntr))); if (opaque_cntr == NULL) { log_error_and_cleanup("failed to allocate shared memory", -1, s); - return; + return !OK; } *opaque_cntr = 1UL; - tmpnam(opaque_lock_name); - /* FIXME: get the opaque_lock_name from a directive so we're portable - * to non-process-inheriting operating systems, like Win32. */ + 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); if (sts != APR_SUCCESS) { log_error_and_cleanup("failed to create lock (opaque_lock)", sts, s); - return; + return !OK; } /* setup one-time-nonce counter */ - otn_counter = apr_rmm_malloc(client_rmm, sizeof(*otn_counter)); + otn_counter = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(*otn_counter))); if (otn_counter == NULL) { log_error_and_cleanup("failed to allocate shared memory", -1, s); - return; + return !OK; } *otn_counter = 0; /* no lock here */ /* success */ - return; + return OK; } #endif /* APR_HAS_SHARED_MEMORY */ @@ -364,7 +401,10 @@ static int initialize_module(apr_pool_t *p, apr_pool_t *plog, * last child dies. Therefore we can never clean up the old stuff, * creating a creeping memory leak. */ - initialize_tables(s, p); + if (initialize_tables(s, p) != OK) { + return !OK; + } + /* Call cleanup_tables on exit or restart */ apr_pool_cleanup_register(p, NULL, cleanup_tables, apr_pool_cleanup_null); #endif /* APR_HAS_SHARED_MEMORY */ return OK; @@ -378,15 +418,21 @@ static void initialize_child(apr_pool_t *p, server_rec *s) return; } - /* FIXME: get the client_lock_name from a directive so we're portable - * to non-process-inheriting operating systems, like Win32. */ + /* Get access to rmm in child */ + sts = apr_rmm_attach(&client_rmm, + NULL, + apr_shm_baseaddr_get(client_shm), + p); + if (sts != APR_SUCCESS) { + log_error_and_cleanup("failed to attach to rmm", sts, s); + return; + } + sts = apr_global_mutex_child_init(&client_lock, client_lock_name, p); if (sts != APR_SUCCESS) { log_error_and_cleanup("failed to create lock (client_lock)", sts, s); return; } - /* FIXME: get the opaque_lock_name from a directive so we're portable - * to non-process-inheriting operating systems, like Win32. */ sts = apr_global_mutex_child_init(&opaque_lock, opaque_lock_name, p); if (sts != APR_SUCCESS) { log_error_and_cleanup("failed to create lock (opaque_lock)", sts, s); @@ -775,7 +821,7 @@ static long gc(void) client_list->table[idx] = NULL; } if (entry) { /* remove entry */ - apr_rmm_free(client_rmm, (apr_rmm_off_t)entry); + apr_rmm_free(client_rmm, apr_rmm_offset_get(client_rmm, entry)); num_removed++; } } @@ -811,7 +857,7 @@ static client_entry *add_client(unsigned long key, client_entry *info, /* try to allocate a new entry */ - entry = (client_entry *)apr_rmm_malloc(client_rmm, sizeof(client_entry)); + entry = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(client_entry))); if (!entry) { long num_removed = gc(); ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, @@ -820,8 +866,11 @@ static client_entry *add_client(unsigned long key, client_entry *info, "%ld", num_removed, client_list->num_created - client_list->num_renewed, client_list->num_removed, client_list->num_renewed); - entry = (client_entry *)apr_rmm_malloc(client_rmm, sizeof(client_entry)); + entry = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(client_entry))); if (!entry) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "unable to allocate new auth_digest client"); + apr_global_mutex_unlock(client_lock); return NULL; /* give up */ } } @@ -1093,7 +1142,7 @@ static client_entry *gen_client(const request_rec *r) apr_global_mutex_lock(opaque_lock); op = (*opaque_cntr)++; - apr_global_mutex_lock(opaque_lock); + apr_global_mutex_unlock(opaque_lock); if (!(entry = add_client(op, &new_entry, r->server))) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, |