mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
expose cachedQueryURL in overlay's monitor entry (partial fulfilment of ITS#5178; needs new register_overlay() code in back-monitor)
This commit is contained in:
parent
d4f88422fd
commit
ef7569fdc0
@ -33,6 +33,8 @@
|
||||
#include "ldap_rq.h"
|
||||
#include "avl.h"
|
||||
|
||||
#include "../back-monitor/back-monitor.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef LDAP_DEVEL
|
||||
@ -46,6 +48,11 @@
|
||||
* Extended Operation that allows to remove a query from the cache
|
||||
*/
|
||||
#define PCACHE_EXOP_QUERY_DELETE "1.3.6.1.4.1.4203.666.11.9.6.1"
|
||||
|
||||
/*
|
||||
* Monitoring
|
||||
*/
|
||||
#define PCACHE_MONITOR
|
||||
#endif
|
||||
|
||||
/* query cache structs */
|
||||
@ -101,6 +108,8 @@ typedef struct cached_query_s {
|
||||
*
|
||||
* quick hack: parse URI, call add_query() and then fix
|
||||
* CachedQuery.expiry_time and CachedQuery.q_uuid
|
||||
*
|
||||
* NOTE: if the <attrset> changes, all stored URLs will be invalidated.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -209,20 +218,48 @@ typedef struct cache_manager_s {
|
||||
ldap_pvt_thread_mutex_t cache_mutex;
|
||||
|
||||
query_manager* qm; /* query cache managed by the cache manager */
|
||||
|
||||
#ifdef PCACHE_MONITOR
|
||||
void *monitor_cb;
|
||||
struct berval monitor_ndn;
|
||||
#endif /* PCACHE_MONITOR */
|
||||
} cache_manager;
|
||||
|
||||
#ifdef PCACHE_MONITOR
|
||||
static int pcache_monitor_db_init( BackendDB *be );
|
||||
static int pcache_monitor_db_open( BackendDB *be );
|
||||
static int pcache_monitor_db_close( BackendDB *be );
|
||||
static int pcache_monitor_db_destroy( BackendDB *be );
|
||||
#endif /* PCACHE_MONITOR */
|
||||
|
||||
static int pcache_debug;
|
||||
|
||||
#ifdef PCACHE_CONTROL_PRIVDB
|
||||
static int privDB_cid;
|
||||
#endif /* PCACHE_CONTROL_PRIVDB */
|
||||
|
||||
static AttributeDescription *ad_queryId, *ad_cachedQueryURL;
|
||||
static AttributeDescription *ad_queryId, *ad_cachedQueryURL;
|
||||
|
||||
#ifdef PCACHE_MONITOR
|
||||
static ObjectClass *oc_olmPCache;
|
||||
#endif /* PCACHE_MONITOR */
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
char *oid;
|
||||
} s_oid[] = {
|
||||
{ "PCacheOID", "1.3.6.1.4.1.4203.666.11.9.1" },
|
||||
{ "PCacheAttributes", "PCacheOID:1" },
|
||||
{ "PCacheObjectClasses", "PCacheOID:2" },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static struct {
|
||||
char *desc;
|
||||
AttributeDescription **adp;
|
||||
} as[] = {
|
||||
{ "( 1.3.6.1.4.1.4203.666.11.9.1.1 "
|
||||
} s_ad[] = {
|
||||
{ "( PCacheAttributes:1 "
|
||||
"NAME 'queryId' "
|
||||
"DESC 'ID of query the entry belongs to, formatted as a UUID' "
|
||||
"EQUALITY octetStringMatch "
|
||||
@ -230,7 +267,7 @@ static struct {
|
||||
"NO-USER-MODIFICATION "
|
||||
"USAGE directoryOperation )",
|
||||
&ad_queryId },
|
||||
{ "( 1.3.6.1.4.1.4203.666.11.9.1.2 "
|
||||
{ "( PCacheAttributes:2 "
|
||||
"NAME 'cachedQueryURL' "
|
||||
"DESC 'URI describing a cached query' "
|
||||
"EQUALITY caseExactMatch "
|
||||
@ -238,6 +275,25 @@ static struct {
|
||||
"NO-USER-MODIFICATION "
|
||||
"USAGE directoryOperation )",
|
||||
&ad_cachedQueryURL },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static struct {
|
||||
char *desc;
|
||||
ObjectClass **ocp;
|
||||
} s_oc[] = {
|
||||
#ifdef PCACHE_MONITOR
|
||||
/* augments an existing object, so it must be AUXILIARY */
|
||||
{ "( PCacheObjectClasses:1 "
|
||||
"NAME ( 'olmPCache' ) "
|
||||
"SUP top AUXILIARY "
|
||||
"MAY ( "
|
||||
"cachedQueryURL"
|
||||
") )",
|
||||
&oc_olmPCache },
|
||||
#endif /* PCACHE_MONITOR */
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -2399,6 +2455,8 @@ pcache_op_privdb(
|
||||
if ( type == SLAP_OP_BIND && rc == LDAP_SUCCESS ) {
|
||||
op->o_conn->c_authz_cookie = cm->db.be_private;
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3739,7 +3797,12 @@ pcache_db_init(
|
||||
ldap_pvt_thread_mutex_init(&qm->lru_mutex);
|
||||
|
||||
ldap_pvt_thread_mutex_init(&cm->cache_mutex);
|
||||
|
||||
#ifndef PCACHE_MONITOR
|
||||
return 0;
|
||||
#else /* PCACHE_MONITOR */
|
||||
return pcache_monitor_db_init( be );
|
||||
#endif /* PCACHE_MONITOR */
|
||||
}
|
||||
|
||||
static int
|
||||
@ -3951,8 +4014,15 @@ pcache_db_open(
|
||||
SLAP_DBFLAGS( &cm->db ) &= ~SLAP_DBFLAG_MONITORING;
|
||||
}
|
||||
|
||||
if ( !cm->defer_db_open )
|
||||
if ( !cm->defer_db_open ) {
|
||||
rc = pcache_db_open2( on, cr );
|
||||
}
|
||||
|
||||
#ifdef PCACHE_MONITOR
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
rc = pcache_monitor_db_open( be );
|
||||
}
|
||||
#endif /* PCACHE_MONITOR */
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -4081,6 +4151,12 @@ pcache_db_close(
|
||||
free( qm->attr_sets );
|
||||
qm->attr_sets = NULL;
|
||||
|
||||
#ifdef PCACHE_MONITOR
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
rc = pcache_monitor_db_close( be );
|
||||
}
|
||||
#endif /* PCACHE_MONITOR */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -4103,6 +4179,10 @@ pcache_db_destroy(
|
||||
free( qm );
|
||||
free( cm );
|
||||
|
||||
#ifdef PCACHE_MONITOR
|
||||
pcache_monitor_db_destroy( be );
|
||||
#endif /* PCACHE_MONITOR */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4468,6 +4548,235 @@ pcache_op_extended( Operation *op, SlapReply *rs )
|
||||
}
|
||||
#endif /* PCACHE_EXOP_QUERY_DELETE */
|
||||
|
||||
#ifdef PCACHE_MONITOR
|
||||
|
||||
static int
|
||||
pcache_monitor_update(
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
Entry *e,
|
||||
void *priv )
|
||||
{
|
||||
cache_manager *cm = (cache_manager *) priv;
|
||||
query_manager *qm = cm->qm;
|
||||
|
||||
CachedQuery *qc;
|
||||
BerVarray vals = NULL;
|
||||
|
||||
Attribute *a;
|
||||
int num = 0;
|
||||
|
||||
if ( qm->templates != NULL ) {
|
||||
QueryTemplate *tm;
|
||||
|
||||
for ( tm = qm->templates; tm != NULL; tm = tm->qmnext ) {
|
||||
for ( qc = tm->query; qc; qc = qc->next ) {
|
||||
struct berval bv;
|
||||
|
||||
if ( query2url( op, qc, &bv, 1 ) == 0 ) {
|
||||
ber_bvarray_add_x( &vals, &bv, op->o_tmpmemctx );
|
||||
num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert( ad_cachedQueryURL != NULL );
|
||||
|
||||
attr_delete( &e->e_attrs, ad_cachedQueryURL );
|
||||
if ( vals == NULL ) {
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
attr_merge_normalize( e, ad_cachedQueryURL, vals, NULL );
|
||||
ber_bvarray_free_x( vals, op->o_tmpmemctx );
|
||||
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
pcache_monitor_free(
|
||||
Entry *e,
|
||||
void **priv )
|
||||
{
|
||||
struct berval values[ 2 ];
|
||||
Modification mod = { 0 };
|
||||
|
||||
const char *text;
|
||||
char textbuf[ SLAP_TEXT_BUFLEN ];
|
||||
|
||||
int rc;
|
||||
|
||||
/* NOTE: if slap_shutdown != 0, priv might have already been freed */
|
||||
*priv = NULL;
|
||||
|
||||
/* Remove objectClass */
|
||||
mod.sm_op = LDAP_MOD_DELETE;
|
||||
mod.sm_desc = slap_schema.si_ad_objectClass;
|
||||
mod.sm_values = values;
|
||||
mod.sm_numvals = 1;
|
||||
values[ 0 ] = oc_olmPCache->soc_cname;
|
||||
BER_BVZERO( &values[ 1 ] );
|
||||
|
||||
rc = modify_delete_values( e, &mod, 1, &text,
|
||||
textbuf, sizeof( textbuf ) );
|
||||
/* don't care too much about return code... */
|
||||
|
||||
/* remove attrs */
|
||||
mod.sm_values = NULL;
|
||||
mod.sm_desc = ad_cachedQueryURL;
|
||||
mod.sm_numvals = 0;
|
||||
rc = modify_delete_values( e, &mod, 1, &text,
|
||||
textbuf, sizeof( textbuf ) );
|
||||
/* don't care too much about return code... */
|
||||
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* call from within pcache_initialize()
|
||||
*/
|
||||
static int
|
||||
pcache_monitor_initialize( void )
|
||||
{
|
||||
static int pcache_monitor_initialized = 0;
|
||||
|
||||
if ( backend_info( "monitor" ) == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( pcache_monitor_initialized++ ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pcache_monitor_db_init( BackendDB *be )
|
||||
{
|
||||
if ( pcache_monitor_initialize() == LDAP_SUCCESS ) {
|
||||
SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_MONITORING;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pcache_monitor_db_open( BackendDB *be )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)be->bd_info;
|
||||
cache_manager *cm = on->on_bi.bi_private;
|
||||
Attribute *a, *next;
|
||||
monitor_callback_t *cb = NULL;
|
||||
int rc = 0;
|
||||
BackendInfo *mi;
|
||||
monitor_extra_t *mbe;
|
||||
struct berval dummy = BER_BVC( "" );
|
||||
|
||||
if ( !SLAP_DBMONITORING( be ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
mi = backend_info( "monitor" );
|
||||
if ( !mi || !mi->bi_extra ) {
|
||||
SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING;
|
||||
return 0;
|
||||
}
|
||||
mbe = mi->bi_extra;
|
||||
|
||||
/* don't bother if monitor is not configured */
|
||||
if ( !mbe->is_configured() ) {
|
||||
static int warning = 0;
|
||||
|
||||
if ( warning++ == 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "pcache_monitor_db_open: "
|
||||
"monitoring disabled; "
|
||||
"configure monitor database to enable\n",
|
||||
0, 0, 0 );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* alloc as many as required (plus 1 for objectClass) */
|
||||
a = attrs_alloc( 1 + 0 );
|
||||
if ( a == NULL ) {
|
||||
rc = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
a->a_desc = slap_schema.si_ad_objectClass;
|
||||
attr_valadd( a, &oc_olmPCache->soc_cname, NULL, 1 );
|
||||
next = a->a_next;
|
||||
|
||||
cb = ch_calloc( sizeof( monitor_callback_t ), 1 );
|
||||
cb->mc_update = pcache_monitor_update;
|
||||
cb->mc_free = pcache_monitor_free;
|
||||
cb->mc_private = (void *)cm;
|
||||
|
||||
/* make sure the database is registered; then add monitor attributes */
|
||||
BER_BVZERO( &cm->monitor_ndn );
|
||||
rc = mbe->register_overlay( be, on, &cm->monitor_ndn );
|
||||
if ( rc == 0 ) {
|
||||
rc = mbe->register_entry_attrs( &cm->monitor_ndn, a, cb,
|
||||
&dummy, -1, &dummy);
|
||||
}
|
||||
|
||||
cleanup:;
|
||||
if ( rc != 0 ) {
|
||||
if ( cb != NULL ) {
|
||||
ch_free( cb );
|
||||
cb = NULL;
|
||||
}
|
||||
|
||||
if ( a != NULL ) {
|
||||
attrs_free( a );
|
||||
a = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* store for cleanup */
|
||||
cm->monitor_cb = (void *)cb;
|
||||
|
||||
/* we don't need to keep track of the attributes, because
|
||||
* bdb_monitor_free() takes care of everything */
|
||||
if ( a != NULL ) {
|
||||
attrs_free( a );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
pcache_monitor_db_close( BackendDB *be )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)be->bd_info;
|
||||
cache_manager *cm = on->on_bi.bi_private;
|
||||
|
||||
if ( cm->monitor_cb != NULL ) {
|
||||
BackendInfo *mi = backend_info( "monitor" );
|
||||
monitor_extra_t *mbe;
|
||||
|
||||
if ( mi && &mi->bi_extra ) {
|
||||
mbe = mi->bi_extra;
|
||||
mbe->unregister_entry_callback( NULL,
|
||||
(monitor_callback_t *)cm->monitor_cb,
|
||||
NULL, 0, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pcache_monitor_db_destroy( BackendDB *be )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* PCACHE_MONITOR */
|
||||
|
||||
static slap_overinst pcache;
|
||||
|
||||
static char *obsolete_names[] = {
|
||||
@ -4483,6 +4792,8 @@ pcache_initialize()
|
||||
{
|
||||
int i, code;
|
||||
struct berval debugbv = BER_BVC("pcache");
|
||||
ConfigArgs c;
|
||||
char *argv[ 4 ];
|
||||
|
||||
code = slap_loglevel_get( &debugbv, &pcache_debug );
|
||||
if ( code ) {
|
||||
@ -4513,14 +4824,42 @@ pcache_initialize()
|
||||
}
|
||||
#endif /* PCACHE_EXOP_QUERY_DELETE */
|
||||
|
||||
for ( i = 0; as[i].desc != NULL; i++ ) {
|
||||
code = register_at( as[i].desc, as[i].adp, 0 );
|
||||
argv[ 0 ] = "back-bdb/back-hdb monitor";
|
||||
c.argv = argv;
|
||||
c.argc = 3;
|
||||
c.fname = argv[0];
|
||||
|
||||
for ( i = 0; s_oid[ i ].name; i++ ) {
|
||||
c.lineno = i;
|
||||
argv[ 1 ] = s_oid[ i ].name;
|
||||
argv[ 2 ] = s_oid[ i ].oid;
|
||||
|
||||
if ( parse_oidm( &c, 0, NULL ) != 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "pcache_initialize: "
|
||||
"unable to add objectIdentifier \"%s=%s\"\n",
|
||||
s_oid[ i ].name, s_oid[ i ].oid, 0 );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 0; s_ad[i].desc != NULL; i++ ) {
|
||||
code = register_at( s_ad[i].desc, s_ad[i].adp, 0 );
|
||||
if ( code ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"pcache_initialize: register_at #%d failed\n", i, 0, 0 );
|
||||
return code;
|
||||
}
|
||||
(*as[i].adp)->ad_type->sat_flags |= SLAP_AT_HIDE;
|
||||
(*s_ad[i].adp)->ad_type->sat_flags |= SLAP_AT_HIDE;
|
||||
}
|
||||
|
||||
for ( i = 0; s_oc[i].desc != NULL; i++ ) {
|
||||
code = register_oc( s_oc[i].desc, s_oc[i].ocp, 0 );
|
||||
if ( code ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"pcache_initialize: register_oc #%d failed\n", i, 0, 0 );
|
||||
return code;
|
||||
}
|
||||
(*s_oc[i].ocp)->soc_flags |= SLAP_OC_HIDE;
|
||||
}
|
||||
|
||||
pcache.on_bi.bi_type = "pcache";
|
||||
|
Loading…
Reference in New Issue
Block a user