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