mirror of
https://github.com/apache/httpd.git
synced 2026-01-06 09:01:14 +03:00
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
This commit is contained in:
3
CHANGES
3
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>]
|
||||
|
||||
|
||||
@@ -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);
|
||||
if (sts != APR_SUCCESS) {
|
||||
log_error_and_cleanup("failed to create shared memory segments", sts, s);
|
||||
return;
|
||||
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;
|
||||
}
|
||||
|
||||
client_list = apr_rmm_malloc(client_rmm, sizeof(*client_list) +
|
||||
sizeof(client_entry*)*num_buckets);
|
||||
/* 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 initialize rmm", sts, s);
|
||||
return !OK;
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user