xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-monitor/operation.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
1 /*	$NetBSD: operation.c,v 1.3 2021/08/14 16:15:00 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-2021 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.3 2021/08/14 16:15:00 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
monitor_subsys_ops_init(BackendDB * be,monitor_subsys_t * ms)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 		return( -1 );
91 	}
92 
93 	attr_merge_one( e_op, mi->mi_ad_monitorOpInitiated, &bv_zero, NULL );
94 	attr_merge_one( e_op, mi->mi_ad_monitorOpCompleted, &bv_zero, NULL );
95 
96 	mp = ( monitor_entry_t * )e_op->e_private;
97 	mp->mp_children = NULL;
98 	ep = &mp->mp_children;
99 
100 	for ( i = 0; i < SLAP_OP_LAST; i++ ) {
101 		struct berval	rdn;
102 		Entry		*e;
103 		struct berval bv;
104 
105 		/*
106 		 * Initiated ops
107 		 */
108 		e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &monitor_op[i].rdn,
109 			mi->mi_oc_monitorOperation, NULL, NULL );
110 
111 		if ( e == NULL ) {
112 			Debug( LDAP_DEBUG_ANY,
113 				"monitor_subsys_ops_init: "
114 				"unable to create entry \"%s,%s\"\n",
115 				monitor_op[ i ].rdn.bv_val,
116 				ms->mss_ndn.bv_val );
117 			return( -1 );
118 		}
119 
120 		BER_BVSTR( &bv, "0" );
121 		attr_merge_one( e, mi->mi_ad_monitorOpInitiated, &bv, NULL );
122 		attr_merge_one( e, mi->mi_ad_monitorOpCompleted, &bv, NULL );
123 
124 		/* steal normalized RDN */
125 		dnRdn( &e->e_nname, &rdn );
126 		ber_dupbv( &monitor_op[ i ].nrdn, &rdn );
127 
128 		mp = monitor_entrypriv_create();
129 		if ( mp == NULL ) {
130 			return -1;
131 		}
132 		e->e_private = ( void * )mp;
133 		mp->mp_info = ms;
134 		mp->mp_flags = ms->mss_flags \
135 			| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
136 
137 		if ( monitor_cache_add( mi, e ) ) {
138 			Debug( LDAP_DEBUG_ANY,
139 				"monitor_subsys_ops_init: "
140 				"unable to add entry \"%s,%s\"\n",
141 				monitor_op[ i ].rdn.bv_val,
142 				ms->mss_ndn.bv_val );
143 			return( -1 );
144 		}
145 
146 		*ep = e;
147 		ep = &mp->mp_next;
148 	}
149 
150 	monitor_cache_release( mi, e_op );
151 
152 	return( 0 );
153 }
154 
155 static int
monitor_subsys_ops_destroy(BackendDB * be,monitor_subsys_t * ms)156 monitor_subsys_ops_destroy(
157 	BackendDB		*be,
158 	monitor_subsys_t	*ms )
159 {
160 	int		i;
161 
162 	for ( i = 0; i < SLAP_OP_LAST; i++ ) {
163 		if ( !BER_BVISNULL( &monitor_op[ i ].nrdn ) ) {
164 			ch_free( monitor_op[ i ].nrdn.bv_val );
165 		}
166 	}
167 
168 	return 0;
169 }
170 
171 static int
monitor_subsys_ops_update(Operation * op,SlapReply * rs,Entry * e)172 monitor_subsys_ops_update(
173 	Operation		*op,
174 	SlapReply		*rs,
175 	Entry                   *e )
176 {
177 	monitor_info_t		*mi = ( monitor_info_t * )op->o_bd->be_private;
178 
179 	ldap_pvt_mp_t		nInitiated = LDAP_PVT_MP_INIT,
180 				nCompleted = LDAP_PVT_MP_INIT;
181 	struct berval		rdn;
182 	int 			i;
183 	Attribute		*a;
184 	slap_counters_t *sc;
185 	static struct berval	bv_ops = BER_BVC( "cn=operations" );
186 
187 	assert( mi != NULL );
188 	assert( e != NULL );
189 
190 	dnRdn( &e->e_nname, &rdn );
191 
192 	if ( dn_match( &rdn, &bv_ops ) ) {
193 		ldap_pvt_mp_init( nInitiated );
194 		ldap_pvt_mp_init( nCompleted );
195 
196 		ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
197 		ldap_pvt_mp_add( nInitiated, slap_counters.sc_ops_initiated );
198 		ldap_pvt_mp_add( nCompleted, slap_counters.sc_ops_completed );
199 		for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
200 			ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
201 			ldap_pvt_mp_add( nInitiated, sc->sc_ops_initiated );
202 			ldap_pvt_mp_add( nCompleted, sc->sc_ops_completed );
203 			ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
204 		}
205 		ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
206 
207 	} else {
208 		for ( i = 0; i < SLAP_OP_LAST; i++ ) {
209 			if ( dn_match( &rdn, &monitor_op[ i ].nrdn ) )
210 			{
211 				ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
212 				ldap_pvt_mp_init_set( nInitiated, slap_counters.sc_ops_initiated_[ i ] );
213 				ldap_pvt_mp_init_set( nCompleted, slap_counters.sc_ops_completed_[ i ] );
214 				for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
215 					ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
216 					ldap_pvt_mp_add( nInitiated, sc->sc_ops_initiated_[ i ] );
217 					ldap_pvt_mp_add( nCompleted, sc->sc_ops_completed_[ i ] );
218 					ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
219 				}
220 				ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
221 				break;
222 			}
223 		}
224 
225 		if ( i == SLAP_OP_LAST ) {
226 			/* not found ... */
227 			return( 0 );
228 		}
229 	}
230 
231 	a = attr_find( e->e_attrs, mi->mi_ad_monitorOpInitiated );
232 	assert ( a != NULL );
233 
234 	/* NOTE: no minus sign is allowed in the counters... */
235 	UI2BV( &a->a_vals[ 0 ], nInitiated );
236 	ldap_pvt_mp_clear( nInitiated );
237 
238 	a = attr_find( e->e_attrs, mi->mi_ad_monitorOpCompleted );
239 	assert ( a != NULL );
240 
241 	/* NOTE: no minus sign is allowed in the counters... */
242 	UI2BV( &a->a_vals[ 0 ], nCompleted );
243 	ldap_pvt_mp_clear( nCompleted );
244 
245 	/* FIXME: touch modifyTimestamp? */
246 
247 	return SLAP_CB_CONTINUE;
248 }
249 
250