]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/monitor.c
- setup framework for monitoring of back-bdb/back-hdb stuff in their
[openldap] / servers / slapd / back-bdb / monitor.c
1 /* monitor.c - monitor bdb backend */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2000-2006 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16
17 #include "portable.h"
18
19 #include <stdio.h>
20 #include <ac/string.h>
21 #include <ac/unistd.h>
22 #include <ac/stdlib.h>
23 #include <ac/errno.h>
24 #include <sys/stat.h>
25 #include "lutil.h"
26 #include "back-bdb.h"
27 #include "../back-monitor/back-monitor.h"
28
29 static ObjectClass              *oc_olmBDBDatabase;
30
31 static AttributeDescription     *ad_olmBDBCounter;
32
33 static int
34 bdb_monitor_update(
35         Operation       *op,
36         SlapReply       *rs,
37         Entry           *e,
38         void            *priv )
39 {
40         struct bdb_info         *bdb = (struct bdb_info *) priv;
41         Attribute               *a;
42
43         /* NOTE: dummy code that increments a olmBDBCounter
44          * any time it's called; replace with something useful */
45         unsigned long           u;
46         char                    buf[ BUFSIZ ];
47         struct berval           bv;
48
49         assert( ad_olmBDBCounter != NULL );
50
51         a = attr_find( e->e_attrs, ad_olmBDBCounter );
52         assert( a != NULL );
53         lutil_atoul( &u, a->a_vals[ 0 ].bv_val );
54         u++;
55         bv.bv_val = buf;
56         bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", u );
57         ber_bvreplace( &a->a_vals[ 0 ], &bv );
58         
59         return SLAP_CB_CONTINUE;
60 }
61
62 static int
63 bdb_monitor_modify(
64         Operation       *op,
65         SlapReply       *rs,
66         Entry           *e,
67         void            *priv )
68 {
69         struct bdb_info         *bdb = (struct bdb_info *) priv;
70         
71         return SLAP_CB_CONTINUE;
72 }
73
74 static int
75 bdb_monitor_free(
76         Entry           *e,
77         void            *priv )
78 {
79         struct bdb_info         *bdb = (struct bdb_info *) priv;
80         
81         return SLAP_CB_CONTINUE;
82 }
83
84 /*
85  * NOTE: there's some confusion in monitor OID arc;
86  * by now, let's consider:
87  * 
88  * Subsystems monitor attributes        1.3.6.1.4.1.4203.666.1.55.0
89  * Databases monitor attributes         1.3.6.1.4.1.4203.666.1.55.0.1
90  * BDB database monitor attributes      1.3.6.1.4.1.4203.666.1.55.0.1.1
91  *
92  * Subsystems monitor objectclasses     1.3.6.1.4.1.4203.666.3.16.0
93  * Databases monitor objectclasses      1.3.6.1.4.1.4203.666.3.16.0.1
94  * BDB database monitor objectclasses   1.3.6.1.4.1.4203.666.3.16.0.1.1
95  */
96 #define BDB_MONITOR_SCHEMA_AD           "1.3.6.1.4.1.4203.666.1.55.0.1.1"
97 #define BDB_MONITOR_SCHEMA_OC           "1.3.6.1.4.1.4203.666.3.16.0.1.1"
98
99 static struct {
100         char                    *name;
101         char                    *desc;
102         AttributeDescription    **ad;
103 }               s_at[] = {
104         { "olmBDBCounter", "( " BDB_MONITOR_SCHEMA_AD ".0 "
105                 "NAME ( 'olmBDBCounter' ) "
106                 "DESC 'A dummy counter' "
107                 "SUP monitorCounter "
108                 "NO-USER-MODIFICATION "
109                 "USAGE directoryOperation )",
110                 &ad_olmBDBCounter },
111
112         { NULL }
113 };
114
115 static struct {
116         char            *name;
117         char            *desc;
118         ObjectClass     **oc;
119 }               s_oc[] = {
120         { "olmBDBDatabase", "( " BDB_MONITOR_SCHEMA_OC ".1 "
121                 "NAME ( 'olmBDBDatabase' ) "
122                 "SUP monitoredObject STRUCTURAL "
123                 "MAY ( "
124                         "olmBDBCounter "
125                         ") )",
126                 &oc_olmBDBDatabase },
127
128         { NULL }
129 };
130
131 /*
132  * call from within bdb_initialize()
133  */
134 int
135 bdb_monitor_initialize( void )
136 {
137         int             i, code;
138         const char      *err;
139
140         static int      bdb_monitor_initialized = 0;
141
142         /* register schema here; if compiled as dynamic object,
143          * must be loaded __after__ back_monitor.la */
144
145         if ( bdb_monitor_initialized++ ) {
146                 return 0;
147         }
148
149         for ( i = 0; s_at[ i ].name != NULL; i++ ) {
150                 LDAPAttributeType       *at;
151
152                 at = ldap_str2attributetype( s_at[ i ].desc,
153                         &code, &err, LDAP_SCHEMA_ALLOW_ALL );
154                 if ( !at ) {
155                         Debug( LDAP_DEBUG_ANY,
156                                 "bdb_monitor_initialize: "
157                                 "AttributeType load failed: %s %s\n",
158                                 ldap_scherr2str( code ), err, 0 );
159                         return LDAP_INVALID_SYNTAX;
160                 }
161
162                 code = at_add( at, 0, NULL, &err );
163                 if ( code != LDAP_SUCCESS ) {
164                         Debug( LDAP_DEBUG_ANY,
165                                 "bdb_monitor_initialize: "
166                                 "AttributeType load failed: %s %s\n",
167                                 scherr2str( code ), err, 0 );
168                         code = LDAP_INVALID_SYNTAX;
169                         goto done_at;
170                 }
171
172                 code = slap_str2ad( s_at[ i ].name,
173                                 s_at[ i ].ad, &err );
174                 if ( code != LDAP_SUCCESS ) {
175                         Debug( LDAP_DEBUG_ANY,
176                                 "bdb_monitor_initialize: "
177                                 "unable to find AttributeDescription "
178                                 "\"%s\": %d (%s)\n",
179                                 s_at[ i ].name, code, err );
180                         code = LDAP_UNDEFINED_TYPE;
181                         goto done_at;
182                 }
183
184 done_at:;
185                 if ( code ) {
186                         ldap_attributetype_free( at );
187                         return code;
188                 }
189
190                 ldap_memfree( at );
191         }
192
193         for ( i = 0; s_oc[ i ].name != NULL; i++ ) {
194                 LDAPObjectClass *oc;
195
196                 oc = ldap_str2objectclass( s_oc[ i ].desc,
197                                 &code, &err, LDAP_SCHEMA_ALLOW_ALL );
198                 if ( !oc ) {
199                         Debug( LDAP_DEBUG_ANY,
200                                 "bdb_monitor_initialize: "
201                                 "ObjectClass load failed: %s %s\n",
202                                 ldap_scherr2str( code ), err, 0 );
203                         return LDAP_INVALID_SYNTAX;
204                 }
205
206                 code = oc_add( oc, 0, NULL, &err );
207                 if ( code != LDAP_SUCCESS ) {
208                         Debug( LDAP_DEBUG_ANY,
209                                 "bdb_monitor_initialize: "
210                                 "ObjectClass load failed: %s %s\n",
211                                 scherr2str( code ), err, 0 );
212                         code = LDAP_INVALID_SYNTAX;
213                         goto done_oc;
214                 }
215
216                 *s_oc[ i ].oc = oc_find( s_oc[ i ].name );
217                 if ( *s_oc[ i ].oc == NULL ) {
218                         code = LDAP_UNDEFINED_TYPE;
219                         Debug( LDAP_DEBUG_ANY,
220                                 "bdb_monitor_initialize: "
221                                 "unable to find objectClass \"%s\"\n",
222                                 s_oc[ i ].name, 0, 0 );
223                         goto done_oc;
224                 }
225
226 done_oc:;
227                 if ( code != LDAP_SUCCESS ) {
228                         ldap_objectclass_free( oc );
229                         return code;
230                 }
231
232                 ldap_memfree( oc );
233         }
234
235         return 0;
236 }
237
238 /*
239  * call from within bdb_db_init()
240  */
241 int
242 bdb_monitor_init( BackendDB *be )
243 {
244         return 0;
245 }
246
247 /*
248  * call from within bdb_db_open()
249  */
250 int
251 bdb_monitor_open( BackendDB *be )
252 {
253         struct bdb_info         *bdb = (struct bdb_info *) be->be_private;
254         Attribute               *a, *next;
255         monitor_callback_t      *cb;
256         struct berval           base = BER_BVC( "cn=databases,cn=monitor" );
257         struct berval           suffix, filter;
258         char                    *ptr;
259         int                     rc = 0;
260
261         /* monitor_back_register_entry_attrs() with a NULL ndn,
262          * base="cn=Databases,cn=Monitor", scope=LDAP_SCOPE_ONE 
263          * and filter="(namingContexts:distinguishedNameMatch:=<suffix>)" */
264
265         suffix.bv_len = ldap_bv2escaped_filter_value_len( &be->be_nsuffix[ 0 ] );
266         if ( suffix.bv_len == be->be_nsuffix[ 0 ].bv_len ) {
267                 suffix = be->be_nsuffix[ 0 ];
268
269         } else {
270                 ldap_bv2escaped_filter_value( &be->be_nsuffix[ 0 ], &suffix );
271         }
272         
273         filter.bv_len = STRLENOF( "(namingContexts:distinguishedNameMatch:=)" ) + suffix.bv_len;
274         ptr = filter.bv_val = ch_malloc( filter.bv_len + 1 );
275         ptr = lutil_strcopy( ptr, "(namingContexts:distinguishedNameMatch:=" );
276         ptr = lutil_strncopy( ptr, suffix.bv_val, suffix.bv_len );
277         ptr[ 0 ] = ')';
278         ptr++;
279         ptr[ 0 ] = '\0';
280         assert( filter.bv_len == ptr - filter.bv_val );
281         
282         if ( suffix.bv_val != be->be_nsuffix[ 0 ].bv_val ) {
283                 ch_free( suffix.bv_val );
284         }
285
286         /* alloc as many as required (plus 1 for objectClass) */
287         a = attrs_alloc( 1 + 1 );
288         if ( a == NULL ) {
289                 rc = 1;
290                 goto cleanup;
291         }
292
293         a->a_desc = slap_schema.si_ad_objectClass;
294         a->a_vals = NULL;
295         value_add_one( &a->a_vals, &oc_olmBDBDatabase->soc_cname );
296         a->a_nvals = a->a_vals;
297         next = a->a_next;
298
299         /* NOTE: dummy code that increments a olmBDBCounter
300          * any time it's called; replace with something useful */
301         {
302                 struct berval   bv = BER_BVC( "0" );
303
304                 next->a_desc = ad_olmBDBCounter;
305                 next->a_vals = NULL;
306                 value_add_one( &next->a_vals, &bv );
307                 next->a_nvals = next->a_vals;
308                 next = a->a_next;
309         }
310
311         cb = ch_calloc( sizeof( monitor_callback_t ), 1 );
312         cb->mc_update = bdb_monitor_update;
313         cb->mc_modify = bdb_monitor_modify;
314         cb->mc_free = bdb_monitor_free;
315         cb->mc_private = (void *)bdb;
316
317         rc = monitor_back_register_entry_attrs( NULL,
318                 a, cb, &base, LDAP_SCOPE_ONELEVEL, &filter );
319
320 cleanup:;
321         if ( rc != 0 ) {
322                 if ( cb != NULL ) {
323                         ch_free( cb );
324                 }
325
326                 if ( a != NULL ) {
327                         attrs_free( a );
328                 }
329         }
330         
331         return rc;
332 }
333
334 /*
335  * call from within bdb_db_close()
336  */
337 int
338 bdb_monitor_close( BackendDB *be )
339 {
340         return 0;
341 }
342
343 /*
344  * call from within bdb_db_destroy()
345  */
346 int
347 bdb_monitor_destroy( BackendDB *be )
348 {
349         return 0;
350 }
351