1 /* conn.c - deal with connection subsystem */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/conn.c,v 1.72.2.7 2008/02/11 23:26:47 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2001-2008 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"
32 monitor_subsys_conn_update(
38 monitor_subsys_conn_create(
46 monitor_subsys_conn_init(
48 monitor_subsys_t
*ms
)
51 Entry
*e
, **ep
, *e_conn
;
53 char buf
[ BACKMONITOR_BUFSIZE
];
58 ms
->mss_update
= monitor_subsys_conn_update
;
59 ms
->mss_create
= monitor_subsys_conn_create
;
61 mi
= ( monitor_info_t
* )be
->be_private
;
63 if ( monitor_cache_get( mi
, &ms
->mss_ndn
, &e_conn
) ) {
64 Debug( LDAP_DEBUG_ANY
,
65 "monitor_subsys_conn_init: "
66 "unable to get entry \"%s\"\n",
67 ms
->mss_ndn
.bv_val
, 0, 0 );
71 mp
= ( monitor_entry_t
* )e_conn
->e_private
;
72 mp
->mp_children
= NULL
;
73 ep
= &mp
->mp_children
;
76 * Max file descriptors
78 BER_BVSTR( &bv
, "cn=Max File Descriptors" );
79 e
= monitor_entry_stub( &ms
->mss_dn
, &ms
->mss_ndn
, &bv
,
80 mi
->mi_oc_monitorCounterObject
, mi
, NULL
, NULL
);
83 Debug( LDAP_DEBUG_ANY
,
84 "monitor_subsys_conn_init: "
85 "unable to create entry \"%s,%s\"\n",
86 bv
.bv_val
, ms
->mss_ndn
.bv_val
, 0 );
92 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%d", dtblsize
);
95 BER_BVSTR( &bv
, "0" );
97 attr_merge_one( e
, mi
->mi_ad_monitorCounter
, &bv
, &bv
);
99 mp
= monitor_entrypriv_create();
103 e
->e_private
= ( void * )mp
;
105 mp
->mp_flags
= ms
->mss_flags \
106 | MONITOR_F_SUB
| MONITOR_F_PERSISTENT
;
107 mp
->mp_flags
&= ~MONITOR_F_VOLATILE_CH
;
109 if ( monitor_cache_add( mi
, e
) ) {
110 Debug( LDAP_DEBUG_ANY
,
111 "monitor_subsys_conn_init: "
112 "unable to add entry \"cn=Total,%s\"\n",
113 ms
->mss_ndn
.bv_val
, 0, 0 );
123 BER_BVSTR( &bv
, "cn=Total" );
124 e
= monitor_entry_stub( &ms
->mss_dn
, &ms
->mss_ndn
, &bv
,
125 mi
->mi_oc_monitorCounterObject
, mi
, NULL
, NULL
);
128 Debug( LDAP_DEBUG_ANY
,
129 "monitor_subsys_conn_init: "
130 "unable to create entry \"cn=Total,%s\"\n",
131 ms
->mss_ndn
.bv_val
, 0, 0 );
135 BER_BVSTR( &bv
, "-1" );
136 attr_merge_one( e
, mi
->mi_ad_monitorCounter
, &bv
, &bv
);
138 mp
= monitor_entrypriv_create();
142 e
->e_private
= ( void * )mp
;
144 mp
->mp_flags
= ms
->mss_flags \
145 | MONITOR_F_SUB
| MONITOR_F_PERSISTENT
;
146 mp
->mp_flags
&= ~MONITOR_F_VOLATILE_CH
;
148 if ( monitor_cache_add( mi
, e
) ) {
149 Debug( LDAP_DEBUG_ANY
,
150 "monitor_subsys_conn_init: "
151 "unable to add entry \"cn=Total,%s\"\n",
152 ms
->mss_ndn
.bv_val
, 0, 0 );
162 BER_BVSTR( &bv
, "cn=Current" );
163 e
= monitor_entry_stub( &ms
->mss_dn
, &ms
->mss_ndn
, &bv
,
164 mi
->mi_oc_monitorCounterObject
, mi
, NULL
, NULL
);
167 Debug( LDAP_DEBUG_ANY
,
168 "monitor_subsys_conn_init: "
169 "unable to create entry \"cn=Current,%s\"\n",
170 ms
->mss_ndn
.bv_val
, 0, 0 );
174 BER_BVSTR( &bv
, "0" );
175 attr_merge_one( e
, mi
->mi_ad_monitorCounter
, &bv
, &bv
);
177 mp
= monitor_entrypriv_create();
181 e
->e_private
= ( void * )mp
;
183 mp
->mp_flags
= ms
->mss_flags \
184 | MONITOR_F_SUB
| MONITOR_F_PERSISTENT
;
185 mp
->mp_flags
&= ~MONITOR_F_VOLATILE_CH
;
187 if ( monitor_cache_add( mi
, e
) ) {
188 Debug( LDAP_DEBUG_ANY
,
189 "monitor_subsys_conn_init: "
190 "unable to add entry \"cn=Current,%s\"\n",
191 ms
->mss_ndn
.bv_val
, 0, 0 );
198 monitor_cache_release( mi
, e_conn
);
204 monitor_subsys_conn_update(
209 monitor_info_t
*mi
= ( monitor_info_t
* )op
->o_bd
->be_private
;
212 static struct berval total_bv
= BER_BVC( "cn=total" ),
213 current_bv
= BER_BVC( "cn=current" );
216 assert( mi
!= NULL
);
219 dnRdn( &e
->e_nname
, &rdn
);
221 if ( dn_match( &rdn
, &total_bv
) ) {
222 n
= connections_nextid();
224 } else if ( dn_match( &rdn
, ¤t_bv
) ) {
228 for ( n
= 0, c
= connection_first( &connindex
);
230 n
++, c
= connection_next( c
, &connindex
) )
234 connection_done( c
);
239 char buf
[LDAP_PVT_INTTYPE_CHARS(long)];
242 a
= attr_find( e
->e_attrs
, mi
->mi_ad_monitorCounter
);
247 snprintf( buf
, sizeof( buf
), "%ld", n
);
249 if ( len
> a
->a_vals
[ 0 ].bv_len
) {
250 a
->a_vals
[ 0 ].bv_val
= ber_memrealloc( a
->a_vals
[ 0 ].bv_val
, len
+ 1 );
252 a
->a_vals
[ 0 ].bv_len
= len
;
253 AC_MEMCPY( a
->a_vals
[ 0 ].bv_val
, buf
, len
+ 1 );
255 /* FIXME: touch modifyTimestamp? */
258 return SLAP_CB_CONTINUE
;
266 monitor_subsys_t
*ms
)
270 char buf
[ BACKMONITOR_BUFSIZE
];
271 char buf2
[ LDAP_LUTIL_GENTIME_BUFSIZE
];
272 char buf3
[ LDAP_LUTIL_GENTIME_BUFSIZE
];
274 struct berval bv
, ctmbv
, mtmbv
, bv2
, bv3
;
275 struct berval bv_unknown
= BER_BVC("unknown");
279 #ifdef HACK_LOCAL_TIME
280 char ctmbuf
[ LDAP_LUTIL_GENTIME_BUFSIZE
];
281 char mtmbuf
[ LDAP_LUTIL_GENTIME_BUFSIZE
];
285 #endif /* HAVE_GMTIME_R */
288 assert( ep
!= NULL
);
290 #ifndef HAVE_GMTIME_R
291 ldap_pvt_thread_mutex_lock( &gmtime_mutex
);
295 tm
= gmtime_r( &c
->c_starttime
, &tm_buf
);
297 tm
= gmtime( &c
->c_starttime
);
299 bv2
.bv_len
= lutil_gentime( buf2
, sizeof( buf2
), tm
);
301 #ifdef HACK_LOCAL_TIME
302 # ifdef HAVE_LOCALTIME_R
303 tm
= localtime_r( &c
->c_starttime
, &tm_buf
);
305 tm
= localtime( &c
->c_starttime
);
307 ctmbv
.bv_len
= lutil_localtime( ctmbuf
, sizeof( ctmbuf
), tm
, -timezone
);
308 ctmbv
.bv_val
= ctmbuf
;
309 #else /* !HACK_LOCAL_TIME */
314 tm
= gmtime_r( &c
->c_activitytime
, &tm_buf
);
316 tm
= gmtime( &c
->c_activitytime
);
318 bv3
.bv_len
= lutil_gentime( buf3
, sizeof( buf3
), tm
);
320 #ifdef HACK_LOCAL_TIME
321 # ifdef HAVE_LOCALTIME_R
322 tm
= localtime_r( &c
->c_activitytime
, &tm_buf
);
324 tm
= localtime( &c
->c_activitytime
);
325 # endif /* HAVE_LOCALTIME_R */
326 mtmbv
.bv_len
= lutil_localtime( mtmbuf
, sizeof( mtmbuf
), tm
, -timezone
);
327 mtmbv
.bv_val
= mtmbuf
;
328 #else /* !HACK_LOCAL_TIME */
332 #ifndef HAVE_GMTIME_R
333 ldap_pvt_thread_mutex_unlock( &gmtime_mutex
);
336 bv
.bv_len
= snprintf( buf
, sizeof( buf
),
337 "cn=Connection %ld", c
->c_connid
);
339 e
= monitor_entry_stub( &ms
->mss_dn
, &ms
->mss_ndn
, &bv
,
340 mi
->mi_oc_monitorConnection
, mi
, &ctmbv
, &mtmbv
);
343 Debug( LDAP_DEBUG_ANY
,
344 "monitor_subsys_conn_create: "
345 "unable to create entry "
346 "\"cn=Connection %ld,%s\"\n",
348 ms
->mss_dn
.bv_val
, 0 );
352 #ifdef MONITOR_LEGACY_CONN
353 /* NOTE: this will disappear, as the exploded data
354 * has been moved to dedicated attributes */
355 bv
.bv_len
= snprintf( buf
, sizeof( buf
),
369 (long) c
->c_protocol
,
370 c
->c_n_ops_received
, c
->c_n_ops_executing
,
371 c
->c_n_ops_pending
, c
->c_n_ops_completed
,
373 /* add low-level counters here */
374 c
->c_n_get
, c
->c_n_read
, c
->c_n_write
,
376 c
->c_currentber
? "r" : "",
377 c
->c_writewaiter
? "w" : "",
378 LDAP_STAILQ_EMPTY( &c
->c_ops
) ? "" : "x",
379 LDAP_STAILQ_EMPTY( &c
->c_pending_ops
) ? "" : "p",
380 connection_state2str( c
->c_conn_state
),
381 c
->c_sasl_bind_in_progress
? "S" : "",
383 c
->c_dn
.bv_len
? c
->c_dn
.bv_val
: SLAPD_ANONYMOUS
,
385 c
->c_listener_url
.bv_val
,
386 BER_BVISNULL( &c
->c_peer_domain
)
387 ? "" : c
->c_peer_domain
.bv_val
,
388 BER_BVISNULL( &c
->c_peer_name
)
389 ? "" : c
->c_peer_name
.bv_val
,
390 c
->c_sock_name
.bv_val
,
394 attr_merge_normalize_one( e
, mi
->mi_ad_monitoredInfo
, &bv
, NULL
);
395 #endif /* MONITOR_LEGACY_CONN */
397 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%lu", c
->c_connid
);
398 attr_merge_one( e
, mi
->mi_ad_monitorConnectionNumber
, &bv
, NULL
);
400 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%ld", (long) c
->c_protocol
);
401 attr_merge_one( e
, mi
->mi_ad_monitorConnectionProtocol
, &bv
, NULL
);
403 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%ld", c
->c_n_ops_received
);
404 attr_merge_one( e
, mi
->mi_ad_monitorConnectionOpsReceived
, &bv
, NULL
);
406 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%ld", c
->c_n_ops_executing
);
407 attr_merge_one( e
, mi
->mi_ad_monitorConnectionOpsExecuting
, &bv
, NULL
);
409 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%ld", c
->c_n_ops_pending
);
410 attr_merge_one( e
, mi
->mi_ad_monitorConnectionOpsPending
, &bv
, NULL
);
412 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%ld", c
->c_n_ops_completed
);
413 attr_merge_one( e
, mi
->mi_ad_monitorConnectionOpsCompleted
, &bv
, NULL
);
415 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%ld", c
->c_n_get
);
416 attr_merge_one( e
, mi
->mi_ad_monitorConnectionGet
, &bv
, NULL
);
418 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%ld", c
->c_n_read
);
419 attr_merge_one( e
, mi
->mi_ad_monitorConnectionRead
, &bv
, NULL
);
421 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%ld", c
->c_n_write
);
422 attr_merge_one( e
, mi
->mi_ad_monitorConnectionWrite
, &bv
, NULL
);
424 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%s%s%s%s%s%s",
425 c
->c_currentber
? "r" : "",
426 c
->c_writewaiter
? "w" : "",
427 LDAP_STAILQ_EMPTY( &c
->c_ops
) ? "" : "x",
428 LDAP_STAILQ_EMPTY( &c
->c_pending_ops
) ? "" : "p",
429 connection_state2str( c
->c_conn_state
),
430 c
->c_sasl_bind_in_progress
? "S" : "" );
431 attr_merge_one( e
, mi
->mi_ad_monitorConnectionMask
, &bv
, NULL
);
433 attr_merge_one( e
, mi
->mi_ad_monitorConnectionAuthzDN
,
434 &c
->c_dn
, &c
->c_ndn
);
436 /* NOTE: client connections leave the c_peer_* fields NULL */
437 assert( !BER_BVISNULL( &c
->c_listener_url
) );
438 attr_merge_one( e
, mi
->mi_ad_monitorConnectionListener
,
439 &c
->c_listener_url
, NULL
);
441 attr_merge_one( e
, mi
->mi_ad_monitorConnectionPeerDomain
,
442 BER_BVISNULL( &c
->c_peer_domain
) ? &bv_unknown
: &c
->c_peer_domain
,
445 attr_merge_one( e
, mi
->mi_ad_monitorConnectionPeerAddress
,
446 BER_BVISNULL( &c
->c_peer_name
) ? &bv_unknown
: &c
->c_peer_name
,
449 assert( !BER_BVISNULL( &c
->c_sock_name
) );
450 attr_merge_one( e
, mi
->mi_ad_monitorConnectionLocalAddress
,
451 &c
->c_sock_name
, NULL
);
453 attr_merge_one( e
, mi
->mi_ad_monitorConnectionStartTime
, &bv2
, NULL
);
455 attr_merge_one( e
, mi
->mi_ad_monitorConnectionActivityTime
, &bv3
, NULL
);
457 mp
= monitor_entrypriv_create();
461 e
->e_private
= ( void * )mp
;
463 mp
->mp_flags
= MONITOR_F_SUB
| MONITOR_F_VOLATILE
;
467 return SLAP_CB_CONTINUE
;
471 monitor_subsys_conn_create(
478 monitor_info_t
*mi
= ( monitor_info_t
* )op
->o_bd
->be_private
;
480 int rc
= SLAP_CB_CONTINUE
;
481 monitor_subsys_t
*ms
;
483 assert( mi
!= NULL
);
484 assert( e_parent
!= NULL
);
485 assert( ep
!= NULL
);
487 ms
= (( monitor_entry_t
*)e_parent
->e_private
)->mp_info
;
497 /* create all the children of e_parent */
498 for ( c
= connection_first( &connindex
);
500 c
= connection_next( c
, &connindex
) )
504 if ( conn_create( mi
, c
, &e
, ms
) != SLAP_CB_CONTINUE
507 for ( ; e_tmp
!= NULL
; ) {
508 mp
= ( monitor_entry_t
* )e_tmp
->e_private
;
512 e_tmp
->e_private
= NULL
;
517 rc
= rs
->sr_err
= LDAP_OTHER
;
520 mp
= ( monitor_entry_t
* )e
->e_private
;
524 connection_done( c
);
530 unsigned long connid
;
532 static struct berval nconn_bv
= BER_BVC( "cn=connection " );
534 rc
= LDAP_NO_SUCH_OBJECT
;
536 /* create exactly the required entry;
537 * the normalized DN must start with "cn=connection ",
538 * followed by the connection id, followed by
539 * the RDN separator "," */
540 if ( ndn
->bv_len
<= nconn_bv
.bv_len
541 || strncmp( ndn
->bv_val
, nconn_bv
.bv_val
, nconn_bv
.bv_len
) != 0 )
546 connid
= strtol( &ndn
->bv_val
[ nconn_bv
.bv_len
], &next
, 10 );
547 if ( next
[ 0 ] != ',' ) {
548 return ( rs
->sr_err
= LDAP_OTHER
);
551 for ( c
= connection_first( &connindex
);
553 c
= connection_next( c
, &connindex
) )
555 if ( c
->c_connid
== connid
) {
556 rc
= conn_create( mi
, c
, ep
, ms
);
557 if ( rc
!= SLAP_CB_CONTINUE
) {
560 } else if ( *ep
== NULL
) {
561 rc
= rs
->sr_err
= LDAP_OTHER
;
568 connection_done( c
);