mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
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:
parent
d1283f8161
commit
1748ec59a6
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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 );
|
||||
|
Loading…
Reference in New Issue
Block a user