diff options
Diffstat (limited to 'servers/slapd/back-monitor/rww.c')
-rw-r--r-- | servers/slapd/back-monitor/rww.c | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/servers/slapd/back-monitor/rww.c b/servers/slapd/back-monitor/rww.c new file mode 100644 index 0000000..f99c4c1 --- /dev/null +++ b/servers/slapd/back-monitor/rww.c @@ -0,0 +1,232 @@ +/* readw.c - deal with read waiters subsystem */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2001-2018 The OpenLDAP Foundation. + * Portions Copyright 2001-2003 Pierangelo Masarati. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * <http://www.OpenLDAP.org/license.html>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Pierangelo Masarati for inclusion + * in OpenLDAP Software. + */ + +#include "portable.h" + +#include <stdio.h> +#include <ac/string.h> + +#include "slap.h" +#include "lutil.h" +#include "back-monitor.h" + +static int +monitor_subsys_rww_destroy( + BackendDB *be, + monitor_subsys_t *ms ); + +static int +monitor_subsys_rww_update( + Operation *op, + SlapReply *rs, + Entry *e ); + +enum { + MONITOR_RWW_READ = 0, + MONITOR_RWW_WRITE, + + MONITOR_RWW_LAST +}; + +static struct monitor_rww_t { + struct berval rdn; + struct berval nrdn; +} monitor_rww[] = { + { BER_BVC("cn=Read"), BER_BVNULL }, + { BER_BVC("cn=Write"), BER_BVNULL }, + { BER_BVNULL, BER_BVNULL } +}; + +int +monitor_subsys_rww_init( + BackendDB *be, + monitor_subsys_t *ms ) +{ + monitor_info_t *mi; + + Entry **ep, *e_conn; + monitor_entry_t *mp; + int i; + + assert( be != NULL ); + + ms->mss_destroy = monitor_subsys_rww_destroy; + ms->mss_update = monitor_subsys_rww_update; + + mi = ( monitor_info_t * )be->be_private; + + if ( monitor_cache_get( mi, &ms->mss_ndn, &e_conn ) ) { + Debug( LDAP_DEBUG_ANY, + "monitor_subsys_rww_init: " + "unable to get entry \"%s\"\n", + ms->mss_ndn.bv_val, 0, 0 ); + return( -1 ); + } + + mp = ( monitor_entry_t * )e_conn->e_private; + mp->mp_children = NULL; + ep = &mp->mp_children; + + for ( i = 0; i < MONITOR_RWW_LAST; i++ ) { + struct berval nrdn, bv; + Entry *e; + + e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &monitor_rww[i].rdn, + mi->mi_oc_monitorCounterObject, NULL, NULL ); + if ( e == NULL ) { + Debug( LDAP_DEBUG_ANY, + "monitor_subsys_rww_init: " + "unable to create entry \"cn=Read,%s\"\n", + ms->mss_ndn.bv_val, 0, 0 ); + return( -1 ); + } + + /* steal normalized RDN */ + dnRdn( &e->e_nname, &nrdn ); + ber_dupbv( &monitor_rww[ i ].nrdn, &nrdn ); + + BER_BVSTR( &bv, "0" ); + attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL ); + + mp = monitor_entrypriv_create(); + if ( mp == NULL ) { + return -1; + } + e->e_private = ( void * )mp; + mp->mp_info = ms; + mp->mp_flags = ms->mss_flags \ + | MONITOR_F_SUB | MONITOR_F_PERSISTENT; + + if ( monitor_cache_add( mi, e ) ) { + Debug( LDAP_DEBUG_ANY, + "monitor_subsys_rww_init: " + "unable to add entry \"%s,%s\"\n", + monitor_rww[ i ].rdn.bv_val, + ms->mss_ndn.bv_val, 0 ); + return( -1 ); + } + + *ep = e; + ep = &mp->mp_next; + } + + monitor_cache_release( mi, e_conn ); + + return( 0 ); +} + +static int +monitor_subsys_rww_destroy( + BackendDB *be, + monitor_subsys_t *ms ) +{ + int i; + + for ( i = 0; i < MONITOR_RWW_LAST; i++ ) { + ber_memfree_x( monitor_rww[ i ].nrdn.bv_val, NULL ); + } + + return 0; +} + +static int +monitor_subsys_rww_update( + Operation *op, + SlapReply *rs, + Entry *e ) +{ + monitor_info_t *mi = (monitor_info_t *)op->o_bd->be_private; + Connection *c; + ber_socket_t connindex; + long nconns, nwritewaiters, nreadwaiters; + + int i; + struct berval nrdn; + + Attribute *a; + char buf[LDAP_PVT_INTTYPE_CHARS(long)]; + long num = 0; + ber_len_t len; + + assert( mi != NULL ); + assert( e != NULL ); + + dnRdn( &e->e_nname, &nrdn ); + + for ( i = 0; !BER_BVISNULL( &monitor_rww[ i ].nrdn ); i++ ) { + if ( dn_match( &nrdn, &monitor_rww[ i ].nrdn ) ) { + break; + } + } + + if ( i == MONITOR_RWW_LAST ) { + return SLAP_CB_CONTINUE; + } + + nconns = nwritewaiters = nreadwaiters = 0; + for ( c = connection_first( &connindex ); + c != NULL; + c = connection_next( c, &connindex ), nconns++ ) + { + if ( c->c_writewaiter ) { + nwritewaiters++; + } + + /* FIXME: ?!? */ + if ( c->c_currentber != NULL ) { + nreadwaiters++; + } + } + connection_done(c); + + switch ( i ) { + case MONITOR_RWW_READ: + num = nreadwaiters; + break; + + case MONITOR_RWW_WRITE: + num = nwritewaiters; + break; + + default: + assert( 0 ); + } + + snprintf( buf, sizeof( buf ), "%ld", num ); + + a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter ); + assert( a != NULL ); + len = strlen( buf ); + if ( len > a->a_vals[ 0 ].bv_len ) { + a->a_vals[ 0 ].bv_val = ber_memrealloc( a->a_vals[ 0 ].bv_val, len + 1 ); + if ( BER_BVISNULL( &a->a_vals[ 0 ] ) ) { + BER_BVZERO( &a->a_vals[ 0 ] ); + return SLAP_CB_CONTINUE; + } + } + AC_MEMCPY( a->a_vals[ 0 ].bv_val, buf, len + 1 ); + a->a_vals[ 0 ].bv_len = len; + + /* FIXME: touch modifyTimestamp? */ + + return SLAP_CB_CONTINUE; +} + |