]> git.sur5r.net Git - openldap/commitdiff
- setup framework for monitoring of back-bdb/back-hdb stuff in their
authorPierangelo Masarati <ando@openldap.org>
Wed, 6 Sep 2006 01:54:54 +0000 (01:54 +0000)
committerPierangelo Masarati <ando@openldap.org>
Wed, 6 Sep 2006 01:54:54 +0000 (01:54 +0000)
  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.

configure
configure.in
servers/slapd/back-bdb/Makefile.in
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/monitor.c [new file with mode: 0644]
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-monitor/init.c
servers/slapd/back-monitor/proto-back-monitor.h

index 43694150d6eb7e845c7ef8b10bf6d2d67af51a3e..83f1233fd80dfe2c70657dd25eb3364fb92a4dfe 100755 (executable)
--- 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
index 692d8d3384e695bfbc5d30e08905a173ded78854..aa2b1fe72ef478b4d4aad9901ba1751312397dab 100644 (file)
@@ -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
index 06a987f4893c30b0922880a8b7bc1a918088c231..4f1d8d0cc9e9d167398feb3128068146aa9bd2dd 100644 (file)
@@ -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
index dccc3290706a1e77cea20792d3712727c958cd1d..fcdab9ad2c5108d75be5218d48f7dbbf19d43abd 100644 (file)
@@ -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 (file)
index 0000000..aaabe0a
--- /dev/null
@@ -0,0 +1,351 @@
+/* monitor.c - monitor bdb backend */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * 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
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+#include <ac/stdlib.h>
+#include <ac/errno.h>
+#include <sys/stat.h>
+#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>)" */
+
+       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;
+}
+
index 19cdb7ddf4469ad816cf0ba2f4b0be9b4d0d85d4..f3b69fc7aaadaededa8f0c1fd86e41c1da510b3f 100644 (file)
@@ -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
index 264b70c5c7ebeaddb433fa30b15d6b6d955bb8c4..3a3d4b543a0edc6cdc28d94c07fc8f798bba2b21 100644 (file)
@@ -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 )
 {
index ebe6a46c687a6f917408c76039f8b34006c7748e..3b97e119a2ad47966b0b7fcf8d96334bde5e1003 100644 (file)
@@ -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