bi->bi_db_open = 0;
bi->bi_db_close = 0;
bi->bi_db_destroy = ldap_back_db_destroy;
+ bi->bi_db_sync = 0;
bi->bi_op_bind = ldap_back_bind;
bi->bi_op_unbind = 0;
flags |= LDBM_NOLOCKING;
}
- if( li->li_dbwritesync ) {
+ if( li->li_dbwritesync && global_backendsyncfreq == 0) {
flags |= LDBM_SYNC;
} else {
flags |= LDBM_NOSYNC;
ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex );
}
+void
+ldbm_cache_sync( Backend *be )
+{
+ struct ldbminfo *li = (struct ldbminfo *) be->be_private;
+ int i;
+
+ ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex );
+ for ( i = 0; i < MAXDBCACHE; i++ ) {
+ if ( li->li_dbcache[i].dbc_name != NULL && li->li_dbcache[i].dbc_dirty ) {
+ Debug( LDAP_DEBUG_TRACE, "ldbm syncing db (%s)\n",
+ li->li_dbcache[i].dbc_name, 0, 0 );
+ ldbm_sync( li->li_dbcache[i].dbc_db );
+ li->li_dbcache[i].dbc_dirty = 0;
+ }
+ }
+ ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex );
+}
+
Datum
ldbm_cache_fetch(
DBCache *db,
bi->bi_db_open = ldbm_back_db_open;
bi->bi_db_close = ldbm_back_db_close;
bi->bi_db_destroy = ldbm_back_db_destroy;
+ bi->bi_db_sync = ldbm_cache_sync;
bi->bi_op_bind = ldbm_back_bind;
bi->bi_op_unbind = ldbm_back_unbind;
void ldbm_cache_close LDAP_P(( Backend *be, DBCache *db ));
void ldbm_cache_really_close LDAP_P(( Backend *be, DBCache *db ));
void ldbm_cache_flush_all LDAP_P(( Backend *be ));
+void ldbm_cache_sync LDAP_P(( Backend *be ));
Datum ldbm_cache_fetch LDAP_P(( DBCache *db, Datum key ));
int ldbm_cache_store LDAP_P(( DBCache *db, Datum key, Datum data, int flags ));
int ldbm_cache_delete LDAP_P(( DBCache *db, Datum key ));
bi->bi_db_open = 0;
bi->bi_db_close = 0;
bi->bi_db_destroy = 0;
+ bi->bi_db_sync = 0;
bi->bi_op_bind = 0;
bi->bi_op_unbind = 0;
bi->bi_db_open = 0;
bi->bi_db_close = 0;
bi->bi_db_destroy = shell_back_db_destroy;
+ bi->bi_db_sync = 0;
bi->bi_op_bind = shell_back_bind;
bi->bi_op_unbind = shell_back_unbind;
bi->bi_db_open = backsql_db_open;
bi->bi_db_close = backsql_db_close;
bi->bi_db_destroy = backsql_db_destroy;
+ bi->bi_db_sync = 0;
#ifdef BACKSQL_ALL_DONE
bi->bi_op_abandon = backsql_abandon;
return -1;
}
+
+int backend_sync( Backend *be )
+{
+ int i;
+ int rc = 0;
+
+ if( be != NULL ) {
+ /* sync a specific backend database */
+
+ if ( be->bd_info->bi_nDB == 0 ) {
+ /* no database of this type, we never opened it */
+ return 0;
+ }
+
+ if ( be->bd_info->bi_db_sync ) {
+ be->bd_info->bi_db_sync( be );
+ }
+
+ return 0;
+ }
+
+ /* sync each backend database */
+ for( i = 0; i < nBackendDB; i++ ) {
+ if ( backendDB[i].bd_info->bi_db_sync ) {
+ rc = backendDB[i].bd_info->bi_db_sync(
+ &backendDB[i] );
+ }
+
+ if(rc != 0) {
+ Debug( LDAP_DEBUG_ANY,
+ "backend_sync: bi_sync %s failed!\n",
+ backendDB[i].be_type, 0, 0 );
+ }
+ }
+
+ return 0;
+}
+
+
int backend_shutdown( Backend *be )
{
int i;
char *replogfile;
int global_lastmod = ON;
int global_idletimeout = 0;
+int global_backendsyncfreq = 0;
char *global_host = NULL;
char *global_realm = NULL;
char *ldap_srvtab = "";
global_idletimeout = i;
+ /* set backend sync frequency */
+ } else if ( strcasecmp( cargv[0], "backendsyncfreq" ) == 0 ) {
+#ifndef NO_THREADS
+ int i;
+ if ( cargc < 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing frquency value in \"backendsyncfreq <seconds>\" line\n",
+ fname, lineno, 0 );
+ return 1;
+ }
+
+ i = atoi( cargv[1] );
+
+ if( i < 0 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: frquency value (%d) invalid \"backendsyncfreq <seconds>\" line\n",
+ fname, lineno, i );
+ return 1;
+ }
+
+ global_backendsyncfreq = i;
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "\"dbsyncfreq\" not supported in non-threaded environment\n");
+ return 1;
+#endif
+
/* include another config file */
} else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
if ( cargc < 2 ) {
}
+static void *
+sync_daemon(
+ void *ptr
+)
+{
+ sleep( 1 );
+
+ Debug( LDAP_DEBUG_ANY, "synchronizer starting\n", 0, 0, 0 );
+
+ while (!slapd_shutdown) {
+
+ sleep( global_backendsyncfreq );
+
+ /*
+ How do we wait for slapd to be idle?
+ Maybe this would work ?
+ while (ldap_pvt_thread_pool_backload(&connection_pool) != 0)
+ sleep(1);
+ */
+
+ if (!slapd_shutdown) {
+ Debug( LDAP_DEBUG_TRACE, "synchronizing\n", 0, 0, 0 );
+ backend_sync( NULL );
+ }
+ }
+
+ Debug( LDAP_DEBUG_ANY, "synchronizer stopping\n", 0, 0, 0 );
+
+ return NULL;
+}
+
+
int slapd_daemon( void )
{
int rc;
#if defined( SLAPD_LISTENER_THREAD )
{
ldap_pvt_thread_t listener_tid;
+ ldap_pvt_thread_t sync_tid;
/* listener as a separate THREAD */
rc = ldap_pvt_thread_create( &listener_tid,
return rc;
}
- /* wait for the listener thread to complete */
- ldap_pvt_thread_join( listener_tid, (void *) NULL );
+ /* sync thread */
+ if ( global_backendsyncfreq > 0 )
+ {
+ rc = ldap_pvt_thread_create( &sync_tid,
+ 0, sync_daemon, NULL );
+
+ if ( rc != 0 )
+ {
+ Debug( LDAP_DEBUG_ANY,
+ "sync ldap_pvt_thread_create failed (%d)\n", rc, 0, 0 );
+ }
+ }
+
+ /* wait for the listener thread to complete */
+ ldap_pvt_thread_join( listener_tid, (void *) NULL );
+
+ if ( global_backendsyncfreq > 0 )
+ {
+ ldap_pvt_thread_join( sync_tid, (void *) NULL );
+ }
}
#else
/* experimental code */
LDAP_SLAPD_F (int) backend_add LDAP_P((BackendInfo *aBackendInfo));
LDAP_SLAPD_F (int) backend_num LDAP_P((Backend *be));
LDAP_SLAPD_F (int) backend_startup LDAP_P((Backend *be));
+LDAP_SLAPD_F (int) backend_sync LDAP_P((Backend *be));
LDAP_SLAPD_F (int) backend_shutdown LDAP_P((Backend *be));
LDAP_SLAPD_F (int) backend_destroy LDAP_P((void));
LDAP_SLAPD_F (slap_access_t) global_default_access;
LDAP_SLAPD_F (int) global_lastmod;
LDAP_SLAPD_F (int) global_idletimeout;
+LDAP_SLAPD_F (int) global_backendsyncfreq;
LDAP_SLAPD_F (int) global_schemacheck;
LDAP_SLAPD_F (char) *global_host;
LDAP_SLAPD_F (char) *global_realm;
int (*bi_db_open) LDAP_P((Backend *bd));
int (*bi_db_close) LDAP_P((Backend *bd));
int (*bi_db_destroy) LDAP_P((Backend *db));
+ int (*bi_db_sync) LDAP_P((Backend *db));
/* LDAP Operations Handling Routines */
int (*bi_op_bind) LDAP_P(( BackendDB *bd,