]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/operation.c
eb7be9baa8e128c5e9e4dbdabd045efbf4a125a1
[openldap] / servers / slapd / back-monitor / operation.c
1 /* operation.c - deal with operation subsystem */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2001-2004 The OpenLDAP Foundation.
6  * Portions Copyright 2001-2003 Pierangelo Masarati.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted only as authorized by the OpenLDAP
11  * Public License.
12  *
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>.
16  */
17 /* ACKNOWLEDGEMENTS:
18  * This work was initially developed by Pierangelo Masarati for inclusion
19  * in OpenLDAP Software.
20  */
21
22 #include "portable.h"
23
24 #include <stdio.h>
25 #include <ac/string.h>
26
27 #include "slap.h"
28 #include "back-monitor.h"
29 #include "lber_pvt.h"
30
31 struct monitor_ops_t {
32         struct berval   rdn;
33         struct berval   nrdn;
34 } monitor_op[] = {
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                      }
46 };
47
48 int
49 monitor_subsys_ops_init(
50         BackendDB               *be
51 )
52 {
53         struct monitorinfo      *mi;
54         
55         Entry                   *e, *e_tmp, *e_op;
56         struct monitorentrypriv *mp;
57         char                    buf[ BACKMONITOR_BUFSIZE ];
58         int                     i;
59         struct berval           bv_zero = BER_BVC("0");
60
61         assert( be != NULL );
62
63         mi = ( struct monitorinfo * )be->be_private;
64
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, 
71                         0, 0 );
72                 return( -1 );
73         }
74
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 );
77
78         e_tmp = NULL;
79
80         for ( i = SLAP_OP_LAST; i-- > 0; ) {
81
82                 /*
83                  * Initiated ops
84                  */
85                 snprintf( buf, sizeof( buf ),
86                                 "dn: %s,%s\n"
87                                 "objectClass: %s\n"
88                                 "structuralObjectClass: %s\n"
89                                 "cn: %s\n"
90                                 "%s: 0\n"
91                                 "%s: 0\n"
92                                 "creatorsName: %s\n"
93                                 "modifiersName: %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 );
107
108                 e = str2entry( buf );
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                                 monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, 0 );
115                         return( -1 );
116                 }
117         
118                 mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
119                 e->e_private = ( void * )mp;
120                 mp->mp_next = e_tmp;
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;
125
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 );
132                         return( -1 );
133                 }
134         
135                 e_tmp = e;
136         }
137
138         mp = ( struct monitorentrypriv * )e_op->e_private;
139         mp->mp_children = e_tmp;
140
141         monitor_cache_release( mi, e_op );
142
143         return( 0 );
144 }
145
146 int
147 monitor_subsys_ops_update(
148         Operation               *op,
149         Entry                   *e
150 )
151 {
152         struct monitorinfo      *mi = 
153                 (struct monitorinfo *)op->o_bd->be_private;
154
155 #ifdef HAVE_GMP
156         mpz_t                   nInitiated,
157                                 nCompleted;
158 #else /* ! HAVE_GMP */
159         unsigned long           nInitiated = 0,
160                                 nCompleted = 0;
161         char                    buf[] = "+9223372036854775807L";
162 #endif /* ! HAVE_GMP */
163         struct berval           rdn;
164         int                     i;
165         Attribute               *a;
166         static struct berval    bv_ops = BER_BVC( "cn=operations" );
167
168         assert( mi );
169         assert( e );
170
171         dnRdn( &e->e_nname, &rdn );
172
173         if ( dn_match( &rdn, &bv_ops ) ) {
174 #ifdef HAVE_GMP
175                 mpz_init( nInitiated );
176                 mpz_init( nCompleted );
177 #endif /* ! HAVE_GMP */
178
179                 ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex );
180                 for ( i = 0; i < SLAP_OP_LAST; i++ ) {
181 #ifdef HAVE_GMP
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_counter.sc_ops_initiated_[ i ];
186                         nCompleted += slap_counter.sc_ops_completed_[ i ];
187 #endif /* ! HAVE_GMP */
188                 }
189                 ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex );
190                 
191         } else {
192                 for ( i = 0; i < SLAP_OP_LAST; i++ ) {
193                         if ( dn_match( &rdn, &monitor_op[ i ].nrdn ) )
194                         {
195                                 ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex );
196 #ifdef HAVE_GMP
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_counter.sc_ops_initiated_[ i ];
201                                 nCompleted = slap_counter.sc_ops_completed_[ i ];
202 #endif /* ! HAVE_GMP */
203                                 ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex );
204                                 break;
205                         }
206                 }
207
208                 if ( i == SLAP_OP_LAST ) {
209                         /* not found ... */
210                         return( 0 );
211                 }
212         }
213
214         a = attr_find( e->e_attrs, mi->mi_ad_monitorOpInitiated );
215         assert ( a != NULL );
216         free( a->a_vals[ 0 ].bv_val );
217 #ifdef HAVE_GMP
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
226          */
227         if ( a->a_vals[ 0 ].bv_val[ a->a_vals[ 0 ].bv_len - 1 ] == '\0' ) {
228                 a->a_vals[ 0 ].bv_len--;
229         }
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 */
234         
235         a = attr_find( e->e_attrs, mi->mi_ad_monitorOpCompleted );
236         assert ( a != NULL );
237         free( a->a_vals[ 0 ].bv_val );
238 #ifdef HAVE_GMP
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
247          */
248         if ( a->a_vals[ 0 ].bv_val[ a->a_vals[ 0 ].bv_len - 1 ] == '\0' ) {
249                 a->a_vals[ 0 ].bv_len--;
250         }
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 */
255         
256         return( 0 );
257 }
258