xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-monitor/operation.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*	$NetBSD: operation.c,v 1.1.1.4 2014/05/28 09:58:50 tron Exp $	*/
2 
3 /* operation.c - deal with operation subsystem */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6  *
7  * Copyright 2001-2014 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 #include "lber_pvt.h"
32 
33 struct monitor_ops_t {
34 	struct berval	rdn;
35 	struct berval	nrdn;
36 } monitor_op[] = {
37 	{ BER_BVC( "cn=Bind" ),		BER_BVNULL },
38 	{ BER_BVC( "cn=Unbind" ),	BER_BVNULL },
39 	{ BER_BVC( "cn=Search" ),	BER_BVNULL },
40 	{ BER_BVC( "cn=Compare" ),	BER_BVNULL },
41 	{ BER_BVC( "cn=Modify" ),	BER_BVNULL },
42 	{ BER_BVC( "cn=Modrdn" ),	BER_BVNULL },
43 	{ BER_BVC( "cn=Add" ),		BER_BVNULL },
44 	{ BER_BVC( "cn=Delete" ),	BER_BVNULL },
45 	{ BER_BVC( "cn=Abandon" ),	BER_BVNULL },
46 	{ BER_BVC( "cn=Extended" ),	BER_BVNULL },
47 	{ BER_BVNULL,			BER_BVNULL }
48 };
49 
50 static int
51 monitor_subsys_ops_destroy(
52 	BackendDB		*be,
53 	monitor_subsys_t	*ms );
54 
55 static int
56 monitor_subsys_ops_update(
57 	Operation		*op,
58 	SlapReply		*rs,
59 	Entry                   *e );
60 
61 int
62 monitor_subsys_ops_init(
63 	BackendDB		*be,
64 	monitor_subsys_t	*ms )
65 {
66 	monitor_info_t	*mi;
67 
68 	Entry		*e_op, **ep;
69 	monitor_entry_t	*mp;
70 	int 		i;
71 	struct berval	bv_zero = BER_BVC( "0" );
72 
73 	assert( be != NULL );
74 
75 	ms->mss_destroy = monitor_subsys_ops_destroy;
76 	ms->mss_update = monitor_subsys_ops_update;
77 
78 	mi = ( monitor_info_t * )be->be_private;
79 
80 	if ( monitor_cache_get( mi,
81 			&ms->mss_ndn, &e_op ) )
82 	{
83 		Debug( LDAP_DEBUG_ANY,
84 			"monitor_subsys_ops_init: "
85 			"unable to get entry \"%s\"\n",
86 			ms->mss_ndn.bv_val,
87 			0, 0 );
88 		return( -1 );
89 	}
90 
91 	attr_merge_one( e_op, mi->mi_ad_monitorOpInitiated, &bv_zero, NULL );
92 	attr_merge_one( e_op, mi->mi_ad_monitorOpCompleted, &bv_zero, NULL );
93 
94 	mp = ( monitor_entry_t * )e_op->e_private;
95 	mp->mp_children = NULL;
96 	ep = &mp->mp_children;
97 
98 	for ( i = 0; i < SLAP_OP_LAST; i++ ) {
99 		struct berval	rdn;
100 		Entry		*e;
101 		struct berval bv;
102 
103 		/*
104 		 * Initiated ops
105 		 */
106 		e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &monitor_op[i].rdn,
107 			mi->mi_oc_monitorOperation, NULL, NULL );
108 
109 		if ( e == NULL ) {
110 			Debug( LDAP_DEBUG_ANY,
111 				"monitor_subsys_ops_init: "
112 				"unable to create entry \"%s,%s\"\n",
113 				monitor_op[ i ].rdn.bv_val,
114 				ms->mss_ndn.bv_val, 0 );
115 			return( -1 );
116 		}
117 
118 		BER_BVSTR( &bv, "0" );
119 		attr_merge_one( e, mi->mi_ad_monitorOpInitiated, &bv, NULL );
120 		attr_merge_one( e, mi->mi_ad_monitorOpCompleted, &bv, NULL );
121 
122 		/* steal normalized RDN */
123 		dnRdn( &e->e_nname, &rdn );
124 		ber_dupbv( &monitor_op[ i ].nrdn, &rdn );
125 
126 		mp = monitor_entrypriv_create();
127 		if ( mp == NULL ) {
128 			return -1;
129 		}
130 		e->e_private = ( void * )mp;
131 		mp->mp_info = ms;
132 		mp->mp_flags = ms->mss_flags \
133 			| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
134 
135 		if ( monitor_cache_add( mi, e ) ) {
136 			Debug( LDAP_DEBUG_ANY,
137 				"monitor_subsys_ops_init: "
138 				"unable to add entry \"%s,%s\"\n",
139 				monitor_op[ i ].rdn.bv_val,
140 				ms->mss_ndn.bv_val, 0 );
141 			return( -1 );
142 		}
143 
144 		*ep = e;
145 		ep = &mp->mp_next;
146 	}
147 
148 	monitor_cache_release( mi, e_op );
149 
150 	return( 0 );
151 }
152 
153 static int
154 monitor_subsys_ops_destroy(
155 	BackendDB		*be,
156 	monitor_subsys_t	*ms )
157 {
158 	int		i;
159 
160 	for ( i = 0; i < SLAP_OP_LAST; i++ ) {
161 		if ( !BER_BVISNULL( &monitor_op[ i ].nrdn ) ) {
162 			ch_free( monitor_op[ i ].nrdn.bv_val );
163 		}
164 	}
165 
166 	return 0;
167 }
168 
169 static int
170 monitor_subsys_ops_update(
171 	Operation		*op,
172 	SlapReply		*rs,
173 	Entry                   *e )
174 {
175 	monitor_info_t		*mi = ( monitor_info_t * )op->o_bd->be_private;
176 
177 	ldap_pvt_mp_t		nInitiated = LDAP_PVT_MP_INIT,
178 				nCompleted = LDAP_PVT_MP_INIT;
179 	struct berval		rdn;
180 	int 			i;
181 	Attribute		*a;
182 	slap_counters_t *sc;
183 	static struct berval	bv_ops = BER_BVC( "cn=operations" );
184 
185 	assert( mi != NULL );
186 	assert( e != NULL );
187 
188 	dnRdn( &e->e_nname, &rdn );
189 
190 	if ( dn_match( &rdn, &bv_ops ) ) {
191 		ldap_pvt_mp_init( nInitiated );
192 		ldap_pvt_mp_init( nCompleted );
193 
194 		ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
195 		for ( i = 0; i < SLAP_OP_LAST; i++ ) {
196 			ldap_pvt_mp_add( nInitiated, slap_counters.sc_ops_initiated_[ i ] );
197 			ldap_pvt_mp_add( nCompleted, slap_counters.sc_ops_completed_[ i ] );
198 		}
199 		for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
200 			ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
201 			for ( i = 0; i < SLAP_OP_LAST; i++ ) {
202 				ldap_pvt_mp_add( nInitiated, sc->sc_ops_initiated_[ i ] );
203 				ldap_pvt_mp_add( nCompleted, sc->sc_ops_completed_[ i ] );
204 			}
205 			ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
206 		}
207 		ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
208 
209 	} else {
210 		for ( i = 0; i < SLAP_OP_LAST; i++ ) {
211 			if ( dn_match( &rdn, &monitor_op[ i ].nrdn ) )
212 			{
213 				ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
214 				ldap_pvt_mp_init_set( nInitiated, slap_counters.sc_ops_initiated_[ i ] );
215 				ldap_pvt_mp_init_set( nCompleted, slap_counters.sc_ops_completed_[ i ] );
216 				for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
217 					ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
218 					ldap_pvt_mp_add( nInitiated, sc->sc_ops_initiated_[ i ] );
219 					ldap_pvt_mp_add( nCompleted, sc->sc_ops_completed_[ i ] );
220 					ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
221 				}
222 				ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
223 				break;
224 			}
225 		}
226 
227 		if ( i == SLAP_OP_LAST ) {
228 			/* not found ... */
229 			return( 0 );
230 		}
231 	}
232 
233 	a = attr_find( e->e_attrs, mi->mi_ad_monitorOpInitiated );
234 	assert ( a != NULL );
235 
236 	/* NOTE: no minus sign is allowed in the counters... */
237 	UI2BV( &a->a_vals[ 0 ], nInitiated );
238 	ldap_pvt_mp_clear( nInitiated );
239 
240 	a = attr_find( e->e_attrs, mi->mi_ad_monitorOpCompleted );
241 	assert ( a != NULL );
242 
243 	/* NOTE: no minus sign is allowed in the counters... */
244 	UI2BV( &a->a_vals[ 0 ], nCompleted );
245 	ldap_pvt_mp_clear( nCompleted );
246 
247 	/* FIXME: touch modifyTimestamp? */
248 
249 	return SLAP_CB_CONTINUE;
250 }
251 
252