]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/rww.c
plug more one-time leaks; rearrange subsystems setup
[openldap] / servers / slapd / back-monitor / rww.c
1 /* readw.c - deal with read waiters subsystem */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2001-2005 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 "lutil.h"
29 #include "back-monitor.h"
30
31 static int
32 monitor_subsys_rww_update(
33         Operation               *op,
34         SlapReply               *rs,
35         Entry                   *e );
36
37 enum {
38         MONITOR_RWW_READ = 0,
39         MONITOR_RWW_WRITE,
40
41         MONITOR_RWW_LAST
42 };
43
44 struct monitor_rww_t {
45         struct berval   rdn;
46         struct berval   nrdn;
47 } monitor_rww[] = {
48         { BER_BVC("cn=Read"),           BER_BVNULL },
49         { BER_BVC("cn=Write"),          BER_BVNULL },
50         { BER_BVNULL,                   BER_BVNULL }
51 };
52
53 int
54 monitor_subsys_rww_init(
55         BackendDB               *be,
56         monitor_subsys_t        *ms
57 )
58 {
59         monitor_info_t  *mi;
60         
61         Entry           **ep, *e_conn;
62         monitor_entry_t *mp;
63         int                     i;
64
65         assert( be != NULL );
66
67         ms->mss_update = monitor_subsys_rww_update;
68
69         mi = ( monitor_info_t * )be->be_private;
70
71         if ( monitor_cache_get( mi, &ms->mss_ndn, &e_conn ) ) {
72                 Debug( LDAP_DEBUG_ANY,
73                         "monitor_subsys_rww_init: "
74                         "unable to get entry \"%s\"\n",
75                         ms->mss_ndn.bv_val, 0, 0 );
76                 return( -1 );
77         }
78
79         mp = ( monitor_entry_t * )e_conn->e_private;
80         mp->mp_children = NULL;
81         ep = &mp->mp_children;
82
83         for ( i = 0; i < MONITOR_RWW_LAST; i++ ) {
84                 char                    buf[ BACKMONITOR_BUFSIZE ];
85                 struct berval           nrdn, bv;
86                 Entry                   *e;
87                 
88                 snprintf( buf, sizeof( buf ),
89                         "dn: %s,%s\n"
90                         "objectClass: %s\n"
91                         "structuralObjectClass: %s\n"
92                         "cn: %s\n"
93                         "creatorsName: %s\n"
94                         "modifiersName: %s\n"
95                         "createTimestamp: %s\n"
96                         "modifyTimestamp: %s\n",
97                         monitor_rww[ i ].rdn.bv_val,
98                         ms->mss_dn.bv_val,
99                         mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
100                         mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
101                         &monitor_rww[ i ].rdn.bv_val[ STRLENOF( "cn=" ) ],
102                         mi->mi_creatorsName.bv_val,
103                         mi->mi_creatorsName.bv_val,
104                         mi->mi_startTime.bv_val,
105                         mi->mi_startTime.bv_val );
106         
107                 e = str2entry( buf );
108                 if ( e == NULL ) {
109                         Debug( LDAP_DEBUG_ANY,
110                                 "monitor_subsys_rww_init: "
111                                 "unable to create entry \"cn=Read,%s\"\n",
112                                 ms->mss_ndn.bv_val, 0, 0 );
113                         return( -1 );
114                 }
115
116                 /* steal normalized RDN */
117                 dnRdn( &e->e_nname, &nrdn );
118                 ber_dupbv( &monitor_rww[ i ].nrdn, &nrdn );
119         
120                 BER_BVSTR( &bv, "0" );
121                 attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, &bv );
122         
123                 mp = monitor_entrypriv_create();
124                 if ( mp == NULL ) {
125                         return -1;
126                 }
127                 e->e_private = ( void * )mp;
128                 mp->mp_info = ms;
129                 mp->mp_flags = ms->mss_flags \
130                         | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
131
132                 if ( monitor_cache_add( mi, e ) ) {
133                         Debug( LDAP_DEBUG_ANY,
134                                 "monitor_subsys_rww_init: "
135                                 "unable to add entry \"%s,%s\"\n",
136                                 monitor_rww[ i ].rdn.bv_val,
137                                 ms->mss_ndn.bv_val, 0 );
138                         return( -1 );
139                 }
140         
141                 *ep = e;
142                 ep = &mp->mp_next;
143         }
144
145         monitor_cache_release( mi, e_conn );
146
147         return( 0 );
148 }
149
150 static int
151 monitor_subsys_rww_update(
152         Operation               *op,
153         SlapReply               *rs,
154         Entry                   *e )
155 {
156         monitor_info_t *mi = (monitor_info_t *)op->o_bd->be_private;
157         Connection      *c;
158         int             connindex;
159         long            nconns, nwritewaiters, nreadwaiters;
160
161         int             i;
162         struct berval   nrdn;
163
164         Attribute       *a;
165         char            buf[] = "+9223372036854775807L";
166         long            num = 0;
167         ber_len_t       len;
168
169         assert( mi != NULL );
170         assert( e != NULL );
171
172         dnRdn( &e->e_nname, &nrdn );
173
174         for ( i = 0; !BER_BVISNULL( &monitor_rww[ i ].nrdn ); i++ ) {
175                 if ( dn_match( &nrdn, &monitor_rww[ i ].nrdn ) ) {
176                         break;
177                 }
178         }
179
180         if ( i == MONITOR_RWW_LAST ) {
181                 return SLAP_CB_CONTINUE;
182         }
183
184         nconns = nwritewaiters = nreadwaiters = 0;
185         for ( c = connection_first( &connindex );
186                         c != NULL;
187                         c = connection_next( c, &connindex ), nconns++ )
188         {
189                 if ( c->c_writewaiter ) {
190                         nwritewaiters++;
191                 }
192
193                 /* FIXME: ?!? */
194                 if ( c->c_currentber != NULL ) {
195                         nreadwaiters++;
196                 }
197         }
198         connection_done(c);
199
200         switch ( i ) {
201         case MONITOR_RWW_READ:
202                 num = nreadwaiters;
203                 break;
204
205         case MONITOR_RWW_WRITE:
206                 num = nwritewaiters;
207                 break;
208
209         default:
210                 assert( 0 );
211         }
212
213         snprintf( buf, sizeof( buf ), "%ld", num );
214
215         a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter );
216         assert( a != NULL );
217         len = strlen( buf );
218         if ( len > a->a_vals[ 0 ].bv_len ) {
219                 a->a_vals[ 0 ].bv_val = ber_memrealloc( a->a_vals[ 0 ].bv_val, len + 1 );
220                 if ( BER_BVISNULL( &a->a_vals[ 0 ] ) ) {
221                         BER_BVZERO( &a->a_vals[ 0 ] );
222                         return SLAP_CB_CONTINUE;
223                 }
224         }
225         AC_MEMCPY( a->a_vals[ 0 ].bv_val, buf, len + 1 );
226         a->a_vals[ 0 ].bv_len = len;
227
228         /* FIXME: touch modifyTimestamp? */
229
230         return SLAP_CB_CONTINUE;
231 }
232