]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/conn.c
More "char *" to struct berval DN changes
[openldap] / servers / slapd / back-monitor / conn.c
1 /* conn.c - deal with connection subsystem */
2 /*
3  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /*
7  * Copyright 2001 The OpenLDAP Foundation, All Rights Reserved.
8  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
9  * 
10  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
11  * 
12  * This work has beed deveolped for the OpenLDAP Foundation 
13  * in the hope that it may be useful to the Open Source community, 
14  * but WITHOUT ANY WARRANTY.
15  * 
16  * Permission is granted to anyone to use this software for any purpose
17  * on any computer system, and to alter it and redistribute it, subject
18  * to the following restrictions:
19  * 
20  * 1. The author and SysNet s.n.c. are not responsible for the consequences
21  *    of use of this software, no matter how awful, even if they arise from
22  *    flaws in it.
23  * 
24  * 2. The origin of this software must not be misrepresented, either by
25  *    explicit claim or by omission.  Since few users ever read sources,
26  *    credits should appear in the documentation.
27  * 
28  * 3. Altered versions must be plainly marked as such, and must not be
29  *    misrepresented as being the original software.  Since few users
30  *    ever read sources, credits should appear in the documentation.
31  *    SysNet s.n.c. cannot be responsible for the consequences of the
32  *    alterations.
33  * 
34  * 4. This notice may not be removed or altered.
35  */
36
37 #include "portable.h"
38
39 #include <stdio.h>
40
41 #include "slap.h"
42 #include "back-monitor.h"
43
44 int
45 monitor_subsys_conn_init(
46         BackendDB               *be
47 )
48 {
49         struct monitorinfo      *mi;
50         
51         Entry                   *e, *e_tmp, *e_conn;
52         struct monitorentrypriv *mp;
53         char                    buf[1024];
54         struct berval           val, *bv[2] = { &val, NULL };
55
56         assert( be != NULL );
57
58         mi = ( struct monitorinfo * )be->be_private;
59
60         if ( monitor_cache_get( mi,
61                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn, &e_conn ) ) {
62 #ifdef NEW_LOGGING
63                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
64                         "monitor_subsys_conn_init: "
65                         "unable to get entry '%s'\n",
66                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn ));
67 #else
68                 Debug( LDAP_DEBUG_ANY,
69                         "monitor_subsys_conn_init: "
70                         "unable to get entry '%s'\n%s%s",
71                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn, 
72                         "", "" );
73 #endif
74                 return( -1 );
75         }
76
77         e_tmp = NULL;
78
79         /*
80          * Total conns
81          */
82         snprintf( buf, sizeof( buf ),
83                 "dn: cn=Total,%s\n"
84                 "objectClass: top\n"
85                 "objectClass: LDAPsubEntry\n"
86 #ifdef SLAPD_MONITORSUBENTRY
87                 "objectClass: monitorSubEntry\n"
88 #else /* !SLAPD_MONITORSUBENTRY */
89                 "objectClass: extensibleObject\n"
90 #endif /* !SLAPD_MONITORSUBENTRY */
91                 "cn: Total\n",
92                 monitor_subsys[SLAPD_MONITOR_CONN].mss_dn );
93         
94         e = str2entry( buf );
95         if ( e == NULL ) {
96 #ifdef NEW_LOGGING
97                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
98                         "monitor_subsys_conn_init: "
99                         "unable to create entry 'cn=Total,%s'\n",
100                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn ));
101 #else
102                 Debug( LDAP_DEBUG_ANY,
103                         "monitor_subsys_conn_init: "
104                         "unable to create entry 'cn=Total,%s'\n%s%s",
105                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn,
106                         "", "" );
107 #endif
108                 return( -1 );
109         }
110         
111         val.bv_val = "0";
112         val.bv_len = 1;
113         attr_merge( e, monitor_ad_desc, bv );
114         
115         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
116         e->e_private = ( void * )mp;
117         mp->mp_next = e_tmp;
118         mp->mp_children = NULL;
119         mp->mp_info = &monitor_subsys[SLAPD_MONITOR_CONN];
120         mp->mp_flags = monitor_subsys[SLAPD_MONITOR_CONN].mss_flags \
121                 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
122         mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
123
124         if ( monitor_cache_add( mi, e ) ) {
125 #ifdef NEW_LOGGING
126                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
127                         "monitor_subsys_conn_init: "
128                         "unable to add entry 'cn=Total,%s'\n",
129                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn ));
130 #else
131                 Debug( LDAP_DEBUG_ANY,
132                         "monitor_subsys_conn_init: "
133                         "unable to add entry 'cn=Total,%s'\n%s%s",
134                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn,
135                         "", "" );
136 #endif
137                 return( -1 );
138         }
139         
140         e_tmp = e;
141
142         /*
143          * Current conns
144          */
145         snprintf( buf, sizeof( buf ),
146                 "dn: cn=Current,%s\n"
147                 "objectClass: top\n"
148                 "objectClass: LDAPsubEntry\n"
149 #ifdef SLAPD_MONITORSUBENTRY
150                 "objectClass: monitorSubEntry\n"
151 #else /* !SLAPD_MONITORSUBENTRY */
152                 "objectClass: extensibleObject\n"
153 #endif /* !SLAPD_MONITORSUBENTRY */
154                 "cn: Current\n",
155                 monitor_subsys[SLAPD_MONITOR_CONN].mss_dn );
156         
157         e = str2entry( buf );
158         if ( e == NULL ) {
159 #ifdef NEW_LOGGING
160                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
161                         "monitor_subsys_conn_init: "
162                         "unable to create entry 'cn=Current,%s'\n",
163                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn ));
164 #else
165                 Debug( LDAP_DEBUG_ANY,
166                         "monitor_subsys_conn_init: "
167                         "unable to create entry 'cn=Current,%s'\n%s%s",
168                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn,
169                         "", "" );
170 #endif
171                 return( -1 );
172         }
173         
174         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
175         e->e_private = ( void * )mp;
176         mp->mp_next = e_tmp;
177         mp->mp_children = NULL;
178         mp->mp_info = &monitor_subsys[SLAPD_MONITOR_CONN];
179         mp->mp_flags = monitor_subsys[SLAPD_MONITOR_CONN].mss_flags \
180                 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
181         mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
182
183         if ( monitor_cache_add( mi, e ) ) {
184 #ifdef NEW_LOGGING
185                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
186                         "monitor_subsys_conn_init: "
187                         "unable to add entry 'cn=Current,%s'\n",
188                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn ));
189 #else
190                 Debug( LDAP_DEBUG_ANY,
191                         "monitor_subsys_conn_init: "
192                         "unable to add entry 'cn=Current,%s'\n%s%s",
193                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn,
194                         "", "" );
195 #endif
196                 return( -1 );
197         }
198         
199         e_tmp = e;
200
201         mp = ( struct monitorentrypriv * )e_conn->e_private;
202         mp->mp_children = e_tmp;
203
204         monitor_cache_release( mi, e_conn );
205
206         return( 0 );
207 }
208
209 int
210 monitor_subsys_conn_update(
211         struct monitorinfo      *mi,
212         Entry                   *e
213 )
214 {
215         long            n = -1;
216
217         assert( mi );
218         assert( e );
219         
220         if ( strncasecmp( e->e_ndn, "CN=TOTAL", 
221                                 sizeof("CN=TOTAL")-1 ) == 0 ) {
222                 n = connections_nextid();
223
224         } else if ( strncasecmp( e->e_ndn, "CN=CURRENT", 
225                                 sizeof("CN=CURRENT")-1 ) == 0 ) {
226                 Connection      *c;
227                 int             connindex;
228
229                 for ( n = 0, c = connection_first( &connindex );
230                                 c != NULL;
231                                 n++, c = connection_next( c, &connindex ) ) {
232                         /* No Op */ ;
233                 }
234                 connection_done(c);
235         }
236
237         if ( n != -1 ) {
238                 Attribute       *a;
239                 char            buf[16];
240
241                 a = attr_find( e->e_attrs, monitor_ad_desc );
242                 if ( a == NULL ) {
243                         return( -1 );
244                 }
245
246                 snprintf( buf, sizeof( buf ), "%ld", n );
247                 ber_bvfree( a->a_vals[ 0 ] );
248                 a->a_vals[ 0 ] = ber_bvstrdup( buf );
249         }
250
251         return( 0 );
252 }
253
254 static int
255 conn_create(
256         Connection              *c,
257         Entry                   **ep
258 )
259 {
260         struct monitorentrypriv *mp;
261         struct tm               *ltm;
262         char                    buf[1024];
263         char                    buf2[22];
264         char                    buf3[22];
265
266         struct berval           val, *bv[2] = { &val, NULL };
267
268         Entry                   *e;
269
270         assert( c != NULL );
271         assert( ep != NULL );
272
273         snprintf( buf, sizeof( buf ),
274                 "dn: cn=%ld,%s\n"
275                 "objectClass: top\n"
276                 "objectClass: LDAPsubEntry\n"
277 #ifdef SLAPD_MONITORSUBENTRY
278                 "objectClass: monitorSubEntry\n"
279 #else /* !SLAPD_MONITORSUBENTRY */
280                 "objectClass: extensibleObject\n"
281 #endif /* !SLAPD_MONITORSUBENTRY */
282                 "cn: %ld\n",
283                 c->c_connid, monitor_subsys[SLAPD_MONITOR_CONN].mss_dn,
284                 c->c_connid );
285         e = str2entry( buf );
286
287         if ( e == NULL) {
288 #ifdef NEW_LOGGING
289                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
290                         "monitor_subsys_conn_create: "
291                         "unable to create entry "
292                         "'cn=%ld,%s' entry\n",
293                         c->c_connid, 
294                         monitor_subsys[SLAPD_MONITOR_CONN].mss_dn ));
295 #else
296                 Debug( LDAP_DEBUG_ANY,
297                         "monitor_subsys_conn_create: "
298                         "unable to create entry "
299                         "'cn=%ld,%s' entry\n%s",
300                         c->c_connid, 
301                         monitor_subsys[SLAPD_MONITOR_CONN].mss_dn, "" );
302 #endif
303                 return( -1 );
304         }
305
306         ldap_pvt_thread_mutex_lock( &gmtime_mutex );
307         
308         ltm = gmtime( &c->c_starttime );
309         strftime( buf2, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
310                         
311         ltm = gmtime( &c->c_activitytime );
312         strftime( buf3, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
313                         
314         ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
315
316         sprintf( buf,
317                 "%ld : %ld "
318                 ": %ld/%ld/%ld/%ld "
319                 ": %ld/%ld/%ld "
320                 ": %s%s%s%s%s%s "
321                 ": %s : %s : %s "
322                 ": %s : %s : %s : %s",
323                 c->c_connid,
324                 (long) c->c_protocol,
325                 c->c_n_ops_received, c->c_n_ops_executing,
326                 c->c_n_ops_pending, c->c_n_ops_completed,
327                 
328                 /* add low-level counters here */
329                 c->c_n_get, c->c_n_read, c->c_n_write,
330                 
331                 c->c_currentber ? "r" : "",
332                 c->c_writewaiter ? "w" : "",
333                 c->c_ops != NULL ? "x" : "",
334                 c->c_pending_ops != NULL ? "p" : "",
335                 connection_state2str( c->c_conn_state ),
336                 c->c_sasl_bind_in_progress ? "S" : "",
337                 
338                 c->c_cdn ? c->c_cdn : SLAPD_ANONYMOUS,
339                 
340                 c->c_listener_url,
341                 c->c_peer_domain,
342                 c->c_peer_name,
343                 c->c_sock_name,
344                 
345                 buf2,
346                 buf3
347                 );
348
349         val.bv_val = buf;
350         val.bv_len = strlen( buf );
351         attr_merge( e, monitor_ad_desc, bv );
352
353         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
354         e->e_private = ( void * )mp;
355         mp->mp_info = &monitor_subsys[ SLAPD_MONITOR_CONN ];
356         mp->mp_children = NULL;
357         mp->mp_flags = MONITOR_F_SUB | MONITOR_F_VOLATILE;
358
359         *ep = e;
360
361         return( 0 );
362 }
363
364 int 
365 monitor_subsys_conn_create( 
366         struct monitorinfo      *mi,
367         const char              *ndn,
368         Entry                   *e_parent,
369         Entry                   **ep
370 )
371 {
372         Connection              *c;
373         int                     connindex;
374         struct monitorentrypriv *mp;
375
376         assert( mi != NULL );
377         assert( e_parent != NULL );
378         assert( ep != NULL );
379
380         *ep = NULL;
381
382         if ( ndn == NULL ) {
383                 Entry *e, *e_tmp = NULL;
384
385                 /* create all the children of e_parent */
386                 for ( c = connection_first( &connindex );
387                                 c != NULL;
388                                 c = connection_next( c, &connindex )) {
389                         if ( conn_create( c, &e ) || e == NULL ) {
390                                 connection_done(c);
391                                 return( -1 );
392                         }
393                         mp = ( struct monitorentrypriv * )e->e_private;
394                         mp->mp_next = e_tmp;
395                         e_tmp = e;
396                 }
397                 connection_done(c);
398
399                 *ep = e;
400         } else {
401                 /* create exactly the required entry */
402                 char *rdn, *value;
403                 unsigned long connid;
404                
405                 rdn = dn_rdn( NULL, ndn );
406                 value = rdn_attr_value( rdn );
407                 connid = atol( value );
408                 free( value );
409                 free( rdn );
410
411                 for ( c = connection_first( &connindex );
412                                 c != NULL;
413                                 c = connection_next( c, &connindex )) {
414                         if ( c->c_connid == connid ) {
415                                 if ( conn_create( c, ep ) || *ep == NULL ) {
416                                         connection_done(c);
417                                         return( -1 );
418                                 }
419                         }
420                 }
421                 
422                 connection_done(c);
423         
424         }
425
426         return( 0 );
427 }
428