1 /* init.c - initialize monitor backend */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2001-2007 The OpenLDAP Foundation.
6 * Portions Copyright 2001-2003 Pierangelo Masarati.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
18 * This work was initially developed by Pierangelo Masarati for inclusion
19 * in OpenLDAP Software.
25 #include <ac/string.h>
31 #include "back-monitor.h"
35 #undef INTEGRATE_CORE_SCHEMA
38 * used by many functions to add description to entries
40 * WARNING: be_monitor may change as new databases are added,
41 * so it should not be used outside monitor_back_db_init()
42 * until monitor_back_db_open is called.
44 BackendDB *be_monitor;
46 static struct monitor_subsys_t **monitor_subsys;
47 static int monitor_subsys_opened;
48 static monitor_info_t monitor_info;
49 static const monitor_extra_t monitor_extra = {
50 monitor_back_is_configured,
51 monitor_back_get_subsys,
52 monitor_back_get_subsys_by_dn,
54 monitor_back_register_subsys,
55 monitor_back_register_backend,
56 monitor_back_register_database,
57 monitor_back_register_overlay_info,
58 monitor_back_register_overlay,
59 monitor_back_register_entry,
60 monitor_back_register_entry_parent,
61 monitor_back_register_entry_attrs,
62 monitor_back_register_entry_callback,
64 monitor_back_unregister_entry,
65 monitor_back_unregister_entry_parent,
66 monitor_back_unregister_entry_attrs,
67 monitor_back_unregister_entry_callback
74 * the known subsystems are added to the subsystems
75 * array at backend initialization; other subsystems
76 * may be added by calling monitor_back_register_subsys()
77 * before the database is opened (e.g. by other backends
78 * or by overlays or modules).
80 static struct monitor_subsys_t known_monitor_subsys[] = {
82 SLAPD_MONITOR_BACKEND_NAME,
83 BER_BVNULL, BER_BVNULL, BER_BVNULL,
84 { BER_BVC( "This subsystem contains information about available backends." ),
86 MONITOR_F_PERSISTENT_CH,
87 monitor_subsys_backend_init,
93 SLAPD_MONITOR_CONN_NAME,
94 BER_BVNULL, BER_BVNULL, BER_BVNULL,
95 { BER_BVC( "This subsystem contains information about connections." ),
97 MONITOR_F_VOLATILE_CH,
98 monitor_subsys_conn_init,
104 SLAPD_MONITOR_DATABASE_NAME,
105 BER_BVNULL, BER_BVNULL, BER_BVNULL,
106 { BER_BVC( "This subsystem contains information about configured databases." ),
108 MONITOR_F_PERSISTENT_CH,
109 monitor_subsys_database_init,
115 SLAPD_MONITOR_LISTENER_NAME,
116 BER_BVNULL, BER_BVNULL, BER_BVNULL,
117 { BER_BVC( "This subsystem contains information about active listeners." ),
119 MONITOR_F_PERSISTENT_CH,
120 monitor_subsys_listener_init,
126 SLAPD_MONITOR_LOG_NAME,
127 BER_BVNULL, BER_BVNULL, BER_BVNULL,
128 { BER_BVC( "This subsystem contains information about logging." ),
129 BER_BVC( "Set the attribute \"managedInfo\" to the desired log levels." ),
132 monitor_subsys_log_init,
138 SLAPD_MONITOR_OPS_NAME,
139 BER_BVNULL, BER_BVNULL, BER_BVNULL,
140 { BER_BVC( "This subsystem contains information about performed operations." ),
142 MONITOR_F_PERSISTENT_CH,
143 monitor_subsys_ops_init,
149 SLAPD_MONITOR_OVERLAY_NAME,
150 BER_BVNULL, BER_BVNULL, BER_BVNULL,
151 { BER_BVC( "This subsystem contains information about available overlays." ),
153 MONITOR_F_PERSISTENT_CH,
154 monitor_subsys_overlay_init,
160 SLAPD_MONITOR_SASL_NAME,
161 BER_BVNULL, BER_BVNULL, BER_BVNULL,
162 { BER_BVC( "This subsystem contains information about SASL." ),
171 SLAPD_MONITOR_SENT_NAME,
172 BER_BVNULL, BER_BVNULL, BER_BVNULL,
173 { BER_BVC( "This subsystem contains statistics." ),
175 MONITOR_F_PERSISTENT_CH,
176 monitor_subsys_sent_init,
182 SLAPD_MONITOR_THREAD_NAME,
183 BER_BVNULL, BER_BVNULL, BER_BVNULL,
184 { BER_BVC( "This subsystem contains information about threads." ),
186 MONITOR_F_PERSISTENT_CH,
187 monitor_subsys_thread_init,
193 SLAPD_MONITOR_TIME_NAME,
194 BER_BVNULL, BER_BVNULL, BER_BVNULL,
195 { BER_BVC( "This subsystem contains information about time." ),
197 MONITOR_F_PERSISTENT_CH,
198 monitor_subsys_time_init,
204 SLAPD_MONITOR_TLS_NAME,
205 BER_BVNULL, BER_BVNULL, BER_BVNULL,
206 { BER_BVC( "This subsystem contains information about TLS." ),
215 SLAPD_MONITOR_RWW_NAME,
216 BER_BVNULL, BER_BVNULL, BER_BVNULL,
217 { BER_BVC( "This subsystem contains information about read/write waiters." ),
219 MONITOR_F_PERSISTENT_CH,
220 monitor_subsys_rww_init,
229 monitor_back_register_subsys(
230 monitor_subsys_t *ms )
234 if ( monitor_subsys ) {
235 for ( ; monitor_subsys[ i ] != NULL; i++ )
236 /* just count'em */ ;
239 monitor_subsys = ch_realloc( monitor_subsys,
240 ( 2 + i ) * sizeof( monitor_subsys_t * ) );
242 if ( monitor_subsys == NULL ) {
246 monitor_subsys[ i ] = ms;
247 monitor_subsys[ i + 1 ] = NULL;
249 /* if a subsystem is registered __AFTER__ subsystem
250 * initialization (depending on the sequence the databases
251 * are listed in slapd.conf), init it */
252 if ( monitor_subsys_opened ) {
254 /* FIXME: this should only be possible
255 * if be_monitor is already initialized */
256 assert( be_monitor != NULL );
258 if ( ms->mss_open && ( *ms->mss_open )( be_monitor, ms ) ) {
262 ms->mss_flags |= MONITOR_F_OPENED;
275 typedef struct entry_limbo_t {
279 struct berval el_ndn;
280 struct berval el_nbase;
282 struct berval el_filter;
283 monitor_callback_t *el_cb;
284 monitor_subsys_t *el_mss;
285 unsigned long el_flags;
286 struct entry_limbo_t *el_next;
290 monitor_back_is_configured( void )
292 return be_monitor != NULL;
296 monitor_back_register_backend(
303 monitor_back_register_overlay_info(
310 monitor_back_register_overlay(
317 monitor_back_register_entry(
319 monitor_callback_t *cb,
320 monitor_subsys_t *mss,
321 unsigned long flags )
325 if ( be_monitor == NULL ) {
326 Debug( LDAP_DEBUG_ANY,
327 "monitor_back_register_entry(\"%s\"): "
328 "monitor database not configured.\n",
329 e->e_name.bv_val, 0, 0 );
333 mi = ( monitor_info_t * )be_monitor->be_private;
335 assert( mi != NULL );
337 assert( e->e_private == NULL );
339 if ( monitor_subsys_opened ) {
340 Entry *e_parent = NULL,
343 struct berval pdn = BER_BVNULL;
344 monitor_entry_t *mp = NULL,
348 if ( monitor_cache_get( mi, &e->e_nname, &e_parent ) == 0 ) {
350 Debug( LDAP_DEBUG_ANY,
351 "monitor_back_register_entry(\"%s\"): "
353 e->e_name.bv_val, 0, 0 );
354 monitor_cache_release( mi, e_parent );
358 dnParent( &e->e_nname, &pdn );
359 if ( monitor_cache_get( mi, &pdn, &e_parent ) != 0 ) {
360 /* parent does not exist */
361 Debug( LDAP_DEBUG_ANY,
362 "monitor_back_register_entry(\"%s\"): "
363 "parent \"%s\" not found\n",
364 e->e_name.bv_val, pdn.bv_val, 0 );
368 assert( e_parent->e_private != NULL );
369 mp_parent = ( monitor_entry_t * )e_parent->e_private;
371 if ( mp_parent->mp_flags & MONITOR_F_VOLATILE ) {
372 /* entry is volatile; cannot append children */
373 Debug( LDAP_DEBUG_ANY,
374 "monitor_back_register_entry(\"%s\"): "
375 "parent \"%s\" is volatile\n",
376 e->e_name.bv_val, e_parent->e_name.bv_val, 0 );
381 mp = monitor_entrypriv_create();
383 Debug( LDAP_DEBUG_ANY,
384 "monitor_back_register_entry(\"%s\"): "
385 "monitor_entrypriv_create() failed\n",
386 e->e_name.bv_val, 0, 0 );
391 e_new = entry_dup( e );
392 if ( e_new == NULL ) {
393 Debug( LDAP_DEBUG_ANY,
394 "monitor_back_register_entry(\"%s\"): "
395 "entry_dup() failed\n",
396 e->e_name.bv_val, 0, 0 );
401 e_new->e_private = ( void * )mp;
404 mp->mp_flags = flags;
407 mp->mp_info = mp_parent->mp_info;
408 mp->mp_flags = mp_parent->mp_flags | MONITOR_F_SUB;
412 ep = &mp_parent->mp_children;
414 mp_parent = ( monitor_entry_t * )(*ep)->e_private;
415 ep = &mp_parent->mp_next;
419 if ( monitor_cache_add( mi, e_new ) ) {
420 Debug( LDAP_DEBUG_ANY,
421 "monitor_back_register_entry(\"%s\"): "
422 "unable to add entry\n",
423 e->e_name.bv_val, 0, 0 );
434 e_new->e_private = NULL;
440 monitor_cache_release( mi, e_parent );
444 entry_limbo_t **elpp, el = { 0 };
446 el.el_type = LIMBO_ENTRY;
448 el.el_e = entry_dup( e );
449 if ( el.el_e == NULL ) {
450 Debug( LDAP_DEBUG_ANY,
451 "monitor_back_register_entry(\"%s\"): "
452 "entry_dup() failed\n",
453 e->e_name.bv_val, 0, 0 );
461 for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
463 elpp = &(*elpp)->el_next )
466 *elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) );
467 if ( *elpp == NULL ) {
468 el.el_e->e_private = NULL;
469 entry_free( el.el_e );
481 monitor_back_register_entry_parent(
483 monitor_callback_t *cb,
484 monitor_subsys_t *mss,
486 struct berval *nbase,
488 struct berval *filter )
491 struct berval ndn = BER_BVNULL;
493 if ( be_monitor == NULL ) {
494 Debug( LDAP_DEBUG_ANY,
495 "monitor_back_register_entry_parent(base=\"%s\" scope=%s filter=\"%s\"): "
496 "monitor database not configured.\n",
497 BER_BVISNULL( nbase ) ? "" : nbase->bv_val,
498 ldap_pvt_scope2str( scope ),
499 BER_BVISNULL( filter ) ? "" : filter->bv_val );
503 mi = ( monitor_info_t * )be_monitor->be_private;
505 assert( mi != NULL );
507 assert( e->e_private == NULL );
509 if ( BER_BVISNULL( filter ) ) {
511 Debug( LDAP_DEBUG_ANY,
512 "monitor_back_register_entry_parent(\"\"): "
513 "need a valid filter\n",
518 if ( monitor_subsys_opened ) {
519 Entry *e_parent = NULL,
522 struct berval e_name = BER_BVNULL,
523 e_nname = BER_BVNULL;
524 monitor_entry_t *mp = NULL,
528 if ( monitor_search2ndn( nbase, scope, filter, &ndn ) ) {
529 /* entry does not exist */
530 Debug( LDAP_DEBUG_ANY,
531 "monitor_back_register_entry_parent(\"\"): "
532 "base=\"%s\" scope=%s filter=\"%s\": "
533 "unable to find entry\n",
534 nbase->bv_val ? nbase->bv_val : "\"\"",
535 ldap_pvt_scope2str( scope ),
540 if ( monitor_cache_get( mi, &ndn, &e_parent ) != 0 ) {
541 /* entry does not exist */
542 Debug( LDAP_DEBUG_ANY,
543 "monitor_back_register_entry_parent(\"%s\"): "
544 "parent entry does not exist\n",
550 assert( e_parent->e_private != NULL );
551 mp_parent = ( monitor_entry_t * )e_parent->e_private;
553 if ( mp_parent->mp_flags & MONITOR_F_VOLATILE ) {
554 /* entry is volatile; cannot append callback */
555 Debug( LDAP_DEBUG_ANY,
556 "monitor_back_register_entry_parent(\"%s\"): "
557 "entry is volatile\n",
558 e_parent->e_name.bv_val, 0, 0 );
563 build_new_dn( &e_name, &e_parent->e_name, &e->e_name, NULL );
564 build_new_dn( &e_nname, &e_parent->e_nname, &e->e_nname, NULL );
566 if ( monitor_cache_get( mi, &e_nname, &e_new ) == 0 ) {
567 /* entry already exists */
568 Debug( LDAP_DEBUG_ANY,
569 "monitor_back_register_entry_parent(\"%s\"): "
570 "entry already exists\n",
571 e_name.bv_val, 0, 0 );
572 monitor_cache_release( mi, e_new );
578 mp = monitor_entrypriv_create();
580 Debug( LDAP_DEBUG_ANY,
581 "monitor_back_register_entry_parent(\"%s\"): "
582 "monitor_entrypriv_create() failed\n",
583 e->e_name.bv_val, 0, 0 );
588 e_new = entry_dup( e );
589 if ( e_new == NULL ) {
590 Debug( LDAP_DEBUG_ANY,
591 "monitor_back_register_entry(\"%s\"): "
592 "entry_dup() failed\n",
593 e->e_name.bv_val, 0, 0 );
597 ch_free( e_new->e_name.bv_val );
598 ch_free( e_new->e_nname.bv_val );
599 e_new->e_name = e_name;
600 e_new->e_nname = e_nname;
602 e_new->e_private = ( void * )mp;
605 mp->mp_flags = flags;
608 mp->mp_info = mp_parent->mp_info;
609 mp->mp_flags = mp_parent->mp_flags | MONITOR_F_SUB;
613 ep = &mp_parent->mp_children;
615 mp_parent = ( monitor_entry_t * )(*ep)->e_private;
616 ep = &mp_parent->mp_next;
620 if ( monitor_cache_add( mi, e_new ) ) {
621 Debug( LDAP_DEBUG_ANY,
622 "monitor_back_register_entry(\"%s\"): "
623 "unable to add entry\n",
624 e->e_name.bv_val, 0, 0 );
630 if ( !BER_BVISNULL( &ndn ) ) {
631 ch_free( ndn.bv_val );
639 e_new->e_private = NULL;
645 monitor_cache_release( mi, e_parent );
649 entry_limbo_t **elpp = NULL, el = { 0 };
651 el.el_type = LIMBO_ENTRY_PARENT;
653 el.el_e = entry_dup( e );
654 if ( el.el_e == NULL ) {
655 Debug( LDAP_DEBUG_ANY,
656 "monitor_back_register_entry(\"%s\"): "
657 "entry_dup() failed\n",
658 e->e_name.bv_val, 0, 0 );
662 if ( !BER_BVISNULL( nbase ) ) {
663 ber_dupbv( &el.el_nbase, nbase );
667 if ( !BER_BVISNULL( filter ) ) {
668 ber_dupbv( &el.el_filter, filter );
675 for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
677 elpp = &(*elpp)->el_next )
680 *elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) );
681 if ( *elpp == NULL ) {
686 if ( *elpp != NULL ) {
691 if ( !BER_BVISNULL( &el.el_filter ) ) {
692 ch_free( el.el_filter.bv_val );
694 if ( !BER_BVISNULL( &el.el_nbase ) ) {
695 ch_free( el.el_nbase.bv_val );
697 entry_free( el.el_e );
706 monitor_search2ndn_cb( Operation *op, SlapReply *rs )
708 if ( rs->sr_type == REP_SEARCH ) {
709 struct berval *ndn = op->o_callback->sc_private;
711 if ( !BER_BVISNULL( ndn ) ) {
712 rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
713 ch_free( ndn->bv_val );
718 ber_dupbv( ndn, &rs->sr_entry->e_nname );
726 struct berval *nbase,
728 struct berval *filter,
731 Connection conn = { 0 };
732 OperationBuffer opbuf;
735 SlapReply rs = { 0 };
736 slap_callback cb = { NULL, monitor_search2ndn_cb, NULL, NULL };
741 if ( be_monitor == NULL ) {
745 op = (Operation *) &opbuf;
746 thrctx = ldap_pvt_thread_pool_context();
747 connection_fake_init( &conn, op, thrctx );
749 op->o_tag = LDAP_REQ_SEARCH;
751 /* use global malloc for now */
752 if ( op->o_tmpmemctx ) {
753 op->o_tmpmemctx = NULL;
755 op->o_tmpmfuncs = &ch_mfuncs;
757 op->o_bd = be_monitor;
758 if ( nbase == NULL || BER_BVISNULL( nbase ) ) {
759 ber_dupbv_x( &op->o_req_dn, &op->o_bd->be_suffix[ 0 ],
761 ber_dupbv_x( &op->o_req_ndn, &op->o_bd->be_nsuffix[ 0 ],
765 if ( dnPrettyNormal( NULL, nbase, &op->o_req_dn, &op->o_req_ndn,
766 op->o_tmpmemctx ) ) {
771 op->o_callback = &cb;
772 cb.sc_private = (void *)ndn;
774 op->ors_scope = scope;
775 op->ors_filter = str2filter_x( op, filter->bv_val );
776 if ( op->ors_filter == NULL ) {
780 ber_dupbv_x( &op->ors_filterstr, filter, op->o_tmpmemctx );
781 op->ors_attrs = slap_anlist_no_attrs;
782 op->ors_attrsonly = 0;
783 op->ors_tlimit = SLAP_NO_LIMIT;
785 op->ors_limit = NULL;
786 op->ors_deref = LDAP_DEREF_NEVER;
789 op->o_managedsait = SLAP_CONTROL_NONCRITICAL;
791 op->o_dn = be_monitor->be_rootdn;
792 op->o_ndn = be_monitor->be_rootndn;
794 rc = op->o_bd->be_search( op, &rs );
797 if ( op->ors_filter != NULL ) {
798 filter_free_x( op, op->ors_filter );
800 if ( !BER_BVISNULL( &op->ors_filterstr ) ) {
801 op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
803 if ( !BER_BVISNULL( &op->o_req_dn ) ) {
804 op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
806 if ( !BER_BVISNULL( &op->o_req_ndn ) ) {
807 op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
814 switch ( rs.sr_err ) {
816 if ( BER_BVISNULL( ndn ) ) {
821 case LDAP_SIZELIMIT_EXCEEDED:
823 if ( !BER_BVISNULL( ndn ) ) {
824 ber_memfree( ndn->bv_val );
835 monitor_back_register_entry_attrs(
836 struct berval *ndn_in,
838 monitor_callback_t *cb,
839 struct berval *nbase,
841 struct berval *filter )
844 struct berval ndn = BER_BVNULL;
845 char *fname = ( a == NULL ? "callback" : "attrs" );
847 if ( be_monitor == NULL ) {
848 char buf[ SLAP_TEXT_BUFLEN ];
850 snprintf( buf, sizeof( buf ),
851 "monitor_back_register_entry_%s(base=\"%s\" scope=%s filter=\"%s\"): "
852 "monitor database not configured.\n",
854 BER_BVISNULL( nbase ) ? "" : nbase->bv_val,
855 ldap_pvt_scope2str( scope ),
856 BER_BVISNULL( filter ) ? "" : filter->bv_val );
857 Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
862 mi = ( monitor_info_t * )be_monitor->be_private;
864 assert( mi != NULL );
866 if ( ndn_in != NULL ) {
870 if ( a == NULL && cb == NULL ) {
875 if ( ( ndn_in == NULL || BER_BVISNULL( &ndn ) )
876 && BER_BVISNULL( filter ) )
879 Debug( LDAP_DEBUG_ANY,
880 "monitor_back_register_entry_%s(\"\"): "
881 "need a valid filter\n",
886 if ( monitor_subsys_opened ) {
888 Attribute **atp = NULL;
889 monitor_entry_t *mp = NULL;
890 monitor_callback_t **mcp = NULL;
894 if ( BER_BVISNULL( &ndn ) ) {
895 if ( monitor_search2ndn( nbase, scope, filter, &ndn ) ) {
896 char buf[ SLAP_TEXT_BUFLEN ];
898 snprintf( buf, sizeof( buf ),
899 "monitor_back_register_entry_%s(\"\"): "
900 "base=\"%s\" scope=%s filter=\"%s\": "
901 "unable to find entry\n",
903 nbase->bv_val ? nbase->bv_val : "\"\"",
904 ldap_pvt_scope2str( scope ),
907 /* entry does not exist */
908 Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
915 if ( monitor_cache_get( mi, &ndn, &e ) != 0 ) {
916 /* entry does not exist */
917 Debug( LDAP_DEBUG_ANY,
918 "monitor_back_register_entry_%s(\"%s\"): "
919 "entry does not exist\n",
920 fname, ndn.bv_val, 0 );
925 assert( e->e_private != NULL );
926 mp = ( monitor_entry_t * )e->e_private;
928 if ( mp->mp_flags & MONITOR_F_VOLATILE ) {
929 /* entry is volatile; cannot append callback */
930 Debug( LDAP_DEBUG_ANY,
931 "monitor_back_register_entry_%s(\"%s\"): "
932 "entry is volatile\n",
933 fname, e->e_name.bv_val, 0 );
939 for ( atp = &e->e_attrs; *atp; atp = &(*atp)->a_next )
940 /* just get to last */ ;
942 for ( ; a != NULL; a = a->a_next ) {
943 assert( a->a_desc != NULL );
944 assert( a->a_vals != NULL );
946 if ( attr_find( e->e_attrs, a->a_desc ) ) {
947 attr_merge( e, a->a_desc, a->a_vals,
948 a->a_nvals == a->a_vals ? NULL : a->a_nvals );
951 *atp = attr_dup( a );
952 if ( *atp == NULL ) {
953 Debug( LDAP_DEBUG_ANY,
954 "monitor_back_register_entry_%s(\"%s\"): "
955 "attr_dup() failed\n",
956 fname, e->e_name.bv_val, 0 );
960 atp = &(*atp)->a_next;
966 for ( mcp = &mp->mp_cb; *mcp; mcp = &(*mcp)->mc_next )
969 /* NOTE: we do not clear cb->mc_next, so this function
970 * can be used to append a list of callbacks */
983 ber_memfree( ndn.bv_val );
987 monitor_cache_release( mi, e );
991 entry_limbo_t **elpp, el = { 0 };
993 el.el_type = LIMBO_ATTRS;
994 if ( !BER_BVISNULL( &ndn ) ) {
995 ber_dupbv( &el.el_ndn, &ndn );
997 if ( !BER_BVISNULL( nbase ) ) {
998 ber_dupbv( &el.el_nbase, nbase);
1000 el.el_scope = scope;
1001 if ( !BER_BVISNULL( filter ) ) {
1002 ber_dupbv( &el.el_filter, filter );
1005 el.el_a = attrs_dup( a );
1008 for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
1010 elpp = &(*elpp)->el_next )
1013 *elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) );
1014 if ( *elpp == NULL ) {
1015 el.el_e->e_private = NULL;
1016 entry_free( el.el_e );
1020 if ( *elpp != NULL ) {
1025 if ( !BER_BVISNULL( &el.el_filter ) ) {
1026 ch_free( el.el_filter.bv_val );
1028 if ( el.el_a != NULL ) {
1029 attrs_free( el.el_a );
1031 if ( !BER_BVISNULL( &el.el_nbase ) ) {
1032 ch_free( &el.el_nbase.bv_val );
1034 if ( !BER_BVISNULL( &el.el_ndn ) ) {
1035 ch_free( el.el_ndn.bv_val );
1045 monitor_back_register_entry_callback(
1047 monitor_callback_t *cb,
1048 struct berval *nbase,
1050 struct berval *filter )
1052 return monitor_back_register_entry_attrs( ndn, NULL, cb,
1053 nbase, scope, filter );
1057 * TODO: add corresponding calls to remove installed callbacks, entries
1058 * and so, in case the entity that installed them is removed (e.g. a
1059 * database, via back-config)
1062 monitor_back_unregister_entry(
1063 struct berval *ndn )
1067 if ( be_monitor == NULL ) {
1068 Debug( LDAP_DEBUG_ANY,
1069 "monitor_back_unregister_entry(\"%s\"): "
1070 "monitor database not configured.\n",
1071 ndn->bv_val, 0, 0 );
1076 /* entry will be regularly freed, and resources released
1077 * according to callbacks */
1078 if ( slapd_shutdown ) {
1082 mi = ( monitor_info_t * )be_monitor->be_private;
1084 assert( mi != NULL );
1086 if ( monitor_subsys_opened ) {
1088 monitor_entry_t *mp = NULL;
1089 monitor_callback_t *cb = NULL;
1091 if ( monitor_cache_remove( mi, ndn, &e ) != 0 ) {
1092 /* entry does not exist */
1093 Debug( LDAP_DEBUG_ANY,
1094 "monitor_back_unregister_entry(\"%s\"): "
1095 "entry removal failed.\n",
1096 ndn->bv_val, 0, 0 );
1100 mp = (monitor_entry_t *)e->e_private;
1101 assert( mp != NULL );
1103 for ( cb = mp->mp_cb; cb != NULL; ) {
1104 monitor_callback_t *next = cb->mc_next;
1106 if ( cb->mc_free ) {
1107 (void)cb->mc_free( e, &cb->mc_private );
1115 e->e_private = NULL;
1119 entry_limbo_t **elpp;
1121 for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
1123 elpp = &(*elpp)->el_next )
1125 entry_limbo_t *elp = *elpp;
1127 if ( elp->el_type == LIMBO_ENTRY
1128 && dn_match( ndn, &elp->el_e->e_nname ) )
1130 monitor_callback_t *cb, *next;
1132 for ( cb = elp->el_cb; cb; cb = next ) {
1133 /* FIXME: call callbacks? */
1137 assert( elp->el_e != NULL );
1138 elp->el_e->e_private = NULL;
1139 entry_free( elp->el_e );
1140 *elpp = elp->el_next;
1147 if ( elpp != NULL ) {
1148 /* not found! where did it go? */
1157 monitor_back_unregister_entry_parent(
1158 struct berval *nrdn,
1159 monitor_callback_t *target_cb,
1160 struct berval *nbase,
1162 struct berval *filter )
1165 struct berval ndn = BER_BVNULL;
1167 if ( be_monitor == NULL ) {
1168 Debug( LDAP_DEBUG_ANY,
1169 "monitor_back_unregister_entry_parent(base=\"%s\" scope=%s filter=\"%s\"): "
1170 "monitor database not configured.\n",
1171 BER_BVISNULL( nbase ) ? "" : nbase->bv_val,
1172 ldap_pvt_scope2str( scope ),
1173 BER_BVISNULL( filter ) ? "" : filter->bv_val );
1178 /* entry will be regularly freed, and resources released
1179 * according to callbacks */
1180 if ( slapd_shutdown ) {
1184 mi = ( monitor_info_t * )be_monitor->be_private;
1186 assert( mi != NULL );
1188 if ( ( nrdn == NULL || BER_BVISNULL( nrdn ) )
1189 && BER_BVISNULL( filter ) )
1192 Debug( LDAP_DEBUG_ANY,
1193 "monitor_back_unregister_entry_parent(\"\"): "
1194 "need a valid filter\n",
1199 if ( monitor_subsys_opened ) {
1201 monitor_entry_t *mp = NULL;
1203 if ( monitor_search2ndn( nbase, scope, filter, &ndn ) ) {
1204 /* entry does not exist */
1205 Debug( LDAP_DEBUG_ANY,
1206 "monitor_back_unregister_entry_parent(\"\"): "
1207 "base=\"%s\" scope=%s filter=\"%s\": "
1208 "unable to find entry\n",
1209 nbase->bv_val ? nbase->bv_val : "\"\"",
1210 ldap_pvt_scope2str( scope ),
1215 if ( monitor_cache_remove( mi, &ndn, &e ) != 0 ) {
1216 /* entry does not exist */
1217 Debug( LDAP_DEBUG_ANY,
1218 "monitor_back_unregister_entry(\"%s\"): "
1219 "entry removal failed.\n",
1221 ber_memfree( ndn.bv_val );
1224 ber_memfree( ndn.bv_val );
1226 mp = (monitor_entry_t *)e->e_private;
1227 assert( mp != NULL );
1229 if ( target_cb != NULL ) {
1230 monitor_callback_t **cbp;
1232 for ( cbp = &mp->mp_cb; *cbp != NULL; cbp = &(*cbp)->mc_next ) {
1233 if ( *cbp == target_cb ) {
1234 if ( (*cbp)->mc_free ) {
1235 (void)(*cbp)->mc_free( e, &(*cbp)->mc_private );
1237 *cbp = (*cbp)->mc_next;
1238 ch_free( target_cb );
1246 e->e_private = NULL;
1250 entry_limbo_t **elpp;
1252 for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
1254 elpp = &(*elpp)->el_next )
1256 entry_limbo_t *elp = *elpp;
1258 if ( elp->el_type == LIMBO_ENTRY_PARENT
1259 && dn_match( nrdn, &elp->el_e->e_nname )
1260 && dn_match( nbase, &elp->el_nbase )
1261 && scope == elp->el_scope
1262 && bvmatch( filter, &elp->el_filter ) )
1264 monitor_callback_t *cb, *next;
1266 for ( cb = elp->el_cb; cb; cb = next ) {
1267 /* FIXME: call callbacks? */
1271 assert( elp->el_e != NULL );
1272 elp->el_e->e_private = NULL;
1273 entry_free( elp->el_e );
1274 if ( !BER_BVISNULL( &elp->el_nbase ) ) {
1275 ch_free( elp->el_nbase.bv_val );
1277 if ( !BER_BVISNULL( &elp->el_filter ) ) {
1278 ch_free( elp->el_filter.bv_val );
1280 *elpp = elp->el_next;
1287 if ( elpp != NULL ) {
1288 /* not found! where did it go? */
1297 monitor_back_unregister_entry_attrs(
1298 struct berval *ndn_in,
1299 Attribute *target_a,
1300 monitor_callback_t *target_cb,
1301 struct berval *nbase,
1303 struct berval *filter )
1306 struct berval ndn = BER_BVNULL;
1307 char *fname = ( target_a == NULL ? "callback" : "attrs" );
1309 if ( be_monitor == NULL ) {
1310 char buf[ SLAP_TEXT_BUFLEN ];
1312 snprintf( buf, sizeof( buf ),
1313 "monitor_back_unregister_entry_%s(base=\"%s\" scope=%s filter=\"%s\"): "
1314 "monitor database not configured.\n",
1316 BER_BVISNULL( nbase ) ? "" : nbase->bv_val,
1317 ldap_pvt_scope2str( scope ),
1318 BER_BVISNULL( filter ) ? "" : filter->bv_val );
1319 Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
1324 /* entry will be regularly freed, and resources released
1325 * according to callbacks */
1326 if ( slapd_shutdown ) {
1330 mi = ( monitor_info_t * )be_monitor->be_private;
1332 assert( mi != NULL );
1334 if ( ndn_in != NULL ) {
1338 if ( target_a == NULL && target_cb == NULL ) {
1343 if ( ( ndn_in == NULL || BER_BVISNULL( &ndn ) )
1344 && BER_BVISNULL( filter ) )
1347 Debug( LDAP_DEBUG_ANY,
1348 "monitor_back_unregister_entry_%s(\"\"): "
1349 "need a valid filter\n",
1354 if ( monitor_subsys_opened ) {
1356 monitor_entry_t *mp = NULL;
1359 if ( BER_BVISNULL( &ndn ) ) {
1360 if ( monitor_search2ndn( nbase, scope, filter, &ndn ) ) {
1361 char buf[ SLAP_TEXT_BUFLEN ];
1363 snprintf( buf, sizeof( buf ),
1364 "monitor_back_unregister_entry_%s(\"\"): "
1365 "base=\"%s\" scope=%d filter=\"%s\": "
1366 "unable to find entry\n",
1368 nbase->bv_val ? nbase->bv_val : "\"\"",
1369 scope, filter->bv_val );
1371 /* entry does not exist */
1372 Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
1379 if ( monitor_cache_get( mi, &ndn, &e ) != 0 ) {
1380 /* entry does not exist */
1381 Debug( LDAP_DEBUG_ANY,
1382 "monitor_back_unregister_entry(\"%s\"): "
1383 "entry removal failed.\n",
1388 mp = (monitor_entry_t *)e->e_private;
1389 assert( mp != NULL );
1391 if ( target_cb != NULL ) {
1392 monitor_callback_t **cbp;
1394 for ( cbp = &mp->mp_cb; *cbp != NULL; cbp = &(*cbp)->mc_next ) {
1395 if ( *cbp == target_cb ) {
1396 if ( (*cbp)->mc_free ) {
1397 (void)(*cbp)->mc_free( e, &(*cbp)->mc_private );
1399 *cbp = (*cbp)->mc_next;
1400 ch_free( target_cb );
1406 if ( target_a != NULL ) {
1409 for ( a = target_a; a != NULL; a = a->a_next ) {
1410 Modification mod = { 0 };
1412 char textbuf[ SLAP_TEXT_BUFLEN ];
1414 mod.sm_op = LDAP_MOD_DELETE;
1415 mod.sm_desc = a->a_desc;
1416 mod.sm_values = a->a_vals;
1417 mod.sm_nvalues = a->a_nvals;
1419 (void)modify_delete_values( e, &mod, 1,
1420 &text, textbuf, sizeof( textbuf ) );
1425 ber_memfree( ndn.bv_val );
1429 monitor_cache_release( mi, e );
1433 entry_limbo_t **elpp;
1435 for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
1437 elpp = &(*elpp)->el_next )
1439 entry_limbo_t *elp = *elpp;
1441 if ( elp->el_type == LIMBO_ATTRS
1442 && dn_match( nbase, &elp->el_nbase )
1443 && scope == elp->el_scope
1444 && bvmatch( filter, &elp->el_filter ) )
1446 monitor_callback_t *cb, *next;
1448 for ( cb = elp->el_cb; cb; cb = next ) {
1449 /* FIXME: call callbacks? */
1453 assert( elp->el_e == NULL );
1454 if ( elp->el_a != NULL ) {
1455 attrs_free( elp->el_a );
1457 if ( !BER_BVISNULL( &elp->el_nbase ) ) {
1458 ch_free( elp->el_nbase.bv_val );
1460 if ( !BER_BVISNULL( &elp->el_filter ) ) {
1461 ch_free( elp->el_filter.bv_val );
1463 *elpp = elp->el_next;
1470 if ( elpp != NULL ) {
1471 /* not found! where did it go? */
1480 monitor_back_unregister_entry_callback(
1482 monitor_callback_t *cb,
1483 struct berval *nbase,
1485 struct berval *filter )
1487 /* TODO: lookup entry (by ndn, if not NULL, and/or by callback);
1488 * unregister the callback; if a is not null, unregister the
1489 * given attrs. In any case, call cb->cb_free */
1490 return monitor_back_unregister_entry_attrs( ndn,
1491 NULL, cb, nbase, scope, filter );
1495 monitor_back_get_subsys( const char *name )
1497 if ( monitor_subsys != NULL ) {
1500 for ( i = 0; monitor_subsys[ i ] != NULL; i++ ) {
1501 if ( strcasecmp( monitor_subsys[ i ]->mss_name, name ) == 0 ) {
1502 return monitor_subsys[ i ];
1511 monitor_back_get_subsys_by_dn(
1515 if ( monitor_subsys != NULL ) {
1519 for ( i = 0; monitor_subsys[ i ] != NULL; i++ ) {
1520 if ( dnIsSuffix( ndn, &monitor_subsys[ i ]->mss_ndn ) ) {
1521 return monitor_subsys[ i ];
1526 for ( i = 0; monitor_subsys[ i ] != NULL; i++ ) {
1527 if ( dn_match( ndn, &monitor_subsys[ i ]->mss_ndn ) ) {
1528 return monitor_subsys[ i ];
1538 monitor_back_initialize(
1541 static char *controls[] = {
1542 LDAP_CONTROL_MANAGEDSAIT,
1546 static ConfigTable monitorcfg[] = {
1547 { NULL, NULL, 0, 0, 0, ARG_IGNORED,
1548 NULL, NULL, NULL, NULL }
1551 static ConfigOCs monitorocs[] = {
1552 { "( OLcfgDbOc:4.1 "
1553 "NAME 'olcMonitorConfig' "
1554 "DESC 'Monitor backend configuration' "
1555 "SUP olcDatabaseConfig "
1557 Cft_Database, monitorcfg },
1566 { "( 1.3.6.1.4.1.4203.666.3.16.1 "
1568 "DESC 'OpenLDAP system monitoring' "
1569 "SUP top STRUCTURAL "
1578 ") )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
1579 offsetof(monitor_info_t, mi_oc_monitor) },
1580 { "( 1.3.6.1.4.1.4203.666.3.16.2 "
1581 "NAME 'monitorServer' "
1582 "DESC 'Server monitoring root entry' "
1583 "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
1584 offsetof(monitor_info_t, mi_oc_monitorServer) },
1585 { "( 1.3.6.1.4.1.4203.666.3.16.3 "
1586 "NAME 'monitorContainer' "
1587 "DESC 'monitor container class' "
1588 "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
1589 offsetof(monitor_info_t, mi_oc_monitorContainer) },
1590 { "( 1.3.6.1.4.1.4203.666.3.16.4 "
1591 "NAME 'monitorCounterObject' "
1592 "DESC 'monitor counter class' "
1593 "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
1594 offsetof(monitor_info_t, mi_oc_monitorCounterObject) },
1595 { "( 1.3.6.1.4.1.4203.666.3.16.5 "
1596 "NAME 'monitorOperation' "
1597 "DESC 'monitor operation class' "
1598 "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
1599 offsetof(monitor_info_t, mi_oc_monitorOperation) },
1600 { "( 1.3.6.1.4.1.4203.666.3.16.6 "
1601 "NAME 'monitorConnection' "
1602 "DESC 'monitor connection class' "
1603 "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
1604 offsetof(monitor_info_t, mi_oc_monitorConnection) },
1605 { "( 1.3.6.1.4.1.4203.666.3.16.7 "
1606 "NAME 'managedObject' "
1607 "DESC 'monitor managed entity class' "
1608 "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
1609 offsetof(monitor_info_t, mi_oc_managedObject) },
1610 { "( 1.3.6.1.4.1.4203.666.3.16.8 "
1611 "NAME 'monitoredObject' "
1612 "DESC 'monitor monitored entity class' "
1613 "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
1614 offsetof(monitor_info_t, mi_oc_monitoredObject) },
1617 { "( 1.3.6.1.4.1.4203.666.1.55.1 "
1618 "NAME 'monitoredInfo' "
1619 "DESC 'monitored info' "
1621 "EQUALITY caseIgnoreMatch "
1622 "SUBSTR caseIgnoreSubstringsMatch "
1623 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} "
1624 "NO-USER-MODIFICATION "
1625 "USAGE dSAOperation )", SLAP_AT_HIDE,
1626 offsetof(monitor_info_t, mi_ad_monitoredInfo) },
1627 { "( 1.3.6.1.4.1.4203.666.1.55.2 "
1628 "NAME 'managedInfo' "
1629 "DESC 'monitor managed info' "
1630 "SUP name )", SLAP_AT_HIDE,
1631 offsetof(monitor_info_t, mi_ad_managedInfo) },
1632 { "( 1.3.6.1.4.1.4203.666.1.55.3 "
1633 "NAME 'monitorCounter' "
1634 "DESC 'monitor counter' "
1635 "EQUALITY integerMatch "
1636 "ORDERING integerOrderingMatch "
1637 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 "
1638 "NO-USER-MODIFICATION "
1639 "USAGE dSAOperation )", SLAP_AT_HIDE,
1640 offsetof(monitor_info_t, mi_ad_monitorCounter) },
1641 { "( 1.3.6.1.4.1.4203.666.1.55.4 "
1642 "NAME 'monitorOpCompleted' "
1643 "DESC 'monitor completed operations' "
1644 "SUP monitorCounter "
1645 "NO-USER-MODIFICATION "
1646 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1647 offsetof(monitor_info_t, mi_ad_monitorOpCompleted) },
1648 { "( 1.3.6.1.4.1.4203.666.1.55.5 "
1649 "NAME 'monitorOpInitiated' "
1650 "DESC 'monitor initiated operations' "
1651 "SUP monitorCounter "
1652 "NO-USER-MODIFICATION "
1653 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1654 offsetof(monitor_info_t, mi_ad_monitorOpInitiated) },
1655 { "( 1.3.6.1.4.1.4203.666.1.55.6 "
1656 "NAME 'monitorConnectionNumber' "
1657 "DESC 'monitor connection number' "
1658 "SUP monitorCounter "
1659 "NO-USER-MODIFICATION "
1660 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1661 offsetof(monitor_info_t, mi_ad_monitorConnectionNumber) },
1662 { "( 1.3.6.1.4.1.4203.666.1.55.7 "
1663 "NAME 'monitorConnectionAuthzDN' "
1664 "DESC 'monitor connection authorization DN' "
1665 /* "SUP distinguishedName " */
1666 "EQUALITY distinguishedNameMatch "
1667 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
1668 "NO-USER-MODIFICATION "
1669 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1670 offsetof(monitor_info_t, mi_ad_monitorConnectionAuthzDN) },
1671 { "( 1.3.6.1.4.1.4203.666.1.55.8 "
1672 "NAME 'monitorConnectionLocalAddress' "
1673 "DESC 'monitor connection local address' "
1674 "SUP monitoredInfo "
1675 "NO-USER-MODIFICATION "
1676 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1677 offsetof(monitor_info_t, mi_ad_monitorConnectionLocalAddress) },
1678 { "( 1.3.6.1.4.1.4203.666.1.55.9 "
1679 "NAME 'monitorConnectionPeerAddress' "
1680 "DESC 'monitor connection peer address' "
1681 "SUP monitoredInfo "
1682 "NO-USER-MODIFICATION "
1683 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1684 offsetof(monitor_info_t, mi_ad_monitorConnectionPeerAddress) },
1685 { "( 1.3.6.1.4.1.4203.666.1.55.10 "
1686 "NAME 'monitorTimestamp' "
1687 "DESC 'monitor timestamp' "
1688 "EQUALITY generalizedTimeMatch "
1689 "ORDERING generalizedTimeOrderingMatch "
1690 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
1692 "NO-USER-MODIFICATION "
1693 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1694 offsetof(monitor_info_t, mi_ad_monitorTimestamp) },
1695 { "( 1.3.6.1.4.1.4203.666.1.55.11 "
1696 "NAME 'monitorOverlay' "
1697 "DESC 'name of overlays defined for a given database' "
1698 "SUP monitoredInfo "
1699 "NO-USER-MODIFICATION "
1700 "USAGE dSAOperation )", SLAP_AT_HIDE,
1701 offsetof(monitor_info_t, mi_ad_monitorOverlay) },
1702 { "( 1.3.6.1.4.1.4203.666.1.55.12 "
1704 "DESC 'read/write status of a given database' "
1705 "EQUALITY booleanMatch "
1706 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "
1708 "USAGE dSAOperation )", SLAP_AT_HIDE,
1709 offsetof(monitor_info_t, mi_ad_readOnly) },
1710 { "( 1.3.6.1.4.1.4203.666.1.55.13 "
1711 "NAME 'restrictedOperation' "
1712 "DESC 'name of restricted operation for a given database' "
1713 "SUP managedInfo )", SLAP_AT_HIDE,
1714 offsetof(monitor_info_t, mi_ad_restrictedOperation ) },
1715 { "( 1.3.6.1.4.1.4203.666.1.55.14 "
1716 "NAME 'monitorConnectionProtocol' "
1717 "DESC 'monitor connection protocol' "
1718 "SUP monitoredInfo "
1719 "NO-USER-MODIFICATION "
1720 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1721 offsetof(monitor_info_t, mi_ad_monitorConnectionProtocol) },
1722 { "( 1.3.6.1.4.1.4203.666.1.55.15 "
1723 "NAME 'monitorConnectionOpsReceived' "
1724 "DESC 'monitor number of operations received by the connection' "
1725 "SUP monitorCounter "
1726 "NO-USER-MODIFICATION "
1727 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1728 offsetof(monitor_info_t, mi_ad_monitorConnectionOpsReceived) },
1729 { "( 1.3.6.1.4.1.4203.666.1.55.16 "
1730 "NAME 'monitorConnectionOpsExecuting' "
1731 "DESC 'monitor number of operations in execution within the connection' "
1732 "SUP monitorCounter "
1733 "NO-USER-MODIFICATION "
1734 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1735 offsetof(monitor_info_t, mi_ad_monitorConnectionOpsExecuting) },
1736 { "( 1.3.6.1.4.1.4203.666.1.55.17 "
1737 "NAME 'monitorConnectionOpsPending' "
1738 "DESC 'monitor number of pending operations within the connection' "
1739 "SUP monitorCounter "
1740 "NO-USER-MODIFICATION "
1741 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1742 offsetof(monitor_info_t, mi_ad_monitorConnectionOpsPending) },
1743 { "( 1.3.6.1.4.1.4203.666.1.55.18 "
1744 "NAME 'monitorConnectionOpsCompleted' "
1745 "DESC 'monitor number of operations completed within the connection' "
1746 "SUP monitorCounter "
1747 "NO-USER-MODIFICATION "
1748 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1749 offsetof(monitor_info_t, mi_ad_monitorConnectionOpsCompleted) },
1750 { "( 1.3.6.1.4.1.4203.666.1.55.19 "
1751 "NAME 'monitorConnectionGet' "
1752 "DESC 'number of times connection_get() was called so far' "
1753 "SUP monitorCounter "
1754 "NO-USER-MODIFICATION "
1755 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1756 offsetof(monitor_info_t, mi_ad_monitorConnectionGet) },
1757 { "( 1.3.6.1.4.1.4203.666.1.55.20 "
1758 "NAME 'monitorConnectionRead' "
1759 "DESC 'number of times connection_read() was called so far' "
1760 "SUP monitorCounter "
1761 "NO-USER-MODIFICATION "
1762 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1763 offsetof(monitor_info_t, mi_ad_monitorConnectionRead) },
1764 { "( 1.3.6.1.4.1.4203.666.1.55.21 "
1765 "NAME 'monitorConnectionWrite' "
1766 "DESC 'number of times connection_write() was called so far' "
1767 "SUP monitorCounter "
1768 "NO-USER-MODIFICATION "
1769 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1770 offsetof(monitor_info_t, mi_ad_monitorConnectionWrite) },
1771 { "( 1.3.6.1.4.1.4203.666.1.55.22 "
1772 "NAME 'monitorConnectionMask' "
1773 "DESC 'monitor connection mask' "
1774 "SUP monitoredInfo "
1775 "NO-USER-MODIFICATION "
1776 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1777 offsetof(monitor_info_t, mi_ad_monitorConnectionMask) },
1778 { "( 1.3.6.1.4.1.4203.666.1.55.23 "
1779 "NAME 'monitorConnectionListener' "
1780 "DESC 'monitor connection listener' "
1781 "SUP monitoredInfo "
1782 "NO-USER-MODIFICATION "
1783 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1784 offsetof(monitor_info_t, mi_ad_monitorConnectionListener) },
1785 { "( 1.3.6.1.4.1.4203.666.1.55.24 "
1786 "NAME 'monitorConnectionPeerDomain' "
1787 "DESC 'monitor connection peer domain' "
1788 "SUP monitoredInfo "
1789 "NO-USER-MODIFICATION "
1790 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1791 offsetof(monitor_info_t, mi_ad_monitorConnectionPeerDomain) },
1792 { "( 1.3.6.1.4.1.4203.666.1.55.25 "
1793 "NAME 'monitorConnectionStartTime' "
1794 "DESC 'monitor connection start time' "
1795 "SUP monitorTimestamp "
1797 "NO-USER-MODIFICATION "
1798 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1799 offsetof(monitor_info_t, mi_ad_monitorConnectionStartTime) },
1800 { "( 1.3.6.1.4.1.4203.666.1.55.26 "
1801 "NAME 'monitorConnectionActivityTime' "
1802 "DESC 'monitor connection activity time' "
1803 "SUP monitorTimestamp "
1805 "NO-USER-MODIFICATION "
1806 "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
1807 offsetof(monitor_info_t, mi_ad_monitorConnectionActivityTime) },
1808 { "( 1.3.6.1.4.1.4203.666.1.55.27 "
1809 "NAME 'monitorIsShadow' "
1810 "DESC 'TRUE if the database is shadow' "
1811 "EQUALITY booleanMatch "
1812 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "
1814 "USAGE dSAOperation )", SLAP_AT_HIDE,
1815 offsetof(monitor_info_t, mi_ad_monitorIsShadow) },
1816 { "( 1.3.6.1.4.1.4203.666.1.55.28 "
1817 "NAME 'monitorUpdateRef' "
1818 "DESC 'update referral for shadow databases' "
1819 "SUP monitoredInfo "
1821 "USAGE dSAOperation )", SLAP_AT_HIDE,
1822 offsetof(monitor_info_t, mi_ad_monitorUpdateRef) },
1823 { "( 1.3.6.1.4.1.4203.666.1.55.29 "
1824 "NAME 'monitorRuntimeConfig' "
1825 "DESC 'TRUE if component allows runtime configuration' "
1826 "EQUALITY booleanMatch "
1827 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "
1829 "USAGE dSAOperation )", SLAP_AT_HIDE,
1830 offsetof(monitor_info_t, mi_ad_monitorRuntimeConfig) },
1838 { "olmAttributes", "1.3.6.1.4.1.4203.666.1.55" },
1839 { "olmSubSystemAttributes", "olmAttributes:0" },
1840 { "olmGenericAttributes", "olmSubSystemAttributes:0" },
1841 { "olmDatabaseAttributes", "olmSubSystemAttributes:1" },
1843 /* for example, back-bdb specific attrs
1844 * are in "olmDatabaseAttributes:1"
1846 * NOTE: developers, please record here OID assignments
1847 * for other modules */
1849 { "olmObjectClasses", "1.3.6.1.4.1.4203.666.3.16" },
1850 { "olmSubSystemObjectClasses", "olmObjectClasses:0" },
1851 { "olmGenericObjectClasses", "olmSubSystemObjectClasses:0" },
1852 { "olmDatabaseObjectClasses", "olmSubSystemObjectClasses:1" },
1854 /* for example, back-bdb specific objectClasses
1855 * are in "olmDatabaseObjectClasses:1"
1857 * NOTE: developers, please record here OID assignments
1858 * for other modules */
1864 monitor_info_t *mi = &monitor_info;
1868 argv[ 0 ] = "monitor";
1873 for ( i = 0; s_oid[ i ].name; i++ ) {
1874 argv[ 1 ] = s_oid[ i ].name;
1875 argv[ 2 ] = s_oid[ i ].oid;
1877 if ( parse_oidm( &c, 0, NULL ) != 0 ) {
1878 Debug( LDAP_DEBUG_ANY,
1879 "monitor_back_initialize: unable to add "
1880 "objectIdentifier \"%s=%s\"\n",
1881 s_oid[ i ].name, s_oid[ i ].oid, 0 );
1886 /* schema integration */
1887 for ( i = 0; mat[ i ].schema; i++ ) {
1889 AttributeDescription **ad =
1890 ((AttributeDescription **)&(((char *)mi)[ mat[ i ].offset ]));
1893 code = register_at( mat[ i ].schema, ad, 0 );
1896 Debug( LDAP_DEBUG_ANY,
1897 "monitor_back_db_init: register_at failed\n", 0, 0, 0 );
1900 (*ad)->ad_type->sat_flags |= mat[ i ].flags;
1903 for ( i = 0; moc[ i ].schema; i++ ) {
1906 ((ObjectClass **)&(((char *)mi)[ moc[ i ].offset ]));
1908 code = register_oc( moc[ i ].schema, Oc, 0 );
1910 Debug( LDAP_DEBUG_ANY,
1911 "monitor_back_db_init: register_oc failed\n", 0, 0, 0 );
1914 (*Oc)->soc_flags |= moc[ i ].flags;
1917 bi->bi_controls = controls;
1921 bi->bi_config = monitor_back_config;
1925 bi->bi_db_init = monitor_back_db_init;
1927 bi->bi_db_config = monitor_back_db_config;
1929 bi->bi_db_open = monitor_back_db_open;
1930 bi->bi_db_close = 0;
1931 bi->bi_db_destroy = monitor_back_db_destroy;
1933 bi->bi_op_bind = monitor_back_bind;
1934 bi->bi_op_unbind = 0;
1935 bi->bi_op_search = monitor_back_search;
1936 bi->bi_op_compare = monitor_back_compare;
1937 bi->bi_op_modify = monitor_back_modify;
1938 bi->bi_op_modrdn = 0;
1940 bi->bi_op_delete = 0;
1941 bi->bi_op_abandon = 0;
1943 bi->bi_extended = 0;
1945 bi->bi_entry_release_rw = 0;
1946 bi->bi_chk_referrals = 0;
1947 bi->bi_operational = monitor_back_operational;
1950 * hooks for slap tools
1952 bi->bi_tool_entry_open = 0;
1953 bi->bi_tool_entry_close = 0;
1954 bi->bi_tool_entry_first = 0;
1955 bi->bi_tool_entry_next = 0;
1956 bi->bi_tool_entry_get = 0;
1957 bi->bi_tool_entry_put = 0;
1958 bi->bi_tool_entry_reindex = 0;
1959 bi->bi_tool_sync = 0;
1960 bi->bi_tool_dn2id_get = 0;
1961 bi->bi_tool_id2entry_get = 0;
1962 bi->bi_tool_entry_modify = 0;
1964 bi->bi_connection_init = 0;
1965 bi->bi_connection_destroy = 0;
1967 bi->bi_extra = (void *)&monitor_extra;
1970 * configuration objectClasses (fake)
1972 bi->bi_cf_ocs = monitorocs;
1974 rc = config_register_schema( monitorcfg, monitorocs );
1983 monitor_back_db_init(
1987 struct berval dn = BER_BVC( SLAPD_MONITOR_DN ),
1992 monitor_subsys_t *ms;
1997 for ( ms = known_monitor_subsys; ms->mss_name != NULL; ms++ ) {
1998 if ( monitor_back_register_subsys( ms ) ) {
2004 * database monitor can be defined once only
2006 if ( be_monitor != NULL ) {
2007 Debug( LDAP_DEBUG_ANY,
2008 "only one monitor database is allowed\n", 0, 0, 0 );
2013 /* indicate system schema supported */
2014 SLAP_BFLAGS(be) |= SLAP_BFLAG_MONITOR;
2016 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn, NULL );
2017 if( rc != LDAP_SUCCESS ) {
2018 Debug( LDAP_DEBUG_ANY,
2019 "unable to normalize/pretty monitor DN \"%s\" (%d)\n",
2024 ber_bvarray_add( &be->be_suffix, &pdn );
2025 ber_bvarray_add( &be->be_nsuffix, &ndn );
2027 /* NOTE: only one monitor database is allowed,
2028 * so we use static storage */
2029 ldap_pvt_thread_mutex_init( &monitor_info.mi_cache_mutex );
2031 be->be_private = &monitor_info;
2033 be2 = select_backend( &ndn, 0, 0 );
2035 char *type = be2->bd_info->bi_type;
2037 if ( overlay_is_over( be2 ) ) {
2038 slap_overinfo *oi = (slap_overinfo *)be2->bd_info->bi_private;
2039 type = oi->oi_orig->bi_type;
2042 Debug( LDAP_DEBUG_ANY,
2043 "\"monitor\" database serving namingContext \"%s\" "
2044 "is hidden by \"%s\" database serving namingContext \"%s\".\n",
2045 pdn.bv_val, type, be2->be_nsuffix[ 0 ].bv_val );
2053 monitor_back_db_open(
2056 monitor_info_t *mi = (monitor_info_t *)be->be_private;
2057 struct monitor_subsys_t **ms;
2058 Entry *e, **ep, *root;
2059 monitor_entry_t *mp;
2061 struct berval bv, rdn = BER_BVC(SLAPD_MONITOR_DN);
2063 #ifdef HAVE_GMTIME_R
2066 static char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
2067 struct berval desc[] = {
2068 BER_BVC("This subtree contains monitoring/managing objects."),
2069 BER_BVC("This object contains information about this server."),
2070 BER_BVC("Most of the information is held in operational"
2071 " attributes, which must be explicitly requested."),
2074 assert( be_monitor != NULL );
2075 if ( be != be_monitor ) {
2082 #ifndef HAVE_GMTIME_R
2083 ldap_pvt_thread_mutex_lock( &gmtime_mutex );
2085 #ifdef HACK_LOCAL_TIME
2086 # ifdef HAVE_LOCALTIME_R
2087 tms = localtime_r( &starttime, &tm_buf );
2089 tms = localtime( &starttime );
2090 # endif /* HAVE_LOCALTIME_R */
2091 lutil_localtime( tmbuf, sizeof(tmbuf), tms, -timezone );
2092 #else /* !HACK_LOCAL_TIME */
2093 # ifdef HAVE_GMTIME_R
2094 tms = gmtime_r( &starttime, &tm_buf );
2096 tms = gmtime( &starttime );
2097 # endif /* HAVE_GMTIME_R */
2098 lutil_gentime( tmbuf, sizeof(tmbuf), tms );
2099 #endif /* !HACK_LOCAL_TIME */
2100 #ifndef HAVE_GMTIME_R
2101 ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
2104 mi->mi_startTime.bv_val = tmbuf;
2105 mi->mi_startTime.bv_len = strlen( tmbuf );
2107 if ( BER_BVISEMPTY( &be->be_rootdn ) ) {
2108 BER_BVSTR( &mi->mi_creatorsName, SLAPD_ANONYMOUS );
2109 BER_BVSTR( &mi->mi_ncreatorsName, SLAPD_ANONYMOUS );
2111 mi->mi_creatorsName = be->be_rootdn;
2112 mi->mi_ncreatorsName = be->be_rootndn;
2116 * creates the "cn=Monitor" entry
2118 e = monitor_entry_stub( NULL, NULL, &rdn, mi->mi_oc_monitorServer, mi,
2122 Debug( LDAP_DEBUG_ANY,
2123 "unable to create \"%s\" entry\n",
2124 SLAPD_MONITOR_DN, 0, 0 );
2128 attr_merge_normalize( e, slap_schema.si_ad_description, desc, NULL );
2130 bv.bv_val = strchr( (char *) Versionstr, '$' );
2131 if ( bv.bv_val != NULL ) {
2135 for ( ; bv.bv_val[ 0 ] == ' '; bv.bv_val++ )
2138 end = strchr( bv.bv_val, '$' );
2139 if ( end != NULL ) {
2142 for ( ; end > bv.bv_val && end[ 0 ] == ' '; end-- )
2147 bv.bv_len = end - bv.bv_val;
2150 bv.bv_len = strlen( bv.bv_val );
2153 if ( attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo,
2155 Debug( LDAP_DEBUG_ANY,
2156 "unable to add monitoredInfo to \"%s\" entry\n",
2157 SLAPD_MONITOR_DN, 0, 0 );
2162 mp = monitor_entrypriv_create();
2166 e->e_private = ( void * )mp;
2167 ep = &mp->mp_children;
2169 if ( monitor_cache_add( mi, e ) ) {
2170 Debug( LDAP_DEBUG_ANY,
2171 "unable to add entry \"%s\" to cache\n",
2172 SLAPD_MONITOR_DN, 0, 0 );
2178 * Create all the subsystem specific entries
2180 for ( i = 0; monitor_subsys[ i ] != NULL; i++ ) {
2181 int len = strlen( monitor_subsys[ i ]->mss_name );
2185 dn.bv_len = len + sizeof( "cn=" ) - 1;
2186 dn.bv_val = ch_calloc( sizeof( char ), dn.bv_len + 1 );
2187 strcpy( dn.bv_val, "cn=" );
2188 strcat( dn.bv_val, monitor_subsys[ i ]->mss_name );
2189 rc = dnPretty( NULL, &dn, &monitor_subsys[ i ]->mss_rdn, NULL );
2191 if ( rc != LDAP_SUCCESS ) {
2192 Debug( LDAP_DEBUG_ANY,
2193 "monitor RDN \"%s\" is invalid\n",
2198 e = monitor_entry_stub( &root->e_name, &root->e_nname,
2199 &monitor_subsys[ i ]->mss_rdn, mi->mi_oc_monitorContainer, mi,
2203 Debug( LDAP_DEBUG_ANY,
2204 "unable to create \"%s\" entry\n",
2205 monitor_subsys[ i ]->mss_dn.bv_val, 0, 0 );
2208 monitor_subsys[i]->mss_dn = e->e_name;
2209 monitor_subsys[i]->mss_ndn = e->e_nname;
2211 if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_desc[ 0 ] ) ) {
2212 attr_merge_normalize( e, slap_schema.si_ad_description,
2213 monitor_subsys[ i ]->mss_desc, NULL );
2216 mp = monitor_entrypriv_create();
2220 e->e_private = ( void * )mp;
2221 mp->mp_info = monitor_subsys[ i ];
2222 mp->mp_flags = monitor_subsys[ i ]->mss_flags;
2224 if ( monitor_cache_add( mi, e ) ) {
2225 Debug( LDAP_DEBUG_ANY,
2226 "unable to add entry \"%s\" to cache\n",
2227 monitor_subsys[ i ]->mss_dn.bv_val, 0, 0 );
2235 assert( be != NULL );
2237 be->be_private = mi;
2240 * opens the monitor backend subsystems
2242 for ( ms = monitor_subsys; ms[ 0 ] != NULL; ms++ ) {
2243 if ( ms[ 0 ]->mss_open && ( *ms[ 0 ]->mss_open )( be, ms[ 0 ] ) )
2247 ms[ 0 ]->mss_flags |= MONITOR_F_OPENED;
2250 monitor_subsys_opened = 1;
2252 if ( mi->mi_entry_limbo ) {
2253 entry_limbo_t *el = (entry_limbo_t *)mi->mi_entry_limbo;
2259 switch ( el->el_type ) {
2261 rc = monitor_back_register_entry(
2268 case LIMBO_ENTRY_PARENT:
2269 rc = monitor_back_register_entry_parent(
2281 rc = monitor_back_register_entry_attrs(
2291 rc = monitor_back_register_entry_callback(
2304 entry_free( el->el_e );
2307 attrs_free( el->el_a );
2309 if ( !BER_BVISNULL( &el->el_ndn ) ) {
2310 ber_memfree( el->el_ndn.bv_val );
2312 if ( !BER_BVISNULL( &el->el_nbase ) ) {
2313 ber_memfree( el->el_nbase.bv_val );
2315 if ( !BER_BVISNULL( &el->el_filter ) ) {
2316 ber_memfree( el->el_filter.bv_val );
2318 if ( el->el_cb && rc != 0 ) {
2319 if ( el->el_cb->mc_dispose ) {
2320 el->el_cb->mc_dispose( &el->el_cb->mc_private );
2322 ch_free( el->el_cb );
2330 mi->mi_entry_limbo = NULL;
2337 monitor_back_config(
2345 * eventually, will hold backend specific configuration parameters
2347 return SLAP_CONF_UNKNOWN;
2352 monitor_back_db_config(
2359 monitor_info_t *mi = ( monitor_info_t * )be->be_private;
2362 * eventually, will hold database specific configuration parameters
2364 return SLAP_CONF_UNKNOWN;
2369 monitor_back_db_destroy(
2372 monitor_info_t *mi = ( monitor_info_t * )be->be_private;
2379 * FIXME: destroys all the data
2381 /* NOTE: mi points to static storage; don't free it */
2383 (void)monitor_cache_destroy( mi );
2385 if ( monitor_subsys ) {
2388 for ( i = 0; monitor_subsys[ i ] != NULL; i++ ) {
2389 if ( monitor_subsys[ i ]->mss_destroy ) {
2390 monitor_subsys[ i ]->mss_destroy( be, monitor_subsys[ i ] );
2393 if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_rdn ) ) {
2394 ch_free( monitor_subsys[ i ]->mss_rdn.bv_val );
2398 ch_free( monitor_subsys );
2401 ldap_pvt_thread_mutex_destroy( &monitor_info.mi_cache_mutex );
2403 be->be_private = NULL;
2408 #if SLAPD_MONITOR == SLAPD_MOD_DYNAMIC
2410 /* conditionally define the init_module() function */
2411 SLAP_BACKEND_INIT_MODULE( monitor )
2413 #endif /* SLAPD_MONITOR == SLAPD_MOD_DYNAMIC */