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