Back to index

openldap  2.4.31
rww.c
Go to the documentation of this file.
00001 /* readw.c - deal with read waiters subsystem */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 2001-2012 The OpenLDAP Foundation.
00006  * Portions Copyright 2001-2003 Pierangelo Masarati.
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted only as authorized by the OpenLDAP
00011  * Public License.
00012  *
00013  * A copy of this license is available in file LICENSE in the
00014  * top-level directory of the distribution or, alternatively, at
00015  * <http://www.OpenLDAP.org/license.html>.
00016  */
00017 /* ACKNOWLEDGEMENTS:
00018  * This work was initially developed by Pierangelo Masarati for inclusion
00019  * in OpenLDAP Software.
00020  */
00021 
00022 #include "portable.h"
00023 
00024 #include <stdio.h>
00025 #include <ac/string.h>
00026 
00027 #include "slap.h"
00028 #include "lutil.h"
00029 #include "back-monitor.h"
00030 
00031 static int
00032 monitor_subsys_rww_destroy(
00033        BackendDB            *be,
00034        monitor_subsys_t     *ms );
00035 
00036 static int
00037 monitor_subsys_rww_update(
00038        Operation            *op,
00039        SlapReply            *rs,
00040        Entry                   *e );
00041 
00042 enum {
00043        MONITOR_RWW_READ = 0,
00044        MONITOR_RWW_WRITE,
00045 
00046        MONITOR_RWW_LAST
00047 };
00048 
00049 static struct monitor_rww_t {
00050        struct berval rdn;
00051        struct berval nrdn;
00052 } monitor_rww[] = {
00053        { BER_BVC("cn=Read"),              BER_BVNULL },
00054        { BER_BVC("cn=Write"),             BER_BVNULL },
00055        { BER_BVNULL,               BER_BVNULL }
00056 };
00057 
00058 int
00059 monitor_subsys_rww_init(
00060        BackendDB            *be,
00061        monitor_subsys_t     *ms )
00062 {
00063        monitor_info_t       *mi;
00064        
00065        Entry         **ep, *e_conn;
00066        monitor_entry_t      *mp;
00067        int                  i;
00068 
00069        assert( be != NULL );
00070 
00071        ms->mss_destroy = monitor_subsys_rww_destroy;
00072        ms->mss_update = monitor_subsys_rww_update;
00073 
00074        mi = ( monitor_info_t * )be->be_private;
00075 
00076        if ( monitor_cache_get( mi, &ms->mss_ndn, &e_conn ) ) {
00077               Debug( LDAP_DEBUG_ANY,
00078                      "monitor_subsys_rww_init: "
00079                      "unable to get entry \"%s\"\n",
00080                      ms->mss_ndn.bv_val, 0, 0 );
00081               return( -1 );
00082        }
00083 
00084        mp = ( monitor_entry_t * )e_conn->e_private;
00085        mp->mp_children = NULL;
00086        ep = &mp->mp_children;
00087 
00088        for ( i = 0; i < MONITOR_RWW_LAST; i++ ) {
00089               struct berval        nrdn, bv;
00090               Entry                *e;
00091               
00092               e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &monitor_rww[i].rdn,
00093                      mi->mi_oc_monitorCounterObject, mi, NULL, NULL );
00094               if ( e == NULL ) {
00095                      Debug( LDAP_DEBUG_ANY,
00096                             "monitor_subsys_rww_init: "
00097                             "unable to create entry \"cn=Read,%s\"\n",
00098                             ms->mss_ndn.bv_val, 0, 0 );
00099                      return( -1 );
00100               }
00101 
00102               /* steal normalized RDN */
00103               dnRdn( &e->e_nname, &nrdn );
00104               ber_dupbv( &monitor_rww[ i ].nrdn, &nrdn );
00105        
00106               BER_BVSTR( &bv, "0" );
00107               attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
00108        
00109               mp = monitor_entrypriv_create();
00110               if ( mp == NULL ) {
00111                      return -1;
00112               }
00113               e->e_private = ( void * )mp;
00114               mp->mp_info = ms;
00115               mp->mp_flags = ms->mss_flags \
00116                      | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
00117 
00118               if ( monitor_cache_add( mi, e ) ) {
00119                      Debug( LDAP_DEBUG_ANY,
00120                             "monitor_subsys_rww_init: "
00121                             "unable to add entry \"%s,%s\"\n",
00122                             monitor_rww[ i ].rdn.bv_val,
00123                             ms->mss_ndn.bv_val, 0 );
00124                      return( -1 );
00125               }
00126        
00127               *ep = e;
00128               ep = &mp->mp_next;
00129        }
00130 
00131        monitor_cache_release( mi, e_conn );
00132 
00133        return( 0 );
00134 }
00135 
00136 static int
00137 monitor_subsys_rww_destroy(
00138        BackendDB            *be,
00139        monitor_subsys_t     *ms )
00140 {
00141        int           i;
00142 
00143        for ( i = 0; i < MONITOR_RWW_LAST; i++ ) {
00144               ber_memfree_x( monitor_rww[ i ].nrdn.bv_val, NULL );
00145        }
00146 
00147        return 0;
00148 }
00149 
00150 static int
00151 monitor_subsys_rww_update(
00152        Operation            *op,
00153        SlapReply            *rs,
00154        Entry                   *e )
00155 {
00156        monitor_info_t *mi = (monitor_info_t *)op->o_bd->be_private;
00157        Connection    *c;
00158        ber_socket_t  connindex;
00159        long          nconns, nwritewaiters, nreadwaiters;
00160 
00161        int           i;
00162        struct berval nrdn;
00163 
00164        Attribute     *a;
00165        char          buf[LDAP_PVT_INTTYPE_CHARS(long)];
00166        long          num = 0;
00167        ber_len_t     len;
00168 
00169        assert( mi != NULL );
00170        assert( e != NULL );
00171 
00172        dnRdn( &e->e_nname, &nrdn );
00173 
00174        for ( i = 0; !BER_BVISNULL( &monitor_rww[ i ].nrdn ); i++ ) {
00175               if ( dn_match( &nrdn, &monitor_rww[ i ].nrdn ) ) {
00176                      break;
00177               }
00178        }
00179 
00180        if ( i == MONITOR_RWW_LAST ) {
00181               return SLAP_CB_CONTINUE;
00182        }
00183 
00184        nconns = nwritewaiters = nreadwaiters = 0;
00185        for ( c = connection_first( &connindex );
00186                      c != NULL;
00187                      c = connection_next( c, &connindex ), nconns++ )
00188        {
00189               if ( c->c_writewaiter ) {
00190                      nwritewaiters++;
00191               }
00192 
00193               /* FIXME: ?!? */
00194               if ( c->c_currentber != NULL ) {
00195                      nreadwaiters++;
00196               }
00197        }
00198        connection_done(c);
00199 
00200        switch ( i ) {
00201        case MONITOR_RWW_READ:
00202               num = nreadwaiters;
00203               break;
00204 
00205        case MONITOR_RWW_WRITE:
00206               num = nwritewaiters;
00207               break;
00208 
00209        default:
00210               assert( 0 );
00211        }
00212 
00213        snprintf( buf, sizeof( buf ), "%ld", num );
00214 
00215        a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter );
00216        assert( a != NULL );
00217        len = strlen( buf );
00218        if ( len > a->a_vals[ 0 ].bv_len ) {
00219               a->a_vals[ 0 ].bv_val = ber_memrealloc( a->a_vals[ 0 ].bv_val, len + 1 );
00220               if ( BER_BVISNULL( &a->a_vals[ 0 ] ) ) {
00221                      BER_BVZERO( &a->a_vals[ 0 ] );
00222                      return SLAP_CB_CONTINUE;
00223               }
00224        }
00225        AC_MEMCPY( a->a_vals[ 0 ].bv_val, buf, len + 1 );
00226        a->a_vals[ 0 ].bv_len = len;
00227 
00228        /* FIXME: touch modifyTimestamp? */
00229 
00230        return SLAP_CB_CONTINUE;
00231 }
00232