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