summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Earl Poirier <poirier@apache.org>2009-08-26 20:29:49 +0200
committerDaniel Earl Poirier <poirier@apache.org>2009-08-26 20:29:49 +0200
commit1bc6da5bb44a67db371a19244c65a3d511b477d6 (patch)
treee7366c4bf591492b688d1ae9cb389b0a63c9e714
parentBring back OS/2 support. (diff)
downloadapache2-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--CHANGES3
-rw-r--r--modules/aaa/mod_auth_digest.c117
2 files changed, 86 insertions, 34 deletions
diff --git a/CHANGES b/CHANGES
index 39a932fb35..174e9a2a3f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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,