From 813c28c25eba91c18a2487deea1d44d8af710b51 Mon Sep 17 00:00:00 2001 From: Bradley Nicholes Date: Wed, 11 Feb 2004 18:07:46 +0000 Subject: [PATCH] Fix the shared memory caching issues in util_ldap PR #18756 Submitted by: Matthieu Estrade, Brad Nicholes Reviewed by: Mathieu Estrade, Brad Nicholes, Jeff Trawick git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/APACHE_2_0_BRANCH@102632 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 + STATUS | 13 +-- include/util_ldap.h | 28 +++-- modules/experimental/util_ldap.c | 97 +++++++++++----- modules/experimental/util_ldap_cache.c | 128 +++++++++++---------- modules/experimental/util_ldap_cache.h | 93 ++++++++------- modules/experimental/util_ldap_cache_mgr.c | 89 ++++++++------ 7 files changed, 264 insertions(+), 187 deletions(-) diff --git a/CHANGES b/CHANGES index e2d178b6e1b..dff81bf84d3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ Changes with Apache 2.0.49 + *) mod_auth_ldap: Fix some segfaults in the cache logic. PR 18756. + [Matthieu Estrade , Brad Nicholes] + *) mod_cgid: Restart the cgid daemon if it crashes. PR 19849 [Glenn Nielsen ] diff --git a/STATUS b/STATUS index 53c3d0ca6d1..e5edeb72f24 100644 --- a/STATUS +++ b/STATUS @@ -1,5 +1,5 @@ APACHE 2.0 STATUS: -*-text-*- -Last modified at [$Date: 2004/02/10 14:53:27 $] +Last modified at [$Date: 2004/02/11 18:07:45 $] Release: @@ -230,17 +230,6 @@ PATCHES TO BACKPORT FROM 2.1 nd replies: But if it can't be 0 the alternatives thereafter make no sense anymore, right? - * LDAP cache fixes from Matthieu Estrade; see PR 18756 - include/util_ldap.h r1.12 - modules/experimental/util_ldap.c r1.15, r1.16 - modules/experimental/util_ldap_cache.c r1.9, r1.10 - modules/experimental/util_ldap_cache.h r1.7, r1.8 - modules/experimental/util_ldap_cache_mgr.c r1.6, r1.7, r1.8, r1.10 - +1: trawick (this stuff can sure use more eyes, but some users - have already tested the patch successfully) - bnicholes (looks good on Netware but then NetWare does not - use shared memory.) - * mod_auth_digest: Allow sub-requests with different methods than the original request. PR 25040. modules/aaa/mod_auth_digest.c: r1.82 diff --git a/include/util_ldap.h b/include/util_ldap.h index 38f4944228e..4f9c24f8cdb 100644 --- a/include/util_ldap.h +++ b/include/util_ldap.h @@ -36,6 +36,10 @@ #include "http_protocol.h" #include "http_request.h" +#if APR_HAS_SHARED_MEMORY +#include "apr_rmm.h" +#include "apr_shm.h" +#endif /* Create a set of LDAP_DECLARE(type), LDLDAP_DECLARE(type) and * LDAP_DECLARE_DATA with appropriate export and import tags for the platform @@ -58,7 +62,6 @@ #define LDAP_DECLARE_DATA __declspec(dllimport) #endif - /* * LDAP Connections */ @@ -99,9 +102,11 @@ typedef struct util_ldap_state_t { apr_pool_t *pool; /* pool from which this state is allocated */ #if APR_HAS_THREADS apr_thread_mutex_t *mutex; /* mutex lock for the connection list */ + apr_thread_rwlock_t *util_ldap_cache_lock; #endif apr_size_t cache_bytes; /* Size (in bytes) of shared memory cache */ + char *cache_file; /* filename for shm */ long search_cache_ttl; /* TTL for search cache */ long search_cache_size; /* Size (in entries) of search cache */ long compare_cache_ttl; /* TTL for compare cache */ @@ -111,6 +116,15 @@ typedef struct util_ldap_state_t { char *cert_auth_file; int cert_file_type; int ssl_support; + +#if APR_HAS_SHARED_MEMORY + apr_shm_t *cache_shm; + apr_rmm_t *cache_rmm; +#endif + + /* cache ald */ + void *util_ldap_cache; + } util_ldap_state_t; @@ -247,21 +261,21 @@ LDAP_DECLARE(int) util_ldap_ssl_supported(request_rec *r); * @param reqsize The size of the shared memory segement to request. A size * of zero requests the max size possible from * apr_shmem_init() - * @deffunc void util_ldap_cache_init(apr_pool_t *p) + * @deffunc void util_ldap_cache_init(apr_pool_t *p, util_ldap_state_t *st) * @return The status code returned is the status code of the * apr_smmem_init() call. Regardless of the status, the cache * will be set up at least for in-process or in-thread operation. */ -apr_status_t util_ldap_cache_init(apr_pool_t *pool, apr_size_t reqsize); +apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st); /** * Display formatted stats for cache * @param The pool to allocate the returned string from * @tip This function returns a string allocated from the provided pool that describes * various stats about the cache. - * @deffunc char *util_ald_cache_display(apr_pool_t *pool) + * @deffunc char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st) */ -char *util_ald_cache_display(apr_pool_t *pool); +char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st); /* from apr_ldap_cache_mgr.c */ @@ -271,9 +285,9 @@ char *util_ald_cache_display(apr_pool_t *pool); * @param The pool to allocate the returned string from * @tip This function returns a string allocated from the provided pool that describes * various stats about the cache. - * @deffunc char *util_ald_cache_display(apr_pool_t *pool) + * @deffunc char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st) */ -char *util_ald_cache_display(apr_pool_t *pool); +char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st); #endif /* APU_HAS_LDAP */ #endif /* UTIL_LDAP_H */ diff --git a/modules/experimental/util_ldap.c b/modules/experimental/util_ldap.c index 2890abad4a1..2f2d3e1b3d7 100644 --- a/modules/experimental/util_ldap.c +++ b/modules/experimental/util_ldap.c @@ -102,6 +102,7 @@ void *util_ldap_create_config(apr_pool_t *p, server_rec *s); */ int util_ldap_handler(request_rec *r) { + util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module); r->allowed |= (1 << M_GET); if (r->method_number != M_GET) @@ -132,7 +133,7 @@ int util_ldap_handler(request_rec *r) "\n", r ); - ap_rputs(util_ald_cache_display(r->pool), r); + ap_rputs(util_ald_cache_display(r->pool, st), r); ap_rputs("\n

