]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/conn.c
b9555b2f666815ad42e66e0ab93ea0d3b54ad826
[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           bv[2];
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->bv_val ));
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->bv_val, 
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->bv_val );
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->bv_val ));
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->bv_val,
106                         "", "" );
107 #endif
108                 return( -1 );
109         }
110         
111         bv[1].bv_val = NULL;
112         bv[0].bv_val = "0";
113         bv[0].bv_len = 1;
114         attr_merge( e, monitor_ad_desc, bv );
115         
116         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
117         e->e_private = ( void * )mp;
118         mp->mp_next = e_tmp;
119         mp->mp_children = NULL;
120         mp->mp_info = &monitor_subsys[SLAPD_MONITOR_CONN];
121         mp->mp_flags = monitor_subsys[SLAPD_MONITOR_CONN].mss_flags \
122                 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
123         mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
124
125         if ( monitor_cache_add( mi, e ) ) {
126 #ifdef NEW_LOGGING
127                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
128                         "monitor_subsys_conn_init: "
129                         "unable to add entry 'cn=Total,%s'\n",
130                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn->bv_val ));
131 #else
132                 Debug( LDAP_DEBUG_ANY,
133                         "monitor_subsys_conn_init: "
134                         "unable to add entry 'cn=Total,%s'\n%s%s",
135                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn->bv_val,
136                         "", "" );
137 #endif
138                 return( -1 );
139         }
140         
141         e_tmp = e;
142
143         /*
144          * Current conns
145          */
146         snprintf( buf, sizeof( buf ),
147                 "dn: cn=Current,%s\n"
148                 "objectClass: top\n"
149                 "objectClass: LDAPsubEntry\n"
150 #ifdef SLAPD_MONITORSUBENTRY
151                 "objectClass: monitorSubEntry\n"
152 #else /* !SLAPD_MONITORSUBENTRY */
153                 "objectClass: extensibleObject\n"
154 #endif /* !SLAPD_MONITORSUBENTRY */
155                 "cn: Current\n",
156                 monitor_subsys[SLAPD_MONITOR_CONN].mss_dn->bv_val );
157         
158         e = str2entry( buf );
159         if ( e == NULL ) {
160 #ifdef NEW_LOGGING
161                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
162                         "monitor_subsys_conn_init: "
163                         "unable to create entry 'cn=Current,%s'\n",
164                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn->bv_val ));
165 #else
166                 Debug( LDAP_DEBUG_ANY,
167                         "monitor_subsys_conn_init: "
168                         "unable to create entry 'cn=Current,%s'\n%s%s",
169                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn->bv_val,
170                         "", "" );
171 #endif
172                 return( -1 );
173         }
174         
175         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
176         e->e_private = ( void * )mp;
177         mp->mp_next = e_tmp;
178         mp->mp_children = NULL;
179         mp->mp_info = &monitor_subsys[SLAPD_MONITOR_CONN];
180         mp->mp_flags = monitor_subsys[SLAPD_MONITOR_CONN].mss_flags \
181                 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
182         mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
183
184         if ( monitor_cache_add( mi, e ) ) {
185 #ifdef NEW_LOGGING
186                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
187                         "monitor_subsys_conn_init: "
188                         "unable to add entry 'cn=Current,%s'\n",
189                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn->bv_val ));
190 #else
191                 Debug( LDAP_DEBUG_ANY,
192                         "monitor_subsys_conn_init: "
193                         "unable to add entry 'cn=Current,%s'\n%s%s",
194                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn->bv_val,
195                         "", "" );
196 #endif
197                 return( -1 );
198         }
199         
200         e_tmp = e;
201
202         mp = ( struct monitorentrypriv * )e_conn->e_private;
203         mp->mp_children = e_tmp;
204
205         monitor_cache_release( mi, e_conn );
206
207         return( 0 );
208 }
209
210 int
211 monitor_subsys_conn_update(
212         struct monitorinfo      *mi,
213         Entry                   *e
214 )
215 {
216         long            n = -1;
217
218         assert( mi );
219         assert( e );
220         
221         if ( strncasecmp( e->e_ndn, "CN=TOTAL", 
222                                 sizeof("CN=TOTAL")-1 ) == 0 ) {
223                 n = connections_nextid();
224
225         } else if ( strncasecmp( e->e_ndn, "CN=CURRENT", 
226                                 sizeof("CN=CURRENT")-1 ) == 0 ) {
227                 Connection      *c;
228                 int             connindex;
229
230                 for ( n = 0, c = connection_first( &connindex );
231                                 c != NULL;
232                                 n++, c = connection_next( c, &connindex ) ) {
233                         /* No Op */ ;
234                 }
235                 connection_done(c);
236         }
237
238         if ( n != -1 ) {
239                 Attribute       *a;
240                 char            buf[16];
241
242                 a = attr_find( e->e_attrs, monitor_ad_desc );
243                 if ( a == NULL ) {
244                         return( -1 );
245                 }
246
247                 snprintf( buf, sizeof( buf ), "%ld", n );
248                 free( a->a_vals[ 0 ].bv_val );
249                 ber_str2bv( buf, 0, 1, a->a_vals );
250         }
251
252         return( 0 );
253 }
254
255 static int
256 conn_create(
257         Connection              *c,
258         Entry                   **ep
259 )
260 {
261         struct monitorentrypriv *mp;
262         struct tm               *ltm;
263         char                    buf[1024];
264         char                    buf2[22];
265         char                    buf3[22];
266
267         struct berval           bv[2];
268
269         Entry                   *e;
270
271         assert( c != NULL );
272         assert( ep != NULL );
273
274         snprintf( buf, sizeof( buf ),
275                 "dn: cn=%ld,%s\n"
276                 "objectClass: top\n"
277                 "objectClass: LDAPsubEntry\n"
278 #ifdef SLAPD_MONITORSUBENTRY
279                 "objectClass: monitorSubEntry\n"
280 #else /* !SLAPD_MONITORSUBENTRY */
281                 "objectClass: extensibleObject\n"
282 #endif /* !SLAPD_MONITORSUBENTRY */
283                 "cn: %ld\n",
284                 c->c_connid, monitor_subsys[SLAPD_MONITOR_CONN].mss_dn->bv_val,
285                 c->c_connid );
286         e = str2entry( buf );
287
288         if ( e == NULL) {
289 #ifdef NEW_LOGGING
290                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
291                         "monitor_subsys_conn_create: "
292                         "unable to create entry "
293                         "'cn=%ld,%s' entry\n",
294                         c->c_connid, 
295                         monitor_subsys[SLAPD_MONITOR_CONN].mss_dn->bv_val ));
296 #else
297                 Debug( LDAP_DEBUG_ANY,
298                         "monitor_subsys_conn_create: "
299                         "unable to create entry "
300                         "'cn=%ld,%s' entry\n",
301                         c->c_connid, 
302                         monitor_subsys[SLAPD_MONITOR_CONN].mss_dn->bv_val, 0 );
303 #endif
304                 return( -1 );
305         }
306
307         ldap_pvt_thread_mutex_lock( &gmtime_mutex );
308         
309         ltm = gmtime( &c->c_starttime );
310         strftime( buf2, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
311                         
312         ltm = gmtime( &c->c_activitytime );
313         strftime( buf3, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
314                         
315         ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
316
317         sprintf( buf,
318                 "%ld : %ld "
319                 ": %ld/%ld/%ld/%ld "
320                 ": %ld/%ld/%ld "
321                 ": %s%s%s%s%s%s "
322                 ": %s : %s : %s "
323                 ": %s : %s : %s : %s",
324                 c->c_connid,
325                 (long) c->c_protocol,
326                 c->c_n_ops_received, c->c_n_ops_executing,
327                 c->c_n_ops_pending, c->c_n_ops_completed,
328                 
329                 /* add low-level counters here */
330                 c->c_n_get, c->c_n_read, c->c_n_write,
331                 
332                 c->c_currentber ? "r" : "",
333                 c->c_writewaiter ? "w" : "",
334                 STAILQ_EMPTY( &c->c_ops ) ? "" : "x",
335                 STAILQ_EMPTY( &c->c_pending_ops ) ? "" : "p",
336                 connection_state2str( c->c_conn_state ),
337                 c->c_sasl_bind_in_progress ? "S" : "",
338                 
339                 c->c_cdn ? c->c_cdn : SLAPD_ANONYMOUS,
340                 
341                 c->c_listener_url,
342                 c->c_peer_domain,
343                 c->c_peer_name,
344                 c->c_sock_name,
345                 
346                 buf2,
347                 buf3
348                 );
349
350         bv[1].bv_val = NULL;
351         bv[0].bv_val = buf;
352         bv[0].bv_len = strlen( buf );
353         attr_merge( e, monitor_ad_desc, bv );
354
355         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
356         e->e_private = ( void * )mp;
357         mp->mp_info = &monitor_subsys[ SLAPD_MONITOR_CONN ];
358         mp->mp_children = NULL;
359         mp->mp_flags = MONITOR_F_SUB | MONITOR_F_VOLATILE;
360
361         *ep = e;
362
363         return( 0 );
364 }
365
366 int 
367 monitor_subsys_conn_create( 
368         struct monitorinfo      *mi,
369         struct berval           *ndn,
370         Entry                   *e_parent,
371         Entry                   **ep
372 )
373 {
374         Connection              *c;
375         int                     connindex;
376         struct monitorentrypriv *mp;
377
378         assert( mi != NULL );
379         assert( e_parent != NULL );
380         assert( ep != NULL );
381
382         *ep = NULL;
383
384         if ( ndn == NULL ) {
385                 Entry *e, *e_tmp = NULL;
386
387                 /* create all the children of e_parent */
388                 for ( c = connection_first( &connindex );
389                                 c != NULL;
390                                 c = connection_next( c, &connindex )) {
391                         if ( conn_create( c, &e ) || e == NULL ) {
392                                 connection_done(c);
393                                 return( -1 );
394                         }
395                         mp = ( struct monitorentrypriv * )e->e_private;
396                         mp->mp_next = e_tmp;
397                         e_tmp = e;
398                 }
399                 connection_done(c);
400
401                 *ep = e;
402
403         } else {
404                 LDAPRDN         *values = NULL;
405                 const char      *text = NULL;
406                 unsigned long   connid;
407                
408                 /* create exactly the required entry */
409
410                 if ( ldap_str2rdn( ndn->bv_val, &values, &text, LDAP_DN_FORMAT_LDAP ) ) {
411                         return( -1 );
412                 }
413                 
414                 assert( values );
415                 assert( values[ 0 ][ 0 ] );
416
417                 connid = atol( values[ 0 ][ 0 ]->la_value.bv_val );
418
419                 ldap_rdnfree( values );
420
421                 for ( c = connection_first( &connindex );
422                                 c != NULL;
423                                 c = connection_next( c, &connindex )) {
424                         if ( c->c_connid == connid ) {
425                                 if ( conn_create( c, ep ) || *ep == NULL ) {
426                                         connection_done(c);
427                                         return( -1 );
428                                 }
429                         }
430                 }
431                 
432                 connection_done(c);
433         
434         }
435
436         return( 0 );
437 }
438