diff options
Diffstat (limited to 'ldap/servers/slapd')
25 files changed, 640 insertions, 476 deletions
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c index 0e2cc9b4..fb162cfe 100644 --- a/ldap/servers/slapd/add.c +++ b/ldap/servers/slapd/add.c @@ -93,7 +93,7 @@ do_add( Slapi_PBlock *pb ) ber = operation->o_ber; /* count the add request */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsAddEntryOps); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAddEntryOps); /* * Parse the add request. It looks like this: diff --git a/ldap/servers/slapd/agtmmap.c b/ldap/servers/slapd/agtmmap.c index db04273a..9be091b2 100644 --- a/ldap/servers/slapd/agtmmap.c +++ b/ldap/servers/slapd/agtmmap.c @@ -87,8 +87,8 @@ agt_mmap_context_t mmap_tbl[2] = { {AGT_MAP_UNINIT, NULL, (caddr_t) -1, NULL}, * mode -> Must be one of O_RDONLY / O_RDWR. * O_RDWR creates the file if it does not exist. * Outputs: - * hdl -> Opaque handle to the mapped file. Should be passed - * Passed to a subsequent agt_mupdate_stats() or + * hdl -> Opaque handle to the mapped file. Should be + * passed to a subsequent agt_mupdate_stats() or * agt_mread_stats() or agt_mclose_stats() call. * Return Values: * Returns 0 on successfully doing the memmap or error codes diff --git a/ldap/servers/slapd/agtmmap.h b/ldap/servers/slapd/agtmmap.h index e329324d..14f622a3 100644 --- a/ldap/servers/slapd/agtmmap.h +++ b/ldap/servers/slapd/agtmmap.h @@ -123,32 +123,32 @@ struct ops_stats_t{ /* * Ops Table attributes */ - PRUint32 dsAnonymousBinds; - PRUint32 dsUnAuthBinds; - PRUint32 dsSimpleAuthBinds; - PRUint32 dsStrongAuthBinds; - PRUint32 dsBindSecurityErrors; - PRUint32 dsInOps; - PRUint32 dsReadOps; - PRUint32 dsCompareOps; - PRUint32 dsAddEntryOps; - PRUint32 dsRemoveEntryOps; - PRUint32 dsModifyEntryOps; - PRUint32 dsModifyRDNOps; - PRUint32 dsListOps; - PRUint32 dsSearchOps; - PRUint32 dsOneLevelSearchOps; - PRUint32 dsWholeSubtreeSearchOps; - PRUint32 dsReferrals; - PRUint32 dsChainings; - PRUint32 dsSecurityErrors; - PRUint32 dsErrors; - PRUint32 dsConnections; /* Number of currently connected clients */ - PRUint32 dsConnectionSeq; /* Monotonically increasing number bumped on each new conn est */ - PRUint32 dsBytesRecv; /* Count of bytes read from clients */ - PRUint32 dsBytesSent; /* Count of bytes sent to clients */ - PRUint32 dsEntriesReturned; /* Number of entries returned by the server */ - PRUint32 dsReferralsReturned; /* Number of entries returned by the server */ + PRUint64 dsAnonymousBinds; + PRUint64 dsUnAuthBinds; + PRUint64 dsSimpleAuthBinds; + PRUint64 dsStrongAuthBinds; + PRUint64 dsBindSecurityErrors; + PRUint64 dsInOps; + PRUint64 dsReadOps; + PRUint64 dsCompareOps; + PRUint64 dsAddEntryOps; + PRUint64 dsRemoveEntryOps; + PRUint64 dsModifyEntryOps; + PRUint64 dsModifyRDNOps; + PRUint64 dsListOps; + PRUint64 dsSearchOps; + PRUint64 dsOneLevelSearchOps; + PRUint64 dsWholeSubtreeSearchOps; + PRUint64 dsReferrals; + PRUint64 dsChainings; + PRUint64 dsSecurityErrors; + PRUint64 dsErrors; + PRUint64 dsConnections; /* Number of currently connected clients */ + PRUint64 dsConnectionSeq; /* Monotonically increasing number bumped on each new conn est */ + PRUint64 dsBytesRecv; /* Count of bytes read from clients */ + PRUint64 dsBytesSent; /* Count of bytes sent to clients */ + PRUint64 dsEntriesReturned; /* Number of entries returned by the server */ + PRUint64 dsReferralsReturned; /* Number of entries returned by the server */ }; struct entries_stats_t @@ -156,11 +156,11 @@ struct entries_stats_t /* * Entries Table Attributes */ - PRUint32 dsMasterEntries; - PRUint32 dsCopyEntries; - PRUint32 dsCacheEntries; - PRUint32 dsCacheHits; - PRUint32 dsSlaveHits; + PRUint64 dsMasterEntries; + PRUint64 dsCopyEntries; + PRUint64 dsCacheEntries; + PRUint64 dsCacheHits; + PRUint64 dsSlaveHits; }; struct int_stats_t diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h index 4c002991..078aea6b 100644 --- a/ldap/servers/slapd/back-ldbm/back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h @@ -339,7 +339,7 @@ struct backentry { /* for the in-core cache of entries */ struct cache { size_t c_maxsize; /* max size in bytes */ - size_t c_cursize; /* size in bytes */ + Slapi_Counter *c_cursize; /* size in bytes */ long c_maxentries; /* max entries allowed (-1: no limit) */ long c_curentries; /* current # entries in cache */ Hashtable *c_dntable; @@ -347,8 +347,8 @@ struct cache { #ifdef UUIDCACHE_ON Hashtable *c_uuidtable; #endif - u_long c_hits; /* for analysis of hits/misses */ - u_long c_tries; + Slapi_Counter *c_hits; /* for analysis of hits/misses */ + Slapi_Counter *c_tries; struct backentry *c_lruhead; /* add entries here */ struct backentry *c_lrutail; /* remove entries here */ PRLock *c_mutex; /* lock for cache operations */ diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c index 90fc8149..38ca6aab 100644 --- a/ldap/servers/slapd/back-ldbm/cache.c +++ b/ldap/servers/slapd/back-ldbm/cache.c @@ -405,8 +405,15 @@ int cache_init(struct cache *cache, size_t maxsize, long maxentries) LDAPDebug(LDAP_DEBUG_TRACE, "=> cache_init\n", 0, 0, 0); cache->c_maxsize = maxsize; cache->c_maxentries = maxentries; - cache->c_cursize = cache->c_curentries = 0; - cache->c_hits = cache->c_tries = 0; + cache->c_cursize = slapi_counter_new(); + cache->c_curentries = 0; + if (config_get_slapi_counters()) { + cache->c_hits = slapi_counter_new(); + cache->c_tries = slapi_counter_new(); + } else { + cache->c_hits = NULL; + cache->c_tries = NULL; + } cache->c_lruhead = cache->c_lrutail = NULL; cache_make_hashes(cache); @@ -421,7 +428,7 @@ int cache_init(struct cache *cache, size_t maxsize, long maxentries) } #define CACHE_FULL(cache) \ - (((cache)->c_cursize > (cache)->c_maxsize) || \ + ((slapi_counter_get_value((cache)->c_cursize) > (cache)->c_maxsize) || \ (((cache)->c_maxentries > 0) && \ ((cache)->c_curentries > (cache)->c_maxentries))) @@ -466,7 +473,7 @@ static struct backentry * cache_flush(struct cache *cache) if (e) lru_detach(cache, e); LOG("<= cache_flush (down to %lu entries, %lu bytes)\n", cache->c_curentries, - cache->c_cursize, 0); + slapi_counter_get_value(cache->c_cursize), 0); return e; } @@ -623,16 +630,16 @@ static size_t cache_entry_size(struct backentry *e) * if it ever wants to pull out more info, we might want to change all * these u_long *'s to a struct */ -void cache_get_stats(struct cache *cache, u_long *hits, u_long *tries, +void cache_get_stats(struct cache *cache, PRUint64 *hits, PRUint64 *tries, long *nentries, long *maxentries, size_t *size, size_t *maxsize) { PR_Lock(cache->c_mutex); - if (hits) *hits = cache->c_hits; - if (tries) *tries = cache->c_tries; + if (hits) *hits = slapi_counter_get_value(cache->c_hits); + if (tries) *tries = slapi_counter_get_value(cache->c_tries); if (nentries) *nentries = cache->c_curentries; if (maxentries) *maxentries = cache->c_maxentries; - if (size) *size = cache->c_cursize; + if (size) *size = slapi_counter_get_value(cache->c_cursize); if (maxsize) *maxsize = cache->c_maxsize; PR_Unlock(cache->c_mutex); } @@ -735,10 +742,11 @@ static int cache_remove_int(struct cache *cache, struct backentry *e) if (ret == 0) { /* won't be on the LRU list since it has a refcount on it */ /* adjust cache size */ - cache->c_cursize -= e->size; + slapi_counter_subtract(cache->c_cursize, e->size); cache->c_curentries--; LOG("<= cache_remove (size %lu): cache now %lu entries, %lu bytes\n", - e->size, cache->c_curentries, cache->c_cursize); + e->size, cache->c_curentries, + slapi_counter_get_value(cache->c_cursize)); } /* mark for deletion (will be erased when refcount drops to zero) */ @@ -775,7 +783,7 @@ int cache_remove(struct cache *cache, struct backentry *e) int cache_replace(struct cache *cache, struct backentry *olde, struct backentry *newe) { - int found; + int found; const char *oldndn; const char *newndn; #ifdef UUIDCACHE_ON @@ -799,31 +807,31 @@ int cache_replace(struct cache *cache, struct backentry *olde, PR_Lock(cache->c_mutex); /* - * First, remove the old entry from all the hashtables. - * If the old entry is in cache but not in at least one of the - * cache tables, operation error - */ - if ( (olde->ep_state & ENTRY_STATE_NOTINCACHE) == 0 ) { - - found = remove_hash(cache->c_dntable, (void *)oldndn, strlen(oldndn)); - found &= remove_hash(cache->c_idtable, &(olde->ep_id), sizeof(ID)); + * First, remove the old entry from all the hashtables. + * If the old entry is in cache but not in at least one of the + * cache tables, operation error + */ + if ( (olde->ep_state & ENTRY_STATE_NOTINCACHE) == 0 ) { + + found = remove_hash(cache->c_dntable, (void *)oldndn, strlen(oldndn)); + found &= remove_hash(cache->c_idtable, &(olde->ep_id), sizeof(ID)); #ifdef UUIDCACHE_ON - found &= remove_hash(cache->c_uuidtable, (void *)olduuid, strlen(olduuid)); + found &= remove_hash(cache->c_uuidtable, (void *)olduuid, strlen(olduuid)); #endif - if (!found) { - LOG("cache replace: cache index tables out of sync\n", 0, 0, 0); - PR_Unlock(cache->c_mutex); - return 1; - } - } + if (!found) { + LOG("cache replace: cache index tables out of sync\n", 0, 0, 0); + PR_Unlock(cache->c_mutex); + return 1; + } + } if (! entry_same_dn(newe, (void *)oldndn) && - (newe->ep_state & ENTRY_STATE_NOTINCACHE) == 0) { + (newe->ep_state & ENTRY_STATE_NOTINCACHE) == 0) { /* if we're doing a modrdn, the new entry can be in the dn table * already, so we need to remove that too. */ if (remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn))) { - cache->c_cursize -= newe->size; + slapi_counter_subtract(cache->c_cursize, newe->size); cache->c_curentries--; LOG("cache replace remove entry size %lu\n", newe->size, 0, 0); } @@ -857,12 +865,12 @@ int cache_replace(struct cache *cache, struct backentry *olde, /* adjust cache meta info */ newe->ep_refcnt = 1; newe->size = cache_entry_size(newe); - cache->c_cursize += (newe->size - olde->size); + slapi_counter_add(cache->c_cursize, newe->size - olde->size); olde->ep_state = ENTRY_STATE_DELETED; newe->ep_state = 0; PR_Unlock(cache->c_mutex); LOG("<= cache_replace OK, cache size now %lu cache count now %ld\n", - cache->c_cursize, cache->c_curentries, 0); + slapi_counter_get_value(cache->c_cursize), cache->c_curentries, 0); return 0; } @@ -930,11 +938,13 @@ struct backentry *cache_find_dn(struct cache *cache, const char *dn, unsigned lo } if (e->ep_refcnt == 0) lru_delete(cache, e); + PR_Unlock(cache->c_mutex); e->ep_refcnt++; - cache->c_hits++; + slapi_counter_increment(cache->c_hits); + } else { + PR_Unlock(cache->c_mutex); } - cache->c_tries++; - PR_Unlock(cache->c_mutex); + slapi_counter_increment(cache->c_tries); LOG("<= cache_find_dn (%sFOUND)\n", e ? "" : "NOT ", 0, 0); return e; @@ -959,11 +969,13 @@ struct backentry *cache_find_id(struct cache *cache, ID id) } if (e->ep_refcnt == 0) lru_delete(cache, e); + PR_Unlock(cache->c_mutex); e->ep_refcnt++; - cache->c_hits++; + slapi_counter_increment(cache->c_hits); + } else { + PR_Unlock(cache->c_mutex); } - cache->c_tries++; - PR_Unlock(cache->c_mutex); + slapi_counter_increment(cache->c_tries); LOG("<= cache_find_id (%sFOUND)\n", e ? "" : "NOT ", 0, 0); return e; @@ -988,11 +1000,13 @@ struct backentry *cache_find_uuid(struct cache *cache, const char *uuid) } if (e->ep_refcnt == 0) lru_delete(cache, e); + PR_Unlock(cache->c_mutex); e->ep_refcnt++; - cache->c_hits++; + slapi_counter_increment(cache->c_hits); + } else { + PR_Unlock(cache->c_mutex); } - cache->c_tries++; - PR_Unlock(cache->c_mutex); + slapi_counter_increment(cache->c_tries); LOG("<= cache_find_uuid (%sFOUND)\n", e ? "" : "NOT ", 0, 0); return e; @@ -1126,7 +1140,7 @@ static int cache_add_int(struct cache *cache, struct backentry *e, int state, 0, 0); remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn)); remove_hash(cache->c_idtable, &(e->ep_id), sizeof(ID)); - e->ep_state |= ENTRY_STATE_NOTINCACHE; + e->ep_state |= ENTRY_STATE_NOTINCACHE; PR_Unlock(cache->c_mutex); return -1; } @@ -1140,11 +1154,11 @@ static int cache_add_int(struct cache *cache, struct backentry *e, int state, e->ep_refcnt = 1; e->size = cache_entry_size(e); - cache->c_cursize += e->size; + slapi_counter_add(cache->c_cursize, e->size); cache->c_curentries++; /* don't add to lru since refcnt = 1 */ LOG("added entry of size %lu -> total now %lu out of max %lu\n", - e->size, cache->c_cursize, cache->c_maxsize); + e->size, slapi_counter_get_value(cache->c_cursize), cache->c_maxsize); if (cache->c_maxentries >= 0) { LOG(" total entries %ld out of %ld\n", cache->c_curentries, cache->c_maxentries, 0); diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c index ccf172bd..152ab791 100644 --- a/ldap/servers/slapd/bind.c +++ b/ldap/servers/slapd/bind.c @@ -345,7 +345,7 @@ do_bind( Slapi_PBlock *pb ) * All SASL auth methods are categorized as strong binds, * although they are not necessarily stronger than simple. */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsStrongAuthBinds); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsStrongAuthBinds); if ( saslmech == NULL || *saslmech == '\0' ) { send_ldap_result( pb, LDAP_AUTH_METHOD_NOT_SUPPORTED, NULL, "SASL mechanism absent", 0, NULL ); @@ -423,13 +423,13 @@ do_bind( Slapi_PBlock *pb ) } break; case LDAP_AUTH_SIMPLE: - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsSimpleAuthBinds); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsSimpleAuthBinds); /* accept null binds */ if (dn == NULL || *dn == '\0') { - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds); /* by definition its anonymous is also UnAuthenticated so increment that counter */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds); /* call preop plugins */ if (plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) == 0){ @@ -455,7 +455,7 @@ do_bind( Slapi_PBlock *pb ) if ( isroot && method == LDAP_AUTH_SIMPLE ) { if ( cred.bv_len == 0 ) { /* unauthenticated bind */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds); } else { /* a passwd was supplied -- check it */ @@ -473,7 +473,7 @@ do_bind( Slapi_PBlock *pb ) send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL ); /* increment BindSecurityErrorcount */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors); value_done(&cv); goto free_and_return; } @@ -617,11 +617,11 @@ do_bind( Slapi_PBlock *pb ) if(cred.bv_len == 0) { /* its an UnAuthenticated Bind, DN specified but no pw */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds); }else{ /* password must have been invalid */ /* increment BindSecurityError count */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors); } } diff --git a/ldap/servers/slapd/compare.c b/ldap/servers/slapd/compare.c index 90f6afc8..f33d27af 100644 --- a/ldap/servers/slapd/compare.c +++ b/ldap/servers/slapd/compare.c @@ -77,7 +77,7 @@ do_compare( Slapi_PBlock *pb ) LDAPDebug( LDAP_DEBUG_TRACE, "do_compare\n", 0, 0, 0 ); /* count the compare request */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsCompareOps); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsCompareOps); /* have to init this here so we can "done" it below if we short circuit */ slapi_sdn_init(&sdn); diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c index 6584eb86..5ea4f778 100644 --- a/ldap/servers/slapd/connection.c +++ b/ldap/servers/slapd/connection.c @@ -220,8 +220,8 @@ connection_reset(Connection* conn, int ns, PRNetAddr * from, int fromLen, int is conn->c_connid = slapi_counter_increment(num_conns); if (! in_referral_mode) { - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsConnectionSeq); - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsConnections); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsConnectionSeq); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsConnections); } /* @@ -650,7 +650,7 @@ static int add_to_select_set(Connection *conn); static void inc_op_count(Connection* conn) { PR_AtomicIncrement(&conn->c_opscompleted); - PR_AtomicIncrement(&ops_completed); + slapi_counter_increment(ops_completed); } static int connection_increment_reference(Connection *conn) @@ -828,8 +828,8 @@ static int process_operation(Connection *conn, Operation *op) slapi_pblock_set (pb, SLAPI_DESTROY_CONTENT, &destroy_content); if (! config_check_referral_mode()) { - PR_AtomicIncrement(&ops_initiated); - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsInOps); + slapi_counter_increment(ops_initiated); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsInOps); } if ( (tag = ber_get_int( op->o_ber, &msgid )) @@ -2064,8 +2064,8 @@ connection_threadmain() connection_make_new_pb(&pb,conn); PR_Unlock(conn->c_mutex); if (! config_check_referral_mode()) { - PR_AtomicIncrement(&ops_initiated); - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsInOps); + slapi_counter_increment(ops_initiated); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsInOps); } } /* Once we're here we have a pb */ @@ -2171,7 +2171,7 @@ done: /* number of ops on this connection */ PR_AtomicIncrement(&conn->c_opscompleted); /* total number of ops for the server */ - PR_AtomicIncrement(&ops_completed); + slapi_counter_increment(ops_completed); /* If this op isn't a persistent search, remove it */ if ( !( pb->pb_op->o_flags & OP_FLAG_PS )) { /* delete from connection operation queue & decr refcnt */ @@ -2247,8 +2247,8 @@ connection_activity(Connection *conn) PR_Unlock( op_thread_lock ); if (! config_check_referral_mode()) { - PR_AtomicIncrement(&ops_initiated); - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsInOps); + slapi_counter_increment(ops_initiated); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsInOps); } return 0; } @@ -2567,7 +2567,7 @@ disconnect_server_nomutex( Connection *conn, PRUint64 opconnid, int opid, PRErro } if (! config_check_referral_mode()) { - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsConnections); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsConnections); } conn->c_gettingber = 0; diff --git a/ldap/servers/slapd/defbackend.c b/ldap/servers/slapd/defbackend.c index bb87cac4..dd948d07 100644 --- a/ldap/servers/slapd/defbackend.c +++ b/ldap/servers/slapd/defbackend.c @@ -216,7 +216,7 @@ defbackend_bind( Slapi_PBlock *pb ) slapi_pblock_get( pb, SLAPI_BIND_METHOD, &method ); slapi_pblock_get( pb, SLAPI_BIND_CREDENTIALS, &cred ); if ( method == LDAP_AUTH_SIMPLE && cred->bv_len == 0 ) { - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds); rc = SLAPI_BIND_ANONYMOUS; } else { send_nobackend_ldap_result( pb ); diff --git a/ldap/servers/slapd/delete.c b/ldap/servers/slapd/delete.c index 39096d79..3db5f552 100644 --- a/ldap/servers/slapd/delete.c +++ b/ldap/servers/slapd/delete.c @@ -80,7 +80,7 @@ do_delete( Slapi_PBlock *pb ) ber = operation->o_ber; /* count the delete request */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsRemoveEntryOps); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsRemoveEntryOps); /* * Parse the delete request. It looks like this: diff --git a/ldap/servers/slapd/fe.h b/ldap/servers/slapd/fe.h index b3e62961..ddc85b66 100644 --- a/ldap/servers/slapd/fe.h +++ b/ldap/servers/slapd/fe.h @@ -56,9 +56,8 @@ extern __declspec(dllimport) int slapd_ldap_debug; #endif /* DONT_DECLARE_SLAPD_LDAP_DEBUG */ #endif #endif -extern PRInt32 ops_initiated; -extern PRInt32 ops_completed; -extern PRLock *ops_mutex; +extern Slapi_Counter *ops_initiated; +extern Slapi_Counter *ops_completed; extern PRThread *listener_tid; extern PRThread *listener_tid; extern Slapi_Counter *num_conns; diff --git a/ldap/servers/slapd/globals.c b/ldap/servers/slapd/globals.c index c57a89ca..3be43127 100644 --- a/ldap/servers/slapd/globals.c +++ b/ldap/servers/slapd/globals.c @@ -88,9 +88,8 @@ Slapi_PBlock *repl_pb = NULL; /* * global variables that need mutex protection */ -PRInt32 ops_initiated; -PRInt32 ops_completed; -PRLock *ops_mutex; +Slapi_Counter *ops_initiated; +Slapi_Counter *ops_completed; Slapi_Counter *num_conns; @@ -171,4 +170,17 @@ set_entry_points() sep->sep_slapd_ssl_init2 = (caddr_t)slapd_ssl_init2; set_dll_entry_points( sep ); + /* To apply the nsslapd-counters config value properly, + these values are initialized here after config file is read */ + if (config_get_slapi_counters()) { + ops_initiated = slapi_counter_new(); + ops_completed = slapi_counter_new(); + g_set_num_entries_sent( slapi_counter_new() ); + g_set_num_bytes_sent( slapi_counter_new() ); + } else { + ops_initiated = NULL; + ops_completed = NULL; + g_set_num_entries_sent( NULL ); + g_set_num_bytes_sent( NULL ); + } } diff --git a/ldap/servers/slapd/init.c b/ldap/servers/slapd/init.c index 0fa2e11c..174e8ca6 100644 --- a/ldap/servers/slapd/init.c +++ b/ldap/servers/slapd/init.c @@ -73,16 +73,12 @@ slapd_init() /* We don't worry about free'ing this stuff * since the only time we want to do that is when * the process is exiting. */ - ops_mutex = PR_NewLock(); num_conns = slapi_counter_new(); - g_set_num_sent_mutex( PR_NewLock() ); g_set_current_conn_count_mutex( PR_NewLock() ); slapd_re_init(); - if ( ops_mutex == NULL || - g_get_num_sent_mutex() == NULL || - g_get_current_conn_count_mutex() == NULL ) + if ( g_get_current_conn_count_mutex() == NULL ) { LDAPDebug( LDAP_DEBUG_ANY, "init: PR_NewLock failed\n", 0, 0, 0 ); diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c index dd2275b0..9c58d06e 100644 --- a/ldap/servers/slapd/libglobs.c +++ b/ldap/servers/slapd/libglobs.c @@ -488,6 +488,10 @@ static struct config_get_and_set { NULL, 0, (void**)&global_slapdFrontendConfig.ldapi_auto_dn_suffix, CONFIG_STRING, NULL}, #endif + {CONFIG_SLAPI_COUNTER_ATTRIBUTE, config_set_slapi_counters, + NULL, 0, + (void**)&global_slapdFrontendConfig.slapi_counters, CONFIG_ON_OFF, + config_get_slapi_counters}, {CONFIG_ACCESSLOG_MINFREEDISKSPACE_ATTRIBUTE, NULL, log_set_mindiskspace, SLAPD_ACCESS_LOG, (void**)&global_slapdFrontendConfig.accesslog_minfreespace, CONFIG_INT, NULL}, @@ -836,6 +840,7 @@ FrontendConfig_init () { #if defined(ENABLE_AUTO_DN_SUFFIX) cfg->ldapi_auto_dn_suffix = slapi_ch_strdup("cn=peercred,cn=external,cn=auth"); #endif + cfg->slapi_counters = LDAP_ON; cfg->threadnumber = SLAPD_DEFAULT_MAX_THREADS; cfg->maxthreadsperconn = SLAPD_DEFAULT_MAX_THREADS_PER_CONN; cfg->reservedescriptors = SLAPD_DEFAULT_RESERVE_FDS; @@ -1398,6 +1403,22 @@ int config_set_ldapi_auto_dn_suffix( const char *attrname, char *value, char *er } #endif +/* + * Set nsslapd-counters: on | off to the internal config variable slapi_counters. + * If set to off, slapi_counters is not initialized and the counters are not + * incremented. Note: counters which are necessary for the server's running + * are not disabled. + */ +int config_set_slapi_counters( const char *attrname, char *value, char *errorbuf, int apply ) +{ + int retVal = LDAP_SUCCESS; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + + retVal = config_set_onoff(attrname, value, + &(slapdFrontendConfig->slapi_counters), errorbuf, apply); + + return retVal; +} int config_set_securelistenhost( const char *attrname, char *value, char *errorbuf, int apply ) { @@ -3438,6 +3459,17 @@ char *config_get_ldapi_auto_dn_suffix(){ } #endif +int config_get_slapi_counters() +{ + int retVal; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + CFG_LOCK_READ(slapdFrontendConfig); + retVal = slapdFrontendConfig->slapi_counters; + CFG_UNLOCK_READ(slapdFrontendConfig); + + return retVal; +} + char * config_get_workingdir() { slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); diff --git a/ldap/servers/slapd/libslapd.def b/ldap/servers/slapd/libslapd.def index bda133c7..d48719f1 100644 --- a/ldap/servers/slapd/libslapd.def +++ b/ldap/servers/slapd/libslapd.def @@ -211,8 +211,6 @@ EXPORTS g_set_num_bytes_sent @173 g_get_num_entries_sent @174 g_set_num_entries_sent @175 - g_get_num_sent_mutex @176 - g_set_num_sent_mutex @177 g_get_default_referral @178 g_set_default_referral @179 slapi_ch_bvdup @180 diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c index 3a328cd8..536ae4cc 100644 --- a/ldap/servers/slapd/main.c +++ b/ldap/servers/slapd/main.c @@ -1039,7 +1039,12 @@ main( int argc, char **argv) slapdFrontendConfig->configdir); eq_init(); /* must be done before plugins started */ - snmp_collator_start(); + + /* Start the SNMP collator if counters are enabled. */ + if (config_get_slapi_counters()) { + snmp_collator_start(); + } + ps_init_psearch_system(); /* must come before plugin_startall() */ /* Initailize the mapping tree */ diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c index 9bcce536..895cb108 100644 --- a/ldap/servers/slapd/modify.c +++ b/ldap/servers/slapd/modify.c @@ -138,7 +138,7 @@ do_modify( Slapi_PBlock *pb ) ber = operation->o_ber; /* count the modify request */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsModifyEntryOps); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsModifyEntryOps); /* * Parse the modify request. It looks like this: diff --git a/ldap/servers/slapd/modrdn.c b/ldap/servers/slapd/modrdn.c index 2872ab1d..823f2dd0 100644 --- a/ldap/servers/slapd/modrdn.c +++ b/ldap/servers/slapd/modrdn.c @@ -79,7 +79,7 @@ do_modrdn( Slapi_PBlock *pb ) LDAPDebug( LDAP_DEBUG_TRACE, "do_modrdn\n", 0, 0, 0 ); /* count the modrdn request */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsModifyRDNOps); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsModifyRDNOps); slapi_pblock_get( pb, SLAPI_OPERATION, &operation); ber = operation->o_ber; diff --git a/ldap/servers/slapd/monitor.c b/ldap/servers/slapd/monitor.c index 0f336c39..571e0fd4 100644 --- a/ldap/servers/slapd/monitor.c +++ b/ldap/servers/slapd/monitor.c @@ -93,30 +93,22 @@ monitor_info(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *ret connection_table_as_entry(the_connection_table, e); - PR_Lock( ops_mutex ); - sprintf( buf, "%ld", (long) ops_initiated ); - PR_Unlock( ops_mutex ); + sprintf( buf, "%" PRIu64, slapi_counter_get_value(ops_initiated) ); val.bv_val = buf; val.bv_len = strlen( buf ); attrlist_replace( &e->e_attrs, "opsinitiated", vals ); - PR_Lock( ops_mutex ); - sprintf( buf, "%ld", (long) ops_completed ); - PR_Unlock( ops_mutex ); + sprintf( buf, "%" PRIu64, slapi_counter_get_value(ops_completed) ); val.bv_val = buf; val.bv_len = strlen( buf ); attrlist_replace( &e->e_attrs, "opscompleted", vals ); - PR_Lock( g_get_num_sent_mutex() ); - len = PR_snprintf ( buf, BUFSIZ, "%llu", g_get_num_entries_sent() ); - PR_Unlock( g_get_num_sent_mutex() ); + len = PR_snprintf ( buf, BUFSIZ, "%" PRIu64, g_get_num_entries_sent() ); val.bv_val = buf; val.bv_len = ( unsigned long ) len; attrlist_replace( &e->e_attrs, "entriessent", vals ); - PR_Lock( g_get_num_sent_mutex() ); - len = PR_snprintf ( buf, BUFSIZ, "%llu", g_get_num_bytes_sent() ); - PR_Unlock( g_get_num_sent_mutex() ); + len = PR_snprintf ( buf, BUFSIZ, "%" PRIu64, g_get_num_bytes_sent() ); val.bv_val = buf; val.bv_len = ( unsigned long ) len; attrlist_replace( &e->e_attrs, "bytessent", vals ); diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index 74e382b7..0bfa98ba 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -255,6 +255,7 @@ int config_set_ldapi_search_base_dn( const char *attrname, char *value, char *er #if defined(ENABLE_AUTO_DN_SUFFIX) int config_set_ldapi_auto_dn_suffix( const char *attrname, char *value, char *errorbuf, int apply ); #endif +int config_set_slapi_counters( const char *attrname, char *value, char *errorbuf, int apply ); int config_set_srvtab( const char *attrname, char *value, char *errorbuf, int apply ); int config_set_sizelimit( const char *attrname, char *value, char *errorbuf, int apply ); int config_set_lastmod( const char *attrname, char *value, char *errorbuf, int apply ); @@ -370,6 +371,7 @@ char *config_get_ldapi_search_base_dn(); #if defined(ENABLE_AUTO_DN_SUFFIX) char *config_get_ldapi_auto_dn_suffix(); #endif +int config_get_slapi_counters(); char *config_get_srvtab(); int config_get_sizelimit(); char *config_get_pw_storagescheme(); @@ -821,14 +823,12 @@ void reslimit_cleanup( void ); /* * result.c */ -void g_set_num_entries_sent( PRUint64 val ); +void g_set_num_entries_sent( Slapi_Counter *counter ); PRUint64 g_get_num_entries_sent(); -void g_set_num_bytes_sent( PRUint64 val ); +void g_set_num_bytes_sent( Slapi_Counter *counter ); PRUint64 g_get_num_bytes_sent(); -void g_set_num_sent_mutex( PRLock *plock ); void g_set_default_referral( struct berval **ldap_url ); struct berval **g_get_default_referral(); -PRLock *g_get_num_sent_mutex(); void disconnect_server( Connection *conn, PRUint64 opconnid, int opid, PRErrorCode reason, PRInt32 error ); int send_ldap_search_entry( Slapi_PBlock *pb, Slapi_Entry *e, LDAPControl **ectrls, char **attrs, int attrsonly ); diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c index f9213352..387353e4 100644 --- a/ldap/servers/slapd/result.c +++ b/ldap/servers/slapd/result.c @@ -60,9 +60,8 @@ #include <ssl.h> -PRUint64 num_entries_sent; -PRUint64 num_bytes_sent; -PRLock *num_sent_mutex; +Slapi_Counter *num_entries_sent; +Slapi_Counter *num_bytes_sent; static long current_conn_count; static PRLock *current_conn_count_mutex; @@ -82,34 +81,24 @@ static void log_referral( Operation *op ); #define SLAPI_SEND_VATTR_FLAG_REALONLY 0x01 #define SLAPI_SEND_VATTR_FLAG_VIRTUALONLY 0x02 -void g_set_num_entries_sent( PRUint64 val ) +void g_set_num_entries_sent( Slapi_Counter *counter ) { - num_entries_sent = val; + num_entries_sent = counter; } PRUint64 g_get_num_entries_sent() { - return( num_entries_sent ); + return( slapi_counter_get_value(num_entries_sent) ); } -void g_set_num_bytes_sent( PRUint64 val ) +void g_set_num_bytes_sent( Slapi_Counter *counter ) { - num_bytes_sent = val; + num_bytes_sent = counter; } PRUint64 g_get_num_bytes_sent() { - return( num_bytes_sent ); -} - -void g_set_num_sent_mutex( PRLock *plock ) -{ - num_sent_mutex = plock; -} - -PRLock *g_get_num_sent_mutex() -{ - return( num_sent_mutex ); + return( slapi_counter_get_value(num_bytes_sent) ); } static void @@ -327,8 +316,7 @@ send_ldap_result_ext( || err == LDAP_INSUFFICIENT_ACCESS || err == LDAP_AUTH_UNKNOWN ) { - if(g_get_global_snmp_vars()->ops_tbl.dsSecurityErrors!=NULL) - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsSecurityErrors); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsSecurityErrors); }else if( err != LDAP_REFERRAL && err != LDAP_OPT_REFERRALS && err != LDAP_PARTIAL_RESULTS) @@ -338,8 +326,7 @@ send_ldap_result_ext( --referrals -- partially seviced operations will not be conted as an error */ - if(g_get_global_snmp_vars()->ops_tbl.dsErrors!=NULL) - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsErrors); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsErrors); } } @@ -413,7 +400,7 @@ send_ldap_result_ext( int len; /* count the referral */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsReferrals); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsReferrals); /* * figure out how much space we need @@ -486,7 +473,7 @@ send_ldap_result_ext( */ /* count the referral */ if (! config_check_referral_mode()) - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsReferrals); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsReferrals); rc = ber_printf( ber, "{it{esst{s", operation->o_msgid, tag, err, matched ? matched : "", text ? text : "", LDAP_TAG_REFERRAL, urls[0]->bv_val ); @@ -677,7 +664,7 @@ send_ldap_referral ( char *attrs[2] = { NULL, NULL }; /* count the referral */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsReferrals); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsReferrals); attrs[0] = refAttr; if ( e != NULL && @@ -1526,14 +1513,13 @@ flush_ber( "flush_ber() wrote %u bytes to socket %d\n", bytes, conn->c_sd, 0 ); LL_I2L ( b, bytes ) ; - LL_ADD ( num_bytes_sent, num_bytes_sent, b); + slapi_counter_add(num_bytes_sent, b); if ( type == _LDAP_SEND_ENTRY ) { - LL_I2L ( b, 1 ); - LL_ADD ( num_entries_sent, num_entries_sent, b ); + slapi_counter_increment(num_entries_sent); } if (! config_check_referral_mode()) - (*(g_get_global_snmp_vars()->ops_tbl.dsBytesSent))+= bytes; + slapi_counter_add(g_get_global_snmp_vars()->ops_tbl.dsBytesSent, bytes); } } @@ -1542,11 +1528,11 @@ flush_ber( plugin_call_plugins( pb, SLAPI_PLUGIN_POST_RESULT_FN ); break; case _LDAP_SEND_REFERRAL: - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsReferralsReturned); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsReferralsReturned); plugin_call_plugins( pb, SLAPI_PLUGIN_POST_REFERRAL_FN ); break; case _LDAP_SEND_ENTRY: - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsEntriesReturned); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsEntriesReturned); plugin_call_plugins( pb, SLAPI_PLUGIN_POST_ENTRY_FN ); break; } diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c index 6ffe08e4..280bf2a3 100644 --- a/ldap/servers/slapd/search.c +++ b/ldap/servers/slapd/search.c @@ -87,7 +87,7 @@ do_search( Slapi_PBlock *pb ) ber = operation->o_ber; /* count the search request */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsSearchOps); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsSearchOps); /* * Parse the search request. It looks like this: @@ -141,11 +141,11 @@ do_search( Slapi_PBlock *pb ) /* check and record the scope for snmp */ if ( scope == LDAP_SCOPE_ONELEVEL) { /* count the one level search request */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsOneLevelSearchOps); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsOneLevelSearchOps); } else if (scope == LDAP_SCOPE_SUBTREE) { /* count the subtree search request */ - snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsWholeSubtreeSearchOps); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsWholeSubtreeSearchOps); } /* filter - returns a "normalized" version */ diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index e850bef4..38025aae 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -152,6 +152,7 @@ typedef struct symbol_t { #define SLAPD_LOGGING 1 #define NUM_SNMP_INT_TBL_ROWS 5 +#define SNMP_FIELD_LENGTH 100 /* include NSPR header files */ #include "nspr.h" @@ -1529,57 +1530,56 @@ typedef int (*value_compare_fn_type)(const struct berval *,const struct berval * #include "proto-slap.h" LDAPMod** entry2mods(Slapi_Entry *, LDAPMod **, int *, int); -/* SNMP Variables */ +/* SNMP Counter Variables */ struct snmp_ops_tbl_t{ - PRUint32 *dsAnonymousBinds; - PRUint32 *dsUnAuthBinds; - PRUint32 *dsSimpleAuthBinds; - PRUint32 *dsStrongAuthBinds; - PRUint32 *dsBindSecurityErrors; - PRUint32 *dsInOps; - PRUint32 *dsReadOps; - PRUint32 *dsCompareOps; - PRUint32 *dsAddEntryOps; - PRUint32 *dsRemoveEntryOps; - PRUint32 *dsModifyEntryOps; - PRUint32 *dsModifyRDNOps; - PRUint32 *dsListOps; - PRUint32 *dsSearchOps; - PRUint32 *dsOneLevelSearchOps; - PRUint32 *dsWholeSubtreeSearchOps; - PRUint32 *dsReferrals; - PRUint32 *dsChainings; - PRUint32 *dsSecurityErrors; - PRUint32 *dsErrors; - PRUint32 *dsConnections; /* Number of currently connected clients */ - PRUint32 *dsConnectionSeq; /* Monotonically increasing number bumped on each new conn est */ - PRUint32 *dsBytesRecv; /* Count of bytes read from clients */ - PRUint32 *dsBytesSent; /* Count of bytes sent to clients */ - PRUint32 *dsEntriesReturned; - PRUint32 *dsReferralsReturned; + Slapi_Counter *dsAnonymousBinds; + Slapi_Counter *dsUnAuthBinds; + Slapi_Counter *dsSimpleAuthBinds; + Slapi_Counter *dsStrongAuthBinds; + Slapi_Counter *dsBindSecurityErrors; + Slapi_Counter *dsInOps; + Slapi_Counter *dsReadOps; + Slapi_Counter *dsCompareOps; + Slapi_Counter *dsAddEntryOps; + Slapi_Counter *dsRemoveEntryOps; + Slapi_Counter *dsModifyEntryOps; + Slapi_Counter *dsModifyRDNOps; + Slapi_Counter *dsListOps; + Slapi_Counter *dsSearchOps; + Slapi_Counter *dsOneLevelSearchOps; + Slapi_Counter *dsWholeSubtreeSearchOps; + Slapi_Counter *dsReferrals; + Slapi_Counter *dsChainings; + Slapi_Counter *dsSecurityErrors; + Slapi_Counter *dsErrors; + Slapi_Counter *dsConnections; /* Number of currently connected clients */ + Slapi_Counter *dsConnectionSeq; /* Monotonically increasing number bumped on each new conn est */ + Slapi_Counter *dsBytesRecv; /* Count of bytes read from clients */ + Slapi_Counter *dsBytesSent; /* Count of bytes sent to clients */ + Slapi_Counter *dsEntriesReturned; + Slapi_Counter *dsReferralsReturned; }; struct snmp_entries_tbl_t{ - /* entries table */ - PRUint32 *dsMasterEntries; - PRUint32 *dsCopyEntries; - PRUint32 *dsCacheEntries; - PRUint32 *dsCacheHits; - PRUint32 *dsSlaveHits; + /* entries table */ + Slapi_Counter *dsMasterEntries; + Slapi_Counter *dsCopyEntries; + Slapi_Counter *dsCacheEntries; + Slapi_Counter *dsCacheHits; + Slapi_Counter *dsSlaveHits; }; struct snmp_int_tbl_t{ - /* interaction table */ - PRUint32 *dsIntIndex; - char *dsName; - time_t *dsTimeOfCreation; - time_t *dsTimeOfLastAttempt; - time_t *dsTimeOfLastSuccess; - PRUint32 *dsFailuresSinceLastSuccess; - PRUint32 *dsFailures; - PRUint32 *dsSuccesses; - char *dsURL; + PRUint32 dsIntIndex; + char dsName[SNMP_FIELD_LENGTH]; + time_t dsTimeOfCreation; + time_t dsTimeOfLastAttempt; + time_t dsTimeOfLastSuccess; + PRUint32 dsFailuresSinceLastSuccess; + PRUint32 dsFailures; + PRUint32 dsSuccesses; + char dsURL[SNMP_FIELD_LENGTH]; }; /* operation statistics */ @@ -1709,6 +1709,7 @@ typedef struct _slapdEntryPoints { #define CONFIG_LDAPI_GIDNUMBER_TYPE_ATTRIBUTE "nsslapd-ldapigidnumbertype" #define CONFIG_LDAPI_SEARCH_BASE_DN_ATTRIBUTE "nsslapd-ldapientrysearchbase" #define CONFIG_LDAPI_AUTO_DN_SUFFIX_ATTRIBUTE "nsslapd-ldapiautodnsuffix" +#define CONFIG_SLAPI_COUNTER_ATTRIBUTE "nsslapd-counters" #define CONFIG_SECURITY_ATTRIBUTE "nsslapd-security" #define CONFIG_SSL3CIPHERS_ATTRIBUTE "nsslapd-SSL3ciphers" #define CONFIG_ACCESSLOG_ATTRIBUTE "nsslapd-accesslog" @@ -1979,6 +1980,7 @@ typedef struct _slapdFrontendConfig { char *ldapi_gidnumber_type; /* type that contains gid number */ char *ldapi_search_base_dn; /* base dn to search for mapped entries */ char *ldapi_auto_dn_suffix; /* suffix to be appended to auto gen DNs */ + int slapi_counters; /* switch to turn slapi_counters on/off */ #ifndef _WIN32 struct passwd *localuserinfo; /* userinfo of localuser */ #endif /* _WIN32 */ diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h index 2a8eff12..7820db52 100644 --- a/ldap/servers/slapd/slapi-private.h +++ b/ldap/servers/slapd/slapi-private.h @@ -1208,14 +1208,6 @@ void DS_Sleep(PRIntervalTime ticks); #define PRLDAP_SET_PORT(myaddr,myport) \ ((myaddr)->raw.family == PR_AF_INET6 ? ((myaddr)->ipv6.port = PR_htons(myport)) : ((myaddr)->inet.port = PR_htons(myport))) -/* - * snmp_collator.c - * wrapper functions to ease the cast burdon between net-snmp APIs which expect - * unsigned int and PR_AtomicIncrement/PR_AtomicSet which expect signed int. - */ -void snmp_increment_counter(PRUint32 *counter); -void snmp_set_counter(PRUint32 *counter, PRInt32 newval); - #ifdef __cplusplus } #endif diff --git a/ldap/servers/slapd/snmp_collator.c b/ldap/servers/slapd/snmp_collator.c index 1fd5d0c5..c7d87e05 100644 --- a/ldap/servers/slapd/snmp_collator.c +++ b/ldap/servers/slapd/snmp_collator.c @@ -48,6 +48,7 @@ #include <sys/ipc.h> #include <sys/msg.h> #include <dirent.h> +#include <semaphore.h> #endif #include <time.h> #include <signal.h> @@ -62,6 +63,14 @@ #include "prcvar.h" #include "plstr.h" +#ifdef HPUX +/* HP-UX doesn't define SEM_FAILED like other platforms, so + * we define it ourselves. */ +#define SEM_FAILED ((sem_t *)(-1)) +#endif + +#define SNMP_NUM_SEM_WAITS 10 + #include "snmp_collator.h" #include "../snmp/ntagt/nslagtcom_nt.h" @@ -70,12 +79,18 @@ /* strlen of url portions ie "ldap://:/" */ #define URL_CHARS_LEN 9 -char *make_ds_url(char *host, int port); -void print_snmp_interaction_table(); -int search_interaction_table(char *dsURL, int *isnew); +static char *make_ds_url(char *host, int port); +static void print_snmp_interaction_table(); +static int search_interaction_table(char *dsURL, int *isnew); static void loadConfigStats(); static Slapi_Entry *getConfigEntry( Slapi_Entry **e ); static void freeConfigEntry( Slapi_Entry **e ); +static void snmp_update_ops_table(); +static void snmp_update_entries_table(); +static void snmp_update_interactions_table(); +static void snmp_update_cache_stats(); +static void snmp_collator_create_semaphore(); +static void snmp_collator_sem_wait(); /* snmp stats stuff */ struct agt_stats_t *stats=NULL; @@ -94,12 +109,14 @@ static HANDLE hLogFile = INVALID_HANDLE_VALUE; static TCHAR szSpoolRootDir[_MAX_PATH]; #else static char szStatsFile[_MAX_PATH]; +static char stats_sem_name[_MAX_PATH]; #endif /* _WIN32*/ static Slapi_Eq_Context snmp_eq_ctx; static int snmp_collator_stopped = 0; -/* lock stuff */ +/* synchronization stuff */ static PRLock *interaction_table_mutex; +static sem_t *stats_sem; /*********************************************************************************** @@ -110,88 +127,80 @@ static PRLock *interaction_table_mutex; * ************************************************************************************/ -int snmp_collator_init(){ - int i; +static int snmp_collator_init(){ + int i; + + /* + * Create the global SNMP counters + */ + g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsSimpleAuthBinds = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsStrongAuthBinds = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsInOps = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsReadOps = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsCompareOps = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsAddEntryOps = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsRemoveEntryOps = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsModifyEntryOps = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsModifyRDNOps = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsListOps = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsSearchOps = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsOneLevelSearchOps = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsWholeSubtreeSearchOps = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsReferrals = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsChainings = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsSecurityErrors = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsErrors = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsConnections = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsConnectionSeq = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsBytesRecv = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsBytesSent = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsEntriesReturned = slapi_counter_new(); + g_get_global_snmp_vars()->ops_tbl.dsReferralsReturned = slapi_counter_new(); + g_get_global_snmp_vars()->entries_tbl.dsMasterEntries = slapi_counter_new(); + g_get_global_snmp_vars()->entries_tbl.dsCopyEntries = slapi_counter_new(); + g_get_global_snmp_vars()->entries_tbl.dsCacheEntries = slapi_counter_new(); + g_get_global_snmp_vars()->entries_tbl.dsCacheHits = slapi_counter_new(); + g_get_global_snmp_vars()->entries_tbl.dsSlaveHits = slapi_counter_new(); + + /* Initialize the global interaction table */ + for(i=0; i < NUM_SNMP_INT_TBL_ROWS; i++) + { + g_get_global_snmp_vars()->int_tbl[i].dsIntIndex = i + 1; + strncpy(g_get_global_snmp_vars()->int_tbl[i].dsName, "Not Available", + sizeof(g_get_global_snmp_vars()->int_tbl[i].dsName)); + g_get_global_snmp_vars()->int_tbl[i].dsTimeOfCreation = 0; + g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastAttempt = 0; + g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastSuccess = 0; + g_get_global_snmp_vars()->int_tbl[i].dsFailuresSinceLastSuccess = 0; + g_get_global_snmp_vars()->int_tbl[i].dsFailures = 0; + g_get_global_snmp_vars()->int_tbl[i].dsSuccesses = 0; + strncpy(g_get_global_snmp_vars()->int_tbl[i].dsURL, "Not Available", + sizeof(g_get_global_snmp_vars()->int_tbl[i].dsURL)); + } + + /* Get the semaphore */ + snmp_collator_sem_wait(); - /* - * Initialize the mmap structure - */ + /* Initialize the mmap structure */ memset((void *) stats, 0, sizeof(*stats)); + + /* Load header stats table */ strncpy(stats->hdr_stats.dsVersion, SLAPD_VERSION_STR, (sizeof(stats->hdr_stats.dsVersion)/sizeof(char)) - 1); stats->hdr_stats.restarted = 0; stats->hdr_stats.startTime = time(0); /* This is a bit off, hope it's ok */ - - /* load config stats */ loadConfigStats(); - /* point these at the mmaped data */ - g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds = &(stats->ops_stats.dsAnonymousBinds); - g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds = &(stats->ops_stats.dsUnAuthBinds); - g_get_global_snmp_vars()->ops_tbl.dsSimpleAuthBinds = &(stats->ops_stats.dsSimpleAuthBinds); - g_get_global_snmp_vars()->ops_tbl.dsStrongAuthBinds = &(stats->ops_stats.dsStrongAuthBinds); - g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors = &(stats->ops_stats.dsBindSecurityErrors); - g_get_global_snmp_vars()->ops_tbl.dsInOps = &(stats->ops_stats.dsInOps); - g_get_global_snmp_vars()->ops_tbl.dsReadOps = &(stats->ops_stats.dsReadOps); - g_get_global_snmp_vars()->ops_tbl.dsCompareOps = &(stats->ops_stats.dsCompareOps); - g_get_global_snmp_vars()->ops_tbl.dsAddEntryOps = &(stats->ops_stats.dsAddEntryOps); - g_get_global_snmp_vars()->ops_tbl.dsRemoveEntryOps = &(stats->ops_stats.dsRemoveEntryOps); - g_get_global_snmp_vars()->ops_tbl.dsModifyEntryOps = &(stats->ops_stats.dsModifyEntryOps); - g_get_global_snmp_vars()->ops_tbl.dsModifyRDNOps = &(stats->ops_stats.dsModifyRDNOps); - g_get_global_snmp_vars()->ops_tbl.dsListOps = &(stats->ops_stats.dsListOps); - g_get_global_snmp_vars()->ops_tbl.dsSearchOps = &(stats->ops_stats.dsSearchOps); - g_get_global_snmp_vars()->ops_tbl.dsOneLevelSearchOps = &(stats->ops_stats.dsOneLevelSearchOps); - g_get_global_snmp_vars()->ops_tbl.dsWholeSubtreeSearchOps = &(stats->ops_stats.dsWholeSubtreeSearchOps); - g_get_global_snmp_vars()->ops_tbl.dsReferrals = &(stats->ops_stats.dsReferrals); - g_get_global_snmp_vars()->ops_tbl.dsChainings = &(stats->ops_stats.dsChainings); - g_get_global_snmp_vars()->ops_tbl.dsSecurityErrors = &(stats->ops_stats.dsSecurityErrors); - g_get_global_snmp_vars()->ops_tbl.dsErrors = &(stats->ops_stats.dsErrors); - g_get_global_snmp_vars()->ops_tbl.dsConnections = &(stats->ops_stats.dsConnections); - g_get_global_snmp_vars()->ops_tbl.dsConnectionSeq = &(stats->ops_stats.dsConnectionSeq); - g_get_global_snmp_vars()->ops_tbl.dsBytesRecv = &(stats->ops_stats.dsBytesRecv); - g_get_global_snmp_vars()->ops_tbl.dsBytesSent = &(stats->ops_stats.dsBytesSent); - g_get_global_snmp_vars()->ops_tbl.dsEntriesReturned = &(stats->ops_stats.dsEntriesReturned); - g_get_global_snmp_vars()->ops_tbl.dsReferralsReturned = &(stats->ops_stats.dsReferralsReturned); - - /* entries table */ - - g_get_global_snmp_vars()->entries_tbl.dsMasterEntries = &(stats->entries_stats.dsMasterEntries); - g_get_global_snmp_vars()->entries_tbl.dsCopyEntries = &(stats->entries_stats.dsCopyEntries); - g_get_global_snmp_vars()->entries_tbl.dsCacheEntries = &(stats->entries_stats.dsCacheEntries); - g_get_global_snmp_vars()->entries_tbl.dsCacheHits = &(stats->entries_stats.dsCacheHits); - g_get_global_snmp_vars()->entries_tbl.dsSlaveHits = &(stats->entries_stats.dsSlaveHits); - - /* interaction table */ - - /* set pointers to table */ - for(i=0; i < NUM_SNMP_INT_TBL_ROWS; i++) - { - stats->int_stats[i].dsIntIndex=i; - g_get_global_snmp_vars()->int_tbl[i].dsIntIndex = &(stats->int_stats[i].dsIntIndex); - g_get_global_snmp_vars()->int_tbl[i].dsName = stats->int_stats[i].dsName; - g_get_global_snmp_vars()->int_tbl[i].dsTimeOfCreation = &(stats->int_stats[i].dsTimeOfCreation); - g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastAttempt = &(stats->int_stats[i].dsTimeOfLastAttempt); - g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastSuccess = &(stats->int_stats[i].dsTimeOfLastSuccess); - g_get_global_snmp_vars()->int_tbl[i].dsFailuresSinceLastSuccess - = &(stats->int_stats[i].dsFailuresSinceLastSuccess); - g_get_global_snmp_vars()->int_tbl[i].dsFailures = &(stats->int_stats[i].dsFailures); - g_get_global_snmp_vars()->int_tbl[i].dsSuccesses = &(stats->int_stats[i].dsSuccesses); - g_get_global_snmp_vars()->int_tbl[i].dsURL = stats->int_stats[i].dsURL; - } + /* update the mmap'd tables */ + snmp_update_ops_table(); + snmp_update_entries_table(); + snmp_update_interactions_table(); - /* initialize table contents */ - for(i=0; i < NUM_SNMP_INT_TBL_ROWS; i++) - { - *(g_get_global_snmp_vars()->int_tbl[i].dsIntIndex) = i + 1; - strcpy(g_get_global_snmp_vars()->int_tbl[i].dsName, "Not Available"); - *(g_get_global_snmp_vars()->int_tbl[i].dsTimeOfCreation) = 0; - *(g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastAttempt) = 0; - *(g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastSuccess) = 0; - *(g_get_global_snmp_vars()->int_tbl[i].dsFailuresSinceLastSuccess) = 0; - *(g_get_global_snmp_vars()->int_tbl[i].dsFailures) = 0; - *(g_get_global_snmp_vars()->int_tbl[i].dsSuccesses) = 0; - strcpy(g_get_global_snmp_vars()->int_tbl[i].dsURL, "Not Available"); - } + /* Release the semaphore */ + sem_post(stats_sem); /* create lock for interaction table */ interaction_table_mutex = PR_NewLock(); @@ -202,7 +211,7 @@ int snmp_collator_init(){ /*********************************************************************************** - * given the name, wether or not it was successfull and the URL updates snmp + * given the name, whether or not it was successful and the URL updates snmp * interaction table appropriately * * @@ -231,32 +240,34 @@ void set_snmp_interaction_row(char *host, int port, int error) if(isnew){ /* fillin the new row from scratch*/ - *(g_get_global_snmp_vars()->int_tbl[index].dsIntIndex) = index; - strcpy(g_get_global_snmp_vars()->int_tbl[index].dsName, dsName); - *(g_get_global_snmp_vars()->int_tbl[index].dsTimeOfCreation) = time(0); - *(g_get_global_snmp_vars()->int_tbl[index].dsTimeOfLastAttempt) = time(0); + g_get_global_snmp_vars()->int_tbl[index].dsIntIndex = index; + strncpy(g_get_global_snmp_vars()->int_tbl[index].dsName, dsName, + sizeof(g_get_global_snmp_vars()->int_tbl[index].dsName)); + g_get_global_snmp_vars()->int_tbl[index].dsTimeOfCreation = time(0); + g_get_global_snmp_vars()->int_tbl[index].dsTimeOfLastAttempt = time(0); if(error == 0){ - *(g_get_global_snmp_vars()->int_tbl[index].dsTimeOfLastSuccess) = time(0); - *(g_get_global_snmp_vars()->int_tbl[index].dsFailuresSinceLastSuccess) = 0; - *(g_get_global_snmp_vars()->int_tbl[index].dsFailures) = 0; - *(g_get_global_snmp_vars()->int_tbl[index].dsSuccesses) = 1; + g_get_global_snmp_vars()->int_tbl[index].dsTimeOfLastSuccess = time(0); + g_get_global_snmp_vars()->int_tbl[index].dsFailuresSinceLastSuccess = 0; + g_get_global_snmp_vars()->int_tbl[index].dsFailures = 0; + g_get_global_snmp_vars()->int_tbl[index].dsSuccesses = 1; }else{ - *(g_get_global_snmp_vars()->int_tbl[index].dsTimeOfLastSuccess) = 0; - *(g_get_global_snmp_vars()->int_tbl[index].dsFailuresSinceLastSuccess) = 1; - *(g_get_global_snmp_vars()->int_tbl[index].dsFailures) = 1; - *(g_get_global_snmp_vars()->int_tbl[index].dsSuccesses) = 0; + g_get_global_snmp_vars()->int_tbl[index].dsTimeOfLastSuccess = 0; + g_get_global_snmp_vars()->int_tbl[index].dsFailuresSinceLastSuccess = 1; + g_get_global_snmp_vars()->int_tbl[index].dsFailures = 1; + g_get_global_snmp_vars()->int_tbl[index].dsSuccesses = 0; } - strcpy(g_get_global_snmp_vars()->int_tbl[index].dsURL, dsURL); + strncpy(g_get_global_snmp_vars()->int_tbl[index].dsURL, dsURL, + sizeof(g_get_global_snmp_vars()->int_tbl[index].dsURL)); }else{ /* just update the appropriate fields */ - *(g_get_global_snmp_vars()->int_tbl[index].dsTimeOfLastAttempt) = time(0); + g_get_global_snmp_vars()->int_tbl[index].dsTimeOfLastAttempt = time(0); if(error == 0){ - *(g_get_global_snmp_vars()->int_tbl[index].dsTimeOfLastSuccess) = time(0); - *(g_get_global_snmp_vars()->int_tbl[index].dsFailuresSinceLastSuccess) = 0; - *(g_get_global_snmp_vars()->int_tbl[index].dsSuccesses) += 1; + g_get_global_snmp_vars()->int_tbl[index].dsTimeOfLastSuccess = time(0); + g_get_global_snmp_vars()->int_tbl[index].dsFailuresSinceLastSuccess = 0; + g_get_global_snmp_vars()->int_tbl[index].dsSuccesses += 1; }else{ - *(g_get_global_snmp_vars()->int_tbl[index].dsFailuresSinceLastSuccess) +=1; - *(g_get_global_snmp_vars()->int_tbl[index].dsFailures) +=1; + g_get_global_snmp_vars()->int_tbl[index].dsFailuresSinceLastSuccess +=1; + g_get_global_snmp_vars()->int_tbl[index].dsFailures +=1; } } @@ -274,7 +285,7 @@ void set_snmp_interaction_row(char *host, int port, int error) * * this should point to root DSE ************************************************************************************/ -char *make_ds_url(char *host, int port){ +static char *make_ds_url(char *host, int port){ char *url; @@ -291,14 +302,14 @@ char *make_ds_url(char *host, int port){ * so caller can rewrite this row ************************************************************************************/ -int search_interaction_table(char *dsURL, int *isnew) +static int search_interaction_table(char *dsURL, int *isnew) { int i; int index = 0; time_t oldestattempt; time_t currentattempt; - oldestattempt = *(g_get_global_snmp_vars()->int_tbl[0].dsTimeOfLastAttempt); + oldestattempt = g_get_global_snmp_vars()->int_tbl[0].dsTimeOfLastAttempt; *isnew = 1; for(i=0; i < NUM_SNMP_INT_TBL_ROWS; i++){ @@ -314,7 +325,7 @@ int search_interaction_table(char *dsURL, int *isnew) break; }else{ /* not found so figure out oldest row */ - currentattempt = *(g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastAttempt); + currentattempt = g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastAttempt; if(currentattempt <= oldestattempt){ index=i; @@ -328,19 +339,19 @@ int search_interaction_table(char *dsURL, int *isnew) } /* for debuging until subagent part working, print contents of interaction table */ -void print_snmp_interaction_table() +static void print_snmp_interaction_table() { int i; for(i=0; i < NUM_SNMP_INT_TBL_ROWS; i++) { - fprintf(stderr, " dsIntIndex: %d \n", *(g_get_global_snmp_vars()->int_tbl[i].dsIntIndex)); + fprintf(stderr, " dsIntIndex: %d \n", g_get_global_snmp_vars()->int_tbl[i].dsIntIndex); fprintf(stderr, " dsName: %s \n", g_get_global_snmp_vars()->int_tbl[i].dsName); - fprintf(stderr, " dsTimeOfCreation: %ld \n", *(g_get_global_snmp_vars()->int_tbl[i].dsTimeOfCreation)); - fprintf(stderr, " dsTimeOfLastAttempt: %ld \n", *(g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastAttempt)); - fprintf(stderr, " dsTimeOfLastSuccess: %ld \n", *(g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastSuccess)); - fprintf(stderr, "dsFailuresSinceLastSuccess: %d \n", *(g_get_global_snmp_vars()->int_tbl[i].dsFailuresSinceLastSuccess)); - fprintf(stderr, " dsFailures: %d \n", *(g_get_global_snmp_vars()->int_tbl[i].dsFailures)); - fprintf(stderr, " dsSuccesses: %d \n", *(g_get_global_snmp_vars()->int_tbl[i].dsSuccesses)); + fprintf(stderr, " dsTimeOfCreation: %ld \n", g_get_global_snmp_vars()->int_tbl[i].dsTimeOfCreation); + fprintf(stderr, " dsTimeOfLastAttempt: %ld \n", g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastAttempt); + fprintf(stderr, " dsTimeOfLastSuccess: %ld \n", g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastSuccess); + fprintf(stderr, "dsFailuresSinceLastSuccess: %d \n", g_get_global_snmp_vars()->int_tbl[i].dsFailuresSinceLastSuccess); + fprintf(stderr, " dsFailures: %d \n", g_get_global_snmp_vars()->int_tbl[i].dsFailures); + fprintf(stderr, " dsSuccesses: %d \n", g_get_global_snmp_vars()->int_tbl[i].dsSuccesses); fprintf(stderr, " dsURL: %s \n", g_get_global_snmp_vars()->int_tbl[i].dsURL); fprintf(stderr, "\n"); } @@ -418,6 +429,8 @@ int snmp_collator_start() } PR_snprintf(szStatsFile, sizeof(szStatsFile), "%s/%s%s", statspath, instname, AGT_STATS_EXTENSION); + PR_snprintf(stats_sem_name, sizeof(stats_sem_name), "%s%s", + instname, AGT_STATS_EXTENSION); tmpstatsfile = szStatsFile; slapi_ch_free_string(&statspath); slapi_ch_free_string(&instdir); @@ -427,27 +440,22 @@ int snmp_collator_start() { if (err != EEXIST) /* Ignore if file already exists */ { - printf("Failed to open stats file (%s) (error %d).\n", - szStatsFile, err); + LDAPDebug( LDAP_DEBUG_ANY, "Failed to open stats file (%s) (error %d).\n", + szStatsFile, err, 0 ); exit(1); } } -/* read config entry for entity table data */ + /* Create semaphore for stats file access */ + snmp_collator_create_semaphore(); -/* point stats struct at mmap data */ + /* point stats struct at mmap data */ stats = (struct agt_stats_t *) mmap_tbl [hdl].fp; -/* initialize stats data */ - + /* initialize stats data */ snmp_collator_init(); -/* -* now that memmap is open and things point the right way -* an atomic set or increment anywhere in slapd should set -* the snmp memmap vars correctly and be able to be polled by snmp -*/ - /* Arrange to be called back periodically */ + /* Arrange to be called back periodically to update the mmap'd stats file. */ snmp_eq_ctx = slapi_eq_repeat(snmp_collator_update, NULL, (time_t)0, SLAPD_SNMP_UPDATE_INTERVAL); return 0; @@ -472,6 +480,9 @@ int snmp_collator_stop() slapi_eq_cancel(snmp_eq_ctx); snmp_collator_stopped = 1; + /* acquire the semaphore */ + snmp_collator_sem_wait(); + /* close the memory map */ if ((err = agt_mclose_stats(hdl)) != 0) { @@ -485,6 +496,10 @@ int snmp_collator_stop() tmpstatsfile, errno); } + /* close and delete semaphore */ + sem_close(stats_sem); + sem_unlink(stats_sem_name); + /* delete lock */ PR_DestroyLock(interaction_table_mutex); @@ -498,166 +513,304 @@ int snmp_collator_stop() return 0; } +/* + * snmp_collator_create_semaphore() + * + * Create a semaphore to synchronize access to the stats file with + * the SNMP sub-agent. NSPR doesn't support a trywait function + * for semaphores, so we just use POSIX semaphores directly. + */ +static void +snmp_collator_create_semaphore() +{ + /* First just try to create the semaphore. This should usually just work. */ + if ((stats_sem = sem_open(stats_sem_name, O_CREAT | O_EXCL, SLAPD_DEFAULT_FILE_MODE, 1)) == SEM_FAILED) { + if (errno == EEXIST) { + /* It appears that we didn't exit cleanly last time and left the semaphore + * around. Recreate it since we don't know what state it is in. */ + sem_unlink(stats_sem_name); + if ((stats_sem = sem_open(stats_sem_name, O_CREAT | O_EXCL, SLAPD_DEFAULT_FILE_MODE, 1)) == SEM_FAILED) { + /* No dice */ + LDAPDebug( LDAP_DEBUG_ANY, "Failed to create semaphore for stats file (%s). Error %d.\n", + szStatsFile, errno, 0 ); + exit(1); + } + } else { + /* Some other problem occurred creating the semaphore. */ + LDAPDebug( LDAP_DEBUG_ANY, "Failed to create semaphore for stats file (%s). Error %d.\n", + szStatsFile, errno, 0 ); + exit(1); + } + } + + /* If we've reached this point, everything should be good. */ + return; +} + +/* + * snmp_collator_sem_wait() + * + * A wrapper used to get the semaphore. We don't want to block, + * but we want to retry a specified number of times in case the + * semaphore is help by the sub-agent. + */ +static void +snmp_collator_sem_wait() +{ + int i = 0; + int got_sem = 0; + + for (i=0; i < SNMP_NUM_SEM_WAITS; i++) { + if (sem_trywait(stats_sem) == 0) { + got_sem = 1; + break; + } + PR_Sleep(PR_SecondsToInterval(1)); + } + + if (!got_sem) { + /* If we've been unable to get the semaphore, there's + * something wrong (likely the sub-agent went out to + * lunch). We remove the old semaphore and recreate + * a new one to avoid hanging up the server. */ + sem_close(stats_sem); + sem_unlink(stats_sem_name); + snmp_collator_create_semaphore(); + } +} + /*********************************************************************************** * * int snmp_collator_update() * -* our architecture changed from mail server and we right to mmapped -* area as soon as operation completed, rather than maintining the same data twice -* and doing a polled update. However, to keep traps working correctly (as they depend) -* on the time in the header, it is more efficient to write the header info -* in a polled fashion (ever 1 sec) +* Event callback function that updates the mmap'd stats file +* for the SNMP sub-agent. This will use a semaphore while +* updating the stats file to prevent the SNMP sub-agent from +* reading it in the middle of an update. * ************************************************************************************/ void snmp_collator_update(time_t start_time, void *arg) { - Slapi_Backend *be, *be_next; - char *cookie = NULL; - Slapi_PBlock *search_result_pb = NULL; - Slapi_Entry **search_entries; - Slapi_Attr *attr = NULL; - Slapi_Value *sval = NULL; - int search_result; - - if (snmp_collator_stopped) { - return; - } + if (snmp_collator_stopped) { + return; + } + + /* force an update of the backend cache stats. */ + snmp_update_cache_stats(); + + /* get the semaphore */ + snmp_collator_sem_wait(); /* just update the update time in the header */ if( stats != NULL){ stats->hdr_stats.updateTime = time(0); } + /* update the mmap'd tables */ + snmp_update_ops_table(); + snmp_update_entries_table(); + snmp_update_interactions_table(); + + /* release the semaphore */ + sem_post(stats_sem); +} + +/* + * snmp_update_ops_table() + * + * Updates the mmap'd operations table. The semaphore + * should be acquired before you call this. + */ +static void +snmp_update_ops_table() +{ + stats->ops_stats.dsAnonymousBinds = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds); + stats->ops_stats.dsUnAuthBinds = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds); + stats->ops_stats.dsSimpleAuthBinds = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsSimpleAuthBinds); + stats->ops_stats.dsStrongAuthBinds = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsStrongAuthBinds); + stats->ops_stats.dsBindSecurityErrors = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors); + stats->ops_stats.dsInOps = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsInOps); + stats->ops_stats.dsReadOps = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsReadOps); + stats->ops_stats.dsCompareOps = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsCompareOps); + stats->ops_stats.dsAddEntryOps = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsAddEntryOps); + stats->ops_stats.dsRemoveEntryOps = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsRemoveEntryOps); + stats->ops_stats.dsModifyEntryOps = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsModifyEntryOps); + stats->ops_stats.dsModifyRDNOps = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsModifyRDNOps); + stats->ops_stats.dsListOps = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsListOps); + stats->ops_stats.dsSearchOps = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsSearchOps); + stats->ops_stats.dsOneLevelSearchOps = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsOneLevelSearchOps); + stats->ops_stats.dsWholeSubtreeSearchOps = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsWholeSubtreeSearchOps); + stats->ops_stats.dsReferrals = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsReferrals); + stats->ops_stats.dsChainings = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsChainings); + stats->ops_stats.dsSecurityErrors = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsSecurityErrors); + stats->ops_stats.dsErrors = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsErrors); + stats->ops_stats.dsConnections = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsConnections); + stats->ops_stats.dsConnectionSeq = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsConnectionSeq); + stats->ops_stats.dsBytesRecv = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsBytesRecv); + stats->ops_stats.dsBytesSent = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsBytesSent); + stats->ops_stats.dsEntriesReturned = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsEntriesReturned); + stats->ops_stats.dsReferralsReturned = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsReferralsReturned); +} + +/* + * snmp_update_entries_table() + * + * Updated the mmap'd entries table. The semaphore should + * be acquired before you call this. + */ +static void +snmp_update_entries_table() +{ + stats->entries_stats.dsMasterEntries = slapi_counter_get_value(g_get_global_snmp_vars()->entries_tbl.dsMasterEntries); + stats->entries_stats.dsCopyEntries = slapi_counter_get_value(g_get_global_snmp_vars()->entries_tbl.dsCopyEntries); + stats->entries_stats.dsCacheEntries = slapi_counter_get_value(g_get_global_snmp_vars()->entries_tbl.dsCacheEntries); + stats->entries_stats.dsCacheHits = slapi_counter_get_value(g_get_global_snmp_vars()->entries_tbl.dsCacheHits); + stats->entries_stats.dsSlaveHits = slapi_counter_get_value(g_get_global_snmp_vars()->entries_tbl.dsSlaveHits); +} + +/* + * snmp_update_interactions_table() + * + * Updates the mmap'd interactions table. The semaphore should + * be acquired before you call this. + */ +static void +snmp_update_interactions_table() +{ + int i; + + for(i=0; i < NUM_SNMP_INT_TBL_ROWS; i++) { + stats->int_stats[i].dsIntIndex = i; + strncpy(stats->int_stats[i].dsName, g_get_global_snmp_vars()->int_tbl[i].dsName, + sizeof(stats->int_stats[i].dsName)); + stats->int_stats[i].dsTimeOfCreation = g_get_global_snmp_vars()->int_tbl[i].dsTimeOfCreation; + stats->int_stats[i].dsTimeOfLastAttempt = g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastAttempt; + stats->int_stats[i].dsTimeOfLastSuccess = g_get_global_snmp_vars()->int_tbl[i].dsTimeOfLastSuccess; + stats->int_stats[i].dsFailuresSinceLastSuccess = g_get_global_snmp_vars()->int_tbl[i].dsFailuresSinceLastSuccess; + stats->int_stats[i].dsFailures = g_get_global_snmp_vars()->int_tbl[i].dsFailures; + stats->int_stats[i].dsSuccesses = g_get_global_snmp_vars()->int_tbl[i].dsSuccesses; + strncpy(stats->int_stats[i].dsURL, g_get_global_snmp_vars()->int_tbl[i].dsURL, + sizeof(stats->int_stats[i].dsURL)); + } +} + +/* + * snmp_update_cache_stats() + * + * Reads the backend cache stats from the backend monitor entry and + * updates the global counter used by the SNMP sub-agent as well as + * the SNMP monitor entry. + */ +static void +snmp_update_cache_stats() +{ + Slapi_Backend *be, *be_next; + char *cookie = NULL; + Slapi_PBlock *search_result_pb = NULL; + Slapi_Entry **search_entries; + int search_result; + /* set the cache hits/cache entries info */ - be = slapi_get_first_backend(&cookie); - if (!be) - return; + be = slapi_get_first_backend(&cookie); + if (!be) + return; - be_next = slapi_get_next_backend(cookie); + be_next = slapi_get_next_backend(cookie); - slapi_ch_free ((void **) &cookie); + slapi_ch_free ((void **) &cookie); - /* for now, only do it if there is only 1 backend, otherwise don't know - which backend to pick */ + /* for now, only do it if there is only 1 backend, otherwise don't know + * which backend to pick */ if(be_next == NULL) { - Slapi_DN monitordn; - slapi_sdn_init(&monitordn); - be_getmonitordn(be,&monitordn); + Slapi_DN monitordn; + slapi_sdn_init(&monitordn); + be_getmonitordn(be,&monitordn); - /* do a search on the monitor dn to get info */ + /* do a search on the monitor dn to get info */ search_result_pb = slapi_search_internal( slapi_sdn_get_dn(&monitordn), - LDAP_SCOPE_BASE, - "objectclass=*", - NULL, - NULL, - 0); - slapi_sdn_done(&monitordn); - - slapi_pblock_get( search_result_pb, SLAPI_PLUGIN_INTOP_RESULT, &search_result); - - if(search_result == 0) - { - const struct berval *val = NULL; - /* get the entrycachehits */ - slapi_pblock_get( search_result_pb,SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, - &search_entries); - if(slapi_entry_attr_find( search_entries[0], "entrycachehits", &attr) == 0 ) - { - /* get the values out of the attribute */ - val = NULL; - slapi_attr_first_value( attr, &sval ); - if(NULL != sval) - { - val= slapi_value_get_berval( sval ); - } - } - - /* if we got a value for entrycachehits, then set it */ - if(val != NULL) - { - snmp_set_counter(g_get_global_snmp_vars()->entries_tbl.dsCacheHits, atoi(val->bv_val)); - - } + LDAP_SCOPE_BASE, + "objectclass=*", + NULL, + NULL, + 0); + slapi_sdn_done(&monitordn); + + slapi_pblock_get( search_result_pb, SLAPI_PLUGIN_INTOP_RESULT, &search_result); + + if(search_result == 0) + { + slapi_pblock_get( search_result_pb,SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, + &search_entries); + + /* set the entrycachehits */ + slapi_counter_set_value(g_get_global_snmp_vars()->entries_tbl.dsCacheHits, + slapi_entry_attr_get_ulonglong(search_entries[0], "entrycachehits")); - /* get the currententrycachesize */ - attr = NULL; - val = NULL; - sval = NULL; - if(slapi_entry_attr_find( search_entries[0], "currententrycachesize", &attr) == 0 ) - { - /* get the values out of the attribute */ - slapi_attr_first_value( attr,&sval ); - if(NULL != sval) { - val= slapi_value_get_berval( sval ); - } - } - - /* if we got a value for currententrycachesize, then set it */ - if(val != NULL) - { - snmp_set_counter(g_get_global_snmp_vars()->entries_tbl.dsCacheEntries, atoi(val->bv_val)); - - } - - } - - slapi_free_search_results_internal(search_result_pb); - slapi_pblock_destroy(search_result_pb); + /* set the currententrycachesize */ + slapi_counter_set_value(g_get_global_snmp_vars()->entries_tbl.dsCacheEntries, + slapi_entry_attr_get_ulonglong(search_entries[0], "currententrycachesize")); + } + + slapi_free_search_results_internal(search_result_pb); + slapi_pblock_destroy(search_result_pb); } } -/* NGK - We should not be using a plain int here. All of these counters - * are PRUint32 types for now, but they will be PRUint64 once converted - * to use Slapi_Counter. */ static void -add_counter_to_value(Slapi_Entry *e, const char *type, int countervalue) +add_counter_to_value(Slapi_Entry *e, const char *type, PRUint64 countervalue) { char value[40]; - sprintf(value,"%d",countervalue); + sprintf(value,"%" PRIu64, countervalue); slapi_entry_attr_set_charptr( e, type, value); } void snmp_as_entry(Slapi_Entry *e) { - add_counter_to_value(e,"AnonymousBinds",stats->ops_stats.dsAnonymousBinds); - add_counter_to_value(e,"UnAuthBinds",stats->ops_stats.dsUnAuthBinds); - add_counter_to_value(e,"SimpleAuthBinds",stats->ops_stats.dsSimpleAuthBinds); - add_counter_to_value(e,"StrongAuthBinds",stats->ops_stats.dsStrongAuthBinds); - add_counter_to_value(e,"BindSecurityErrors",stats->ops_stats.dsBindSecurityErrors); - add_counter_to_value(e,"InOps",stats->ops_stats.dsInOps); - add_counter_to_value(e,"ReadOps",stats->ops_stats.dsReadOps); - add_counter_to_value(e,"CompareOps",stats->ops_stats.dsCompareOps); - add_counter_to_value(e,"AddEntryOps",stats->ops_stats.dsAddEntryOps); - add_counter_to_value(e,"RemoveEntryOps",stats->ops_stats.dsRemoveEntryOps); - add_counter_to_value(e,"ModifyEntryOps",stats->ops_stats.dsModifyEntryOps); - add_counter_to_value(e,"ModifyRDNOps",stats->ops_stats.dsModifyRDNOps); - add_counter_to_value(e,"ListOps",stats->ops_stats.dsListOps); - add_counter_to_value(e,"SearchOps",stats->ops_stats.dsSearchOps); - add_counter_to_value(e,"OneLevelSearchOps",stats->ops_stats.dsOneLevelSearchOps); - add_counter_to_value(e,"WholeSubtreeSearchOps",stats->ops_stats.dsWholeSubtreeSearchOps); - add_counter_to_value(e,"Referrals",stats->ops_stats.dsReferrals); - add_counter_to_value(e,"Chainings",stats->ops_stats.dsChainings); - add_counter_to_value(e,"SecurityErrors",stats->ops_stats.dsSecurityErrors); - add_counter_to_value(e,"Errors",stats->ops_stats.dsErrors); - add_counter_to_value(e,"Connections",stats->ops_stats.dsConnections); - add_counter_to_value(e,"ConnectionSeq",stats->ops_stats.dsConnectionSeq); - add_counter_to_value(e,"BytesRecv",stats->ops_stats.dsBytesRecv); - add_counter_to_value(e,"BytesSent",stats->ops_stats.dsBytesSent); - add_counter_to_value(e,"EntriesReturned",stats->ops_stats.dsEntriesReturned); - add_counter_to_value(e,"ReferralsReturned",stats->ops_stats.dsReferralsReturned); - add_counter_to_value(e,"MasterEntries",stats->entries_stats.dsMasterEntries); - add_counter_to_value(e,"CopyEntries",stats->entries_stats.dsCopyEntries); - add_counter_to_value(e,"CacheEntries",stats->entries_stats.dsCacheEntries); - add_counter_to_value(e,"CacheHits",stats->entries_stats.dsCacheHits); - add_counter_to_value(e,"SlaveHits",stats->entries_stats.dsSlaveHits); + add_counter_to_value(e,"AnonymousBinds", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds)); + add_counter_to_value(e,"UnAuthBinds", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds)); + add_counter_to_value(e,"SimpleAuthBinds", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsSimpleAuthBinds)); + add_counter_to_value(e,"StrongAuthBinds", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsStrongAuthBinds)); + add_counter_to_value(e,"BindSecurityErrors", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors)); + add_counter_to_value(e,"InOps", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsInOps)); + add_counter_to_value(e,"ReadOps", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsReadOps)); + add_counter_to_value(e,"CompareOps", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsCompareOps)); + add_counter_to_value(e,"AddEntryOps", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsAddEntryOps)); + add_counter_to_value(e,"RemoveEntryOps", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsRemoveEntryOps)); + add_counter_to_value(e,"ModifyEntryOps", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsModifyEntryOps)); + add_counter_to_value(e,"ModifyRDNOps", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsModifyRDNOps)); + add_counter_to_value(e,"ListOps", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsListOps)); + add_counter_to_value(e,"SearchOps", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsSearchOps)); + add_counter_to_value(e,"OneLevelSearchOps", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsOneLevelSearchOps)); + add_counter_to_value(e,"WholeSubtreeSearchOps", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsWholeSubtreeSearchOps)); + add_counter_to_value(e,"Referrals", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsReferrals)); + add_counter_to_value(e,"Chainings", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsChainings)); + add_counter_to_value(e,"SecurityErrors", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsSecurityErrors)); + add_counter_to_value(e,"Errors", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsErrors)); + add_counter_to_value(e,"Connections", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsConnections)); + add_counter_to_value(e,"ConnectionSeq", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsConnectionSeq)); + add_counter_to_value(e,"BytesRecv", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsBytesRecv)); + add_counter_to_value(e,"BytesSent", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsBytesSent)); + add_counter_to_value(e,"EntriesReturned", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsEntriesReturned)); + add_counter_to_value(e,"ReferralsReturned", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsReferralsReturned)); + add_counter_to_value(e,"MasterEntries", slapi_counter_get_value(g_get_global_snmp_vars()->entries_tbl.dsMasterEntries)); + add_counter_to_value(e,"CopyEntries", slapi_counter_get_value(g_get_global_snmp_vars()->entries_tbl.dsCopyEntries)); + add_counter_to_value(e,"CacheEntries", slapi_counter_get_value(g_get_global_snmp_vars()->entries_tbl.dsCacheEntries)); + add_counter_to_value(e,"CacheHits", slapi_counter_get_value(g_get_global_snmp_vars()->entries_tbl.dsCacheHits)); + add_counter_to_value(e,"SlaveHits", slapi_counter_get_value(g_get_global_snmp_vars()->entries_tbl.dsSlaveHits)); } +/* + * loadConfigStats() + * + * Reads the header table SNMP settings and sets them in the mmap'd stats + * file. This should be done only when the semaphore is held. + */ static void loadConfigStats() { Slapi_Entry *entry = NULL; @@ -726,20 +879,3 @@ freeConfigEntry( Slapi_Entry **e ) { } } -/* - * wrapper functions to ease the cast burdon between net=snmp APIs which expect - * unsigned int and PR_AtomicIncrement/PR_AtomicSet which expect signed int. - * NSPR_API(PRInt32) PR_AtomicSet(PRInt32 *val, PRInt32 newval); - * NSPR_API(PRInt32) PR_AtomicIncrement(PRInt32 *val); - */ -void -snmp_increment_counter(PRUint32 *counter) -{ - PR_AtomicIncrement((PRInt32 *)counter); -} - -void snmp_set_counter(PRUint32 *counter, PRInt32 newval) -{ - PR_AtomicSet((PRInt32 *)counter, newval); -} - |