\n", r); @@ -467,9 +468,7 @@ LDAP_DECLARE(int) util_ldap_cache_comparedn(request_rec *r, util_ldap_connection LDAPMessage *res, *entry; char *searchdn; - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(r->server->module_config, - &ldap_module); + util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module); /* read lock this function */ LDAP_CACHE_LOCK_CREATE(st->pool); @@ -478,7 +477,7 @@ LDAP_DECLARE(int) util_ldap_cache_comparedn(request_rec *r, util_ldap_connection LDAP_CACHE_WRLOCK(); curnode.url = url; - curl = util_ald_cache_fetch(util_ldap_cache, &curnode); + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); if (curl == NULL) { curl = util_ald_create_caches(st, url); } @@ -598,7 +597,7 @@ LDAP_DECLARE(int) util_ldap_cache_compare(request_rec *r, util_ldap_connection_t /* get cache entry (or create one) */ LDAP_CACHE_WRLOCK(); curnode.url = url; - curl = util_ald_cache_fetch(util_ldap_cache, &curnode); + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); if (curl == NULL) { curl = util_ald_create_caches(st, url); } @@ -721,7 +720,7 @@ LDAP_DECLARE(int) util_ldap_cache_checkuserid(request_rec *r, util_ldap_connecti /* Get the cache node for this url */ LDAP_CACHE_WRLOCK(); curnode.url = url; - curl = (util_url_node_t *)util_ald_cache_fetch(util_ldap_cache, &curnode); + curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache, &curnode); if (curl == NULL) { curl = util_ald_create_caches(st, url); } @@ -923,6 +922,26 @@ static const char *util_ldap_set_cache_bytes(cmd_parms *cmd, void *dummy, const return NULL; } +static const char *util_ldap_set_cache_file(cmd_parms *cmd, void *dummy, const char *file) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, + &ldap_module); + + if (file) { + st->cache_file = ap_server_root_relative(st->pool, file); + } + else { + st->cache_file = NULL; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "LDAP cache: Setting shared memory cache file to %s bytes.", + st->cache_file); + + return NULL; +} + static const char *util_ldap_set_cache_ttl(cmd_parms *cmd, void *dummy, const char *ttl) { util_ldap_state_t *st = @@ -1052,22 +1071,6 @@ void *util_ldap_create_config(apr_pool_t *p, server_rec *s) return st; } -static void util_ldap_init_module(apr_pool_t *pool, server_rec *s) -{ - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(s->module_config, - &ldap_module); - - apr_status_t result = util_ldap_cache_init(pool, st->cache_bytes); - char buf[MAX_STRING_LEN]; - - apr_strerror(result, buf, sizeof(buf)); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s, - "[%d] ldap cache init: %s", - getpid(), buf); -} - - static apr_status_t util_ldap_cleanup_module(void *data) { server_rec *s = data; @@ -1089,13 +1092,46 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { int rc = LDAP_SUCCESS; + apr_status_t result; + char buf[MAX_STRING_LEN]; - util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config( - s->module_config, - &ldap_module); + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(s->module_config, &ldap_module); - /* log the LDAP SDK used - */ +#if APR_HAS_SHARED_MEMORY + server_rec *s_vhost; + util_ldap_state_t *st_vhost; + + /* initializing cache if file is here and we already don't have shm addr*/ + if (st->cache_file && !st->cache_shm) { +#endif + result = util_ldap_cache_init(p, st); + apr_strerror(result, buf, sizeof(buf)); + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s, + "LDAP cache init: %s", buf); + +#if APR_HAS_SHARED_MEMORY + /* merge config in all vhost */ + s_vhost = s->next; + while (s_vhost) { + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s, + "LDAP merging Shared Cache conf: shm=0x%x rmm=0x%x for VHOST: %s", + st->cache_shm, st->cache_rmm, s_vhost->server_hostname); + + st_vhost = (util_ldap_state_t *)ap_get_module_config(s_vhost->module_config, &ldap_module); + st_vhost->cache_shm = st->cache_shm; + st_vhost->cache_rmm = st->cache_rmm; + st_vhost->cache_file = st->cache_file; + s_vhost = s_vhost->next; + } + } + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0 , s, "LDAP cache: Unable to init Shared Cache: no file"); + } +#endif + + /* log the LDAP SDK used + */ #if APR_HAS_NETSCAPE_LDAPSDK ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, @@ -1258,6 +1294,10 @@ command_rec util_ldap_cmds[] = { "Sets the size of the shared memory cache in bytes. " "Zero means disable the shared memory cache. Defaults to 100KB."), + AP_INIT_TAKE1("LDAPSharedCacheFile", util_ldap_set_cache_file, NULL, RSRC_CONF, + "Sets the file of the shared memory cache." + "Nothing means disable the shared memory cache."), + AP_INIT_TAKE1("LDAPCacheEntries", util_ldap_set_cache_entries, NULL, RSRC_CONF, "Sets the maximum number of entries that are possible in the LDAP " "search cache. " @@ -1292,7 +1332,6 @@ command_rec util_ldap_cmds[] = { static void util_ldap_register_hooks(apr_pool_t *p) { ap_hook_post_config(util_ldap_post_config,NULL,NULL,APR_HOOK_MIDDLE); - ap_hook_child_init(util_ldap_init_module, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_handler(util_ldap_handler, NULL, NULL, APR_HOOK_MIDDLE); } diff --git a/modules/experimental/util_ldap_cache.c b/modules/experimental/util_ldap_cache.c index f7f333c6841..a279a57e010 100644 --- a/modules/experimental/util_ldap_cache.c +++ b/modules/experimental/util_ldap_cache.c @@ -27,8 +27,9 @@ #ifdef APU_HAS_LDAP +#if APR_HAS_SHARED_MEMORY #define MODLDAP_SHMEM_CACHE "/tmp/mod_ldap_cache" - +#endif /* ------------------------------------------------------------------ */ @@ -46,14 +47,14 @@ int util_ldap_url_node_compare(void *a, void *b) return(strcmp(na->url, nb->url) == 0); } -void *util_ldap_url_node_copy(void *c) +void *util_ldap_url_node_copy(util_ald_cache_t *cache, void *c) { util_url_node_t *n = (util_url_node_t *)c; - util_url_node_t *node = (util_url_node_t *)util_ald_alloc(sizeof(util_url_node_t)); + util_url_node_t *node = (util_url_node_t *)util_ald_alloc(cache, sizeof(util_url_node_t)); if (node) { - if (!(node->url = util_ald_strdup(n->url))) { - util_ald_free(node->url); + if (!(node->url = util_ald_strdup(cache, n->url))) { + util_ald_free(cache, node->url); return NULL; } node->search_cache = n->search_cache; @@ -66,15 +67,15 @@ void *util_ldap_url_node_copy(void *c) } } -void util_ldap_url_node_free(void *n) +void util_ldap_url_node_free(util_ald_cache_t *cache, void *n) { util_url_node_t *node = (util_url_node_t *)n; - util_ald_free(node->url); + util_ald_free(cache, node->url); util_ald_destroy_cache(node->search_cache); util_ald_destroy_cache(node->compare_cache); util_ald_destroy_cache(node->dn_compare_cache); - util_ald_free(node); + util_ald_free(cache, node); } /* ------------------------------------------------------------------ */ @@ -92,10 +93,10 @@ int util_ldap_search_node_compare(void *a, void *b) ((util_search_node_t *)b)->username) == 0); } -void *util_ldap_search_node_copy(void *c) +void *util_ldap_search_node_copy(util_ald_cache_t *cache, void *c) { util_search_node_t *node = (util_search_node_t *)c; - util_search_node_t *newnode = util_ald_alloc(sizeof(util_search_node_t)); + util_search_node_t *newnode = util_ald_alloc(cache, sizeof(util_search_node_t)); /* safety check */ if (newnode) { @@ -105,13 +106,13 @@ void *util_ldap_search_node_copy(void *c) int k = 0; int i = 0; while (node->vals[k++]); - if (!(newnode->vals = util_ald_alloc(sizeof(char *) * (k+1)))) { - util_ldap_search_node_free(newnode); + if (!(newnode->vals = util_ald_alloc(cache, sizeof(char *) * (k+1)))) { + util_ldap_search_node_free(cache, newnode); return NULL; } while (node->vals[i]) { - if (!(newnode->vals[i] = util_ald_strdup(node->vals[i]))) { - util_ldap_search_node_free(newnode); + if (!(newnode->vals[i] = util_ald_strdup(cache, node->vals[i]))) { + util_ldap_search_node_free(cache, newnode); return NULL; } i++; @@ -120,10 +121,10 @@ void *util_ldap_search_node_copy(void *c) else { newnode->vals = NULL; } - if (!(newnode->username = util_ald_strdup(node->username)) || - !(newnode->dn = util_ald_strdup(node->dn)) || - !(newnode->bindpw = util_ald_strdup(node->bindpw)) ) { - util_ldap_search_node_free(newnode); + if (!(newnode->username = util_ald_strdup(cache, node->username)) || + !(newnode->dn = util_ald_strdup(cache, node->dn)) || + !(newnode->bindpw = util_ald_strdup(cache, node->bindpw)) ) { + util_ldap_search_node_free(cache, newnode); return NULL; } newnode->lastbind = node->lastbind; @@ -132,20 +133,20 @@ void *util_ldap_search_node_copy(void *c) return (void *)newnode; } -void util_ldap_search_node_free(void *n) +void util_ldap_search_node_free(util_ald_cache_t *cache, void *n) { int i = 0; util_search_node_t *node = (util_search_node_t *)n; if (node->vals) { while (node->vals[i]) { - util_ald_free(node->vals[i++]); + util_ald_free(cache, node->vals[i++]); } - util_ald_free(node->vals); + util_ald_free(cache, node->vals); } - util_ald_free(node->username); - util_ald_free(node->dn); - util_ald_free(node->bindpw); - util_ald_free(node); + util_ald_free(cache, node->username); + util_ald_free(cache, node->dn); + util_ald_free(cache, node->bindpw); + util_ald_free(cache, node); } /* ------------------------------------------------------------------ */ @@ -165,16 +166,16 @@ int util_ldap_compare_node_compare(void *a, void *b) strcmp(na->value, nb->value) == 0); } -void *util_ldap_compare_node_copy(void *c) +void *util_ldap_compare_node_copy(util_ald_cache_t *cache, void *c) { util_compare_node_t *n = (util_compare_node_t *)c; - util_compare_node_t *node = (util_compare_node_t *)util_ald_alloc(sizeof(util_compare_node_t)); + util_compare_node_t *node = (util_compare_node_t *)util_ald_alloc(cache, sizeof(util_compare_node_t)); if (node) { - if (!(node->dn = util_ald_strdup(n->dn)) || - !(node->attrib = util_ald_strdup(n->attrib)) || - !(node->value = util_ald_strdup(n->value))) { - util_ldap_compare_node_free(node); + if (!(node->dn = util_ald_strdup(cache, n->dn)) || + !(node->attrib = util_ald_strdup(cache, n->attrib)) || + !(node->value = util_ald_strdup(cache, n->value))) { + util_ldap_compare_node_free(cache, node); return NULL; } node->lastcompare = n->lastcompare; @@ -186,13 +187,13 @@ void *util_ldap_compare_node_copy(void *c) } } -void util_ldap_compare_node_free(void *n) +void util_ldap_compare_node_free(util_ald_cache_t *cache, void *n) { util_compare_node_t *node = (util_compare_node_t *)n; - util_ald_free(node->dn); - util_ald_free(node->attrib); - util_ald_free(node->value); - util_ald_free(node); + util_ald_free(cache, node->dn); + util_ald_free(cache, node->attrib); + util_ald_free(cache, node->value); + util_ald_free(cache, node); } /* ------------------------------------------------------------------ */ @@ -208,14 +209,14 @@ int util_ldap_dn_compare_node_compare(void *a, void *b) ((util_dn_compare_node_t *)b)->reqdn) == 0); } -void *util_ldap_dn_compare_node_copy(void *c) +void *util_ldap_dn_compare_node_copy(util_ald_cache_t *cache, void *c) { util_dn_compare_node_t *n = (util_dn_compare_node_t *)c; - util_dn_compare_node_t *node = (util_dn_compare_node_t *)util_ald_alloc(sizeof(util_dn_compare_node_t)); + util_dn_compare_node_t *node = (util_dn_compare_node_t *)util_ald_alloc(cache, sizeof(util_dn_compare_node_t)); if (node) { - if (!(node->reqdn = util_ald_strdup(n->reqdn)) || - !(node->dn = util_ald_strdup(n->dn))) { - util_ldap_dn_compare_node_free(node); + if (!(node->reqdn = util_ald_strdup(cache, n->reqdn)) || + !(node->dn = util_ald_strdup(cache, n->dn))) { + util_ldap_dn_compare_node_free(cache, node); return NULL; } return node; @@ -225,12 +226,12 @@ void *util_ldap_dn_compare_node_copy(void *c) } } -void util_ldap_dn_compare_node_free(void *n) +void util_ldap_dn_compare_node_free(util_ald_cache_t *cache, void *n) { util_dn_compare_node_t *node = (util_dn_compare_node_t *)n; - util_ald_free(node->reqdn); - util_ald_free(node->dn); - util_ald_free(node); + util_ald_free(cache, node->reqdn); + util_ald_free(cache, node->dn); + util_ald_free(cache, node); } @@ -240,46 +241,53 @@ apr_status_t util_ldap_cache_module_kill(void *data); apr_status_t util_ldap_cache_module_kill(void *data) { + util_ldap_state_t *st = (util_ldap_state_t *)data; + #if APR_HAS_SHARED_MEMORY - if (util_ldap_shm != NULL) { - apr_status_t result = apr_shm_destroy(util_ldap_shm); - util_ldap_shm = NULL; + if (st->cache_shm != NULL) { + apr_status_t result = apr_shm_destroy(st->cache_shm); + st->cache_shm = NULL; + apr_file_remove(st->cache_file, st->pool); return result; } #endif - util_ald_destroy_cache(util_ldap_cache); + util_ald_destroy_cache(st->util_ldap_cache); return APR_SUCCESS; } -apr_status_t util_ldap_cache_init(apr_pool_t *pool, apr_size_t reqsize) +apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st) { #if APR_HAS_SHARED_MEMORY apr_status_t result; - result = apr_shm_create(&util_ldap_shm, reqsize, MODLDAP_SHMEM_CACHE, pool); + if (!st->cache_file) { + return -1; + } + + result = apr_shm_create(&st->cache_shm, st->cache_bytes, st->cache_file, st->pool); if (result == EEXIST) { /* * The cache could have already been created (i.e. we may be a child process). See * if we can attach to the existing shared memory */ - result = apr_shm_attach(&util_ldap_shm, MODLDAP_SHMEM_CACHE, pool); + result = apr_shm_attach(&st->cache_shm, st->cache_file, st->pool); } if (result != APR_SUCCESS) { return result; } /* This will create a rmm "handler" to get into the shared memory area */ - apr_rmm_init(&util_ldap_rmm, NULL, - (void *)apr_shm_baseaddr_get(util_ldap_shm), reqsize, pool); + apr_rmm_init(&st->cache_rmm, NULL, (void *)apr_shm_baseaddr_get(st->cache_shm), st->cache_bytes, st->pool); #endif - apr_pool_cleanup_register(pool, NULL, util_ldap_cache_module_kill, apr_pool_cleanup_null); + apr_pool_cleanup_register(st->pool, st , util_ldap_cache_module_kill, apr_pool_cleanup_null); - util_ldap_cache = util_ald_create_cache(50, - util_ldap_url_node_hash, - util_ldap_url_node_compare, - util_ldap_url_node_copy, - util_ldap_url_node_free); + st->util_ldap_cache = + util_ald_create_cache(st, + util_ldap_url_node_hash, + util_ldap_url_node_compare, + util_ldap_url_node_copy, + util_ldap_url_node_free); return APR_SUCCESS; } diff --git a/modules/experimental/util_ldap_cache.h b/modules/experimental/util_ldap_cache.h index 3fb680ef87c..2b16fcca6bd 100644 --- a/modules/experimental/util_ldap_cache.h +++ b/modules/experimental/util_ldap_cache.h @@ -28,8 +28,10 @@ * LDAP Cache Manager */ +#if APR_HAS_SHARED_MEMORY #include #include /* EDD */ +#endif typedef struct util_cache_node_t { void *payload; /* Pointer to the payload */ @@ -37,47 +39,48 @@ typedef struct util_cache_node_t { struct util_cache_node_t *next; } util_cache_node_t; -typedef struct util_ald_cache_t { - unsigned long size; /* Size of cache array */ - unsigned long maxentries; /* Maximum number of cache entries */ - unsigned long numentries; /* Current number of cache entries */ - unsigned long fullmark; /* Used to keep track of when cache becomes 3/4 full */ - apr_time_t marktime; /* Time that the cache became 3/4 full */ - unsigned long (*hash)(void *); /* Func to hash the payload */ - int (*compare)(void *, void *); /* Func to compare two payloads */ - void * (*copy)(void *); /* Func to alloc mem and copy payload to new mem */ - void (*free)(void *); /* Func to free mem used by the payload */ +typedef struct util_ald_cache util_ald_cache_t; + +struct util_ald_cache { + unsigned long size; /* Size of cache array */ + unsigned long maxentries; /* Maximum number of cache entries */ + unsigned long numentries; /* Current number of cache entries */ + unsigned long fullmark; /* Used to keep track of when cache becomes 3/4 full */ + apr_time_t marktime; /* Time that the cache became 3/4 full */ + unsigned long (*hash)(void *); /* Func to hash the payload */ + int (*compare)(void *, void *); /* Func to compare two payloads */ + void * (*copy)(util_ald_cache_t *cache, void *); /* Func to alloc mem and copy payload to new mem */ + void (*free)(util_ald_cache_t *cache, void *); /* Func to free mem used by the payload */ util_cache_node_t **nodes; - unsigned long numpurges; /* No. of times the cache has been purged */ - double avg_purgetime; /* Average time to purge the cache */ - apr_time_t last_purge; /* Time of the last purge */ - unsigned long npurged; /* Number of elements purged in last purge. This is not - obvious: it won't be 3/4 the size of the cache if - there were a lot of expired entries. */ + unsigned long numpurges; /* No. of times the cache has been purged */ + double avg_purgetime; /* Average time to purge the cache */ + apr_time_t last_purge; /* Time of the last purge */ + unsigned long npurged; /* Number of elements purged in last purge. This is not + obvious: it won't be 3/4 the size of the cache if + there were a lot of expired entries. */ - unsigned long fetches; /* Number of fetches */ - unsigned long hits; /* Number of cache hits */ - unsigned long inserts; /* Number of inserts */ - unsigned long removes; /* Number of removes */ -} util_ald_cache_t; + unsigned long fetches; /* Number of fetches */ + unsigned long hits; /* Number of cache hits */ + unsigned long inserts; /* Number of inserts */ + unsigned long removes; /* Number of removes */ #if APR_HAS_SHARED_MEMORY -apr_shm_t *util_ldap_shm; -apr_rmm_t *util_ldap_rmm; + apr_shm_t *shm_addr; + apr_rmm_t *rmm_addr; #endif -util_ald_cache_t *util_ldap_cache; + +}; #if APR_HAS_THREADS -apr_thread_rwlock_t *util_ldap_cache_lock; #define LDAP_CACHE_LOCK_CREATE(p) \ - if (!util_ldap_cache_lock) apr_thread_rwlock_create(&util_ldap_cache_lock, p) + if (!st->util_ldap_cache_lock) apr_thread_rwlock_create(&st->util_ldap_cache_lock, st->pool) #define LDAP_CACHE_WRLOCK() \ - apr_thread_rwlock_wrlock(util_ldap_cache_lock) + apr_thread_rwlock_wrlock(st->util_ldap_cache_lock) #define LDAP_CACHE_UNLOCK() \ - apr_thread_rwlock_unlock(util_ldap_cache_lock) + apr_thread_rwlock_unlock(st->util_ldap_cache_lock) #define LDAP_CACHE_RDLOCK() \ - apr_thread_rwlock_rdlock(util_ldap_cache_lock) + apr_thread_rwlock_rdlock(st->util_ldap_cache_lock) #else #define LDAP_CACHE_LOCK_CREATE(p) #define LDAP_CACHE_WRLOCK() @@ -152,35 +155,39 @@ typedef struct util_dn_compare_node_t { /* util_ldap_cache.c */ unsigned long util_ldap_url_node_hash(void *n); int util_ldap_url_node_compare(void *a, void *b); -void *util_ldap_url_node_copy(void *c); -void util_ldap_url_node_free(void *n); +void *util_ldap_url_node_copy(util_ald_cache_t *cache, void *c); +void util_ldap_url_node_free(util_ald_cache_t *cache, void *n); unsigned long util_ldap_search_node_hash(void *n); int util_ldap_search_node_compare(void *a, void *b); -void *util_ldap_search_node_copy(void *c); -void util_ldap_search_node_free(void *n); +void *util_ldap_search_node_copy(util_ald_cache_t *cache, void *c); +void util_ldap_search_node_free(util_ald_cache_t *cache, void *n); unsigned long util_ldap_compare_node_hash(void *n); int util_ldap_compare_node_compare(void *a, void *b); -void *util_ldap_compare_node_copy(void *c); -void util_ldap_compare_node_free(void *n); +void *util_ldap_compare_node_copy(util_ald_cache_t *cache, void *c); +void util_ldap_compare_node_free(util_ald_cache_t *cache, void *n); unsigned long util_ldap_dn_compare_node_hash(void *n); int util_ldap_dn_compare_node_compare(void *a, void *b); -void *util_ldap_dn_compare_node_copy(void *c); -void util_ldap_dn_compare_node_free(void *n); +void *util_ldap_dn_compare_node_copy(util_ald_cache_t *cache, void *c); +void util_ldap_dn_compare_node_free(util_ald_cache_t *cache, void *n); /* util_ldap_cache_mgr.c */ -void util_ald_free(const void *ptr); -void *util_ald_alloc(unsigned long size); -const char *util_ald_strdup(const char *s); +/* Cache alloc and free function, dealing or not with shm */ +void util_ald_free(util_ald_cache_t *cache, const void *ptr); +void *util_ald_alloc(util_ald_cache_t *cache, unsigned long size); +const char *util_ald_strdup(util_ald_cache_t *cache, const char *s); + +/* Cache managing function */ unsigned long util_ald_hash_string(int nstr, ...); void util_ald_cache_purge(util_ald_cache_t *cache); util_url_node_t *util_ald_create_caches(util_ldap_state_t *s, const char *url); -util_ald_cache_t *util_ald_create_cache(unsigned long maxentries, +util_ald_cache_t *util_ald_create_cache(util_ldap_state_t *st, unsigned long (*hashfunc)(void *), int (*comparefunc)(void *, void *), - void * (*copyfunc)(void *), - void (*freefunc)(void *)); + void * (*copyfunc)(util_ald_cache_t *cache, void *), + void (*freefunc)(util_ald_cache_t *cache, void *)); + void util_ald_destroy_cache(util_ald_cache_t *cache); void *util_ald_cache_fetch(util_ald_cache_t *cache, void *payload); void util_ald_cache_insert(util_ald_cache_t *cache, void *payload); diff --git a/modules/experimental/util_ldap_cache_mgr.c b/modules/experimental/util_ldap_cache_mgr.c index a8f794ef892..3706514e150 100644 --- a/modules/experimental/util_ldap_cache_mgr.c +++ b/modules/experimental/util_ldap_cache_mgr.c @@ -73,14 +73,17 @@ static const unsigned long primes[] = 0 }; -void util_ald_free(const void *ptr) +void util_ald_free(util_ald_cache_t *cache, const void *ptr) { #if APR_HAS_SHARED_MEMORY - if (util_ldap_shm) { + if (cache->rmm_addr) { if (ptr) - apr_rmm_free(util_ldap_rmm, apr_rmm_offset_get(util_ldap_rmm, (void *)ptr)); - } else { + /* Free in shared memory */ + apr_rmm_free(cache->rmm_addr, apr_rmm_offset_get(cache->rmm_addr, (void *)ptr)); + } + else { if (ptr) + /* Cache shm is not used */ free((void *)ptr); } #else @@ -89,14 +92,17 @@ void util_ald_free(const void *ptr) #endif } -void *util_ald_alloc(unsigned long size) +void *util_ald_alloc(util_ald_cache_t *cache, unsigned long size) { if (0 == size) return NULL; #if APR_HAS_SHARED_MEMORY - if (util_ldap_shm) { - return (void *)apr_rmm_addr_get(util_ldap_rmm, apr_rmm_calloc(util_ldap_rmm, size)); - } else { + if (cache->rmm_addr) { + /* allocate from shared memory */ + return (void *)apr_rmm_addr_get(cache->rmm_addr, apr_rmm_calloc(cache->rmm_addr, size)); + } + else { + /* Cache shm is not used */ return (void *)calloc(sizeof(char), size); } #else @@ -104,11 +110,12 @@ void *util_ald_alloc(unsigned long size) #endif } -const char *util_ald_strdup(const char *s) +const char *util_ald_strdup(util_ald_cache_t *cache, const char *s) { #if APR_HAS_SHARED_MEMORY - if (util_ldap_shm) { - char *buf = (char *)apr_rmm_addr_get(util_ldap_rmm, apr_rmm_calloc(util_ldap_rmm, strlen(s)+1)); + if (cache->rmm_addr) { + /* allocate from shared memory */ + char *buf = (char *)apr_rmm_addr_get(cache->rmm_addr, apr_rmm_calloc(cache->rmm_addr, strlen(s)+1)); if (buf) { strcpy(buf, s); return buf; @@ -117,6 +124,7 @@ const char *util_ald_strdup(const char *s) return NULL; } } else { + /* Cache shm is not used */ return strdup(s); } #else @@ -178,8 +186,8 @@ void util_ald_cache_purge(util_ald_cache_t *cache) while (p != NULL) { if (p->add_time < cache->marktime) { q = p->next; - (*cache->free)(p->payload); - util_ald_free(p); + (*cache->free)(cache, p->payload); + util_ald_free(cache, p); cache->numentries--; cache->npurged++; p = q; @@ -208,17 +216,17 @@ util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url) util_ald_cache_t *dn_compare_cache; /* create the three caches */ - search_cache = util_ald_create_cache(st->search_cache_size, + search_cache = util_ald_create_cache(st, util_ldap_search_node_hash, util_ldap_search_node_compare, util_ldap_search_node_copy, util_ldap_search_node_free); - compare_cache = util_ald_create_cache(st->compare_cache_size, + compare_cache = util_ald_create_cache(st, util_ldap_compare_node_hash, util_ldap_compare_node_compare, util_ldap_compare_node_copy, util_ldap_compare_node_free); - dn_compare_cache = util_ald_create_cache(st->compare_cache_size, + dn_compare_cache = util_ald_create_cache(st, util_ldap_dn_compare_node_hash, util_ldap_dn_compare_node_compare, util_ldap_dn_compare_node_copy, @@ -233,7 +241,7 @@ util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url) curl->compare_cache = compare_cache; curl->dn_compare_cache = dn_compare_cache; - util_ald_cache_insert(util_ldap_cache, curl); + util_ald_cache_insert(st->util_ldap_cache, curl); } @@ -241,32 +249,36 @@ util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url) } -util_ald_cache_t *util_ald_create_cache(unsigned long maxentries, +util_ald_cache_t *util_ald_create_cache(util_ldap_state_t *st, unsigned long (*hashfunc)(void *), int (*comparefunc)(void *, void *), - void * (*copyfunc)(void *), - void (*freefunc)(void *)) + void * (*copyfunc)(util_ald_cache_t *cache, void *), + void (*freefunc)(util_ald_cache_t *cache, void *)) { util_ald_cache_t *cache; unsigned long i; - if (maxentries <= 0) + if (st->search_cache_size <= 0) return NULL; - cache = (util_ald_cache_t *)util_ald_alloc(sizeof(util_ald_cache_t)); +#if APR_HAS_SHARED_MEMORY + cache = (util_ald_cache_t *)apr_rmm_addr_get(st->cache_rmm, apr_rmm_calloc(st->cache_rmm, sizeof(util_ald_cache_t))); +#else + cache = (util_ald_cache_t *)calloc(sizeof(util_ald_cache_t), 1); +#endif if (!cache) return NULL; - cache->maxentries = maxentries; + cache->maxentries = st->search_cache_size; cache->numentries = 0; - cache->size = maxentries / 3; + cache->size = st->search_cache_size / 3; if (cache->size < 64) cache->size = 64; for (i = 0; primes[i] && primes[i] < cache->size; ++i) ; cache->size = primes[i]? primes[i] : primes[i-1]; - cache->nodes = (util_cache_node_t **)util_ald_alloc(cache->size * sizeof(util_cache_node_t *)); + cache->nodes = (util_cache_node_t **)util_ald_alloc(cache, cache->size * sizeof(util_cache_node_t *)); if (!cache->nodes) { - util_ald_free(cache); + util_ald_free(cache, cache); return NULL; } @@ -306,13 +318,13 @@ void util_ald_destroy_cache(util_ald_cache_t *cache) q = NULL; while (p != NULL) { q = p->next; - (*cache->free)(p->payload); - util_ald_free(p); + (*cache->free)(cache, p->payload); + util_ald_free(cache, p); p = q; } } - util_ald_free(cache->nodes); - util_ald_free(cache); + util_ald_free(cache, cache->nodes); + util_ald_free(cache, cache); } void *util_ald_cache_fetch(util_ald_cache_t *cache, void *payload) @@ -351,11 +363,13 @@ void util_ald_cache_insert(util_ald_cache_t *cache, void *payload) if (cache == NULL || payload == NULL) return; + if ((node = (util_cache_node_t *)util_ald_alloc(cache, sizeof(util_cache_node_t))) == NULL) + return; + cache->inserts++; hashval = (*cache->hash)(payload) % cache->size; - node = (util_cache_node_t *)util_ald_alloc(sizeof(util_cache_node_t)); node->add_time = apr_time_now(); - node->payload = (*cache->copy)(payload); + node->payload = (*cache->copy)(cache, payload); node->next = cache->nodes[hashval]; cache->nodes[hashval] = node; if (++cache->numentries == cache->fullmark) @@ -392,8 +406,8 @@ void util_ald_cache_remove(util_ald_cache_t *cache, void *payload) /* We found the node and it's not the first in the list */ q->next = p->next; } - (*cache->free)(p->payload); - util_ald_free(p); + (*cache->free)(cache, p->payload); + util_ald_free(cache, p); cache->numentries--; } @@ -460,16 +474,19 @@ char *util_ald_cache_display_stats(apr_pool_t *p, util_ald_cache_t *cache, char return buf; } -char *util_ald_cache_display(apr_pool_t *pool) +char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st) { unsigned long i; char *buf, *t1, *t2, *t3; + util_ald_cache_t *util_ldap_cache = st->util_ldap_cache; + + if (!util_ldap_cache) { return "Cache has not been enabled/initialised."; } - buf = util_ald_cache_display_stats(pool, util_ldap_cache, "LDAP URL Cache"); + buf = util_ald_cache_display_stats(pool, st->util_ldap_cache, "LDAP URL Cache"); for (i=0; i < util_ldap_cache->size; ++i) { util_cache_node_t *p; -- 2.47.2