1 /* thread.c - deal with thread subsystem */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2001-2006 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>
28 #include "back-monitor.h"
33 monitor_subsys_thread_update(
49 ldap_pvt_thread_pool_param_t param;
52 { BER_BVC( "cn=Max" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_MAX, MT_UNKNOWN },
53 { BER_BVC( "cn=Max Pending" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_MAX_PENDING, MT_UNKNOWN },
54 { BER_BVC( "cn=Open" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_OPEN, MT_UNKNOWN },
55 { BER_BVC( "cn=Starting" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_STARTING, MT_UNKNOWN },
56 { BER_BVC( "cn=Active" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_ACTIVE, MT_UNKNOWN },
57 { BER_BVC( "cn=Pending" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_PENDING, MT_UNKNOWN },
58 { BER_BVC( "cn=Backload" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD, MT_UNKNOWN },
59 #if 0 /* not meaningful right now */
60 { BER_BVC( "cn=Active Max" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_ACTIVE_MAX, MT_UNKNOWN },
61 { BER_BVC( "cn=Pending Max" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_PENDING_MAX, MT_UNKNOWN },
62 { BER_BVC( "cn=Backload Max" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD_MAX,MT_UNKNOWN },
64 { BER_BVC( "cn=State" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_STATE, MT_UNKNOWN },
66 { BER_BVC( "cn=Runqueue" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN, MT_RUNQUEUE },
67 { BER_BVC( "cn=Tasklist" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN, MT_TASKLIST },
73 * initializes log subentry
76 monitor_subsys_thread_init(
83 Entry *e, **ep, *e_thread;
86 ms->mss_update = monitor_subsys_thread_update;
88 mi = ( monitor_info_t * )be->be_private;
90 if ( monitor_cache_get( mi, &ms->mss_ndn, &e_thread ) ) {
91 Debug( LDAP_DEBUG_ANY,
92 "monitor_subsys_thread_init: unable to get entry \"%s\"\n",
98 mp = ( monitor_entry_t * )e_thread->e_private;
99 mp->mp_children = NULL;
100 ep = &mp->mp_children;
102 for ( i = 0; !BER_BVISNULL( &mt[ i ].rdn ); i++ ) {
103 static char buf[ BACKMONITOR_BUFSIZE ];
106 struct berval bv = BER_BVNULL;
111 e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn,
113 mi->mi_oc_monitoredObject, mi, NULL, NULL );
115 Debug( LDAP_DEBUG_ANY,
116 "monitor_subsys_thread_init: "
117 "unable to create entry \"%s,%s\"\n",
119 ms->mss_ndn.bv_val, 0 );
123 /* NOTE: reference to the normalized DN of the entry,
124 * under the assumption it's not modified */
125 dnRdn( &e->e_nname, &mt[ i ].nrdn );
127 switch ( mt[ i ].param ) {
128 case LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN:
131 case LDAP_PVT_THREAD_POOL_PARAM_STATE:
132 if ( ldap_pvt_thread_pool_query( &connection_pool,
133 mt[ i ].param, (void *)&state ) == 0 )
135 ber_str2bv( state, 0, 0, &bv );
138 BER_BVSTR( &bv, "unknown" );
143 /* NOTE: in case of error, it'll be set to -1 */
144 (void)ldap_pvt_thread_pool_query( &connection_pool,
145 mt[ i ].param, (void *)&count );
147 bv.bv_len = snprintf( buf, sizeof( buf ), "%d", count );
151 if ( !BER_BVISNULL( &bv ) ) {
152 attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo, &bv, NULL );
155 mp = monitor_entrypriv_create();
159 e->e_private = ( void * )mp;
161 mp->mp_flags = ms->mss_flags \
162 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
164 if ( monitor_cache_add( mi, e ) ) {
165 Debug( LDAP_DEBUG_ANY,
166 "monitor_subsys_thread_init: "
167 "unable to add entry \"%s,%s\"\n",
169 ms->mss_ndn.bv_val, 0 );
177 monitor_cache_release( mi, e_thread );
183 monitor_subsys_thread_update(
188 monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private;
190 BerVarray vals = NULL;
191 char buf[ BACKMONITOR_BUFSIZE ];
192 struct berval rdn, bv;
198 assert( mi != NULL );
200 dnRdn( &e->e_nname, &rdn );
202 for ( i = 0; !BER_BVISNULL( &mt[ i ].nrdn ); i++ ) {
203 if ( dn_match( &mt[ i ].nrdn, &rdn ) ) {
209 if ( BER_BVISNULL( &mt[ which ].nrdn ) ) {
210 return SLAP_CB_CONTINUE;
213 a = attr_find( e->e_attrs, mi->mi_ad_monitoredInfo );
215 switch ( mt[ which ].param ) {
216 case LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN:
217 switch ( mt[ which ].mt ) {
220 if ( a->a_nvals != a->a_vals ) {
221 ber_bvarray_free( a->a_nvals );
223 ber_bvarray_free( a->a_vals );
230 ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
231 LDAP_STAILQ_FOREACH( re, &slapd_rq.run_list, rnext ) {
232 bv.bv_len = snprintf( buf, sizeof( buf ), "{%d}%s(%s)",
233 i, re->tname, re->tspec );
234 if ( bv.bv_len < sizeof( buf ) ) {
235 value_add_one( &vals, &bv );
239 ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
242 attr_merge_normalize( e, mi->mi_ad_monitoredInfo, vals, NULL );
243 ber_bvarray_free( vals );
249 if ( a->a_nvals != a->a_vals ) {
250 ber_bvarray_free( a->a_nvals );
252 ber_bvarray_free( a->a_vals );
259 ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
260 LDAP_STAILQ_FOREACH( re, &slapd_rq.task_list, tnext ) {
261 bv.bv_len = snprintf( buf, sizeof( buf ), "{%d}%s(%s)",
262 i, re->tname, re->tspec );
263 if ( bv.bv_len < sizeof( buf ) ) {
264 value_add_one( &vals, &bv );
268 ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
271 attr_merge_normalize( e, mi->mi_ad_monitoredInfo, vals, NULL );
272 ber_bvarray_free( vals );
281 case LDAP_PVT_THREAD_POOL_PARAM_STATE:
283 return rs->sr_err = LDAP_OTHER;
285 if ( ldap_pvt_thread_pool_query( &connection_pool,
286 mt[ i ].param, (void *)&state ) == 0 )
288 ber_str2bv( state, 0, 0, &bv );
289 ber_bvreplace( &a->a_vals[ 0 ], &bv );
295 return rs->sr_err = LDAP_OTHER;
297 if ( ldap_pvt_thread_pool_query( &connection_pool,
298 mt[ i ].param, (void *)&count ) == 0 )
301 bv.bv_len = snprintf( buf, sizeof( buf ), "%d", count );
302 if ( bv.bv_len < sizeof( buf ) ) {
303 ber_bvreplace( &a->a_vals[ 0 ], &bv );
309 /* FIXME: touch modifyTimestamp? */
311 return SLAP_CB_CONTINUE;