]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/sent.c
use GMP for multiple precision in counters
[openldap] / servers / slapd / back-monitor / sent.c
1 /* sent.c - deal with data sent 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
30 enum {
31         MONITOR_SENT_ENTRIES = 0,
32         MONITOR_SENT_REFERRALS,
33         MONITOR_SENT_PDU,
34         MONITOR_SENT_BYTES,
35
36         MONITOR_SENT_LAST
37 };
38
39 struct monitor_sent_t {
40         struct berval   rdn;
41         struct berval   nrdn;
42 } monitor_sent[] = {
43         { BER_BVC("cn=Bytes"),          BER_BVC("cn=bytes")             },
44         { BER_BVC("cn=PDU"),            BER_BVC("cn=pdu")               },
45         { BER_BVC("cn=Entries"),        BER_BVC("cn=entries")           },
46         { BER_BVC("cn=Referrals"),      BER_BVC("cn=referrals")         },
47         { BER_BVNULL,                   BER_BVNULL                      }
48 };
49
50 int
51 monitor_subsys_sent_init(
52         BackendDB               *be
53 )
54 {
55         struct monitorinfo      *mi;
56         
57         Entry                   *e_tmp, *e_sent;
58         struct monitorentrypriv *mp;
59         int                     i;
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_SENT].mss_ndn, &e_sent ) ) {
67                 Debug( LDAP_DEBUG_ANY,
68                         "monitor_subsys_sent_init: "
69                         "unable to get entry \"%s\"\n%s%s",
70                         monitor_subsys[SLAPD_MONITOR_SENT].mss_ndn.bv_val, 
71                         "", "" );
72                 return( -1 );
73         }
74
75         e_tmp = NULL;
76
77         for ( i = MONITOR_SENT_LAST; --i >= 0; ) {
78                 char                    buf[ BACKMONITOR_BUFSIZE ];
79                 struct berval           bv;
80                 Entry                   *e;
81
82                 snprintf( buf, sizeof( buf ),
83                                 "dn: %s,%s\n"
84                                 "objectClass: %s\n"
85                                 "structuralObjectClass: %s\n"
86                                 "cn: %s\n"
87                                 "creatorsName: %s\n"
88                                 "modifiersName: %s\n"
89                                 "createTimestamp: %s\n"
90                                 "modifyTimestamp: %s\n",
91                                 monitor_sent[i].rdn.bv_val,
92                                 monitor_subsys[SLAPD_MONITOR_SENT].mss_dn.bv_val,
93                                 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
94                                 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
95                                 &monitor_sent[i].rdn.bv_val[STRLENOF( "cn=" )],
96                                 mi->mi_creatorsName.bv_val,
97                                 mi->mi_creatorsName.bv_val,
98                                 mi->mi_startTime.bv_val,
99                                 mi->mi_startTime.bv_val );
100
101                 e = str2entry( buf );
102                 if ( e == NULL ) {
103                         Debug( LDAP_DEBUG_ANY,
104                                 "monitor_subsys_sent_init: "
105                                 "unable to create entry \"%s,%s\"\n",
106                                 monitor_sent[i].rdn.bv_val,
107                                 monitor_subsys[SLAPD_MONITOR_SENT].mss_ndn.bv_val, 0 );
108                         return( -1 );
109                 }
110         
111                 bv.bv_val = "0";
112                 bv.bv_len = 1;
113                 attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
114         
115                 mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
116                 e->e_private = ( void * )mp;
117                 mp->mp_next = e_tmp;
118                 mp->mp_children = NULL;
119                 mp->mp_info = &monitor_subsys[SLAPD_MONITOR_SENT];
120                 mp->mp_flags = monitor_subsys[SLAPD_MONITOR_SENT].mss_flags \
121                         | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
122
123                 if ( monitor_cache_add( mi, e ) ) {
124                         Debug( LDAP_DEBUG_ANY,
125                                 "monitor_subsys_sent_init: "
126                                 "unable to add entry \"%s,%s\"\n%s%s",
127                                 monitor_sent[i].rdn.bv_val,
128                                 monitor_subsys[SLAPD_MONITOR_SENT].mss_ndn.bv_val, 0 );
129                         return( -1 );
130                 }
131         
132                 e_tmp = e;
133         }
134
135         mp = ( struct monitorentrypriv * )e_sent->e_private;
136         mp->mp_children = e_tmp;
137
138         monitor_cache_release( mi, e_sent );
139
140         return( 0 );
141 }
142
143 int
144 monitor_subsys_sent_update(
145         Operation               *op,
146         Entry                   *e
147 )
148 {
149         struct monitorinfo      *mi = 
150                 (struct monitorinfo *)op->o_bd->be_private;
151         
152         struct berval           rdn;
153 #ifdef HAVE_GMP
154         mpz_t                   n;
155 #else /* ! HAVE_GMP */
156         unsigned long           n;
157 #endif /* ! HAVE_GMP */
158         Attribute               *a;
159 #ifndef HAVE_GMP
160         char                    buf[] = "+9223372036854775807L";
161 #endif /* ! HAVE_GMP */
162         int                     i;
163
164         assert( mi );
165         assert( e );
166
167         dnRdn( &e->e_nname, &rdn );
168
169         for ( i = 0; i < MONITOR_SENT_LAST; i++ ) {
170                 if ( dn_match( &rdn, &monitor_sent[i].nrdn ) ) {
171                         break;
172                 }
173         }
174
175         if ( i == MONITOR_SENT_LAST ) {
176                 return 0;
177         }
178
179         ldap_pvt_thread_mutex_lock(&slap_counters.sc_sent_mutex);
180         switch ( i ) {
181         case MONITOR_SENT_ENTRIES:
182 #ifdef HAVE_GMP
183                 mpz_init_set( n, slap_counters.sc_entries );
184 #else /* ! HAVE_GMP */
185                 n = slap_counters.sc_entries;
186 #endif /* ! HAVE_GMP */
187                 break;
188
189         case MONITOR_SENT_REFERRALS:
190 #ifdef HAVE_GMP
191                 mpz_init_set( n, slap_counters.sc_refs );
192 #else /* ! HAVE_GMP */
193                 n = slap_counters.sc_refs;
194 #endif /* ! HAVE_GMP */
195                 break;
196
197         case MONITOR_SENT_PDU:
198 #ifdef HAVE_GMP
199                 mpz_init_set( n, slap_counters.sc_pdu );
200 #else /* ! HAVE_GMP */
201                 n = slap_counters.sc_pdu;
202 #endif /* ! HAVE_GMP */
203                 break;
204
205         case MONITOR_SENT_BYTES:
206 #ifdef HAVE_GMP
207                 mpz_init_set( n, slap_counters.sc_bytes );
208 #else /* ! HAVE_GMP */
209                 n = slap_counters.sc_bytes;
210 #endif /* ! HAVE_GMP */
211                 break;
212
213         default:
214                 assert(0);
215         }
216         ldap_pvt_thread_mutex_unlock(&slap_counters.sc_sent_mutex);
217         
218         a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter );
219         if ( a == NULL ) {
220                 return -1;
221         }
222
223         free( a->a_vals[ 0 ].bv_val );
224 #ifdef HAVE_GMP
225         /* NOTE: there should be no minus sign allowed in the counters... */
226         a->a_vals[ 0 ].bv_len = mpz_sizeinbase( n, 10 );
227         a->a_vals[ 0 ].bv_val = ber_memalloc( a->a_vals[ 0 ].bv_len + 1 );
228         (void)mpz_get_str( a->a_vals[ 0 ].bv_val, 10, n );
229         mpz_clear( n );
230         /* NOTE: according to the documentation, the result 
231          * of mpz_sizeinbase() can exceed the length of the
232          * string representation of the number by 1
233          */
234         if ( a->a_vals[ 0 ].bv_val[ a->a_vals[ 0 ].bv_len - 1 ] == '\0' ) {
235                 a->a_vals[ 0 ].bv_len--;
236         }
237 #else /* ! HAVE_GMP */
238         snprintf( buf, sizeof( buf ), "%lu", n );
239         ber_str2bv( buf, 0, 1, &a->a_vals[ 0 ] );
240 #endif /* ! HAVE_GMP */
241
242         return 0;
243 }
244