X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Foverlays%2Fpcache.c;h=3b667e5380175c13fbb37fbde40bbba5ca7500de;hb=d7bdb8cb2499737d97393aae24de9a183a2d229a;hp=1b009b750926f7113de87f4343c5b8a181290e99;hpb=932d924f5091af39b6be547c9771dfdc9e4640f7;p=openldap diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c index 1b009b7509..3b667e5380 100644 --- a/servers/slapd/overlays/pcache.c +++ b/servers/slapd/overlays/pcache.c @@ -29,7 +29,6 @@ #include #include "slap.h" -#include "ldap_pvt.h" #include "lutil.h" #include "ldap_rq.h" @@ -39,6 +38,7 @@ typedef struct Query_s { Filter* filter; /* Search Filter */ AttributeName* attrs; /* Projected attributes */ + AttributeName* save_attrs; /* original attributes, saved for response */ struct berval base; /* Search Base */ int scope; /* Search scope */ } Query; @@ -117,6 +117,11 @@ typedef struct cache_manager_s { int max_entries; /* max number of entries cached */ int num_entries_limit; /* max # of entries in a cacheable query */ + char response_cb; /* install the response callback + * at the tail of the callback list */ +#define PCACHE_RESPONSE_CB_HEAD 0 +#define PCACHE_RESPONSE_CB_TAIL 1 + int cc_period; /* interval between successive consistency checks (sec) */ int cc_paused; void *cc_arg; @@ -254,13 +259,8 @@ add_query_on_top (query_manager* qm, CachedQuery* qc) qc->lru_down = top; qc->lru_up = NULL; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "Base of added query = %s\n", - q->base.bv_val, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Base of added query = %s\n", q->base.bv_val, 0, 0 ); -#endif } /* remove_query from LRU list */ @@ -515,13 +515,8 @@ query_containment(query_manager *qm, MatchingRule* mrule = NULL; if (inputf != NULL) { -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "Lock QC index = %d\n", - template_index, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Lock QC index = %d\n", template_index, 0, 0 ); -#endif ldap_pvt_thread_rdwr_rlock(&(templa[template_index].t_rwlock)); for(qc=templa[template_index].query; qc != NULL; qc= qc->next) { q = (Query*)qc; @@ -551,15 +546,9 @@ query_containment(query_manager *qm, &(fs->f_ava->aa_value), &text); if (rc != LDAP_SUCCESS) { ldap_pvt_thread_rdwr_runlock(&(templa[template_index].t_rwlock)); -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "Unlock: Exiting QC index=%d\n", - template_index, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Unlock: Exiting QC index=%d\n", template_index, 0, 0 ); -#endif return 0; } } @@ -628,15 +617,9 @@ query_containment(query_manager *qm, } } } -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "Not answerable: Unlock QC index=%d\n", - template_index, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Not answerable: Unlock QC index=%d\n", template_index, 0, 0 ); -#endif ldap_pvt_thread_rdwr_runlock(&(templa[template_index].t_rwlock)); } return 0; @@ -674,13 +657,8 @@ static void add_query( new_cached_query->lru_up = NULL; new_cached_query->lru_down = NULL; new_cached_query->expiry_time = slap_get_time() + templ->ttl; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "Added query expires at %ld\n", - (long) new_cached_query->expiry_time, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Added query expires at %ld\n", (long) new_cached_query->expiry_time, 0, 0 ); -#endif new_query = (Query*)new_cached_query; ber_dupbv(&new_query->base, &query->base); @@ -689,13 +667,8 @@ static void add_query( new_query->attrs = query->attrs; /* Adding a query */ -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "Lock AQ index = %d\n", - template_index, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Lock AQ index = %d\n", template_index, 0, 0 ); -#endif ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock); if (templ->query == NULL) templ->query_last = new_cached_query; @@ -705,21 +678,11 @@ static void add_query( new_cached_query->prev = NULL; templ->query = new_cached_query; templ->no_of_queries++; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "TEMPLATE %d QUERIES++ %d\n", - template_index, templ->no_of_queries, 0 ); -#else Debug( LDAP_DEBUG_ANY, "TEMPLATE %d QUERIES++ %d\n", template_index, templ->no_of_queries, 0 ); -#endif -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "Unlock AQ index = %d \n", - template_index, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Unlock AQ index = %d \n", template_index, 0, 0 ); -#endif ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock); /* Adding on top of LRU list */ @@ -760,15 +723,9 @@ static void cache_replacement(query_manager* qm, struct berval *result) result->bv_len = 0; if (!bottom) { -#ifdef NEW_LOGGING - LDAP_LOG ( BACK_META, DETAIL1, - "Cache replacement invoked without " - "any query in LRU list\n", 0, 0, 0 ); -#else Debug ( LDAP_DEBUG_ANY, "Cache replacement invoked without " "any query in LRU list\n", 0, 0, 0 ); -#endif return; } @@ -779,25 +736,12 @@ static void cache_replacement(query_manager* qm, struct berval *result) *result = bottom->q_uuid; bottom->q_uuid.bv_val = NULL; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "Lock CR index = %d\n", temp_id, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Lock CR index = %d\n", temp_id, 0, 0 ); -#endif ldap_pvt_thread_rdwr_wlock(&(qm->templates[temp_id].t_rwlock)); remove_from_template(bottom, (qm->templates+temp_id)); -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "TEMPLATE %d QUERIES-- %d\n", - temp_id, qm->templates[temp_id].no_of_queries, 0 ); -#else Debug( LDAP_DEBUG_ANY, "TEMPLATE %d QUERIES-- %d\n", temp_id, qm->templates[temp_id].no_of_queries, 0 ); -#endif -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "Unlock CR index = %d\n", temp_id, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Unlock CR index = %d\n", temp_id, 0, 0 ); -#endif ldap_pvt_thread_rdwr_wunlock(&(qm->templates[temp_id].t_rwlock)); free_query(bottom); } @@ -869,8 +813,8 @@ remove_query_data ( op->o_req_ndn = op->o_bd->be_nsuffix[0]; op->ors_scope = LDAP_SCOPE_SUBTREE; op->ors_deref = LDAP_DEREF_NEVER; - op->ors_slimit = -1; - op->ors_tlimit = -1; + op->ors_slimit = SLAP_NO_LIMIT; + op->ors_tlimit = SLAP_NO_LIMIT; op->ors_filter = &filter; op->ors_filterstr.bv_val = filter_str; op->ors_filterstr.bv_len = strlen(filter_str); @@ -886,14 +830,8 @@ remove_query_data ( op->o_req_ndn = qi->xdn; if ( qi->del) { -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "DELETING ENTRY TEMPLATE=%s\n", - query_uuid->bv_val, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "DELETING ENTRY TEMPLATE=%s\n", query_uuid->bv_val, 0, 0 ); -#endif op->o_tag = LDAP_REQ_DELETE; @@ -913,15 +851,9 @@ remove_query_data ( mod.sml_values = vals; mod.sml_nvalues = NULL; mod.sml_next = NULL; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "REMOVING TEMP ATTR : TEMPLATE=%s\n", - query_uuid->bv_val, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "REMOVING TEMP ATTR : TEMPLATE=%s\n", query_uuid->bv_val, 0, 0 ); -#endif op->orm_modlist = &mod; @@ -1086,77 +1018,38 @@ cache_entries( op_tmp.o_dn = cm->db.be_rootdn; op_tmp.o_ndn = cm->db.be_rootndn; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "UUID for query being added = %s\n", - uuidbuf, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "UUID for query being added = %s\n", uuidbuf, 0, 0 ); -#endif /* !NEW_LOGGING */ for ( e=si->head; e; e=si->head ) { si->head = e->e_private; e->e_private = NULL; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL2, "LOCKING REMOVE MUTEX\n", - 0, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_NONE, "LOCKING REMOVE MUTEX\n", 0, 0, 0 ); -#endif /* !NEW_LOGGING */ ldap_pvt_thread_mutex_lock(&cm->remove_mutex); -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL2, "LOCKED REMOVE MUTEX\n", 0, 0, 0); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_NONE, "LOCKED REMOVE MUTEX\n", 0, 0, 0); -#endif /* !NEW_LOGGING */ while ( cm->cur_entries > (cm->max_entries) ) { qm->crfunc(qm, &crp_uuid); if (crp_uuid.bv_val) { -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "Removing query UUID %s\n", - crp_uuid.bv_val, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "Removing query UUID %s\n", crp_uuid.bv_val, 0, 0 ); -#endif /* !NEW_LOGGING */ return_val = remove_query_data(&op_tmp, rs, &crp_uuid); -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "QUERY REMOVED, SIZE=%d\n", - return_val, 0, 0); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "QUERY REMOVED, SIZE=%d\n", return_val, 0, 0); -#endif /* !NEW_LOGGING */ ldap_pvt_thread_mutex_lock( &cm->cache_mutex ); cm->cur_entries -= return_val; cm->num_cached_queries--; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "STORED QUERIES = %lu\n", - cm->num_cached_queries, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n", cm->num_cached_queries, 0, 0 ); -#endif /* !NEW_LOGGING */ ldap_pvt_thread_mutex_unlock( &cm->cache_mutex ); -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "QUERY REMOVED, CACHE =" - "%d entries\n", - cm->cur_entries, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "QUERY REMOVED, CACHE =" "%d entries\n", cm->cur_entries, 0, 0 ); -#endif /* !NEW_LOGGING */ } } @@ -1164,27 +1057,16 @@ cache_entries( ldap_pvt_thread_mutex_unlock(&cm->remove_mutex); ldap_pvt_thread_mutex_lock(&cm->cache_mutex); cm->cur_entries += return_val; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "ENTRY ADDED/MERGED, CACHED ENTRIES=%d\n", - cm->cur_entries, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "ENTRY ADDED/MERGED, CACHED ENTRIES=%d\n", cm->cur_entries, 0, 0 ); -#endif /* !NEW_LOGGING */ return_val = 0; ldap_pvt_thread_mutex_unlock(&cm->cache_mutex); } ldap_pvt_thread_mutex_lock(&cm->cache_mutex); cm->num_cached_queries++; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %lu\n", - cm->num_cached_queries, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n", cm->num_cached_queries, 0, 0 ); -#endif /* !NEW_LOGGING */ ldap_pvt_thread_mutex_unlock(&cm->cache_mutex); return return_val; @@ -1225,8 +1107,17 @@ proxy_cache_response( si->tail = NULL; } } - } else if ( rs->sr_type == REP_RESULT && si->count ) { - if ( cache_entries( op, rs, &uuid ) == 0) { + + if (rs->sr_attrs != op->ors_attrs ) { + op->o_tmpfree( rs->sr_attrs, op->o_tmpmemctx ); + } + rs->sr_attrs = si->query.save_attrs; + op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx ); + op->ors_attrs = si->query.save_attrs; + si->query.save_attrs = NULL; + + } else if ( rs->sr_type == REP_RESULT ) { + if ( si->count && cache_entries( op, rs, &uuid ) == 0 ) { qm->addfunc(qm, &si->query, si->template_id, &uuid); /* If the consistency checker suspended itself, * wake it back up @@ -1240,6 +1131,9 @@ proxy_cache_response( ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex ); } } + + /* free self */ + op->o_callback->sc_cleanup = slap_freeself_cb; } return SLAP_CB_CONTINUE; } @@ -1335,19 +1229,15 @@ proxy_cache_search( return SLAP_CB_CONTINUE; } -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "query template of incoming query = %s\n", - tempstr.bv_val, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "query template of incoming query = %s\n", tempstr.bv_val, 0, 0 ); -#endif /* !NEW_LOGGING */ /* find attr set */ attr_set = get_attr_set(op->ors_attrs, qm, cm->numattrsets); query.filter = op->ors_filter; query.attrs = op->ors_attrs; + query.save_attrs = NULL; query.base = op->o_req_ndn; query.scope = op->ors_scope; @@ -1361,14 +1251,8 @@ proxy_cache_search( cacheable = 1; template_id = i; } -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL2, - "Entering QC, querystr = %s\n", - op->ors_filterstr.bv_val, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_NONE, "Entering QC, querystr = %s\n", op->ors_filterstr.bv_val, 0, 0 ); -#endif /* !NEW_LOGGING */ answerable = (*(qm->qcfunc))(qm, &query, i); if (answerable) @@ -1377,27 +1261,27 @@ proxy_cache_search( } op->o_tmpfree( tempstr.bv_val, op->o_tmpmemctx ); + query.save_attrs = op->ors_attrs; + query.attrs = NULL; + if (answerable) { - BackendDB *be = op->o_bd; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "QUERY ANSWERABLE\n", 0, 0, 0 ); -#else /* !NEW_LOGGING */ + /* Need to clear the callbacks of the original operation, + * in case there are other overlays */ + BackendDB *save_bd = op->o_bd; + slap_callback *save_cb = op->o_callback; + Debug( LDAP_DEBUG_ANY, "QUERY ANSWERABLE\n", 0, 0, 0 ); -#endif /* !NEW_LOGGING */ free(filter_attrs); ldap_pvt_thread_rdwr_runlock(&qm->templates[i].t_rwlock); op->o_bd = &cm->db; + op->o_callback = NULL; i = cm->db.bd_info->bi_op_search( op, rs ); - op->o_bd = be; + op->o_bd = save_bd; + op->o_callback = save_cb; return i; } -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "QUERY NOT ANSWERABLE\n", - 0, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "QUERY NOT ANSWERABLE\n", 0, 0, 0 ); -#endif /* !NEW_LOGGING */ ldap_pvt_thread_mutex_lock(&cm->cache_mutex); if (cm->num_cached_queries >= cm->max_queries) { @@ -1406,23 +1290,20 @@ proxy_cache_search( ldap_pvt_thread_mutex_unlock(&cm->cache_mutex); if (cacheable) { - slap_callback *cb; - struct search_info *si; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "QUERY CACHEABLE\n", 0, 0, 0 ); -#else /* !NEW_LOGGING */ + slap_callback *cb; + struct search_info *si; + Debug( LDAP_DEBUG_ANY, "QUERY CACHEABLE\n", 0, 0, 0 ); -#endif /* !NEW_LOGGING */ query.filter = str2filter(op->ors_filterstr.bv_val); if (op->ors_attrs) { - for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ ) { - if ( op->ors_attrs[count].an_desc == slap_schema.si_ad_objectClass ) + for ( count = 0; !BER_BVISNULL( &op->ors_attrs[ count ].an_name ); count++ ) { + if ( op->ors_attrs[count].an_desc == slap_schema.si_ad_objectClass ) { oc_attr_absent = 0; + } } - query.attrs = (AttributeName*)ch_malloc( ( count + 1 + oc_attr_absent ) - *sizeof(AttributeName)); - for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ ) { + query.attrs = (AttributeName *)ch_malloc( ( count + 1 + oc_attr_absent ) + *sizeof(AttributeName) ); + for ( count = 0; !BER_BVISNULL( &op->ors_attrs[ count ].an_name ); count++ ) { ber_dupbv( &query.attrs[count].an_name, &op->ors_attrs[count].an_name ); query.attrs[count].an_desc = op->ors_attrs[count].an_desc; } @@ -1435,10 +1316,9 @@ proxy_cache_search( query.attrs[ count ].an_name.bv_val = NULL; query.attrs[ count ].an_name.bv_len = 0; } - op->o_tmpfree(op->ors_attrs, op->o_tmpmemctx); add_filter_attrs(op, &op->ors_attrs, query.attrs, filter_attrs); + cb = op->o_tmpalloc( sizeof(*cb) + sizeof(*si), op->o_tmpmemctx); - cb->sc_next = op->o_callback; cb->sc_response = proxy_cache_response; cb->sc_cleanup = NULL; cb->sc_private = (cb+1); @@ -1451,16 +1331,25 @@ proxy_cache_search( si->count = 0; si->head = NULL; si->tail = NULL; - op->o_callback = cb; + + if ( cm->response_cb == PCACHE_RESPONSE_CB_HEAD ) { + cb->sc_next = op->o_callback; + op->o_callback = cb; + + } else { + slap_callback **pcb; + + /* need to move the callback at the end, in case other + * overlays are present, so that the final entry is + * actually cached */ + cb->sc_next = NULL; + for ( pcb = &op->o_callback; *pcb; pcb = &(*pcb)->sc_next ); + *pcb = cb; + } + } else { -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "QUERY NOT CACHEABLE\n", - 0, 0, 0); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "QUERY NOT CACHEABLE\n", 0, 0, 0); -#endif /* !NEW_LOGGING */ } free(filter_attrs); @@ -1547,62 +1436,28 @@ consistency_check( ldap_pvt_thread_mutex_lock(&qm->lru_mutex); remove_query(qm, query); ldap_pvt_thread_mutex_unlock(&qm->lru_mutex); -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "Lock CR index = %d\n", - i, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "Lock CR index = %d\n", i, 0, 0 ); -#endif /* !NEW_LOGGING */ ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock); remove_from_template(query, templ); -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "TEMPLATE %d QUERIES-- %d\n", - i, templ->no_of_queries, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "TEMPLATE %d QUERIES-- %d\n", i, templ->no_of_queries, 0 ); -#endif /* !NEW_LOGGING */ -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "Unlock CR index = %d\n", - i, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "Unlock CR index = %d\n", i, 0, 0 ); -#endif /* !NEW_LOGGING */ ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock); return_val = remove_query_data(&op, &rs, &query->q_uuid); -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "STALE QUERY REMOVED, SIZE=%d\n", - return_val, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "STALE QUERY REMOVED, SIZE=%d\n", return_val, 0, 0 ); -#endif /* !NEW_LOGGING */ ldap_pvt_thread_mutex_lock(&cm->cache_mutex); cm->cur_entries -= return_val; cm->num_cached_queries--; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %lu\n", - cm->num_cached_queries, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n", cm->num_cached_queries, 0, 0 ); -#endif /* !NEW_LOGGING */ ldap_pvt_thread_mutex_unlock(&cm->cache_mutex); -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "STALE QUERY REMOVED, CACHE =" - "%d entries\n", - cm->cur_entries, 0, 0 ); -#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ANY, "STALE QUERY REMOVED, CACHE =" "%d entries\n", cm->cur_entries, 0, 0 ); -#endif /* !NEW_LOGGING */ query_prev = query; query = query->prev; free_query(query_prev); @@ -1635,16 +1490,23 @@ proxy_cache_config( char **argv ) { - slap_overinst *on = (slap_overinst *)be->bd_info; + slap_overinst *on = (slap_overinst *)be->bd_info; cache_manager* cm = on->on_bi.bi_private; query_manager* qm = cm->qm; QueryTemplate* temp; AttributeName* attr_name; AttributeName* attrarray; const char* text=NULL; + char *save_argv0 = NULL; int index, i; int num; + int rc = 0; + + if ( strncasecmp( argv[0], "proxycache-", STRLENOF( "proxycache-" ) ) == 0 ) { + save_argv0 = argv[0]; + argv[0] += STRLENOF( "proxycache-" ); + } if ( strcasecmp( argv[0], "proxycache" ) == 0 ) { if ( argc < 6 ) { @@ -1676,15 +1538,9 @@ proxy_cache_config( cm->num_entries_limit = atoi( argv[4] ); cm->cc_period = atoi( argv[5] ); -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "Total # of attribute sets to be cached = %d\n", - cm->numattrsets, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Total # of attribute sets to be cached = %d\n", cm->numattrsets, 0, 0 ); -#endif qm->attr_sets = ( struct attr_set * )ch_malloc( cm->numattrsets * sizeof( struct attr_set )); for ( i = 0; i < cm->numattrsets; i++ ) { @@ -1697,13 +1553,8 @@ proxy_cache_config( " \"\n", fname, lineno ); return( 1 ); } -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "Attribute Set # %d\n", - atoi( argv[1] ), 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Attribute Set # %d\n", atoi( argv[1] ), 0, 0 ); -#endif if (atoi(argv[1]) >= cm->numattrsets) { fprintf( stderr, "%s; line %d index out of bounds \n", fname, lineno ); @@ -1716,13 +1567,8 @@ proxy_cache_config( (argc-1) * sizeof( AttributeName )); attr_name = qm->attr_sets[index].attrs; for ( i = 2; i < argc; i++ ) { -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "\t %s\n", - argv[i], 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "\t %s\n", argv[i], 0, 0 ); -#endif ber_str2bv( argv[i], 0, 1, &attr_name->an_name); attr_name->an_desc = NULL; @@ -1741,15 +1587,9 @@ proxy_cache_config( return( 1 ); } if (( i = atoi( argv[2] )) >= cm->numattrsets ) { -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "%s: line %d, template index invalid\n", - fname, lineno, 0 ); -#else Debug( LDAP_DEBUG_ANY, "%s: line %d, template index invalid\n", fname, lineno, 0 ); -#endif return 1; } num = cm->numtemplates; @@ -1763,55 +1603,62 @@ proxy_cache_config( temp->ttl = atoi( argv[3] ); temp->no_of_queries = 0; if ( argv[1] == NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, - "Templates string not specified " - "for template %d\n", num, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Templates string not specified " "for template %d\n", num, 0, 0 ); -#endif return 1; } ber_str2bv( argv[1], 0, 1, &temp->querystr ); -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "Template:\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "Template:\n", 0, 0, 0 ); -#endif -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, " query template: %s\n", - temp->querystr.bv_val, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, " query template: %s\n", temp->querystr.bv_val, 0, 0 ); -#endif temp->attr_set_index = i; -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, " attributes: \n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, " attributes: \n", 0, 0, 0 ); -#endif if ( ( attrarray = qm->attr_sets[i].attrs ) != NULL ) { for ( i=0; attrarray[i].an_name.bv_val; i++ ) -#ifdef NEW_LOGGING - LDAP_LOG( BACK_META, DETAIL1, "\t%s\n", - attrarray[i].an_name.bv_val, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "\t%s\n", attrarray[i].an_name.bv_val, 0, 0 ); -#endif } temp++; temp->querystr.bv_val = NULL; cm->numtemplates++; + + } else if ( strcasecmp( argv[0], "response-callback" ) == 0 ) { + /* set to "tail" to put the response callback + * at the end of the callback list; this is required + * in case other overlays are present, so that the + * final entry is cached. */ + + if ( argc < 2 ) { + Debug( LDAP_DEBUG_ANY, + "missing specifier for \"response-callback {head(default)|tail}\" " + "callback position\n", 0, 0, 0 ); + return 1; + } + + if ( strcasecmp( argv[1], "head" ) == 0 ) { + cm->response_cb = PCACHE_RESPONSE_CB_HEAD; + + } else if ( strcasecmp( argv[1], "tail" ) == 0 ) { + cm->response_cb = PCACHE_RESPONSE_CB_TAIL; + + } else { + Debug( LDAP_DEBUG_ANY, + "unknown specifier %s for \"response-callback {head(default)|tail}\" " + "callback position\n", argv[1], 0, 0 ); + return 1; + } } /* anything else */ else { - return cm->db.bd_info->bi_db_config( &cm->db, fname, lineno, argc, argv ); + rc = cm->db.bd_info->bi_db_config( &cm->db, fname, lineno, argc, argv ); } - return 0; + + if ( save_argv0 ) { + argv[0] = save_argv0; + } + + return rc; } static int @@ -1831,6 +1678,7 @@ proxy_cache_init( cm->db = *be; SLAP_DBFLAGS(&cm->db) |= SLAP_DBFLAG_NO_SCHEMA_CHECK; cm->db.be_private = NULL; + cm->db.be_pcl_mutexp = &cm->db.be_pcl_mutex; cm->qm = qm; cm->numattrsets = 0; cm->numtemplates = 0; @@ -1839,6 +1687,7 @@ proxy_cache_init( cm->max_entries = 0; cm->cur_entries = 0; cm->max_queries = 10000; + cm->response_cb = PCACHE_RESPONSE_CB_TAIL; cm->cc_period = 1000; cm->cc_paused = 0; @@ -1862,20 +1711,42 @@ proxy_cache_open( BackendDB *be ) { - slap_overinst *on = (slap_overinst *)be->bd_info; - cache_manager *cm = on->on_bi.bi_private; - int rc = 0; + slap_overinst *on = (slap_overinst *)be->bd_info; + cache_manager *cm = on->on_bi.bi_private; + int rc = 0; + int i; - if ( cm->db.bd_info->bi_db_open ) { - rc = cm->db.bd_info->bi_db_open( &cm->db ); + /* consistency check (add more...) */ + for ( i = 0; i < cm->numattrsets; i++ ) { + if ( cm->qm->attr_sets[i].attrs == NULL ) { + fprintf( stderr, "proxy_cache_open(): " + "attr set %d (of %d) missing\n", + i, cm->numattrsets ); + return 1; + } } + rc = backend_startup_one( &cm->db ); + /* There is no runqueue in TOOL mode */ if ( slapMode & SLAP_SERVER_MODE ) { ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex ); ldap_pvt_runqueue_insert( &syncrepl_rq, cm->cc_period, consistency_check, on ); ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex ); + + /* Cached database must have the rootdn */ + if ( BER_BVISNULL( &cm->db.be_rootndn ) + || BER_BVISEMPTY( &cm->db.be_rootndn ) ) + { + fprintf( stderr, "proxy_cache_open(): " + "underlying database of type \"%s\"\n" + " serving naming context \"%s\"\n" + " has no \"rootdn\", required by \"proxycache\".\n", + on->on_info->oi_orig->bi_type, + cm->db.be_suffix[0].bv_val ); + return 1; + } } return rc;