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 )
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;
# 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);
#include "ldap_rq.h"
#include "rewrite.h"
+
+#include "back-monitor/back-monitor.h"
+
#define SUFFIXM_CTX "<suffix massage>"
#ifdef LDAP_CONTROL_X_DIRSYNC
#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;
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;
}
- 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 ) {
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
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 ) )
{
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 ) )
{
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 );
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 ) )
{
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 ) )
{
return rc;
}
+static int
+syncrepl_monitor_add( syncinfo_t *si );
+
+static int
+syncrepl_monitor_del( syncinfo_t *si );
+
static void *
do_syncrepl(
void *ctx,
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 */
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;
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 );
}
ldap_pvt_thread_mutex_destroy( &sie->si_mutex );
+ ldap_pvt_thread_mutex_destroy( &sie->si_monitor_mutex );
bindconf_free( &sie->si_bindconf );
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 )
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 );