]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/rww.c
Referrals should not (except in special cases) be
[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-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 "lutil.h"
29 #include "back-monitor.h"
30
31 int
32 monitor_subsys_rww_init(
33         BackendDB               *be
34 )
35 {
36         struct monitorinfo      *mi;
37         
38         Entry                   *e, *e_tmp, *e_conn;
39         struct monitorentrypriv *mp;
40         char                    buf[ BACKMONITOR_BUFSIZE ];
41         struct berval           bv;
42
43         assert( be != NULL );
44
45         mi = ( struct monitorinfo * )be->be_private;
46
47         if ( monitor_cache_get( mi,
48                         &monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn, &e_conn ) ) {
49 #ifdef NEW_LOGGING
50                 LDAP_LOG( OPERATION, CRIT,
51                         "monitor_subsys_rww_init: "
52                         "unable to get entry '%s'\n",
53                         monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
54 #else
55                 Debug( LDAP_DEBUG_ANY,
56                         "monitor_subsys_rww_init: "
57                         "unable to get entry '%s'\n%s%s",
58                         monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 
59                         "", "" );
60 #endif
61                 return( -1 );
62         }
63
64         e_tmp = NULL;
65
66         /*
67          * Total conns
68          */
69         snprintf( buf, sizeof( buf ),
70                 "dn: cn=Read,%s\n"
71                 "objectClass: %s\n"
72                 "structuralObjectClass: %s\n"
73                 "cn: Read\n"
74                 "creatorsName: %s\n"
75                 "modifiersName: %s\n"
76                 "createTimestamp: %s\n"
77                 "modifyTimestamp: %s\n",
78                 monitor_subsys[SLAPD_MONITOR_RWW].mss_dn.bv_val,
79                 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
80                 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
81                 mi->mi_creatorsName.bv_val,
82                 mi->mi_creatorsName.bv_val,
83                 mi->mi_startTime.bv_val,
84                 mi->mi_startTime.bv_val );
85         
86         e = str2entry( buf );
87         if ( e == NULL ) {
88 #ifdef NEW_LOGGING
89                 LDAP_LOG( OPERATION, CRIT,
90                         "monitor_subsys_rww_init: "
91                         "unable to create entry 'cn=Read,%s'\n",
92                         monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
93 #else
94                 Debug( LDAP_DEBUG_ANY,
95                         "monitor_subsys_rww_init: "
96                         "unable to create entry 'cn=Read,%s'\n",
97                         monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
98 #endif
99                 return( -1 );
100         }
101         
102         bv.bv_val = "0";
103         bv.bv_len = 1;
104         attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
105         
106         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
107         e->e_private = ( void * )mp;
108         mp->mp_next = e_tmp;
109         mp->mp_children = NULL;
110         mp->mp_info = &monitor_subsys[SLAPD_MONITOR_RWW];
111         mp->mp_flags = monitor_subsys[SLAPD_MONITOR_RWW].mss_flags \
112                 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
113
114         if ( monitor_cache_add( mi, e ) ) {
115 #ifdef NEW_LOGGING
116                 LDAP_LOG( OPERATION, CRIT,
117                         "monitor_subsys_rww_init: "
118                         "unable to add entry 'cn=Read,%s'\n",
119                         monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
120 #else
121                 Debug( LDAP_DEBUG_ANY,
122                         "monitor_subsys_rww_init: "
123                         "unable to add entry 'cn=Read,%s'\n",
124                         monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
125 #endif
126                 return( -1 );
127         }
128         
129         e_tmp = e;
130
131         /*
132          * Current conns
133          */
134         snprintf( buf, sizeof( buf ),
135                         "dn: cn=Write,%s\n"
136                         "objectClass: %s\n"
137                         "structuralObjectClass: %s\n"
138                         "cn: Write\n"
139                         "creatorsName: %s\n"
140                         "modifiersName: %s\n"
141                         "createTimestamp: %s\n"
142                         "modifyTimestamp: %s\n",
143                         monitor_subsys[SLAPD_MONITOR_RWW].mss_dn.bv_val,
144                         mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
145                         mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
146                         mi->mi_creatorsName.bv_val,
147                         mi->mi_creatorsName.bv_val,
148                         mi->mi_startTime.bv_val,
149                         mi->mi_startTime.bv_val );
150         
151         e = str2entry( buf );
152         if ( e == NULL ) {
153 #ifdef NEW_LOGGING
154                 LDAP_LOG( OPERATION, CRIT,
155                         "monitor_subsys_rww_init: "
156                         "unable to create entry 'cn=Write,%s'\n",
157                         monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
158 #else
159                 Debug( LDAP_DEBUG_ANY,
160                         "monitor_subsys_rww_init: "
161                         "unable to create entry 'cn=Write,%s'\n",
162                         monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
163 #endif
164                 return( -1 );
165         }
166         
167         bv.bv_val = "0";
168         bv.bv_len = 1;
169         attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
170         
171         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
172         e->e_private = ( void * )mp;
173         mp->mp_next = e_tmp;
174         mp->mp_children = NULL;
175         mp->mp_info = &monitor_subsys[SLAPD_MONITOR_RWW];
176         mp->mp_flags = monitor_subsys[SLAPD_MONITOR_RWW].mss_flags \
177                 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
178
179         if ( monitor_cache_add( mi, e ) ) {
180 #ifdef NEW_LOGGING
181                 LDAP_LOG( OPERATION, CRIT,
182                         "monitor_subsys_rww_init: "
183                         "unable to add entry 'cn=Write,%s'\n",
184                         monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
185 #else
186                 Debug( LDAP_DEBUG_ANY,
187                         "monitor_subsys_rww_init: "
188                         "unable to add entry 'cn=Write,%s'\n",
189                         monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
190 #endif
191                 return( -1 );
192         }
193         
194         e_tmp = e;
195
196         mp = ( struct monitorentrypriv * )e_conn->e_private;
197         mp->mp_children = e_tmp;
198
199         monitor_cache_release( mi, e_conn );
200
201         return( 0 );
202 }
203
204 int
205 monitor_subsys_rww_update(
206         Operation               *op,
207         Entry                   *e
208 )
209 {
210         struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
211         Connection              *c;
212         int                     connindex;
213         long                    nconns, nwritewaiters, nreadwaiters;
214
215 #define RWW_NONE        0
216 #define RWW_READ        1
217 #define RWW_WRITE       2
218         int                     type = RWW_NONE;
219         
220         Attribute               *a;
221         char                    buf[] = "+9223372036854775807L";
222         long                    num = 0;
223
224         assert( mi != NULL );
225         assert( e != NULL );
226         
227         if ( strncasecmp( e->e_ndn, "cn=read", 
228                                 sizeof("cn=read")-1 ) == 0 ) {
229                 type = RWW_READ;
230
231         } else if ( strncasecmp( e->e_ndn, "cn=write", 
232                                 sizeof("cn=write")-1 ) == 0 ) {
233                 type = RWW_WRITE;
234
235         } else {
236                 return( 0 );
237         }
238
239         nconns = nwritewaiters = nreadwaiters = 0;
240         for ( c = connection_first( &connindex );
241                         c != NULL;
242                         c = connection_next( c, &connindex ), nconns++ ) {
243                 if ( c->c_writewaiter ) {
244                         nwritewaiters++;
245                 }
246                 if ( c->c_currentber != NULL ) {
247                         nreadwaiters++;
248                 }
249         }
250         connection_done(c);
251
252         switch ( type ) {
253         case RWW_READ:
254                 num = nreadwaiters;
255                 break;
256
257         case RWW_WRITE:
258                 num = nwritewaiters;
259                 break;
260
261         default:
262                 assert( 0 );
263         }
264
265         snprintf( buf, sizeof( buf ), "%ld", num );
266
267         a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter );
268         assert( a );
269         free( a->a_vals[0].bv_val );
270         ber_str2bv( buf, 0, 1, &a->a_vals[ 0 ] );
271
272         return( 0 );
273 }
274