1 /* conn.c - deal with connection subsystem */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2001-2004 The OpenLDAP Foundation.
6 * Portions Copyright 2001-2003 Pierangelo Masarati.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
18 * This work was initially developed by Pierangelo Masarati for inclusion
19 * in OpenLDAP Software.
25 #include <ac/string.h>
29 #include "back-monitor.h"
31 #define CONN_CN_PREFIX "Connection"
34 monitor_subsys_conn_init(
38 struct monitorinfo *mi;
40 Entry *e, *e_tmp, *e_conn;
41 struct monitorentrypriv *mp;
42 char buf[ BACKMONITOR_BUFSIZE ];
47 mi = ( struct monitorinfo * )be->be_private;
49 if ( monitor_cache_get( mi,
50 &monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn, &e_conn ) ) {
52 LDAP_LOG( OPERATION, CRIT,
53 "monitor_subsys_conn_init: "
54 "unable to get entry '%s'\n",
55 monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
57 Debug( LDAP_DEBUG_ANY,
58 "monitor_subsys_conn_init: "
59 "unable to get entry '%s'\n%s%s",
60 monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
71 snprintf( buf, sizeof( buf ),
74 "structuralObjectClass: %s\n"
78 "createTimestamp: %s\n"
79 "modifyTimestamp: %s\n",
80 monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val,
81 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
82 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
83 mi->mi_creatorsName.bv_val,
84 mi->mi_creatorsName.bv_val,
85 mi->mi_startTime.bv_val,
86 mi->mi_startTime.bv_val );
91 LDAP_LOG( OPERATION, CRIT,
92 "monitor_subsys_conn_init: "
93 "unable to create entry 'cn=Total,%s'\n",
94 monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
96 Debug( LDAP_DEBUG_ANY,
97 "monitor_subsys_conn_init: "
98 "unable to create entry 'cn=Total,%s'\n%s%s",
99 monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
107 attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
109 mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
110 e->e_private = ( void * )mp;
112 mp->mp_children = NULL;
113 mp->mp_info = &monitor_subsys[SLAPD_MONITOR_CONN];
114 mp->mp_flags = monitor_subsys[SLAPD_MONITOR_CONN].mss_flags \
115 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
116 mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
118 if ( monitor_cache_add( mi, e ) ) {
120 LDAP_LOG( OPERATION, CRIT,
121 "monitor_subsys_conn_init: "
122 "unable to add entry 'cn=Total,%s'\n",
123 monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
125 Debug( LDAP_DEBUG_ANY,
126 "monitor_subsys_conn_init: "
127 "unable to add entry 'cn=Total,%s'\n%s%s",
128 monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
139 snprintf( buf, sizeof( buf ),
140 "dn: cn=Current,%s\n"
142 "structuralObjectClass: %s\n"
145 "modifiersName: %s\n"
146 "createTimestamp: %s\n"
147 "modifyTimestamp: %s\n",
148 monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val,
149 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
150 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
151 mi->mi_creatorsName.bv_val,
152 mi->mi_creatorsName.bv_val,
153 mi->mi_startTime.bv_val,
154 mi->mi_startTime.bv_val );
156 e = str2entry( buf );
159 LDAP_LOG( OPERATION, CRIT,
160 "monitor_subsys_conn_init: "
161 "unable to create entry 'cn=Current,%s'\n",
162 monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
164 Debug( LDAP_DEBUG_ANY,
165 "monitor_subsys_conn_init: "
166 "unable to create entry 'cn=Current,%s'\n%s%s",
167 monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
175 attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
177 mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
178 e->e_private = ( void * )mp;
180 mp->mp_children = NULL;
181 mp->mp_info = &monitor_subsys[SLAPD_MONITOR_CONN];
182 mp->mp_flags = monitor_subsys[SLAPD_MONITOR_CONN].mss_flags \
183 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
184 mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
186 if ( monitor_cache_add( mi, e ) ) {
188 LDAP_LOG( OPERATION, CRIT,
189 "monitor_subsys_conn_init: "
190 "unable to add entry 'cn=Current,%s'\n",
191 monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
193 Debug( LDAP_DEBUG_ANY,
194 "monitor_subsys_conn_init: "
195 "unable to add entry 'cn=Current,%s'\n%s%s",
196 monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
204 mp = ( struct monitorentrypriv * )e_conn->e_private;
205 mp->mp_children = e_tmp;
207 monitor_cache_release( mi, e_conn );
213 monitor_subsys_conn_update(
218 struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
224 if ( strncasecmp( e->e_ndn, "cn=total",
225 sizeof("cn=total")-1 ) == 0 ) {
226 n = connections_nextid();
228 } else if ( strncasecmp( e->e_ndn, "cn=current",
229 sizeof("cn=current")-1 ) == 0 ) {
233 for ( n = 0, c = connection_first( &connindex );
235 n++, c = connection_next( c, &connindex ) ) {
243 char buf[] = "+9223372036854775807L";
245 a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter );
250 snprintf( buf, sizeof( buf ), "%ld", n );
251 free( a->a_vals[ 0 ].bv_val );
252 ber_str2bv( buf, 0, 1, a->a_vals );
260 struct monitorinfo *mi,
265 struct monitorentrypriv *mp;
267 char buf[ BACKMONITOR_BUFSIZE ];
268 char buf2[ LDAP_LUTIL_GENTIME_BUFSIZE ];
269 char buf3[ LDAP_LUTIL_GENTIME_BUFSIZE ];
276 char ctmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
278 char mtmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
281 #endif /* HAVE_GMTIME_R */
284 assert( ep != NULL );
286 #ifndef HAVE_GMTIME_R
287 ldap_pvt_thread_mutex_lock( &gmtime_mutex );
289 #ifdef HACK_LOCAL_TIME
290 # ifdef HAVE_LOCALTIME_R
291 ctm = localtime_r( &c->c_starttime, &tm_buf );
292 lutil_localtime( ctmbuf, sizeof( ctmbuf ), ctm, -timezone );
293 mtm = localtime_r( &c->c_activitytime, &tm_buf );
294 lutil_localtime( mtmbuf, sizeof( mtmbuf ), mtm, -timezone );
296 ctm = localtime( &c->c_starttime );
297 lutil_localtime( ctmbuf, sizeof( ctmbuf ), ctm, -timezone );
298 mtm = localtime( &c->c_activitytime );
299 lutil_localtime( mtmbuf, sizeof( mtmbuf ), mtm, -timezone );
300 # endif /* HAVE_LOCALTIME_R */
301 #else /* !HACK_LOCAL_TIME */
302 # ifdef HAVE_GMTIME_R
303 ctm = gmtime_r( &c->c_starttime, &tm_buf );
304 lutil_gentime( ctmbuf, sizeof( ctmbuf ), ctm );
305 mtm = gmtime_r( &c->c_activitytime, &tm_buf );
306 lutil_gentime( mtmbuf, sizeof( mtmbuf ), mtm );
308 ctm = gmtime( &c->c_starttime );
309 lutil_gentime( ctmbuf, sizeof( ctmbuf ), ctm );
310 mtm = gmtime( &c->c_activitytime );
311 lutil_gentime( mtmbuf, sizeof( mtmbuf ), mtm );
312 # endif /* HAVE_GMTIME_R */
313 #endif /* !HACK_LOCAL_TIME */
314 #ifndef HAVE_GMTIME_R
315 ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
318 snprintf( buf, sizeof( buf ),
319 "dn: cn=" CONN_CN_PREFIX " %ld,%s\n"
321 "structuralObjectClass: %s\n"
322 "cn: " CONN_CN_PREFIX " %ld\n"
324 "modifiersName: %s\n"
325 "createTimestamp: %s\n"
326 "modifyTimestamp: %s\n",
327 c->c_connid, monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val,
328 mi->mi_oc_monitorConnection->soc_cname.bv_val,
329 mi->mi_oc_monitorConnection->soc_cname.bv_val,
331 mi->mi_creatorsName.bv_val,
332 mi->mi_creatorsName.bv_val,
336 e = str2entry( buf );
340 LDAP_LOG( OPERATION, CRIT,
341 "monitor_subsys_conn_create: "
342 "unable to create entry "
343 "'cn=" CONN_CN_PREFIX " %ld,%s' entry\n",
344 c->c_connid, monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val, 0 );
346 Debug( LDAP_DEBUG_ANY,
347 "monitor_subsys_conn_create: "
348 "unable to create entry "
349 "'cn=" CONN_CN_PREFIX " %ld,%s' entry\n",
351 monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val, 0 );
356 #ifndef HAVE_GMTIME_R
357 ldap_pvt_thread_mutex_lock( &gmtime_mutex );
361 ltm = gmtime_r( &c->c_starttime, &tm_buf );
363 ltm = gmtime( &c->c_starttime );
365 lutil_gentime( buf2, sizeof( buf2 ), ltm );
368 ltm = gmtime_r( &c->c_activitytime, &tm_buf );
370 ltm = gmtime( &c->c_activitytime );
372 lutil_gentime( buf3, sizeof( buf3 ), ltm );
374 #ifndef HAVE_GMTIME_R
375 ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
376 #endif /* HAVE_GMTIME_R */
385 ": %s : %s : %s : %s",
387 (long) c->c_protocol,
388 c->c_n_ops_received, c->c_n_ops_executing,
389 c->c_n_ops_pending, c->c_n_ops_completed,
391 /* add low-level counters here */
392 c->c_n_get, c->c_n_read, c->c_n_write,
394 c->c_currentber ? "r" : "",
395 c->c_writewaiter ? "w" : "",
396 LDAP_STAILQ_EMPTY( &c->c_ops ) ? "" : "x",
397 LDAP_STAILQ_EMPTY( &c->c_pending_ops ) ? "" : "p",
398 connection_state2str( c->c_conn_state ),
399 c->c_sasl_bind_in_progress ? "S" : "",
401 c->c_dn.bv_len ? c->c_dn.bv_val : SLAPD_ANONYMOUS,
403 c->c_listener_url.bv_val,
404 c->c_peer_domain.bv_val,
405 c->c_peer_name.bv_val,
406 c->c_sock_name.bv_val,
413 bv.bv_len = strlen( buf );
414 attr_merge_one( e, mi->mi_ad_monitoredInfo, &bv, NULL );
416 /* connection number */
417 snprintf( buf, sizeof( buf ), "%ld", c->c_connid );
419 bv.bv_len = strlen( buf );
420 attr_merge_one( e, mi->mi_ad_monitorConnectionNumber, &bv, NULL );
423 attr_merge_one( e, mi->mi_ad_monitorConnectionAuthzDN,
424 &c->c_dn, &c->c_ndn );
427 attr_merge_one( e, mi->mi_ad_monitorConnectionLocalAddress,
428 &c->c_sock_name, NULL );
431 attr_merge_one( e, mi->mi_ad_monitorConnectionPeerAddress,
432 &c->c_peer_name, NULL );
434 mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
435 e->e_private = ( void * )mp;
436 mp->mp_info = &monitor_subsys[ SLAPD_MONITOR_CONN ];
437 mp->mp_children = NULL;
438 mp->mp_flags = MONITOR_F_SUB | MONITOR_F_VOLATILE;
446 monitor_subsys_conn_create(
453 struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
456 struct monitorentrypriv *mp;
458 assert( mi != NULL );
459 assert( e_parent != NULL );
460 assert( ep != NULL );
465 Entry *e, *e_tmp = NULL;
467 /* create all the children of e_parent */
468 for ( c = connection_first( &connindex );
470 c = connection_next( c, &connindex )) {
471 if ( conn_create( mi, c, &e ) || e == NULL ) {
473 for ( ; e_tmp != NULL; ) {
474 mp = ( struct monitorentrypriv * )e_tmp->e_private;
478 e_tmp->e_private = NULL;
485 mp = ( struct monitorentrypriv * )e->e_private;
494 LDAPRDN values = NULL;
495 const char *text = NULL;
496 unsigned long connid;
498 /* create exactly the required entry */
500 if ( ldap_bv2rdn( ndn, &values, (char **)&text,
501 LDAP_DN_FORMAT_LDAP ) )
507 assert( values[ 0 ] );
509 connid = atol( values[ 0 ]->la_value.bv_val
510 + sizeof( CONN_CN_PREFIX ) );
512 ldap_rdnfree( values );
514 for ( c = connection_first( &connindex );
516 c = connection_next( c, &connindex )) {
517 if ( c->c_connid == connid ) {
518 if ( conn_create( mi, c, ep ) || *ep == NULL ) {
519 connection_done( c );