Home | History | Annotate | Line # | Download | only in back-monitor
sent.c revision 1.1.1.1
      1 /* sent.c - deal with data sent subsystem */
      2 /* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/sent.c,v 1.42.2.4 2008/02/11 23:26:47 kurt Exp $ */
      3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      4  *
      5  * Copyright 2001-2008 The OpenLDAP Foundation.
      6  * Portions Copyright 2001-2003 Pierangelo Masarati.
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted only as authorized by the OpenLDAP
     11  * Public License.
     12  *
     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>.
     16  */
     17 /* ACKNOWLEDGEMENTS:
     18  * This work was initially developed by Pierangelo Masarati for inclusion
     19  * in OpenLDAP Software.
     20  */
     21 
     22 #include "portable.h"
     23 
     24 #include <stdio.h>
     25 #include <ac/string.h>
     26 
     27 #include "slap.h"
     28 #include "back-monitor.h"
     29 
     30 static int
     31 monitor_subsys_sent_destroy(
     32 	BackendDB		*be,
     33 	monitor_subsys_t	*ms );
     34 
     35 static int
     36 monitor_subsys_sent_update(
     37 	Operation		*op,
     38 	SlapReply		*rs,
     39 	Entry                   *e );
     40 
     41 enum {
     42 	MONITOR_SENT_BYTES = 0,
     43 	MONITOR_SENT_PDU,
     44 	MONITOR_SENT_ENTRIES,
     45 	MONITOR_SENT_REFERRALS,
     46 
     47 	MONITOR_SENT_LAST
     48 };
     49 
     50 struct monitor_sent_t {
     51 	struct berval	rdn;
     52 	struct berval	nrdn;
     53 } monitor_sent[] = {
     54 	{ BER_BVC("cn=Bytes"),		BER_BVNULL },
     55 	{ BER_BVC("cn=PDU"),		BER_BVNULL },
     56 	{ BER_BVC("cn=Entries"),	BER_BVNULL },
     57 	{ BER_BVC("cn=Referrals"),	BER_BVNULL },
     58 	{ BER_BVNULL,			BER_BVNULL }
     59 };
     60 
     61 int
     62 monitor_subsys_sent_init(
     63 	BackendDB		*be,
     64 	monitor_subsys_t	*ms )
     65 {
     66 	monitor_info_t	*mi;
     67 
     68 	Entry		**ep, *e_sent;
     69 	monitor_entry_t	*mp;
     70 	int			i;
     71 
     72 	assert( be != NULL );
     73 
     74 	ms->mss_destroy = monitor_subsys_sent_destroy;
     75 	ms->mss_update = monitor_subsys_sent_update;
     76 
     77 	mi = ( monitor_info_t * )be->be_private;
     78 
     79 	if ( monitor_cache_get( mi, &ms->mss_ndn, &e_sent ) ) {
     80 		Debug( LDAP_DEBUG_ANY,
     81 			"monitor_subsys_sent_init: "
     82 			"unable to get entry \"%s\"\n",
     83 			ms->mss_ndn.bv_val, 0, 0 );
     84 		return( -1 );
     85 	}
     86 
     87 	mp = ( monitor_entry_t * )e_sent->e_private;
     88 	mp->mp_children = NULL;
     89 	ep = &mp->mp_children;
     90 
     91 	for ( i = 0; i < MONITOR_SENT_LAST; i++ ) {
     92 		struct berval		nrdn, bv;
     93 		Entry			*e;
     94 
     95 		e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn,
     96 			&monitor_sent[i].rdn, mi->mi_oc_monitorCounterObject,
     97 			mi, NULL, NULL );
     98 
     99 		if ( e == NULL ) {
    100 			Debug( LDAP_DEBUG_ANY,
    101 				"monitor_subsys_sent_init: "
    102 				"unable to create entry \"%s,%s\"\n",
    103 				monitor_sent[ i ].rdn.bv_val,
    104 				ms->mss_ndn.bv_val, 0 );
    105 			return( -1 );
    106 		}
    107 
    108 		/* steal normalized RDN */
    109 		dnRdn( &e->e_nname, &nrdn );
    110 		ber_dupbv( &monitor_sent[ i ].nrdn, &nrdn );
    111 
    112 		BER_BVSTR( &bv, "0" );
    113 		attr_merge_normalize_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
    114 
    115 		mp = monitor_entrypriv_create();
    116 		if ( mp == NULL ) {
    117 			return -1;
    118 		}
    119 		e->e_private = ( void * )mp;
    120 		mp->mp_info = ms;
    121 		mp->mp_flags = ms->mss_flags \
    122 			| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
    123 
    124 		if ( monitor_cache_add( mi, e ) ) {
    125 			Debug( LDAP_DEBUG_ANY,
    126 				"monitor_subsys_sent_init: "
    127 				"unable to add entry \"%s,%s\"\n",
    128 				monitor_sent[ i ].rdn.bv_val,
    129 				ms->mss_ndn.bv_val, 0 );
    130 			return( -1 );
    131 		}
    132 
    133 		*ep = e;
    134 		ep = &mp->mp_next;
    135 	}
    136 
    137 	monitor_cache_release( mi, e_sent );
    138 
    139 	return( 0 );
    140 }
    141 
    142 static int
    143 monitor_subsys_sent_destroy(
    144 	BackendDB		*be,
    145 	monitor_subsys_t	*ms )
    146 {
    147 	int		i;
    148 
    149 	for ( i = 0; i < MONITOR_SENT_LAST; i++ ) {
    150 		if ( !BER_BVISNULL( &monitor_sent[ i ].nrdn ) ) {
    151 			ch_free( monitor_sent[ i ].nrdn.bv_val );
    152 		}
    153 	}
    154 
    155 	return 0;
    156 }
    157 
    158 static int
    159 monitor_subsys_sent_update(
    160 	Operation		*op,
    161 	SlapReply		*rs,
    162 	Entry                   *e )
    163 {
    164 	monitor_info_t	*mi = ( monitor_info_t *)op->o_bd->be_private;
    165 
    166 	struct berval		nrdn;
    167 	ldap_pvt_mp_t		n;
    168 	Attribute		*a;
    169 	slap_counters_t *sc;
    170 	int			i;
    171 
    172 	assert( mi != NULL );
    173 	assert( e != NULL );
    174 
    175 	dnRdn( &e->e_nname, &nrdn );
    176 
    177 	for ( i = 0; i < MONITOR_SENT_LAST; i++ ) {
    178 		if ( dn_match( &nrdn, &monitor_sent[ i ].nrdn ) ) {
    179 			break;
    180 		}
    181 	}
    182 
    183 	if ( i == MONITOR_SENT_LAST ) {
    184 		return SLAP_CB_CONTINUE;
    185 	}
    186 
    187 	ldap_pvt_thread_mutex_lock(&slap_counters.sc_mutex);
    188 	switch ( i ) {
    189 	case MONITOR_SENT_ENTRIES:
    190 		ldap_pvt_mp_init_set( n, slap_counters.sc_entries );
    191 		for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
    192 			ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
    193 			ldap_pvt_mp_add( n, sc->sc_entries );
    194 			ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
    195 		}
    196 		break;
    197 
    198 	case MONITOR_SENT_REFERRALS:
    199 		ldap_pvt_mp_init_set( n, slap_counters.sc_refs );
    200 		for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
    201 			ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
    202 			ldap_pvt_mp_add( n, sc->sc_refs );
    203 			ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
    204 		}
    205 		break;
    206 
    207 	case MONITOR_SENT_PDU:
    208 		ldap_pvt_mp_init_set( n, slap_counters.sc_pdu );
    209 		for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
    210 			ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
    211 			ldap_pvt_mp_add( n, sc->sc_pdu );
    212 			ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
    213 		}
    214 		break;
    215 
    216 	case MONITOR_SENT_BYTES:
    217 		ldap_pvt_mp_init_set( n, slap_counters.sc_bytes );
    218 		for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
    219 			ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
    220 			ldap_pvt_mp_add( n, sc->sc_bytes );
    221 			ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
    222 		}
    223 		break;
    224 
    225 	default:
    226 		assert(0);
    227 	}
    228 	ldap_pvt_thread_mutex_unlock(&slap_counters.sc_mutex);
    229 
    230 	a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter );
    231 	assert( a != NULL );
    232 
    233 	/* NOTE: no minus sign is allowed in the counters... */
    234 	UI2BV( &a->a_vals[ 0 ], n );
    235 	ldap_pvt_mp_clear( n );
    236 
    237 	/* FIXME: touch modifyTimestamp? */
    238 
    239 	return SLAP_CB_CONTINUE;
    240 }
    241 
    242