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