1 /* operation.c - deal with operation subsystem */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2001-2004 The OpenLDAP Foundation.
6 * Portions Copyright 2001-2003 Pierangelo Masarati.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
18 * This work was initially developed by Pierangelo Masarati for inclusion
19 * in OpenLDAP Software.
25 #include <ac/string.h>
28 #include "back-monitor.h"
31 struct monitor_ops_t {
35 { BER_BVC( "cn=Bind" ), BER_BVC( "cn=bind" ) },
36 { BER_BVC( "cn=Unbind" ), BER_BVC( "cn=unbind" ) },
37 { BER_BVC( "cn=Add" ), BER_BVC( "cn=add" ) },
38 { BER_BVC( "cn=Delete" ), BER_BVC( "cn=delete" ) },
39 { BER_BVC( "cn=Modrdn" ), BER_BVC( "cn=modrdn" ) },
40 { BER_BVC( "cn=Modify" ), BER_BVC( "cn=modify" ) },
41 { BER_BVC( "cn=Compare" ), BER_BVC( "cn=compare" ) },
42 { BER_BVC( "cn=Search" ), BER_BVC( "cn=search" ) },
43 { BER_BVC( "cn=Abandon" ), BER_BVC( "cn=abandon" ) },
44 { BER_BVC( "cn=Extended" ), BER_BVC( "cn=extended" ) },
45 { BER_BVNULL, BER_BVNULL }
49 monitor_subsys_ops_init(
53 struct monitorinfo *mi;
55 Entry *e, *e_tmp, *e_op;
56 struct monitorentrypriv *mp;
57 char buf[ BACKMONITOR_BUFSIZE ];
59 struct berval bv_zero = BER_BVC("0");
63 mi = ( struct monitorinfo * )be->be_private;
65 if ( monitor_cache_get( mi,
66 &monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn, &e_op ) ) {
67 Debug( LDAP_DEBUG_ANY,
68 "monitor_subsys_ops_init: "
69 "unable to get entry \"%s\"\n",
70 monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val,
75 attr_merge_one( e_op, mi->mi_ad_monitorOpInitiated, &bv_zero, NULL );
76 attr_merge_one( e_op, mi->mi_ad_monitorOpCompleted, &bv_zero, NULL );
80 for ( i = SLAP_OP_LAST; i-- > 0; ) {
85 snprintf( buf, sizeof( buf ),
88 "structuralObjectClass: %s\n"
94 "createTimestamp: %s\n"
95 "modifyTimestamp: %s\n",
96 monitor_op[ i ].rdn.bv_val,
97 monitor_subsys[SLAPD_MONITOR_OPS].mss_dn.bv_val,
98 mi->mi_oc_monitorOperation->soc_cname.bv_val,
99 mi->mi_oc_monitorOperation->soc_cname.bv_val,
100 &monitor_op[ i ].rdn.bv_val[STRLENOF( "cn=" )],
101 mi->mi_ad_monitorOpInitiated->ad_cname.bv_val,
102 mi->mi_ad_monitorOpCompleted->ad_cname.bv_val,
103 mi->mi_creatorsName.bv_val,
104 mi->mi_creatorsName.bv_val,
105 mi->mi_startTime.bv_val,
106 mi->mi_startTime.bv_val );
108 e = str2entry( buf );
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 monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, 0 );
118 mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
119 e->e_private = ( void * )mp;
121 mp->mp_children = NULL;
122 mp->mp_info = &monitor_subsys[SLAPD_MONITOR_OPS];
123 mp->mp_flags = monitor_subsys[SLAPD_MONITOR_OPS].mss_flags \
124 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
126 if ( monitor_cache_add( mi, e ) ) {
127 Debug( LDAP_DEBUG_ANY,
128 "monitor_subsys_ops_init: "
129 "unable to add entry \"%s,%s\"\n",
130 monitor_op[ i ].rdn.bv_val,
131 monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, 0 );
138 mp = ( struct monitorentrypriv * )e_op->e_private;
139 mp->mp_children = e_tmp;
141 monitor_cache_release( mi, e_op );
147 monitor_subsys_ops_update(
152 struct monitorinfo *mi =
153 (struct monitorinfo *)op->o_bd->be_private;
158 #else /* ! HAVE_GMP */
159 unsigned long nInitiated = 0,
161 char buf[] = "+9223372036854775807L";
162 #endif /* ! HAVE_GMP */
166 static struct berval bv_ops = BER_BVC( "cn=operations" );
171 dnRdn( &e->e_nname, &rdn );
173 if ( dn_match( &rdn, &bv_ops ) ) {
175 mpz_init( nInitiated );
176 mpz_init( nCompleted );
177 #endif /* ! HAVE_GMP */
179 ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex );
180 for ( i = 0; i < SLAP_OP_LAST; i++ ) {
182 mpz_add( nInitiated, nInitiated, slap_counters.sc_ops_initiated_[ i ] );
183 mpz_add( nCompleted, nCompleted, slap_counters.sc_ops_completed_[ i ] );
184 #else /* ! HAVE_GMP */
185 nInitiated += slap_counters.sc_ops_initiated_[ i ];
186 nCompleted += slap_counters.sc_ops_completed_[ i ];
187 #endif /* ! HAVE_GMP */
189 ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex );
192 for ( i = 0; i < SLAP_OP_LAST; i++ ) {
193 if ( dn_match( &rdn, &monitor_op[ i ].nrdn ) )
195 ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex );
197 mpz_init_set( nInitiated, slap_counters.sc_ops_initiated_[ i ] );
198 mpz_init_set( nCompleted, slap_counters.sc_ops_completed_[ i ] );
199 #else /* ! HAVE_GMP */
200 nInitiated = slap_counters.sc_ops_initiated_[ i ];
201 nCompleted = slap_counters.sc_ops_completed_[ i ];
202 #endif /* ! HAVE_GMP */
203 ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex );
208 if ( i == SLAP_OP_LAST ) {
214 a = attr_find( e->e_attrs, mi->mi_ad_monitorOpInitiated );
215 assert ( a != NULL );
216 free( a->a_vals[ 0 ].bv_val );
218 /* NOTE: there should be no minus sign allowed in the counters... */
219 a->a_vals[ 0 ].bv_len = mpz_sizeinbase( nInitiated, 10 );
220 a->a_vals[ 0 ].bv_val = ber_memalloc( a->a_vals[ 0 ].bv_len + 1 );
221 (void)mpz_get_str( a->a_vals[ 0 ].bv_val, 10, nInitiated );
222 mpz_clear( nInitiated );
223 /* NOTE: according to the documentation, the result
224 * of mpz_sizeinbase() can exceed the length of the
225 * string representation of the number by 1
227 if ( a->a_vals[ 0 ].bv_val[ a->a_vals[ 0 ].bv_len - 1 ] == '\0' ) {
228 a->a_vals[ 0 ].bv_len--;
230 #else /* ! HAVE_GMP */
231 snprintf( buf, sizeof( buf ), "%ld", nInitiated );
232 ber_str2bv( buf, 0, 1, &a->a_vals[ 0 ] );
233 #endif /* ! HAVE_GMP */
235 a = attr_find( e->e_attrs, mi->mi_ad_monitorOpCompleted );
236 assert ( a != NULL );
237 free( a->a_vals[ 0 ].bv_val );
239 /* NOTE: there should be no minus sign allowed in the counters... */
240 a->a_vals[ 0 ].bv_len = mpz_sizeinbase( nCompleted, 10 );
241 a->a_vals[ 0 ].bv_val = ber_memalloc( a->a_vals[ 0 ].bv_len + 1 );
242 (void)mpz_get_str( a->a_vals[ 0 ].bv_val, 10, nCompleted );
243 mpz_clear( nCompleted );
244 /* NOTE: according to the documentation, the result
245 * of mpz_sizeinbase() can exceed the length of the
246 * string representation of the number by 1
248 if ( a->a_vals[ 0 ].bv_val[ a->a_vals[ 0 ].bv_len - 1 ] == '\0' ) {
249 a->a_vals[ 0 ].bv_len--;
251 #else /* ! HAVE_GMP */
252 snprintf( buf, sizeof( buf ), "%ld", nCompleted );
253 ber_str2bv( buf, 0, 1, &a->a_vals[ 0 ] );
254 #endif /* ! HAVE_GMP */