]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/conn.c
Fixup bdb_entry_release now that entry_decode uses two memory blocks
[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;
52         struct berval           *bv[2], val;
53
54         assert( be != NULL );
55
56         mi = ( struct monitorinfo * )be->be_private;
57
58         if ( monitor_cache_get( mi,
59                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn, &e ) ) {
60 #ifdef NEW_LOGGING
61                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
62                         "monitor_subsys_conn_init: "
63                         "unable to get entry '%s'\n",
64                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn ));
65 #else
66                 Debug( LDAP_DEBUG_ANY,
67                         "monitor_subsys_conn_init: "
68                         "unable to get entry '%s'\n%s%s",
69                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn, 
70                         "", "" );
71 #endif
72                 return( -1 );
73         }
74
75         bv[0] = &val;
76         bv[1] = NULL;
77
78         monitor_cache_release( mi, e );
79
80         return( 0 );
81 }
82
83 int
84 monitor_subsys_conn_update(
85         struct monitorinfo      *mi,
86         Entry                   *e
87 )
88 {
89         Connection              *c;
90         int                     connindex;
91         int                     nconns, nwritewaiters, nreadwaiters;
92
93         Attribute               *a;
94         struct berval           *bv[2], val, **b = NULL;
95         char                    buf[1024];
96
97         assert( mi != NULL );
98         assert( e != NULL );
99         
100         bv[0] = &val;
101         bv[1] = NULL;
102
103         nconns = nwritewaiters = nreadwaiters = 0;
104         for ( c = connection_first( &connindex );
105                         c != NULL;
106                         c = connection_next( c, &connindex ), nconns++ ) {
107                 if ( c->c_writewaiter ) {
108                         nwritewaiters++;
109                 }
110                 if ( c->c_currentber != NULL ) {
111                         nreadwaiters++;
112                 }
113         }
114         connection_done(c);
115
116 #if 0
117         snprintf( buf, sizeof( buf ), "readwaiters=%d", nreadwaiters );
118
119         if ( ( a = attr_find( e->e_attrs, monitor_ad_desc ) ) != NULL ) {
120                 for ( b = a->a_vals; b[0] != NULL; b++ ) {
121                         if ( strncmp( b[0]->bv_val, "readwaiters=",
122                                         sizeof( "readwaiters=" ) - 1 ) == 0 ) {
123                                 free( b[0]->bv_val );
124                                 b[0] = ber_bvstrdup( buf );
125                                 break;
126                         }
127                 }
128         }
129         
130         if ( b == NULL || b[0] == NULL ) {
131                 val.bv_val = buf;
132                 val.bv_len = strlen( buf );
133                 attr_merge( e, monitor_ad_desc, bv );
134         }
135 #endif
136
137         return( 0 );
138 }
139
140 static int
141 conn_create(
142         Connection              *c,
143         Entry                   **ep
144 )
145 {
146         struct monitorentrypriv *mp;
147         struct tm               *ltm;
148         char                    buf[1024];
149         char                    buf2[22];
150         char                    buf3[22];
151
152         struct berval           *bv[2], val;
153
154         Entry                   *e;
155
156         assert( c != NULL );
157         assert( ep != NULL );
158
159         snprintf( buf, sizeof( buf ),
160                 "dn: cn=%ld,%s\n"
161                 "objectClass: top\n"
162                 "objectClass: LDAPsubEntry\n"
163 #ifdef SLAPD_MONITORSUBENTRY
164                 "objectClass: monitorSubEntry\n"
165 #else /* !SLAPD_MONITORSUBENTRY */
166                 "objectClass: extensibleObject\n"
167 #endif /* !SLAPD_MONITORSUBENTRY */
168                 "cn: %ld\n",
169                 c->c_connid, monitor_subsys[SLAPD_MONITOR_CONN].mss_dn,
170                 c->c_connid );
171         e = str2entry( buf );
172
173         if ( e == NULL) {
174 #ifdef NEW_LOGGING
175                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
176                         "monitor_subsys_conn_create: "
177                         "unable to create entry "
178                         "'cn=%ld,%s' entry\n",
179                         c->c_connid, 
180                         monitor_subsys[SLAPD_MONITOR_CONN].mss_dn ));
181 #else
182                 Debug( LDAP_DEBUG_ANY,
183                         "monitor_subsys_conn_create: "
184                         "unable to create entry "
185                         "'cn=%ld,%s' entry\n%s",
186                         c->c_connid, 
187                         monitor_subsys[SLAPD_MONITOR_CONN].mss_dn, "" );
188 #endif
189                 return( -1 );
190         }
191
192         ldap_pvt_thread_mutex_lock( &gmtime_mutex );
193         
194         ltm = gmtime( &c->c_starttime );
195         strftime( buf2, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
196                         
197         ltm = gmtime( &c->c_activitytime );
198         strftime( buf3, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
199                         
200         ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
201
202         sprintf( buf,
203                 "%ld : %ld "
204                 ": %ld/%ld/%ld/%ld "
205                 ": %ld/%ld/%ld "
206                 ": %s%s%s%s%s%s "
207                 ": %s : %s : %s "
208                 ": %s : %s : %s : %s",
209                 c->c_connid,
210                 (long) c->c_protocol,
211                 c->c_n_ops_received, c->c_n_ops_executing,
212                 c->c_n_ops_pending, c->c_n_ops_completed,
213                 
214                 /* add low-level counters here */
215                 c->c_n_get, c->c_n_read, c->c_n_write,
216                 
217                 c->c_currentber ? "r" : "",
218                 c->c_writewaiter ? "w" : "",
219                 c->c_ops != NULL ? "x" : "",
220                 c->c_pending_ops != NULL ? "p" : "",
221                 connection_state2str( c->c_conn_state ),
222                 c->c_sasl_bind_in_progress ? "S" : "",
223                 
224                 c->c_cdn ? c->c_cdn : SLAPD_ANONYMOUS,
225                 
226                 c->c_listener_url,
227                 c->c_peer_domain,
228                 c->c_peer_name,
229                 c->c_sock_name,
230                 
231                 buf2,
232                 buf3
233                 );
234
235         bv[0] = &val;
236         bv[1] = NULL;
237
238         val.bv_val = buf;
239         val.bv_len = strlen( buf );
240         attr_merge( e, monitor_ad_desc, bv );
241
242         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
243         e->e_private = ( void * )mp;
244         mp->mp_info = &monitor_subsys[ SLAPD_MONITOR_CONN ];
245         mp->mp_children = NULL;
246         mp->mp_flags = MONITOR_F_SUB | MONITOR_F_VOLATILE;
247
248         *ep = e;
249
250         return( 0 );
251 }
252
253 int 
254 monitor_subsys_conn_create( 
255         struct monitorinfo      *mi,
256         const char              *ndn,
257         Entry                   *e_parent,
258         Entry                   **ep
259 )
260 {
261         Connection              *c;
262         int                     connindex;
263         struct monitorentrypriv *mp;
264
265         assert( mi != NULL );
266         assert( e_parent != NULL );
267         assert( ep != NULL );
268
269         *ep = NULL;
270
271         if ( ndn == NULL ) {
272                 Entry *e, *e_tmp = NULL;
273
274                 /* create all the children of e_parent */
275                 for ( c = connection_first( &connindex );
276                                 c != NULL;
277                                 c = connection_next( c, &connindex )) {
278                         if ( conn_create( c, &e ) || e == NULL ) {
279                                 // error
280                         }
281                         mp = ( struct monitorentrypriv * )e->e_private;
282                         mp->mp_next = e_tmp;
283                         e_tmp = e;
284                 }
285                 connection_done(c);
286
287                 *ep = e;
288         } else {
289                 /* create exactly the required entry */
290                 char *rdn, *value;
291                 unsigned long connid;
292                
293                 rdn = dn_rdn( NULL, ndn );
294                 value = rdn_attr_value( rdn );
295                 connid = atol( value );
296                 free( value );
297                 free( rdn );
298
299                 for ( c = connection_first( &connindex );
300                                 c != NULL;
301                                 c = connection_next( c, &connindex )) {
302                         if ( c->c_connid == connid ) {
303                                 if ( conn_create( c, ep ) || *ep == NULL ) {
304                                         // error
305                                 }
306                         }
307                 }
308                 
309                 connection_done(c);
310         
311         }
312
313         return( 0 );
314 }
315