From: Pierangelo Masarati Date: Wed, 6 Sep 2006 01:54:54 +0000 (+0000) Subject: - setup framework for monitoring of back-bdb/back-hdb stuff in their X-Git-Tag: OPENLDAP_REL_ENG_2_3_MP~209 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=55f24ce8f69543f9531ab94618459104c2a8ac0b;p=openldap - setup framework for monitoring of back-bdb/back-hdb stuff in their database entry in cn=monitor - improve support for custom attribute/callback registration in back-monitor - design API for registered antry/attr/callback removal in back-monitor HEADS UP: now back-bdb requires back-monitor to be present, either static or dynamically loaded __before__ back-bdb/back-hdb is initialized. This works for sure if both back-bdb & back-monitor are static or dynamic (provided back-monitor.la is loaded before back_bdb.la); it is not clear what happens if back-bdb is static and back-monitor is dynamic. In case, either make back-bdb monitoring conditional, or hardwire back-monitor much like back-config and back-ldif. --- diff --git a/configure b/configure index 43694150d6..83f1233fd8 100755 --- a/configure +++ b/configure @@ -40109,6 +40109,23 @@ cat >>confdefs.h <<\_ACEOF _ACEOF +if test "$ol_enable_monitor" != no ; then + BUILD_SLAPD=yes + BUILD_MONITOR=$ol_enable_monitor + if test "$ol_enable_monitor" = mod ; then + SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-monitor" + MFLAG=SLAPD_MOD_DYNAMIC + else + SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-monitor" + MFLAG=SLAPD_MOD_STATIC + fi + +cat >>confdefs.h <<_ACEOF +#define SLAPD_MONITOR $MFLAG +_ACEOF + +fi + if test "$ol_enable_bdb" != no ; then BUILD_SLAPD=yes BUILD_BDB=$ol_enable_bdb @@ -40195,23 +40212,6 @@ _ACEOF fi -if test "$ol_enable_monitor" != no ; then - BUILD_SLAPD=yes - BUILD_MONITOR=$ol_enable_monitor - if test "$ol_enable_monitor" = mod ; then - SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-monitor" - MFLAG=SLAPD_MOD_DYNAMIC - else - SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-monitor" - MFLAG=SLAPD_MOD_STATIC - fi - -cat >>confdefs.h <<_ACEOF -#define SLAPD_MONITOR $MFLAG -_ACEOF - -fi - if test "$ol_enable_null" != no ; then BUILD_SLAPD=yes BUILD_NULL=$ol_enable_null diff --git a/configure.in b/configure.in index 692d8d3384..aa2b1fe72e 100644 --- a/configure.in +++ b/configure.in @@ -2562,6 +2562,20 @@ fi AC_DEFINE(SLAPD_MOD_STATIC,1,[statically linked module]) AC_DEFINE(SLAPD_MOD_DYNAMIC,2,[dynamically linked module]) +dnl back-monitor goes first (well, after back-config) +if test "$ol_enable_monitor" != no ; then + BUILD_SLAPD=yes + BUILD_MONITOR=$ol_enable_monitor + if test "$ol_enable_monitor" = mod ; then + SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-monitor" + MFLAG=SLAPD_MOD_DYNAMIC + else + SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-monitor" + MFLAG=SLAPD_MOD_STATIC + fi + AC_DEFINE_UNQUOTED(SLAPD_MONITOR,$MFLAG,[define to support cn=Monitor backend]) +fi + if test "$ol_enable_bdb" != no ; then BUILD_SLAPD=yes BUILD_BDB=$ol_enable_bdb @@ -2628,19 +2642,6 @@ if test "$ol_enable_meta" != no ; then AC_DEFINE_UNQUOTED(SLAPD_META,$MFLAG,[define to support LDAP Metadirectory backend]) fi -if test "$ol_enable_monitor" != no ; then - BUILD_SLAPD=yes - BUILD_MONITOR=$ol_enable_monitor - if test "$ol_enable_monitor" = mod ; then - SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-monitor" - MFLAG=SLAPD_MOD_DYNAMIC - else - SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-monitor" - MFLAG=SLAPD_MOD_STATIC - fi - AC_DEFINE_UNQUOTED(SLAPD_MONITOR,$MFLAG,[define to support cn=Monitor backend]) -fi - if test "$ol_enable_null" != no ; then BUILD_SLAPD=yes BUILD_NULL=$ol_enable_null diff --git a/servers/slapd/back-bdb/Makefile.in b/servers/slapd/back-bdb/Makefile.in index 06a987f489..4f1d8d0cc9 100644 --- a/servers/slapd/back-bdb/Makefile.in +++ b/servers/slapd/back-bdb/Makefile.in @@ -18,14 +18,14 @@ SRCS = init.c tools.c config.c \ extended.c referral.c operational.c \ attr.c index.c key.c dbcache.c filterindex.c \ dn2entry.c dn2id.c error.c id2entry.c idl.c \ - nextid.c cache.c trans.c + nextid.c cache.c trans.c monitor.c OBJS = init.lo tools.lo config.lo \ add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \ extended.lo referral.lo operational.lo \ attr.lo index.lo key.lo dbcache.lo filterindex.lo \ dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo \ - nextid.lo cache.lo trans.lo + nextid.lo cache.lo trans.lo monitor.lo LDAP_INCDIR= ../../../include LDAP_LIBDIR= ../../../libraries diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index dccc329070..fcdab9ad2c 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -422,6 +422,12 @@ bdb_db_open( BackendDB *be ) XLOCK_ID(bdb->bi_dbenv, &bdb->bi_cache.c_locker); } + /* monitor setup */ + rc = bdb_monitor_open( be ); + if ( rc != 0 ) { + goto fail; + } + bdb->bi_flags |= BDB_IS_OPEN; entry_prealloc( bdb->bi_cache.c_maxsize ); @@ -663,6 +669,14 @@ bdb_back_initialize( bi->bi_connection_init = 0; bi->bi_connection_destroy = 0; + /* + * initialize monitor stuff + */ + rc = bdb_monitor_initialize(); + if ( rc ) { + return rc; + } + rc = bdb_back_init_cf( bi ); return rc; diff --git a/servers/slapd/back-bdb/monitor.c b/servers/slapd/back-bdb/monitor.c new file mode 100644 index 0000000000..aaabe0a0d4 --- /dev/null +++ b/servers/slapd/back-bdb/monitor.c @@ -0,0 +1,351 @@ +/* monitor.c - monitor bdb backend */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 2000-2006 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ + +#include "portable.h" + +#include +#include +#include +#include +#include +#include +#include "lutil.h" +#include "back-bdb.h" +#include "../back-monitor/back-monitor.h" + +static ObjectClass *oc_olmBDBDatabase; + +static AttributeDescription *ad_olmBDBCounter; + +static int +bdb_monitor_update( + Operation *op, + SlapReply *rs, + Entry *e, + void *priv ) +{ + struct bdb_info *bdb = (struct bdb_info *) priv; + Attribute *a; + + /* NOTE: dummy code that increments a olmBDBCounter + * any time it's called; replace with something useful */ + unsigned long u; + char buf[ BUFSIZ ]; + struct berval bv; + + assert( ad_olmBDBCounter != NULL ); + + a = attr_find( e->e_attrs, ad_olmBDBCounter ); + assert( a != NULL ); + lutil_atoul( &u, a->a_vals[ 0 ].bv_val ); + u++; + bv.bv_val = buf; + bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", u ); + ber_bvreplace( &a->a_vals[ 0 ], &bv ); + + return SLAP_CB_CONTINUE; +} + +static int +bdb_monitor_modify( + Operation *op, + SlapReply *rs, + Entry *e, + void *priv ) +{ + struct bdb_info *bdb = (struct bdb_info *) priv; + + return SLAP_CB_CONTINUE; +} + +static int +bdb_monitor_free( + Entry *e, + void *priv ) +{ + struct bdb_info *bdb = (struct bdb_info *) priv; + + return SLAP_CB_CONTINUE; +} + +/* + * NOTE: there's some confusion in monitor OID arc; + * by now, let's consider: + * + * Subsystems monitor attributes 1.3.6.1.4.1.4203.666.1.55.0 + * Databases monitor attributes 1.3.6.1.4.1.4203.666.1.55.0.1 + * BDB database monitor attributes 1.3.6.1.4.1.4203.666.1.55.0.1.1 + * + * Subsystems monitor objectclasses 1.3.6.1.4.1.4203.666.3.16.0 + * Databases monitor objectclasses 1.3.6.1.4.1.4203.666.3.16.0.1 + * BDB database monitor objectclasses 1.3.6.1.4.1.4203.666.3.16.0.1.1 + */ +#define BDB_MONITOR_SCHEMA_AD "1.3.6.1.4.1.4203.666.1.55.0.1.1" +#define BDB_MONITOR_SCHEMA_OC "1.3.6.1.4.1.4203.666.3.16.0.1.1" + +static struct { + char *name; + char *desc; + AttributeDescription **ad; +} s_at[] = { + { "olmBDBCounter", "( " BDB_MONITOR_SCHEMA_AD ".0 " + "NAME ( 'olmBDBCounter' ) " + "DESC 'A dummy counter' " + "SUP monitorCounter " + "NO-USER-MODIFICATION " + "USAGE directoryOperation )", + &ad_olmBDBCounter }, + + { NULL } +}; + +static struct { + char *name; + char *desc; + ObjectClass **oc; +} s_oc[] = { + { "olmBDBDatabase", "( " BDB_MONITOR_SCHEMA_OC ".1 " + "NAME ( 'olmBDBDatabase' ) " + "SUP monitoredObject STRUCTURAL " + "MAY ( " + "olmBDBCounter " + ") )", + &oc_olmBDBDatabase }, + + { NULL } +}; + +/* + * call from within bdb_initialize() + */ +int +bdb_monitor_initialize( void ) +{ + int i, code; + const char *err; + + static int bdb_monitor_initialized = 0; + + /* register schema here; if compiled as dynamic object, + * must be loaded __after__ back_monitor.la */ + + if ( bdb_monitor_initialized++ ) { + return 0; + } + + for ( i = 0; s_at[ i ].name != NULL; i++ ) { + LDAPAttributeType *at; + + at = ldap_str2attributetype( s_at[ i ].desc, + &code, &err, LDAP_SCHEMA_ALLOW_ALL ); + if ( !at ) { + Debug( LDAP_DEBUG_ANY, + "bdb_monitor_initialize: " + "AttributeType load failed: %s %s\n", + ldap_scherr2str( code ), err, 0 ); + return LDAP_INVALID_SYNTAX; + } + + code = at_add( at, 0, NULL, &err ); + if ( code != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, + "bdb_monitor_initialize: " + "AttributeType load failed: %s %s\n", + scherr2str( code ), err, 0 ); + code = LDAP_INVALID_SYNTAX; + goto done_at; + } + + code = slap_str2ad( s_at[ i ].name, + s_at[ i ].ad, &err ); + if ( code != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, + "bdb_monitor_initialize: " + "unable to find AttributeDescription " + "\"%s\": %d (%s)\n", + s_at[ i ].name, code, err ); + code = LDAP_UNDEFINED_TYPE; + goto done_at; + } + +done_at:; + if ( code ) { + ldap_attributetype_free( at ); + return code; + } + + ldap_memfree( at ); + } + + for ( i = 0; s_oc[ i ].name != NULL; i++ ) { + LDAPObjectClass *oc; + + oc = ldap_str2objectclass( s_oc[ i ].desc, + &code, &err, LDAP_SCHEMA_ALLOW_ALL ); + if ( !oc ) { + Debug( LDAP_DEBUG_ANY, + "bdb_monitor_initialize: " + "ObjectClass load failed: %s %s\n", + ldap_scherr2str( code ), err, 0 ); + return LDAP_INVALID_SYNTAX; + } + + code = oc_add( oc, 0, NULL, &err ); + if ( code != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, + "bdb_monitor_initialize: " + "ObjectClass load failed: %s %s\n", + scherr2str( code ), err, 0 ); + code = LDAP_INVALID_SYNTAX; + goto done_oc; + } + + *s_oc[ i ].oc = oc_find( s_oc[ i ].name ); + if ( *s_oc[ i ].oc == NULL ) { + code = LDAP_UNDEFINED_TYPE; + Debug( LDAP_DEBUG_ANY, + "bdb_monitor_initialize: " + "unable to find objectClass \"%s\"\n", + s_oc[ i ].name, 0, 0 ); + goto done_oc; + } + +done_oc:; + if ( code != LDAP_SUCCESS ) { + ldap_objectclass_free( oc ); + return code; + } + + ldap_memfree( oc ); + } + + return 0; +} + +/* + * call from within bdb_db_init() + */ +int +bdb_monitor_init( BackendDB *be ) +{ + return 0; +} + +/* + * call from within bdb_db_open() + */ +int +bdb_monitor_open( BackendDB *be ) +{ + struct bdb_info *bdb = (struct bdb_info *) be->be_private; + Attribute *a, *next; + monitor_callback_t *cb; + struct berval base = BER_BVC( "cn=databases,cn=monitor" ); + struct berval suffix, filter; + char *ptr; + int rc = 0; + + /* monitor_back_register_entry_attrs() with a NULL ndn, + * base="cn=Databases,cn=Monitor", scope=LDAP_SCOPE_ONE + * and filter="(namingContexts:distinguishedNameMatch:=)" */ + + suffix.bv_len = ldap_bv2escaped_filter_value_len( &be->be_nsuffix[ 0 ] ); + if ( suffix.bv_len == be->be_nsuffix[ 0 ].bv_len ) { + suffix = be->be_nsuffix[ 0 ]; + + } else { + ldap_bv2escaped_filter_value( &be->be_nsuffix[ 0 ], &suffix ); + } + + filter.bv_len = STRLENOF( "(namingContexts:distinguishedNameMatch:=)" ) + suffix.bv_len; + ptr = filter.bv_val = ch_malloc( filter.bv_len + 1 ); + ptr = lutil_strcopy( ptr, "(namingContexts:distinguishedNameMatch:=" ); + ptr = lutil_strncopy( ptr, suffix.bv_val, suffix.bv_len ); + ptr[ 0 ] = ')'; + ptr++; + ptr[ 0 ] = '\0'; + assert( filter.bv_len == ptr - filter.bv_val ); + + if ( suffix.bv_val != be->be_nsuffix[ 0 ].bv_val ) { + ch_free( suffix.bv_val ); + } + + /* alloc as many as required (plus 1 for objectClass) */ + a = attrs_alloc( 1 + 1 ); + if ( a == NULL ) { + rc = 1; + goto cleanup; + } + + a->a_desc = slap_schema.si_ad_objectClass; + a->a_vals = NULL; + value_add_one( &a->a_vals, &oc_olmBDBDatabase->soc_cname ); + a->a_nvals = a->a_vals; + next = a->a_next; + + /* NOTE: dummy code that increments a olmBDBCounter + * any time it's called; replace with something useful */ + { + struct berval bv = BER_BVC( "0" ); + + next->a_desc = ad_olmBDBCounter; + next->a_vals = NULL; + value_add_one( &next->a_vals, &bv ); + next->a_nvals = next->a_vals; + next = a->a_next; + } + + cb = ch_calloc( sizeof( monitor_callback_t ), 1 ); + cb->mc_update = bdb_monitor_update; + cb->mc_modify = bdb_monitor_modify; + cb->mc_free = bdb_monitor_free; + cb->mc_private = (void *)bdb; + + rc = monitor_back_register_entry_attrs( NULL, + a, cb, &base, LDAP_SCOPE_ONELEVEL, &filter ); + +cleanup:; + if ( rc != 0 ) { + if ( cb != NULL ) { + ch_free( cb ); + } + + if ( a != NULL ) { + attrs_free( a ); + } + } + + return rc; +} + +/* + * call from within bdb_db_close() + */ +int +bdb_monitor_close( BackendDB *be ) +{ + return 0; +} + +/* + * call from within bdb_db_destroy() + */ +int +bdb_monitor_destroy( BackendDB *be ) +{ + return 0; +} + diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h index 19cdb7ddf4..f3b69fc7aa 100644 --- a/servers/slapd/back-bdb/proto-bdb.h +++ b/servers/slapd/back-bdb/proto-bdb.h @@ -426,6 +426,14 @@ int bdb_modify_internal( char *textbuf, size_t textlen ); +/* + * monitor.c + */ +int bdb_monitor_initialize( void ); +int bdb_monitor_init( BackendDB *be ); +int bdb_monitor_open( BackendDB *be ); +int bdb_monitor_close( BackendDB *be ); +int bdb_monitor_destroy( BackendDB *be ); /* * cache.c diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c index 264b70c5c7..3a3d4b543a 100644 --- a/servers/slapd/back-monitor/init.c +++ b/servers/slapd/back-monitor/init.c @@ -471,7 +471,7 @@ monitor_back_register_entry_parent( /* entry does not exist */ Debug( LDAP_DEBUG_ANY, "monitor_back_register_entry_parent(\"\"): " - "base=%s scope=%d filter=%s : " + "base=\"%s\" scope=%d filter=\"%s\": " "unable to find entry\n", base->bv_val ? base->bv_val : "\"\"", scope, filter->bv_val ); @@ -797,7 +797,7 @@ monitor_back_register_entry_attrs( snprintf( buf, sizeof( buf ), "monitor_back_register_entry_%s(\"\"): " - "base=%s scope=%d filter=%s : " + "base=\"%s\" scope=%d filter=\"%s\": " "unable to find entry\n", fname, base->bv_val ? base->bv_val : "\"\"", @@ -838,14 +838,26 @@ monitor_back_register_entry_attrs( for ( atp = &e->e_attrs; *atp; atp = &(*atp)->a_next ) /* just get to last */ ; - *atp = attrs_dup( a ); - if ( *atp == NULL ) { - Debug( LDAP_DEBUG_ANY, - "monitor_back_register_entry_%s(\"%s\"): " - "attrs_dup() failed\n", - fname, e->e_name.bv_val, 0 ); - rc = -1; - goto done; + for ( ; a != NULL; a = a->a_next ) { + assert( a->a_desc != NULL ); + assert( a->a_vals != NULL ); + + if ( attr_find( e->e_attrs, a->a_desc ) ) { + attr_merge( e, a->a_desc, a->a_vals, + a->a_nvals == a->a_vals ? NULL : a->a_nvals ); + + } else { + *atp = attr_dup( a ); + if ( *atp == NULL ) { + Debug( LDAP_DEBUG_ANY, + "monitor_back_register_entry_%s(\"%s\"): " + "attr_dup() failed\n", + fname, e->e_name.bv_val, 0 ); + rc = -1; + goto done; + } + atp = &(*atp)->a_next; + } } } @@ -923,6 +935,57 @@ monitor_back_register_entry_callback( base, scope, filter ); } +/* + * TODO: add corresponding calls to remove installed callbacks, entries + * and so, in case the entity that installed them is removed (e.g. a + * database, via back-config) + */ +int +monitor_back_unregister_entry( + Entry **ep, + monitor_callback_t **cbp ) +{ + /* TODO */ + return 1; +} + +int +monitor_back_unregister_entry_parent( + Entry **ep, + monitor_callback_t **cbp, + struct berval *base, + int scope, + struct berval *filter ) +{ + /* TODO */ + return 1; +} + +int +monitor_back_unregister_entry_attrs( + struct berval *ndn, + Attribute **ap, + monitor_callback_t **cbp, + struct berval *base, + int scope, + struct berval *filter ) +{ + /* TODO */ + return 1; +} + +int +monitor_back_unregister_entry_callback( + struct berval *ndn, + monitor_callback_t **cbp, + struct berval *base, + int scope, + struct berval *filter ) +{ + return monitor_back_unregister_entry_attrs( ndn, NULL, cbp, + base, scope, filter ); +} + monitor_subsys_t * monitor_back_get_subsys( const char *name ) { diff --git a/servers/slapd/back-monitor/proto-back-monitor.h b/servers/slapd/back-monitor/proto-back-monitor.h index ebe6a46c68..3b97e119a2 100644 --- a/servers/slapd/back-monitor/proto-back-monitor.h +++ b/servers/slapd/back-monitor/proto-back-monitor.h @@ -173,6 +173,32 @@ monitor_back_register_entry_callback LDAP_P(( struct berval *base, int scope, struct berval *filter )); +extern int +monitor_back_unregister_entry LDAP_P(( + Entry **ep, + monitor_callback_t **cbp )); +extern int +monitor_back_unregister_entry_parent LDAP_P(( + Entry **ep, + monitor_callback_t **cbp, + struct berval *base, + int scope, + struct berval *filter )); +extern int +monitor_back_unregister_entry_attrs LDAP_P(( + struct berval *ndn, + Attribute **ap, + monitor_callback_t **cbp, + struct berval *base, + int scope, + struct berval *filter )); +extern int +monitor_back_unregister_entry_callback LDAP_P(( + struct berval *ndn, + monitor_callback_t **cbp, + struct berval *base, + int scope, + struct berval *filter )); /* * listener