ITS#9339 Add syncrepl status to cn=monitor

Shows connection address, refresh/persist state, time of last
connect attempt and received data, and last sent and
received cookies per consumer.
This commit is contained in:
Howard Chu 2020-09-06 16:09:35 +01:00 committed by Quanah Gibson-Mount
parent d1283f8161
commit 1748ec59a6
5 changed files with 555 additions and 43 deletions

View File

@ -78,6 +78,8 @@ backend_init_controls( BackendInfo *bi )
return 0;
}
extern int syncrepl_monitor_init(void);
int backend_init(void)
{
int rc = -1;
@ -114,6 +116,9 @@ int backend_init(void)
LDAP_STAILQ_INSERT_TAIL(&backendInfo, bi, bi_next);
}
/* HACK: need schema defined in deterministic order */
syncrepl_monitor_init();
if ( nBackendInfo > 0) {
return 0;

View File

@ -2121,6 +2121,78 @@ destroy_listeners( void )
slap_listeners = NULL;
}
void
slap_sockaddrstr( Sockaddr *sa, struct berval *addrbuf )
{
char *addr;
switch( sa->sa_addr.sa_family ) {
#ifdef LDAP_PF_LOCAL
case AF_LOCAL:
addrbuf->bv_len = snprintf( addrbuf->bv_val, addrbuf->bv_len,
"PATH=%s", sa->sa_un_addr.sun_path );
break;
#endif
#ifdef LDAP_PF_INET6
case AF_INET6:
strcpy(addrbuf->bv_val, "IP=");
if ( IN6_IS_ADDR_V4MAPPED(&sa->sa_in6_addr.sin6_addr) ) {
#if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
addr = inet_ntop( AF_INET,
((struct in_addr *)&sa->sa_in6_addr.sin6_addr.s6_addr[12]),
addrbuf->bv_val+3, addrbuf->bv_len-3 );
#else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
addr = inet_ntoa( *((struct in_addr *)
&sa->sa_in6_addr.sin6_addr.s6_addr[12]) );
#endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
if ( !addr ) addr = SLAP_STRING_UNKNOWN;
if ( addr != addrbuf->bv_val+3 ) {
addrbuf->bv_len = sprintf( addrbuf->bv_val+3, "%s:%d", addr,
(unsigned) ntohs( sa->sa_in6_addr.sin6_port ) ) + 3;
} else {
int len = strlen( addr );
addrbuf->bv_len = sprintf( addr+len, ":%d",
(unsigned) ntohs( sa->sa_in6_addr.sin6_port ) ) + len + 3;
}
} else {
addr = inet_ntop( AF_INET6,
&sa->sa_in6_addr.sin6_addr,
addrbuf->bv_val+4, addrbuf->bv_len-4 );
if ( !addr ) addr = SLAP_STRING_UNKNOWN;
if ( addr != addrbuf->bv_val+4 ) {
addrbuf->bv_len = sprintf( addrbuf->bv_val+3, "[%s]:%d", addr,
(unsigned) ntohs( sa->sa_in6_addr.sin6_port ) ) + 3;
} else {
int len = strlen( addr );
addrbuf->bv_val[3] = '[';
addrbuf->bv_len = sprintf( addr+len, "]:%d",
(unsigned) ntohs( sa->sa_in6_addr.sin6_port ) ) + len + 4;
}
}
break;
#endif /* LDAP_PF_INET6 */
case AF_INET:
strcpy(addrbuf->bv_val, "IP=");
#if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
addr = inet_ntop( AF_INET, &sa->sa_in_addr.sin_addr,
addrbuf->bv_val+3, addrbuf->bv_len-3 );
#else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
addr = inet_ntoa( sa->sa_in_addr.sin_addr );
#endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
if ( !addr ) addr = SLAP_STRING_UNKNOWN;
if ( addr != addrbuf->bv_val+3 ) {
addrbuf->bv_len = sprintf( addrbuf->bv_val+3, "%s:%d", addr,
(unsigned) ntohs( sa->sa_in_addr.sin_port ) ) + 3;
} else {
int len = strlen( addr );
addrbuf->bv_len = sprintf( addr+len, ":%d",
(unsigned) ntohs( sa->sa_in_addr.sin_port ) ) + len + 3;
}
break;
default:
addrbuf->bv_val[0] = '\0';
}
}
static int
slap_listener(
Listener *sl )
@ -2139,18 +2211,12 @@ slap_listener(
char *dnsname = NULL;
const char *peeraddr = NULL;
/* we assume INET6_ADDRSTRLEN > INET_ADDRSTRLEN */
char addr[INET6_ADDRSTRLEN];
#ifdef LDAP_PF_LOCAL
char peername[MAXPATHLEN + sizeof("PATH=")];
char peername[SLAP_ADDRLEN];
struct berval peerbv = BER_BVC(peername);
#ifdef LDAP_PF_LOCAL_SENDMSG
char peerbuf[8];
struct berval peerbv = BER_BVNULL;
#endif
#elif defined(LDAP_PF_INET6)
char peername[sizeof("IP=[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535")];
#else /* ! LDAP_PF_LOCAL && ! LDAP_PF_INET6 */
char peername[sizeof("IP=255.255.255.255:65336")];
#endif /* LDAP_PF_LOCAL */
int cflag;
int tid;
@ -2315,40 +2381,10 @@ slap_listener(
# ifdef LDAP_PF_INET6
case AF_INET6:
if ( IN6_IS_ADDR_V4MAPPED(&from.sa_in6_addr.sin6_addr) ) {
#if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
peeraddr = inet_ntop( AF_INET,
((struct in_addr *)&from.sa_in6_addr.sin6_addr.s6_addr[12]),
addr, sizeof(addr) );
#else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
peeraddr = inet_ntoa( *((struct in_addr *)
&from.sa_in6_addr.sin6_addr.s6_addr[12]) );
#endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
if ( !peeraddr ) peeraddr = SLAP_STRING_UNKNOWN;
sprintf( peername, "IP=%s:%d", peeraddr,
(unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
} else {
peeraddr = inet_ntop( AF_INET6,
&from.sa_in6_addr.sin6_addr,
addr, sizeof addr );
if ( !peeraddr ) peeraddr = SLAP_STRING_UNKNOWN;
sprintf( peername, "IP=[%s]:%d", peeraddr,
(unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
}
break;
# endif /* LDAP_PF_INET6 */
case AF_INET: {
#if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
peeraddr = inet_ntop( AF_INET, &from.sa_in_addr.sin_addr,
addr, sizeof(addr) );
#else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
peeraddr = inet_ntoa( from.sa_in_addr.sin_addr );
#endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
if ( !peeraddr ) peeraddr = SLAP_STRING_UNKNOWN;
sprintf( peername, "IP=%s:%d", peeraddr,
(unsigned) ntohs( from.sa_in_addr.sin_port ) );
} break;
case AF_INET:
slap_sockaddrstr( &from, &peerbv );
break;
default:
slapd_close(sfd);

View File

@ -893,6 +893,7 @@ LDAP_SLAPD_F (void) slap_resume_listeners LDAP_P((void));
LDAP_SLAPD_F (int) slap_pause_server LDAP_P((void));
LDAP_SLAPD_F (int) slap_unpause_server LDAP_P((void));
LDAP_SLAPD_F (void) slap_sockaddrstr LDAP_P((Sockaddr *sa, struct berval *));
LDAP_SLAPD_F (void) slapd_set_write LDAP_P((ber_socket_t s, int wake));
LDAP_SLAPD_F (void) slapd_clr_write LDAP_P((ber_socket_t s, int wake));

View File

@ -2858,6 +2858,14 @@ typedef void (SEND_LDAP_INTERMEDIATE)(
typedef struct Listener Listener;
#ifdef LDAP_PF_LOCAL
#define SLAP_ADDRLEN (MAXPATHLEN + sizeof("PATH="))
#elif defined(LDAP_PF_INET6)
#define SLAP_ADDRLEN sizeof("IP=[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535")
#else
#define SLAP_ADDRLEN sizeof("IP=255.255.255.255:65336")
#endif
/*
* represents a connection from an ldap client
*/

View File

@ -32,6 +32,9 @@
#include "ldap_rq.h"
#include "rewrite.h"
#include "back-monitor/back-monitor.h"
#define SUFFIXM_CTX "<suffix massage>"
#ifdef LDAP_CONTROL_X_DIRSYNC
@ -152,8 +155,19 @@ typedef struct syncinfo_s {
#ifdef LDAP_CONTROL_X_DIRSYNC
struct berval si_dirSyncCookie;
#endif
unsigned long si_prevchange;;
unsigned long si_prevchange;
unsigned long si_lastchange;
/* monitor info */
int si_monitorInited;
time_t si_lastconnect;
time_t si_lastcontact;
struct berval *si_connaddr;
struct berval si_lastCookieRcvd;
struct berval si_lastCookieSent;
struct berval si_monitor_ndn;
ldap_pvt_thread_mutex_t si_monitor_mutex;
ldap_pvt_thread_mutex_t si_mutex;
} syncinfo_t;
@ -912,6 +926,8 @@ do_syncrep1(
void *ssl;
#endif
si->si_lastconnect = slap_get_time();
si->si_refreshDone = 0;
rc = slap_client_connect( &si->si_ld, &si->si_bindconf );
if ( rc != LDAP_SUCCESS ) {
goto done;
@ -1069,10 +1085,13 @@ do_syncrep1(
}
si->si_refreshDone = 0;
Debug( LDAP_DEBUG_SYNC, "do_syncrep1: %s starting refresh (sending cookie=%s)\n",
si->si_ridtxt, si->si_syncCookie.octet_str.bv_val );
ldap_pvt_thread_mutex_lock( &si->si_monitor_mutex );
ber_bvreplace( &si->si_lastCookieSent, &si->si_syncCookie.octet_str );
ldap_pvt_thread_mutex_unlock( &si->si_monitor_mutex );
rc = ldap_sync_search( si, op->o_tmpmemctx );
if( rc != LDAP_SUCCESS ) {
@ -1241,6 +1260,7 @@ do_syncrep2(
rc = SYNC_SHUTDOWN;
goto done;
}
si->si_lastcontact = slap_get_time();
switch( ldap_msgtype( msg ) ) {
case LDAP_RES_SEARCH_ENTRY:
#ifdef LDAP_CONTROL_X_DIRSYNC
@ -1357,6 +1377,10 @@ do_syncrep2(
if ( !BER_BVISNULL( &cookie ) ) {
ch_free( syncCookie.octet_str.bv_val );
ber_dupbv( &syncCookie.octet_str, &cookie );
ldap_pvt_thread_mutex_lock( &si->si_monitor_mutex );
ber_bvreplace( &si->si_lastCookieRcvd, &cookie );
ldap_pvt_thread_mutex_unlock( &si->si_monitor_mutex );
}
if ( !BER_BVISNULL( &syncCookie.octet_str ) )
{
@ -1571,6 +1595,10 @@ logerr:
if ( !BER_BVISNULL( &cookie ) ) {
ch_free( syncCookie.octet_str.bv_val );
ber_dupbv( &syncCookie.octet_str, &cookie);
ldap_pvt_thread_mutex_lock( &si->si_monitor_mutex );
ber_bvreplace( &si->si_lastCookieRcvd, &cookie );
ldap_pvt_thread_mutex_unlock( &si->si_monitor_mutex );
}
if ( !BER_BVISNULL( &syncCookie.octet_str ) )
{
@ -1656,6 +1684,10 @@ logerr:
if ( !BER_BVISNULL( &cookie ) ) {
ch_free( syncCookie.octet_str.bv_val );
ber_dupbv( &syncCookie.octet_str, &cookie );
ldap_pvt_thread_mutex_lock( &si->si_monitor_mutex );
ber_bvreplace( &si->si_lastCookieRcvd, &cookie );
ldap_pvt_thread_mutex_unlock( &si->si_monitor_mutex );
}
if (!BER_BVISNULL( &syncCookie.octet_str ) ) {
slap_parse_sync_cookie( &syncCookie, NULL );
@ -1687,6 +1719,10 @@ logerr:
if ( !BER_BVISNULL( &cookie ) ) {
ch_free( syncCookie.octet_str.bv_val );
ber_dupbv( &syncCookie.octet_str, &cookie );
ldap_pvt_thread_mutex_lock( &si->si_monitor_mutex );
ber_bvreplace( &si->si_lastCookieRcvd, &cookie );
ldap_pvt_thread_mutex_unlock( &si->si_monitor_mutex );
}
if ( !BER_BVISNULL( &syncCookie.octet_str ) )
{
@ -1728,6 +1764,10 @@ logerr:
if ( !BER_BVISNULL( &cookie ) ) {
ch_free( syncCookie.octet_str.bv_val );
ber_dupbv( &syncCookie.octet_str, &cookie );
ldap_pvt_thread_mutex_lock( &si->si_monitor_mutex );
ber_bvreplace( &si->si_lastCookieRcvd, &cookie );
ldap_pvt_thread_mutex_unlock( &si->si_monitor_mutex );
}
if ( !BER_BVISNULL( &syncCookie.octet_str ) )
{
@ -1868,6 +1908,12 @@ done:
return rc;
}
static int
syncrepl_monitor_add( syncinfo_t *si );
static int
syncrepl_monitor_del( syncinfo_t *si );
static void *
do_syncrepl(
void *ctx,
@ -1889,6 +1935,11 @@ do_syncrepl(
if ( slapd_shutdown )
return NULL;
if ( !si->si_monitorInited ) {
syncrepl_monitor_add( si );
si->si_monitorInited = 1;
}
Debug( LDAP_DEBUG_TRACE, "=>do_syncrepl %s\n", si->si_ridtxt );
/* Don't get stuck here while a pause is initiated */
@ -1994,6 +2045,15 @@ reload:
if ( rc == LDAP_SUCCESS ) {
ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s );
if ( si->si_connaddr ) {
Sockaddr addr;
socklen_t len = sizeof( addr );
if ( !getsockname( s, &addr.sa_addr, &len )) {
si->si_connaddr->bv_len = SLAP_ADDRLEN;
slap_sockaddrstr( &addr, si->si_connaddr );
}
}
/* use current DB */
op->o_bd = be;
op->o_dn = op->o_bd->be_rootdn;
@ -5673,6 +5733,10 @@ syncinfo_free( syncinfo_t *sie, int free_all )
do {
si_next = sie->si_next;
if ( !BER_BVISEMPTY( &sie->si_monitor_ndn )) {
syncrepl_monitor_del( sie );
}
if ( sie->si_ld ) {
if ( sie->si_conn ) {
connection_client_stop( sie->si_conn );
@ -5693,6 +5757,7 @@ syncinfo_free( syncinfo_t *sie, int free_all )
}
ldap_pvt_thread_mutex_destroy( &sie->si_mutex );
ldap_pvt_thread_mutex_destroy( &sie->si_monitor_mutex );
bindconf_free( &sie->si_bindconf );
@ -6462,6 +6527,402 @@ parse_syncrepl_line(
return 0;
}
/* monitor entry contains:
provider URLs
timestamp of last contact
cookievals
*/
static ObjectClass *oc_olmSyncRepl;
static AttributeDescription *ad_olmProviderURIList,
*ad_olmConnection, *ad_olmSyncPhase,
*ad_olmNextConnect, *ad_olmLastConnect, *ad_olmLastContact,
*ad_olmLastCookieRcvd, *ad_olmLastCookieSent;
static struct {
char *name;
char *oid;
} s_oid[] = {
{ "olmSyncReplAttributes", "olmOverlayAttributes:1" },
{ "olmSyncReplObjectClasses", "olmOverlayObjectClasses:1" },
{ NULL }
};
static struct {
char *desc;
AttributeDescription **ad;
} s_at[] = {
{ "( olmSyncReplAttributes:1 "
"NAME ( 'olmSRProviderURIList' ) "
"DESC 'List of provider URIs for this consumer instance' "
"SUP monitoredInfo "
"NO-USER-MODIFICATION "
"USAGE dSAOperation )",
&ad_olmProviderURIList },
{ "( olmSyncReplAttributes:2 "
"NAME ( 'olmSRConnection' ) "
"DESC 'Local address:port of connection to provider' "
"SUP monitoredInfo "
"SINGLE-VALUE "
"NO-USER-MODIFICATION "
"USAGE dSAOperation )",
&ad_olmConnection },
{ "( olmSyncReplAttributes:3 "
"NAME ( 'olmSRSyncPhase' ) "
"DESC 'Current syncrepl mode' "
"SUP monitoredInfo "
"SINGLE-VALUE "
"NO-USER-MODIFICATION "
"USAGE dSAOperation )",
&ad_olmSyncPhase },
{ "( olmSyncReplAttributes:4 "
"NAME ( 'olmSRNextConnect' ) "
"DESC 'Scheduled time of next connection attempt' "
"SUP monitorTimestamp "
"SINGLE-VALUE "
"NO-USER-MODIFICATION "
"USAGE dSAOperation )",
&ad_olmNextConnect },
{ "( olmSyncReplAttributes:5 "
"NAME ( 'olmSRLastConnect' ) "
"DESC 'Time last connected to provider' "
"SUP monitorTimestamp "
"SINGLE-VALUE "
"NO-USER-MODIFICATION "
"USAGE dSAOperation )",
&ad_olmLastConnect },
{ "( olmSyncReplAttributes:6 "
"NAME ( 'olmSRLastContact' ) "
"DESC 'Time last message received from provider' "
"SUP monitorTimestamp "
"SINGLE-VALUE "
"NO-USER-MODIFICATION "
"USAGE dSAOperation )",
&ad_olmLastContact },
{ "( olmSyncReplAttributes:7 "
"NAME ( 'olmSRLastCookieRcvd' ) "
"DESC 'Last sync cookie received from provider' "
"SUP monitoredInfo "
"NO-USER-MODIFICATION "
"USAGE dSAOperation )",
&ad_olmLastCookieRcvd },
{ "( olmSyncReplAttributes:8 "
"NAME ( 'olmSRLastCookieSent' ) "
"DESC 'Last sync cookie sent to provider' "
"SUP monitoredInfo "
"NO-USER-MODIFICATION "
"USAGE dSAOperation )",
&ad_olmLastCookieSent },
{ NULL }
};
static struct {
char *desc;
ObjectClass **oc;
} s_oc[] = {
{ "( olmSyncReplObjectClasses:1 "
"NAME ( 'olmSyncReplInstance' ) "
"SUP monitoredObject STRUCTURAL "
"MAY ( "
"olmSRProviderURIList "
"$ olmSRConnection "
"$ olmSRSyncPhase "
"$ olmSRNextConnect "
"$ olmSRLastConnect "
"$ olmSRLastContact "
"$ olmSRLastCookieRcvd "
"$ olmSRLastCookieSent "
") )",
&oc_olmSyncRepl },
{ NULL }
};
static int
syncrepl_monitor_initialized;
int
syncrepl_monitor_init( void )
{
int i, code;
if ( syncrepl_monitor_initialized )
return 0;
if ( backend_info( "monitor" ) == NULL )
return -1;
{
ConfigArgs c;
char *argv[3];
argv[ 0 ] = "syncrepl monitor";
c.argv = argv;
c.argc = 2;
c.fname = argv[0];
for ( i=0; s_oid[i].name; i++ ) {
argv[1] = s_oid[i].name;
argv[2] = s_oid[i].oid;
if ( parse_oidm( &c, 0, NULL )) {
Debug( LDAP_DEBUG_ANY,
"syncrepl_monitor_init: unable to add "
"objectIdentifier \"%s=%s\"\n",
s_oid[i].name, s_oid[i].oid );
return 2;
}
}
}
for ( i=0; s_at[i].desc != NULL; i++ ) {
code = register_at( s_at[i].desc, s_at[i].ad, 1 );
if ( code != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY,
"syncrepl_monitor_init: register_at failed for attributeType (%s)\n",
s_at[i].desc );
return 3;
} else {
(*s_at[i].ad)->ad_type->sat_flags |= SLAP_AT_HIDE;
}
}
for ( i=0; s_oc[i].desc != NULL; i++ ) {
code = register_oc( s_oc[i].desc, s_oc[i].oc, 1 );
if ( code != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY,
"syncrepl_monitor_init: register_oc failed for objectClass (%s)\n",
s_oc[i].desc );
return 4;
} else {
(*s_oc[i].oc)->soc_flags |= SLAP_OC_HIDE;
}
}
syncrepl_monitor_initialized = 1;
return 0;
}
static const struct berval zerotime = BER_BVC("00000101000000Z");
static int
syncrepl_monitor_update(
Operation *op,
SlapReply *rs,
Entry *e,
void *priv )
{
syncinfo_t *si = (syncinfo_t *)priv;
Attribute *a;
int isConnected = 0;
a = attr_find( e->e_attrs, ad_olmConnection );
if ( !a )
return SLAP_CB_CONTINUE;
if ( si->si_ld ) {
isConnected = 1;
} else {
a->a_vals[0].bv_val[0] = '\0';
a->a_vals[0].bv_len = 0;
}
a = a->a_next;
if ( a->a_desc != ad_olmSyncPhase )
return SLAP_CB_CONTINUE;
if ( si->si_refreshDone ) {
struct berval bv = BER_BVC("Persist");
ber_bvreplace( &a->a_vals[0], &bv );
} else {
if ( si->si_syncdata && si->si_logstate == SYNCLOG_FALLBACK ) {
struct berval bv = BER_BVC("Fallback Refresh");
ber_bvreplace( &a->a_vals[0], &bv );
} else {
struct berval bv = BER_BVC("Refresh");
ber_bvreplace( &a->a_vals[0], &bv );
}
}
{
struct tm tm;
char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
ber_len_t len;
a = a->a_next;
if ( a->a_desc != ad_olmNextConnect )
return SLAP_CB_CONTINUE;
if ( !isConnected && si->si_re && si->si_re->next_sched.tv_sec ) {
time_t next_sched = si->si_re->next_sched.tv_sec;
ldap_pvt_gmtime( &next_sched, &tm );
lutil_gentime( tmbuf, sizeof( tmbuf ), &tm );
len = strlen( tmbuf );
assert( len == a->a_vals[0].bv_len );
AC_MEMCPY( a->a_vals[0].bv_val, tmbuf, len );
} else {
AC_MEMCPY( a->a_vals[0].bv_val, zerotime.bv_val, zerotime.bv_len );
}
a = a->a_next;
if ( a->a_desc != ad_olmLastConnect )
return SLAP_CB_CONTINUE;
if ( si->si_lastconnect ) {
ldap_pvt_gmtime( &si->si_lastconnect, &tm );
lutil_gentime( tmbuf, sizeof( tmbuf ), &tm );
len = strlen( tmbuf );
assert( len == a->a_vals[0].bv_len );
AC_MEMCPY( a->a_vals[0].bv_val, tmbuf, len );
}
a = a->a_next;
if ( a->a_desc != ad_olmLastContact )
return SLAP_CB_CONTINUE;
if ( si->si_lastcontact ) {
ldap_pvt_gmtime( &si->si_lastcontact, &tm );
lutil_gentime( tmbuf, sizeof( tmbuf ), &tm );
len = strlen( tmbuf );
assert( len == a->a_vals[0].bv_len );
AC_MEMCPY( a->a_vals[0].bv_val, tmbuf, len );
}
}
a = a->a_next;
if ( a->a_desc != ad_olmLastCookieRcvd )
return SLAP_CB_CONTINUE;
ldap_pvt_thread_mutex_lock( &si->si_monitor_mutex );
if ( !BER_BVISEMPTY( &si->si_lastCookieRcvd ) &&
!bvmatch( &a->a_vals[0], &si->si_lastCookieRcvd ))
ber_bvreplace( &a->a_vals[0], &si->si_lastCookieRcvd );
a = a->a_next;
if ( a->a_desc != ad_olmLastCookieSent ) {
ldap_pvt_thread_mutex_unlock( &si->si_monitor_mutex );
return SLAP_CB_CONTINUE;
}
if ( !BER_BVISEMPTY( &si->si_lastCookieSent ) &&
!bvmatch( &a->a_vals[0], &si->si_lastCookieSent ))
ber_bvreplace( &a->a_vals[0], &si->si_lastCookieSent );
ldap_pvt_thread_mutex_unlock( &si->si_monitor_mutex );
return SLAP_CB_CONTINUE;
}
static int
syncrepl_monitor_add(
syncinfo_t *si
)
{
BackendInfo *mi;
monitor_extra_t *mbe;
struct berval pndn, pdn, rdn, bv;
char rdnbuf[sizeof("cn=Consumer 999")];
Entry *e, *p;
int rc;
if ( !syncrepl_monitor_initialized )
return -1;
mi = backend_info( "monitor" );
if ( !mi || !mi->bi_extra ) {
SLAP_DBFLAGS( si->si_be ) ^= SLAP_DBFLAG_MONITORING;
return 0;
}
mbe = mi->bi_extra;
if ( !mbe->is_configured() ) {
return 0;
}
rc = mbe->register_database( si->si_be, &pndn );
if ( rc ) {
Debug( LDAP_DEBUG_ANY, "syncrepl_monitor_add: "
"failed to register the database with back-monitor\n" );
return rc;
}
rdn.bv_len = sprintf(rdnbuf, "cn=Consumer %03d", si->si_rid );
rdn.bv_val = rdnbuf;
p = mbe->entry_get_unlocked( &pndn );
if ( p ) {
pdn = p->e_name;
} else {
pdn = pndn;
}
e = mbe->entry_stub( &pdn, &pndn, &rdn,
oc_olmSyncRepl, NULL, NULL );
if ( e == NULL ) {
Debug( LDAP_DEBUG_ANY,
"syncrepl_monitor_add: "
"unable to create entry \"%s,%s\"\n",
rdn.bv_val, pndn.bv_val );
return -1;
}
attr_merge_normalize_one( e, ad_olmProviderURIList,
&si->si_bindconf.sb_uri, NULL );
{
char addrbuf[SLAP_ADDRLEN];
struct berval bv = BER_BVC(addrbuf);
addrbuf[0] = '\0';
attr_merge_normalize_one( e, ad_olmConnection, &bv, NULL );
}
{
struct berval bv = BER_BVC("Refresh");
attr_merge_normalize_one( e, ad_olmSyncPhase, &bv, NULL );
}
{
attr_merge_normalize_one( e, ad_olmNextConnect, (struct berval *)&zerotime, NULL );
attr_merge_normalize_one( e, ad_olmLastConnect, (struct berval *)&zerotime, NULL );
attr_merge_normalize_one( e, ad_olmLastContact, (struct berval *)&zerotime, NULL );
}
{
struct berval bv = BER_BVC("");
attr_merge_normalize_one( e, ad_olmLastCookieRcvd, &bv, NULL );
attr_merge_normalize_one( e, ad_olmLastCookieSent, &bv, NULL );
}
{
monitor_callback_t *cb = ch_calloc( sizeof( monitor_callback_t ), 1 );
cb->mc_update = syncrepl_monitor_update;
cb->mc_private = si;
rc = mbe->register_entry( e, cb, NULL, 0 );
}
p = mbe->entry_get_unlocked( &e->e_nname );
if ( p ) {
Attribute *a = attr_find( p->e_attrs, ad_olmConnection );
if ( a ) {
si->si_connaddr = &a->a_vals[0];
a->a_vals[0].bv_len = 0;
}
}
si->si_monitor_ndn = e->e_nname;
BER_BVZERO( &e->e_nname );
entry_free( e );
return rc;
}
static int
syncrepl_monitor_del(
syncinfo_t *si
)
{
BackendInfo *mi;
mi = backend_info( "monitor" );
if ( mi && mi->bi_extra ) {
monitor_extra_t *mbe = mi->bi_extra;
mbe->unregister_entry( &si->si_monitor_ndn );
}
ch_free( si->si_lastCookieSent.bv_val );
ch_free( si->si_lastCookieRcvd.bv_val );
ch_free( si->si_monitor_ndn.bv_val );
return 0;
}
static int
add_syncrepl(
ConfigArgs *c )
@ -6512,6 +6973,7 @@ add_syncrepl(
si->si_presentlist = NULL;
LDAP_LIST_INIT( &si->si_nonpresentlist );
ldap_pvt_thread_mutex_init( &si->si_monitor_mutex );
ldap_pvt_thread_mutex_init( &si->si_mutex );
rc = parse_syncrepl_line( c, si );