mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-20 22:59:34 -05:00
ITS#9354 Tool for monitoring slapd status
This commit is contained in:
parent
dd82fa5393
commit
c59ccf5393
4 changed files with 731 additions and 3 deletions
|
|
@ -14,12 +14,12 @@
|
|||
## <http://www.OpenLDAP.org/license.html>.
|
||||
|
||||
PROGRAMS = slapd-tester slapd-search slapd-read slapd-addel slapd-modrdn \
|
||||
slapd-modify slapd-bind slapd-mtread ldif-filter
|
||||
slapd-modify slapd-bind slapd-mtread ldif-filter slapd-watcher
|
||||
|
||||
SRCS = slapd-common.c \
|
||||
slapd-tester.c slapd-search.c slapd-read.c slapd-addel.c \
|
||||
slapd-modrdn.c slapd-modify.c slapd-bind.c slapd-mtread.c \
|
||||
ldif-filter.c
|
||||
ldif-filter.c slapd-watcher.c
|
||||
|
||||
LDAP_INCDIR= ../../include
|
||||
LDAP_LIBDIR= ../../libraries
|
||||
|
|
@ -62,3 +62,5 @@ ldif-filter: ldif-filter.o $(XLIBS)
|
|||
slapd-mtread: slapd-mtread.o $(OBJS) $(XLIBS)
|
||||
$(LTLINK) -o $@ slapd-mtread.o $(OBJS) $(LIBS)
|
||||
|
||||
slapd-watcher: slapd-watcher.o $(OBJS) $(XLIBS)
|
||||
$(LTLINK) -o $@ slapd-watcher.o $(OBJS) $(LIBS)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
/* global vars */
|
||||
pid_t pid;
|
||||
int debug;
|
||||
|
||||
/* static vars */
|
||||
static char progname[ BUFSIZ ];
|
||||
|
|
@ -311,7 +312,6 @@ tester_config_opt( struct tester_conn_args *config, char opt, char *optarg )
|
|||
|
||||
case 'd':
|
||||
{
|
||||
int debug;
|
||||
if ( lutil_atoi( &debug, optarg ) != 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,5 +87,6 @@ extern void tester_config_finish( struct tester_conn_args *config );
|
|||
extern void tester_init_ld( LDAP **ldp, struct tester_conn_args *conf, int flags );
|
||||
|
||||
extern pid_t pid;
|
||||
extern int debug;
|
||||
|
||||
#endif /* SLAPD_COMMON_H */
|
||||
|
|
|
|||
725
tests/progs/slapd-watcher.c
Normal file
725
tests/progs/slapd-watcher.c
Normal file
|
|
@ -0,0 +1,725 @@
|
|||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 1999-2020 The OpenLDAP Foundation.
|
||||
* 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 Howard Chu for inclusion
|
||||
* in OpenLDAP Software.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ac/stdlib.h"
|
||||
#include "ac/time.h"
|
||||
|
||||
#include "ac/ctype.h"
|
||||
#include "ac/param.h"
|
||||
#include "ac/socket.h"
|
||||
#include "ac/string.h"
|
||||
#include "ac/unistd.h"
|
||||
#include "ac/wait.h"
|
||||
#include "ac/time.h"
|
||||
|
||||
#include "ldap.h"
|
||||
#include "lutil.h"
|
||||
#include "lutil_ldap.h"
|
||||
#include "lber_pvt.h"
|
||||
#include "ldap_pvt.h"
|
||||
|
||||
#include "slapd-common.h"
|
||||
|
||||
#define HAS_MONITOR 1
|
||||
#define HAS_BASE 2
|
||||
#define HAS_ENTRIES 4
|
||||
#define HAS_SREPL 8
|
||||
|
||||
#define MONFILTER "(objectClass=monitorOperation)"
|
||||
|
||||
#define SLAP_SYNC_SID_MAX 4095
|
||||
|
||||
typedef enum {
|
||||
SLAP_OP_BIND = 0,
|
||||
SLAP_OP_UNBIND,
|
||||
SLAP_OP_SEARCH,
|
||||
SLAP_OP_COMPARE,
|
||||
SLAP_OP_MODIFY,
|
||||
SLAP_OP_MODRDN,
|
||||
SLAP_OP_ADD,
|
||||
SLAP_OP_DELETE,
|
||||
SLAP_OP_ABANDON,
|
||||
SLAP_OP_EXTENDED,
|
||||
SLAP_OP_LAST
|
||||
} slap_op_t;
|
||||
|
||||
struct opname {
|
||||
struct berval rdn;
|
||||
char *display;
|
||||
} opnames[] = {
|
||||
{ BER_BVC("cn=Bind"), "Bind" },
|
||||
{ BER_BVC("cn=Unbind"), "Unbind" },
|
||||
{ BER_BVC("cn=Search"), "Search" },
|
||||
{ BER_BVC("cn=Compare"), "Compare" },
|
||||
{ BER_BVC("cn=Modify"), "Modify" },
|
||||
{ BER_BVC("cn=Modrdn"), "ModDN" },
|
||||
{ BER_BVC("cn=Add"), "Add" },
|
||||
{ BER_BVC("cn=Delete"), "Delete" },
|
||||
{ BER_BVC("cn=Abandon"), "Abandon" },
|
||||
{ BER_BVC("cn=Extended"), "Extended" },
|
||||
{ BER_BVNULL, NULL }
|
||||
};
|
||||
|
||||
typedef struct counters {
|
||||
struct timeval time;
|
||||
unsigned long entries;
|
||||
unsigned long ops[SLAP_OP_LAST];
|
||||
} counters;
|
||||
|
||||
typedef struct csns {
|
||||
int num;
|
||||
int *sids;
|
||||
struct berval *vals;
|
||||
struct timeval *tvs;
|
||||
} csns;
|
||||
|
||||
typedef struct activity {
|
||||
time_t active;
|
||||
time_t idle;
|
||||
time_t maxlag;
|
||||
time_t lag;
|
||||
} activity;
|
||||
|
||||
typedef struct server {
|
||||
char *url;
|
||||
LDAP *ld;
|
||||
int flags;
|
||||
int sid;
|
||||
struct berval monitorbase;
|
||||
char *monitorfilter;
|
||||
counters c_prev;
|
||||
counters c_curr;
|
||||
csns csn_prev;
|
||||
csns csn_curr;
|
||||
activity *times;
|
||||
} server;
|
||||
|
||||
static void
|
||||
usage( char *name, char opt )
|
||||
{
|
||||
if ( opt ) {
|
||||
fprintf( stderr, "%s: unable to handle option \'%c\'\n\n",
|
||||
name, opt );
|
||||
}
|
||||
|
||||
fprintf( stderr, "usage: %s "
|
||||
"[-D <dn> [ -w <passwd> ]] "
|
||||
"[-d <level>] "
|
||||
"[-O <SASL secprops>] "
|
||||
"[-R <SASL realm>] "
|
||||
"[-U <SASL authcid> [-X <SASL authzid>]] "
|
||||
"[-x | -Y <SASL mech>] "
|
||||
"[-i <interval>] "
|
||||
"[-s <sids>] "
|
||||
"[-b <baseDN> ] URI[...]\n",
|
||||
name );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
struct berval base;
|
||||
int interval = 10;
|
||||
int numservers;
|
||||
server *servers;
|
||||
char *monfilter;
|
||||
|
||||
struct berval at_namingContexts = BER_BVC("namingContexts");
|
||||
struct berval at_monitorOpCompleted = BER_BVC("monitorOpCompleted");
|
||||
struct berval at_olmMDBEntries = BER_BVC("olmMDBEntries");
|
||||
struct berval at_contextCSN = BER_BVC("contextCSN");
|
||||
|
||||
void timestamp(time_t *tt)
|
||||
{
|
||||
struct tm *tm = gmtime(tt);
|
||||
printf("%d-%02d-%02d %02d:%02d:%02d",
|
||||
tm->tm_year + 1900, tm->tm_mon+1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
|
||||
void deltat(time_t *tt)
|
||||
{
|
||||
struct tm *tm = gmtime(tt);
|
||||
if (tm->tm_mday-1)
|
||||
printf("%02d+", tm->tm_mday-1);
|
||||
printf("%02d:%02d:%02d",
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
|
||||
static char *clearscreen = "\033[H\033[2J";
|
||||
|
||||
void display()
|
||||
{
|
||||
int i, j;
|
||||
struct timeval now;
|
||||
struct tm *tm;
|
||||
time_t now_t;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
now_t = now.tv_sec;
|
||||
printf("%s", clearscreen);
|
||||
timestamp(&now_t);
|
||||
printf("\n");
|
||||
|
||||
for (i=0; i<numservers; i++) {
|
||||
printf("%s\n", servers[i].url );
|
||||
if ( servers[i].flags & HAS_MONITOR ) {
|
||||
double rate;
|
||||
printf(" ");
|
||||
if ( servers[i].flags & HAS_ENTRIES )
|
||||
printf(" Entries ");
|
||||
for ( j = 0; j<SLAP_OP_LAST; j++ )
|
||||
printf(" %9s ", opnames[j].display);
|
||||
printf("\n");
|
||||
printf("Num ");
|
||||
if ( servers[i].flags & HAS_ENTRIES )
|
||||
printf("%10lu ", servers[i].c_curr.entries);
|
||||
for ( j = 0; j<SLAP_OP_LAST; j++ )
|
||||
printf("%10lu ", servers[i].c_curr.ops[j]);
|
||||
printf("\n");
|
||||
printf("Num/s ");
|
||||
if ( servers[i].flags & HAS_ENTRIES ) {
|
||||
rate = (servers[i].c_curr.entries - servers[i].c_prev.entries) / (double)interval;
|
||||
printf("%10.2f ", rate);
|
||||
}
|
||||
for ( j = 0; j<SLAP_OP_LAST; j++ ) {
|
||||
rate = (servers[i].c_curr.ops[j] - servers[i].c_prev.ops[j]) / (double)interval;
|
||||
printf("%10.2f ", rate);
|
||||
}
|
||||
printf("\n");
|
||||
servers[i].c_prev = servers[i].c_curr;
|
||||
}
|
||||
if ( servers[i].flags & HAS_BASE ) {
|
||||
int k;
|
||||
for (j=0; j<servers[i].csn_curr.num; j++) {
|
||||
int sid = servers[i].csn_curr.sids[j];
|
||||
printf("contextCSN: %s", servers[i].csn_curr.vals[j].bv_val );
|
||||
for (k=0; k<servers[i].csn_prev.num; k++)
|
||||
if (servers[i].csn_prev.sids[k] == sid)
|
||||
break;
|
||||
if (k == servers[i].csn_prev.num ||
|
||||
ber_bvcmp(&servers[i].csn_curr.vals[j],
|
||||
&servers[i].csn_prev.vals[k])) {
|
||||
/* a difference */
|
||||
if (servers[i].times[j].idle) {
|
||||
servers[i].times[j].idle = 0;
|
||||
servers[i].times[j].active = 0;
|
||||
servers[i].times[j].maxlag = 0;
|
||||
servers[i].times[j].lag = 0;
|
||||
}
|
||||
if (!servers[i].times[j].active)
|
||||
servers[i].times[j].active = now_t;
|
||||
printf(" actv@");
|
||||
timestamp(&servers[i].times[j].active);
|
||||
} else if ( servers[i].times[j].lag ) {
|
||||
printf(" actv@");
|
||||
timestamp(&servers[i].times[j].active);
|
||||
} else {
|
||||
if (servers[i].times[j].active && !servers[i].times[j].idle)
|
||||
servers[i].times[j].idle = now_t;
|
||||
if (servers[i].times[j].active) {
|
||||
printf(" actv@");
|
||||
timestamp(&servers[i].times[j].active);
|
||||
printf(", idle@");
|
||||
timestamp(&servers[i].times[j].idle);
|
||||
} else {
|
||||
printf(" idle");
|
||||
}
|
||||
}
|
||||
if (sid != servers[i].sid) {
|
||||
int l;
|
||||
for (k=0; k<numservers; k++) {
|
||||
if (servers[k].sid == sid) {
|
||||
for (l=0; l<servers[k].csn_curr.num; l++) {
|
||||
if (servers[k].csn_curr.sids[l] == sid ) {
|
||||
if (ber_bvcmp(&servers[i].csn_curr.vals[j],
|
||||
&servers[k].csn_curr.vals[l])) {
|
||||
struct timeval delta;
|
||||
int ahead = 0;
|
||||
time_t deltatt;
|
||||
delta.tv_sec = servers[k].csn_curr.tvs[l].tv_sec -
|
||||
servers[i].csn_curr.tvs[j].tv_sec;
|
||||
delta.tv_usec = servers[k].csn_curr.tvs[l].tv_usec -
|
||||
servers[i].csn_curr.tvs[j].tv_usec;
|
||||
if (delta.tv_usec < 0) {
|
||||
delta.tv_usec += 1000000;
|
||||
delta.tv_sec--;
|
||||
}
|
||||
if (delta.tv_sec < 0) {
|
||||
delta.tv_sec = -delta.tv_sec;
|
||||
ahead = 1;
|
||||
}
|
||||
deltatt = delta.tv_sec;
|
||||
if (ahead)
|
||||
printf(", ahead ");
|
||||
else
|
||||
printf(", behind ");
|
||||
deltat( &deltatt );
|
||||
servers[i].times[j].lag = deltatt;
|
||||
if (deltatt > servers[i].times[j].maxlag)
|
||||
servers[i].times[j].maxlag = deltatt;
|
||||
} else {
|
||||
servers[i].times[j].lag = 0;
|
||||
printf(", sync'd");
|
||||
}
|
||||
if (servers[i].times[j].maxlag) {
|
||||
printf(", max delta ");
|
||||
deltat( &servers[i].times[j].maxlag );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if ( servers[i].csn_prev.num != servers[i].csn_curr.num ) {
|
||||
servers[i].csn_prev.sids = realloc(servers[i].csn_prev.sids,
|
||||
servers[i].csn_curr.num * sizeof(int));
|
||||
servers[i].csn_prev.vals = realloc(servers[i].csn_prev.vals,
|
||||
servers[i].csn_curr.num * sizeof(struct berval));
|
||||
servers[i].csn_prev.tvs = realloc(servers[i].csn_prev.tvs,
|
||||
servers[i].csn_curr.num * sizeof(struct timeval));
|
||||
for (j=servers[i].csn_prev.num; j < servers[i].csn_curr.num; j++) {
|
||||
BER_BVZERO( &servers[i].csn_prev.vals[j] );
|
||||
}
|
||||
servers[i].csn_prev.num = servers[i].csn_curr.num;
|
||||
for (j=0; j<servers[i].csn_curr.num; j++)
|
||||
servers[i].csn_prev.sids[j] = servers[i].csn_curr.sids[j];
|
||||
}
|
||||
for (j=0; j<servers[i].csn_curr.num; j++)
|
||||
ber_bvreplace(&servers[i].csn_prev.vals[j],
|
||||
&servers[i].csn_curr.vals[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_counters(
|
||||
LDAP *ld,
|
||||
LDAPMessage *e,
|
||||
BerElement *ber,
|
||||
counters *c )
|
||||
{
|
||||
int i, rc;
|
||||
slap_op_t op = SLAP_OP_BIND;
|
||||
struct berval dn, bv, *bvals, **bvp = &bvals;
|
||||
|
||||
do {
|
||||
int done = 0;
|
||||
for ( rc = ldap_get_attribute_ber( ld, e, ber, &bv, bvp );
|
||||
rc == LDAP_SUCCESS;
|
||||
rc = ldap_get_attribute_ber( ld, e, ber, &bv, bvp )) {
|
||||
|
||||
if ( bv.bv_val == NULL ) break;
|
||||
if ( !ber_bvcmp( &bv, &at_monitorOpCompleted ) && bvals ) {
|
||||
c->ops[op] = strtoul( bvals[0].bv_val, NULL, 0 );
|
||||
done = 1;
|
||||
}
|
||||
if ( bvals ) {
|
||||
ber_memfree( bvals );
|
||||
bvals = NULL;
|
||||
}
|
||||
if ( done )
|
||||
break;
|
||||
}
|
||||
ber_free( ber, 0 );
|
||||
e = ldap_next_entry( ld, e );
|
||||
if ( !e )
|
||||
break;
|
||||
ldap_get_dn_ber( ld, e, &ber, &dn );
|
||||
op++;
|
||||
} while ( op < SLAP_OP_LAST );
|
||||
}
|
||||
|
||||
int
|
||||
slap_parse_csn_sid( struct berval *csnp )
|
||||
{
|
||||
char *p, *q;
|
||||
struct berval csn = *csnp;
|
||||
int i;
|
||||
|
||||
p = ber_bvchr( &csn, '#' );
|
||||
if ( !p )
|
||||
return -1;
|
||||
p++;
|
||||
csn.bv_len -= p - csn.bv_val;
|
||||
csn.bv_val = p;
|
||||
|
||||
p = ber_bvchr( &csn, '#' );
|
||||
if ( !p )
|
||||
return -1;
|
||||
p++;
|
||||
csn.bv_len -= p - csn.bv_val;
|
||||
csn.bv_val = p;
|
||||
|
||||
q = ber_bvchr( &csn, '#' );
|
||||
if ( !q )
|
||||
return -1;
|
||||
|
||||
csn.bv_len = q - p;
|
||||
|
||||
i = strtol( p, &q, 16 );
|
||||
if ( p == q || q != p + csn.bv_len || i < 0 || i > SLAP_SYNC_SID_MAX ) {
|
||||
i = -1;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void get_csns(
|
||||
csns *c,
|
||||
struct berval *bvs
|
||||
)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; bvs[i].bv_val; i++) ;
|
||||
if ( c->num != i ) {
|
||||
int j;
|
||||
c->vals = realloc( c->vals, i*sizeof(struct berval));
|
||||
c->sids = realloc( c->sids, i*sizeof(int));
|
||||
c->tvs = realloc( c->tvs, i*sizeof(struct timeval));
|
||||
for (j=c->num; j<i; j++) {
|
||||
BER_BVZERO( &c->vals[j] );
|
||||
}
|
||||
}
|
||||
c->num = i;
|
||||
for (i=0; i<c->num; i++) {
|
||||
struct lutil_tm tm;
|
||||
struct lutil_timet tt;
|
||||
ber_bvreplace( &c->vals[i], &bvs[i] );
|
||||
c->sids[i] = slap_parse_csn_sid( &bvs[i] );
|
||||
lutil_parsetime(c->vals[i].bv_val, &tm);
|
||||
c->tvs[i].tv_usec = tm.tm_usec;
|
||||
lutil_tm2time( &tm, &tt );
|
||||
c->tvs[i].tv_sec = tt.tt_sec;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
int i, rc, *msg1, *msg2;
|
||||
char **sids = NULL;
|
||||
struct tester_conn_args *config;
|
||||
|
||||
config = tester_init( "slapd-watcher", TESTER_TESTER );
|
||||
config->authmethod = LDAP_AUTH_SIMPLE;
|
||||
|
||||
while ( ( i = getopt( argc, argv, "D:O:R:U:X:Y:b:d:i:s:w:x" ) ) != EOF )
|
||||
{
|
||||
switch ( i ) {
|
||||
case 'b': /* base DN for contextCSN lookups */
|
||||
ber_str2bv( optarg, 0, 0, &base );
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
interval = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
sids = ldap_str2charray( optarg, "," );
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( tester_config_opt( config, i, optarg ) == LDAP_SUCCESS )
|
||||
break;
|
||||
|
||||
usage( argv[0], i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tester_config_finish( config );
|
||||
|
||||
/* don't clear the screen if debug is enabled */
|
||||
if (debug)
|
||||
clearscreen = "\n\n";
|
||||
|
||||
numservers = argc - optind;
|
||||
if ( !numservers )
|
||||
usage( argv[0], 0 );
|
||||
|
||||
if ( sids ) {
|
||||
for (i=0; sids[i]; i++ );
|
||||
if ( i != numservers ) {
|
||||
fprintf(stderr, "Number of sids doesn't equal number of server URLs\n");
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
servers = calloc( numservers, sizeof(server));
|
||||
|
||||
if ( base.bv_val ) {
|
||||
monfilter = "(|(entryDN:dnOneLevelMatch:=cn=Databases,cn=Monitor)" MONFILTER ")";
|
||||
} else {
|
||||
monfilter = MONFILTER;
|
||||
}
|
||||
|
||||
if ( numservers > 1 ) {
|
||||
for ( i=0; i<numservers; i++ )
|
||||
if ( sids )
|
||||
servers[i].sid = atoi(sids[i]);
|
||||
else
|
||||
servers[i].sid = i+1;
|
||||
}
|
||||
|
||||
for ( i = 0; i < numservers; i++ ) {
|
||||
int version = LDAP_VERSION3;
|
||||
servers[i].url = argv[i];
|
||||
config->uri = argv[i];
|
||||
tester_init_ld( &servers[i].ld, config, 0 );
|
||||
servers[i].flags = 0;
|
||||
{
|
||||
char *attrs[] = { at_namingContexts.bv_val, at_monitorOpCompleted.bv_val,
|
||||
at_olmMDBEntries.bv_val, NULL };
|
||||
LDAPMessage *res = NULL, *e = NULL;
|
||||
BerElement *ber = NULL;
|
||||
LDAP *ld = servers[i].ld;
|
||||
struct berval dn, bv, *bvals, **bvp = &bvals;
|
||||
int j;
|
||||
|
||||
rc = ldap_search_ext_s( ld, "cn=monitor", LDAP_SCOPE_SUBTREE, monfilter,
|
||||
attrs, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &res );
|
||||
switch(rc) {
|
||||
case LDAP_SIZELIMIT_EXCEEDED:
|
||||
case LDAP_TIMELIMIT_EXCEEDED:
|
||||
case LDAP_SUCCESS:
|
||||
gettimeofday( &servers[i].c_curr.time, 0 );
|
||||
servers[i].flags |= HAS_MONITOR;
|
||||
for ( e = ldap_first_entry( ld, res ); e; e = ldap_next_entry( ld, e )) {
|
||||
ldap_get_dn_ber( ld, e, &ber, &dn );
|
||||
if ( !strncasecmp( dn.bv_val, "cn=Database", sizeof("cn=Database")-1 ) ||
|
||||
!strncasecmp( dn.bv_val, "cn=Frontend", sizeof("cn=Frontend")-1 )) {
|
||||
int matched = 0;
|
||||
for ( rc = ldap_get_attribute_ber( ld, e, ber, &bv, bvp );
|
||||
rc == LDAP_SUCCESS;
|
||||
rc = ldap_get_attribute_ber( ld, e, ber, &bv, bvp )) {
|
||||
if ( bv.bv_val == NULL ) break;
|
||||
if (!ber_bvcmp( &bv, &at_namingContexts ) && bvals ) {
|
||||
for (j=0; bvals[j].bv_val; j++) {
|
||||
if ( !ber_bvstrcasecmp( &base, &bvals[j] )) {
|
||||
matched = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matched) {
|
||||
ber_memfree( bvals );
|
||||
bvals = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ber_bvcmp( &bv, &at_olmMDBEntries )) {
|
||||
ber_dupbv( &servers[i].monitorbase, &dn );
|
||||
servers[i].flags |= HAS_ENTRIES;
|
||||
servers[i].c_curr.entries = strtoul( bvals[0].bv_val, NULL, 0 );
|
||||
}
|
||||
ber_memfree( bvals );
|
||||
bvals = NULL;
|
||||
}
|
||||
} else if (!strncasecmp( dn.bv_val, opnames[0].rdn.bv_val,
|
||||
opnames[0].rdn.bv_len )) {
|
||||
get_counters( ld, e, ber, &servers[i].c_curr );
|
||||
break;
|
||||
}
|
||||
if ( ber )
|
||||
ber_free( ber, 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case LDAP_NO_SUCH_OBJECT:
|
||||
/* no cn=monitor */
|
||||
break;
|
||||
|
||||
default:
|
||||
tester_ldap_error( ld, "ldap_search_ext_s(cn=Monitor)", NULL );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
ldap_msgfree( res );
|
||||
if ( base.bv_val ) {
|
||||
char *attr2[] = { at_contextCSN.bv_val, NULL };
|
||||
rc = ldap_search_ext_s( ld, base.bv_val, LDAP_SCOPE_BASE, "(objectClass=*)",
|
||||
attr2, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &res );
|
||||
switch(rc) {
|
||||
case LDAP_SUCCESS:
|
||||
e = ldap_first_entry( ld, res );
|
||||
if ( e ) {
|
||||
servers[i].flags |= HAS_BASE;
|
||||
ldap_get_dn_ber( ld, e, &ber, &dn );
|
||||
for ( rc = ldap_get_attribute_ber( ld, e, ber, &bv, bvp );
|
||||
rc == LDAP_SUCCESS;
|
||||
rc = ldap_get_attribute_ber( ld, e, ber, &bv, bvp )) {
|
||||
int done = 0;
|
||||
if ( bv.bv_val == NULL ) break;
|
||||
if ( bvals ) {
|
||||
if ( !ber_bvcmp( &bv, &at_contextCSN )) {
|
||||
get_csns( &servers[i].csn_curr, bvals );
|
||||
done = 1;
|
||||
}
|
||||
ber_memfree( bvals );
|
||||
bvals = NULL;
|
||||
if ( done )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ldap_msgfree( res );
|
||||
break;
|
||||
|
||||
default:
|
||||
tester_ldap_error( ld, "ldap_search_ext_s(baseDN)", NULL );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<numservers; i++) {
|
||||
int j;
|
||||
if ( servers[i].flags & HAS_ENTRIES ) {
|
||||
int len = servers[i].monitorbase.bv_len + sizeof("(|(entryDN=)" MONFILTER ")");
|
||||
char *ptr = malloc(len);
|
||||
sprintf(ptr, "(|(entryDN=%s)" MONFILTER ")", servers[i].monitorbase.bv_val );
|
||||
servers[i].monitorfilter = ptr;
|
||||
} else if ( servers[i].flags & HAS_MONITOR ) {
|
||||
servers[i].monitorfilter = MONFILTER;
|
||||
}
|
||||
servers[i].c_prev = servers[i].c_curr;
|
||||
servers[i].csn_prev.num = servers[i].csn_curr.num;
|
||||
servers[i].csn_prev.sids = malloc(servers[i].csn_curr.num * sizeof(int));
|
||||
servers[i].csn_prev.vals = malloc(servers[i].csn_curr.num * sizeof(struct berval));
|
||||
for (j=0; j<servers[i].csn_curr.num; j++) {
|
||||
servers[i].csn_prev.sids[j] = servers[i].csn_curr.sids[j];
|
||||
ber_dupbv(&servers[i].csn_prev.vals[j],
|
||||
&servers[i].csn_curr.vals[j]);
|
||||
}
|
||||
servers[i].times = calloc( numservers, sizeof(activity));
|
||||
}
|
||||
|
||||
msg1 = malloc( numservers * 2 * sizeof(int));
|
||||
msg2 = msg1 + numservers;
|
||||
|
||||
display();
|
||||
|
||||
for (;;) {
|
||||
LDAPMessage *res = NULL, *e = NULL;
|
||||
BerElement *ber = NULL;
|
||||
struct berval dn, bv, *bvals, **bvp = &bvals;
|
||||
LDAP *ld;
|
||||
|
||||
sleep(interval);
|
||||
for (i=0; i<numservers; i++) {
|
||||
ld = servers[i].ld;
|
||||
if ( servers[i].flags & HAS_MONITOR ) {
|
||||
char *attrs[3] = { at_monitorOpCompleted.bv_val };
|
||||
if ( servers[i].flags & HAS_ENTRIES )
|
||||
attrs[1] = at_olmMDBEntries.bv_val;
|
||||
rc = ldap_search_ext( ld, "cn=monitor",
|
||||
LDAP_SCOPE_SUBTREE, servers[i].monitorfilter,
|
||||
attrs, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &msg1[i] );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
tester_ldap_error( ld, "ldap_search_ext(cn=Monitor)", NULL );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
if ( servers[i].flags & HAS_BASE ) {
|
||||
char *attrs[2] = { at_contextCSN.bv_val };
|
||||
rc = ldap_search_ext( ld, base.bv_val,
|
||||
LDAP_SCOPE_BASE, "(objectClass=*)",
|
||||
attrs, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &msg2[i] );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
tester_ldap_error( ld, "ldap_search_ext(baseDN)", NULL );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i=0; i<numservers; i++) {
|
||||
ld = servers[i].ld;
|
||||
if ( servers[i].flags & HAS_MONITOR ) {
|
||||
gettimeofday( &servers[i].c_curr.time, 0 );
|
||||
rc = ldap_result( ld, msg1[i], LDAP_MSG_ALL, NULL, &res );
|
||||
if ( rc < 0 ) {
|
||||
tester_ldap_error( ld, "ldap_result(cn=Monitor)", NULL );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
for ( e = ldap_first_entry( ld, res ); e; e = ldap_next_entry( ld, e )) {
|
||||
ldap_get_dn_ber( ld, e, &ber, &dn );
|
||||
if ( !strncasecmp( dn.bv_val, "cn=Database", sizeof("cn=Database")-1 ) ||
|
||||
!strncasecmp( dn.bv_val, "cn=Frontend", sizeof("cn=Frontend")-1 )) {
|
||||
for ( rc = ldap_get_attribute_ber( ld, e, ber, &bv, bvp );
|
||||
rc == LDAP_SUCCESS;
|
||||
rc = ldap_get_attribute_ber( ld, e, ber, &bv, bvp )) {
|
||||
if ( bv.bv_val == NULL ) break;
|
||||
if ( !ber_bvcmp( &bv, &at_olmMDBEntries )) {
|
||||
if ( !BER_BVISNULL( &servers[i].monitorbase )) {
|
||||
servers[i].c_curr.entries = strtoul( bvals[0].bv_val, NULL, 0 );
|
||||
}
|
||||
}
|
||||
ber_memfree( bvals );
|
||||
bvals = NULL;
|
||||
}
|
||||
} else if (!strncasecmp( dn.bv_val, opnames[0].rdn.bv_val,
|
||||
opnames[0].rdn.bv_len )) {
|
||||
get_counters( ld, e, ber, &servers[i].c_curr );
|
||||
break;
|
||||
}
|
||||
if ( ber )
|
||||
ber_free( ber, 0 );
|
||||
}
|
||||
ldap_msgfree( res );
|
||||
}
|
||||
if ( servers[i].flags & HAS_BASE ) {
|
||||
rc = ldap_result( ld, msg2[i], LDAP_MSG_ALL, NULL, &res );
|
||||
if ( rc < 0 ) {
|
||||
tester_ldap_error( ld, "ldap_result(baseDN)", NULL );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
e = ldap_first_entry( ld, res );
|
||||
if ( e ) {
|
||||
ldap_get_dn_ber( ld, e, &ber, &dn );
|
||||
for ( rc = ldap_get_attribute_ber( ld, e, ber, &bv, bvp );
|
||||
rc == LDAP_SUCCESS;
|
||||
rc = ldap_get_attribute_ber( ld, e, ber, &bv, bvp )) {
|
||||
int done = 0;
|
||||
if ( bv.bv_val == NULL ) break;
|
||||
if ( bvals ) {
|
||||
if ( !ber_bvcmp( &bv, &at_contextCSN )) {
|
||||
get_csns( &servers[i].csn_curr, bvals );
|
||||
done = 1;
|
||||
}
|
||||
ber_memfree( bvals );
|
||||
bvals = NULL;
|
||||
if ( done )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ldap_msgfree( res );
|
||||
}
|
||||
}
|
||||
display();
|
||||
}
|
||||
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
Loading…
Reference in a new issue