]> git.sur5r.net Git - openldap/commitdiff
Suck in LDBM updates including sync daemon and per backend
authorKurt Zeilenga <kurt@openldap.org>
Fri, 27 Jul 2001 01:55:05 +0000 (01:55 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Fri, 27 Jul 2001 01:55:05 +0000 (01:55 +0000)
environments.

CHANGES
include/ldbm.h
libraries/libldbm/ldbm.c
servers/slapd/back-ldbm/back-ldbm.h
servers/slapd/back-ldbm/config.c
servers/slapd/back-ldbm/dbcache.c
servers/slapd/back-ldbm/init.c
servers/slapd/back-ldbm/proto-back-ldbm.h

diff --git a/CHANGES b/CHANGES
index 1f24cc43366048017aa1e2277b1b61a642fdfcaf..8f1d88db750a2f6eebafc3c257dd4f232f785bfe 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -12,13 +12,16 @@ OpenLDAP 2.0.12 Engineering
        Added slapd modrdn children check (ITS#1053,1192)
        Added slapd sb_max_incoming_auth support (ITS#1181)
        Added slapd crypt salt format support (ITS#1202)
+       Added slapd subtree replication support
        Added slurpd include support (ITS#121)
        Added -lldap critical client control checks
+       Added ldbm sync daemon support
+       Added ldbm per-backend db_env support
        Updated slapd schema check handling
-       Updated ldbm to use BerkeleyDB's CDB (ITS#1176)
-       Updated ldbm error handling
        Updated slapd filter checks
        Updated slapd single-value checks
+       Updated ldbm to use BerkeleyDB's CDB (ITS#1176)
+       Updated ldbm error handling
        Updated ldaptcl API (contrib)
        Updated -lldap sasl/tls referral handling
        Updated -lldap pthread code
index b306c0e9ee92f939f7c8c460794d55c5228b06a8..56e92829835f1cd9194a342a5dd40282af4e1103 100644 (file)
 
 #include <ldap_cdefs.h>
 
+/* dummy DB_ENV for non Berkeley DB */
+#if !defined( LDBM_USE_DBBTREE ) && !defined( LDBM_USE_DBHASH )
+#  define DB_ENV void
+#endif
+
 #if defined( LDBM_USE_DBBTREE ) || defined( LDBM_USE_DBHASH )
 
 /*****************************************************************
@@ -49,6 +54,8 @@
 #      ifndef DEFAULT_DB_PAGE_SIZE
 #              define DEFAULT_DB_PAGE_SIZE 4096
 #      endif
+#else
+#  define DB_ENV void
 #endif
 
 
@@ -240,8 +247,11 @@ LDAP_BEGIN_DECL
 LDAP_LDBM_F (int) ldbm_initialize( const char * );
 LDAP_LDBM_F (int) ldbm_shutdown( void );
 
+LDAP_LDBM_F (DB_ENV*) ldbm_initialize_env(const char *, int dbcachesize, int *envdirok);
+LDAP_LDBM_F (void) ldbm_shutdown_env(DB_ENV *);
+
 LDAP_LDBM_F (int) ldbm_errno( LDBM ldbm );
-LDAP_LDBM_F (LDBM) ldbm_open( char *name, int rw, int mode, int dbcachesize );
+LDAP_LDBM_F (LDBM) ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize );
 LDAP_LDBM_F (void) ldbm_close( LDBM ldbm );
 LDAP_LDBM_F (void) ldbm_sync( LDBM ldbm );
 LDAP_LDBM_F (void) ldbm_datum_free( LDBM ldbm, Datum data );
index baaa1c7922947898822e3c3d75ecf18b641fbeb5..a232da13ec49f74b79e0419e4d9edf74ef84da21 100644 (file)
@@ -69,6 +69,11 @@ static ldap_pvt_thread_mutex_t ldbm_big_mutex;
 #define LDBM_UNLOCK    (ldap_pvt_thread_mutex_unlock(&ldbm_big_mutex))
 #endif
 
+#if !defined( HAVE_BERKELEY_DB ) || (DB_VERSION_MAJOR < 3)
+                               /*  a dbEnv for BERKELEYv2  */
+DB_ENV *ldbm_Env = NULL;       /* real or fake, depending on db and version */
+#endif
+
 
 /*******************************************************************
  *                                                                 *
@@ -96,8 +101,7 @@ ldbm_db_errcall( const char *prefix, char *message )
 #endif
 }
 
-/*  a dbEnv for BERKELEYv2  */
-DB_ENV *ldbm_Env = NULL;
+#if DB_VERSION_MAJOR < 3
 
 int ldbm_initialize( const char* home )
 {
@@ -133,16 +137,12 @@ int ldbm_initialize( const char* home )
        ldap_pvt_thread_mutex_init( &ldbm_big_mutex );
 #endif
 
-#if DB_VERSION_MAJOR < 3
        ldbm_Env = calloc( 1, sizeof( DB_ENV ));
 
        if( ldbm_Env == NULL ) return 1;
 
        ldbm_Env->db_errcall    = ldbm_db_errcall;
        ldbm_Env->db_errpfx             = "==>";
-#else
-       ldbm_Env = NULL;
-#endif
 
        envFlags = DB_CREATE;
 
@@ -158,12 +158,8 @@ int ldbm_initialize( const char* home )
 #endif
 #endif
 
-#if DB_VERSION_MAJOR >= 3
-       err = db_env_create( &ldbm_Env, 0 );
-#else
        envFlags |= DB_USE_ENVIRON;
        err = db_appinit( home, NULL, ldbm_Env, envFlags );
-#endif
 
        if ( err ) {
 #ifdef LDAP_SYSLOG
@@ -172,45 +168,12 @@ int ldbm_initialize( const char* home )
                sprintf( error, "%s (%d)\n", STRERROR( err ), err );
 
                syslog( LOG_INFO,
-#if DB_VERSION_MAJOR >= 3
-                       "ldbm_initialize(): FATAL error in db_env_create() : %s\n",
-#else
                        "ldbm_initialize(): FATAL error in db_appinit() : %s\n",
-#endif
                        error );
 #endif
                return( 1 );
        }
 
-#if DB_VERSION_MAJOR > 2
-       ldbm_Env->set_errcall( ldbm_Env, ldbm_db_errcall );
-       ldbm_Env->set_errpfx( ldbm_Env, "==>" );
-
-#ifdef HAVE_BERKELEY_DB_THREAD
-       envFlags |= DB_INIT_CDB | DB_INIT_MPOOL;
-#endif
-       envFlags |= DB_USE_ENVIRON;
-
-#if (DB_VERSION_MAJOR > 3) || (DB_VERSION_MINOR >= 1)
-       err = ldbm_Env->open( ldbm_Env, home, envFlags, 0 );
-#else
-       err = ldbm_Env->open( ldbm_Env, home, NULL, envFlags, 0 );
-#endif
-
-       if ( err != 0 ) {
-#ifdef LDAP_SYSLOG
-               char error[BUFSIZ];
-
-               sprintf( error, "%s (%d)\n", STRERROR( err ), err );
-               syslog( LOG_INFO,
-                       "ldbm_initialize(): FATAL error in dbEnv->open() : %s\n",
-                       error );
-#endif
-               ldbm_Env->close( ldbm_Env, 0 );
-               return( 1 );
-       }
-#endif
-
        return 0;
 }
 
@@ -218,11 +181,7 @@ int ldbm_shutdown( void )
 {
        if( !ldbm_initialized ) return 1;
 
-#if DB_VERSION_MAJOR >= 3
-       ldbm_Env->close( ldbm_Env, 0 );
-#else
        db_appexit( ldbm_Env );
-#endif
 
 #ifndef HAVE_BERKELEY_DB_THREAD
        ldap_pvt_thread_mutex_destroy( &ldbm_big_mutex );
@@ -231,6 +190,26 @@ int ldbm_shutdown( void )
        return 0;
 }
 
+#else  /* Berkeley v3 or greater */
+
+
+int ldbm_initialize( const char * home )
+{
+       /* v3 uses ldbm_initialize_env */
+       return 0;
+}
+
+
+int ldbm_shutdown( void )
+{
+       return 0;
+}
+
+
+#endif
+
+
+
 #else  /* some DB other than Berkeley V2 or greater */
 
 int ldbm_initialize( const char * home )
@@ -254,6 +233,86 @@ int ldbm_shutdown( void )
 #endif /* HAVE_BERKELEY_DB */
 
 
+#if defined( HAVE_BERKELEY_DB ) && (DB_VERSION_MAJOR >= 3)
+
+
+DB_ENV *ldbm_initialize_env(const char *home, int dbcachesize, int *envdirok)
+{
+       DB_ENV *env = NULL;    
+       int     err;
+       u_int32_t       envFlags;
+
+       envFlags = 
+#if defined( DB_PRIVATE )      /* comment out DB_PRIVATE setting to use */
+       DB_PRIVATE |            /* db_stat to view cache behavior */
+#endif
+#if defined( HAVE_BERKELEY_DB_THREAD )
+       DB_THREAD |
+#endif
+       DB_CREATE;
+       
+       err = db_env_create( &env, 0 );
+
+       if ( err ) {
+               char error[BUFSIZ];
+
+               sprintf( error, "%s (%d)\n", STRERROR( err ), err );
+
+#ifdef LDAP_SYSLOG
+               syslog( LOG_INFO, "ldbm_initialize_env(): FATAL error in db_env_create() : %s\n", error );
+#endif
+               return( NULL );
+       }
+
+       env->set_errcall( env, ldbm_db_errcall );
+       env->set_errpfx( env, "==>" );
+       if (dbcachesize)
+               env->set_cachesize( env, 0, dbcachesize, 0 );
+
+       envFlags |= DB_INIT_MPOOL | DB_INIT_CDB | DB_USE_ENVIRON;
+
+       err = env->open( env, home, envFlags, 0 );
+
+       if ( err != 0 )
+       {
+               char error[BUFSIZ];
+
+               sprintf( error, "%s (%d)\n", STRERROR( err ), err );
+
+#ifdef LDAP_SYSLOG
+               syslog( LOG_INFO,
+                       "ldbm_initialize_env(): FATAL error in dbEnv->open() : %s\n",
+                       error );
+#endif
+               env->close( env, 0 );
+               return( NULL );
+       }
+
+       *envdirok = 1;
+       return env;
+}
+
+void ldbm_shutdown_env(DB_ENV *env)
+{
+       env->close( env, 0 );
+}
+
+
+#else
+
+DB_ENV *ldbm_initialize_env(const char *home, int dbcachesize, int *envdirok)
+{
+       return ldbm_Env;
+}
+
+void ldbm_shutdown_env(DB_ENV *env)
+{
+}
+
+
+#endif
+
+
 #if defined( LDBM_USE_DBHASH ) || defined( LDBM_USE_DBBTREE )
 
 /*****************************************************************
@@ -263,7 +322,7 @@ int ldbm_shutdown( void )
  *****************************************************************/
 
 LDBM
-ldbm_open( char *name, int rw, int mode, int dbcachesize )
+ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize )
 {
        LDBM            ret = NULL;
 
@@ -272,7 +331,7 @@ ldbm_open( char *name, int rw, int mode, int dbcachesize )
 
        LDBM_LOCK;
 
-       err = db_create( &ret, ldbm_Env, 0 );
+       err = db_create( &ret, env, 0 );
        if ( err != 0 ) {
                (void)ret->close(ret, 0);
                LDBM_UNLOCK;
@@ -282,6 +341,7 @@ ldbm_open( char *name, int rw, int mode, int dbcachesize )
 
        ret->set_pagesize( ret, DEFAULT_DB_PAGE_SIZE );
        ret->set_malloc( ret, ldbm_malloc );
+       /* ret->set_cachesize( ret, 0, dbcachesize, 0 ); */
 
        err = ret->open( ret, name, NULL, DB_TYPE, rw, mode);
 
@@ -581,7 +641,7 @@ ldbm_errno( LDBM ldbm )
  *****************************************************************/
 
 LDBM
-ldbm_open( char *name, int rw, int mode, int dbcachesize )
+ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize )
 {
        LDBM            db;
 #ifdef HAVE_ST_BLKSIZE
@@ -755,7 +815,7 @@ ldbm_errno( LDBM ldbm )
  *****************************************************************/
 
 LDBM
-ldbm_open( char *name, int rw, int mode, int dbcachesize )
+ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize )
 {
        LDBM            db;
 
@@ -1063,7 +1123,7 @@ ldbm_errno( LDBM ldbm )
 
 /* ARGSUSED */
 LDBM
-ldbm_open( char *name, int rw, int mode, int dbcachesize )
+ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize )
 {
        LDBM ldbm;
 
index b1b374b1a76299a00a31962d40c763540e58a616..74cf0e9b2ceac81fc2d664ba5fceac0d08cdbee7 100644 (file)
@@ -117,6 +117,13 @@ struct ldbminfo {
        DBCache         li_dbcache[MAXDBCACHE];
        ldap_pvt_thread_mutex_t         li_dbcache_mutex;
        ldap_pvt_thread_cond_t          li_dbcache_cv;
+       DB_ENV                  *li_dbenv;
+       int                     li_envdirok;
+       int                     li_dbsyncfreq;
+       int                     li_dbsyncwaitn;
+       int                     li_dbsyncwaitinterval;
+       ldap_pvt_thread_t       li_dbsynctid;
+       int                     li_dbshutdown;
 };
 
 LDAP_END_DECL
index 35b6d907b37c7bd05f5c0abd91e5f5fd21066dc3..70f543e4e84000b6dc00e9d176d88b10e2652f91 100644 (file)
@@ -101,6 +101,60 @@ ldbm_back_db_config(
        {
                li->li_dbwritesync = 0;
 
+       /* run sync thread */
+       } else if ( strcasecmp( argv[0], "dbsync" ) == 0 ) {
+#ifndef NO_THREADS
+               int i;
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_ANY,
+    "%s: line %d: missing frquency value in \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n",
+                           fname, lineno, 0 );
+                       return 1;
+               }
+
+               i = atoi( argv[1] );
+
+               if( i < 0 ) {
+                       Debug( LDAP_DEBUG_ANY,
+    "%s: line %d: frquency value (%d) invalid \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n",
+                           fname, lineno, i );
+                       return 1;
+               }
+
+               li->li_dbsyncfreq = i;
+
+               if ( argc > 2 ) {
+                       i = atoi( argv[2] );
+                       if ( i < 0 ) {
+                               Debug( LDAP_DEBUG_ANY,
+           "%s: line %d: frquency value (%d) invalid \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n",
+                                   fname, lineno, i );
+                               return 1;
+                       }
+                       li ->li_dbsyncwaitn = i;
+               }
+
+               if ( argc > 3 ) {
+                       i = atoi( argv[3] );
+                       if ( i <= 0 ) {
+                               Debug( LDAP_DEBUG_ANY,
+           "%s: line %d: frquency value (%d) invalid \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n",
+                                   fname, lineno, i );
+                               return 1;
+                       }
+                       li ->li_dbsyncwaitinterval = i;
+               }
+
+               /* turn off writesync when sync policy is in place */
+               li->li_dbwritesync = 0;
+
+#else
+               Debug( LDAP_DEBUG_ANY,
+    "\"dbsync\" policies not supported in non-threaded environments\n", 0, 0, 0);
+               return 1;
+#endif
+
+
        /* anything else */
        } else {
                fprintf( stderr,
index 97b5a5e04b9067ad354ef5fc0e096bf2a13a9b2b..fb6472e5257dee141c52dcbf022d48b8ab567d42 100644 (file)
@@ -34,8 +34,11 @@ ldbm_cache_open(
        struct stat     st;
 #endif
 
-       sprintf( buf, "%s" LDAP_DIRSEP "%s%s",
-               li->li_directory, name, suffix );
+       if (li->li_envdirok)
+               sprintf( buf, "%s%s", name, suffix );
+       else
+               sprintf( buf, "%s" LDAP_DIRSEP "%s%s",
+                       li->li_directory, name, suffix );
 
        if( li->li_dblocking ) {
                flags |= LDBM_LOCKING;
@@ -49,8 +52,14 @@ ldbm_cache_open(
                flags |= LDBM_NOSYNC;
        }
        
+#ifdef NEW_LOGGING
+       LDAP_LOG(( "cache", LDAP_LEVEL_ENTRY,
+                  "ldbm_cache_open: \"%s\", %d, %o\n", buf, flags, li->li_mode ));
+#else
        Debug( LDAP_DEBUG_TRACE, "=> ldbm_cache_open( \"%s\", %d, %o )\n", buf,
            flags, li->li_mode );
+#endif
+
 
        curtime = slap_get_time();
        empty = MAXDBCACHE;
@@ -74,7 +83,7 @@ ldbm_cache_open(
                                {
                                        /* we don't want to use an open cache with different
                                         * permissions (esp. if we need write but the open
-                                        * cache is read-only).  So close this one if
+                                        * cache is read-only).  So close this one if
                                         * possible, and re-open below.
                                         *
                                         * FIXME:  what about the case where the refcount
@@ -91,8 +100,14 @@ ldbm_cache_open(
                                        break;
                                }
                                li->li_dbcache[i].dbc_refcnt++;
+#ifdef NEW_LOGGING
+                               LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
+                                          "ldbm_cache_open: cache %d\n", i ));
+#else
                                Debug( LDAP_DEBUG_TRACE,
                                    "<= ldbm_cache_open (cache %d)\n", i, 0, 0 );
+#endif
+
                                ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex );
                                return( &li->li_dbcache[i] );
                        }
@@ -115,9 +130,15 @@ ldbm_cache_open(
                                free( li->li_dbcache[i].dbc_name );
                                li->li_dbcache[i].dbc_name = NULL;
                        } else {
+#ifdef NEW_LOGGING
+                               LDAP_LOG(( "cache", LDAP_LEVEL_INFO,
+                                          "ldbm_cache_open: no unused db to close - waiting\n" ));
+#else
                                Debug( LDAP_DEBUG_ANY,
                                    "ldbm_cache_open no unused db to close - waiting\n",
                                    0, 0, 0 );
+#endif
+
                                ldap_pvt_thread_cond_wait( &li->li_dbcache_cv,
                                            &li->li_dbcache_mutex );
                                /* after waiting for a free slot, go back to square
@@ -128,14 +149,22 @@ ldbm_cache_open(
                }
        } while (i == MAXDBCACHE);
 
-       if ( (li->li_dbcache[i].dbc_db = ldbm_open( buf, flags, li->li_mode,
+       if ( (li->li_dbcache[i].dbc_db = ldbm_open( li->li_dbenv, buf, flags, li->li_mode,
            li->li_dbcachesize )) == NULL )
        {
                int err = errno;
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "cache", LDAP_LEVEL_ERR,
+                          "ldbm_cache_open: \"%s\" failed, errono=%d, reason=%s\n",
+                          buf, err, err > -1 && err < sys_nerr ? sys_errlist[err] :
+                          "unknown" ));
+#else
                Debug( LDAP_DEBUG_TRACE,
                    "<= ldbm_cache_open NULL \"%s\" errno=%d reason=\"%s\")\n",
                    buf, err, err > -1 && err < sys_nerr ?
                    sys_errlist[err] : "unknown" );
+#endif
+
                ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex );
                return( NULL );
        }
@@ -159,11 +188,25 @@ ldbm_cache_open(
 
        assert( li->li_dbcache[i].dbc_maxindirect < 256 );
 
+#ifdef NEW_LOGGING
+       LDAP_LOG(( "cache", LDAP_LEVEL_ARGS,
+                  "ldbm_cache_open: blksize:%ld  maxids:%d  maxindirect:%d\n",
+                  li->li_dbcache[i].dbc_blksize, li->li_dbcache[i].dbc_maxids,
+                  li->li_dbcache[i].dbc_maxindirect ));
+#else
        Debug( LDAP_DEBUG_ARGS,
            "ldbm_cache_open (blksize %ld) (maxids %d) (maxindirect %d)\n",
            li->li_dbcache[i].dbc_blksize, li->li_dbcache[i].dbc_maxids,
            li->li_dbcache[i].dbc_maxindirect );
+#endif
+
+#ifdef NEW_LOGGING
+       LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
+                  "ldbm_cache_open: opened %d\n", i ));
+#else
        Debug( LDAP_DEBUG_TRACE, "<= ldbm_cache_open (opened %d)\n", i, 0, 0 );
+#endif
+
        ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex );
        return( &li->li_dbcache[i] );
 }
@@ -211,19 +254,40 @@ ldbm_cache_flush_all( Backend *be )
        ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex );
        for ( i = 0; i < MAXDBCACHE; i++ ) {
                if ( li->li_dbcache[i].dbc_name != NULL ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
+                                  "ldbm_cache_flush_all: flushing db (%s)\n",
+                                  li->li_dbcache[i].dbc_name ));
+#else
                        Debug( LDAP_DEBUG_TRACE, "ldbm flushing db (%s)\n",
                            li->li_dbcache[i].dbc_name, 0, 0 );
+#endif
+
                        ldbm_sync( li->li_dbcache[i].dbc_db );
                        li->li_dbcache[i].dbc_dirty = 0;
                        if ( li->li_dbcache[i].dbc_refcnt != 0 ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG(( "cache", LDAP_LEVEL_INFO,
+                                          "ldbm_cache_flush_all: couldn't close db (%s), refcnt=%d\n",
+                                          li->li_dbcache[i].dbc_name, li->li_dbcache[i].dbc_refcnt ));
+#else
                                Debug( LDAP_DEBUG_TRACE,
                                       "refcnt = %d, couldn't close db (%s)\n",
                                       li->li_dbcache[i].dbc_refcnt,
                                       li->li_dbcache[i].dbc_name, 0 );
+#endif
+
                        } else {
+#ifdef NEW_LOGGING
+                               LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
+                                          "ldbm_cache_flush_all: ldbm closing db (%s)\n",
+                                          li->li_dbcache[i].dbc_name ));
+#else
                                Debug( LDAP_DEBUG_TRACE,
                                       "ldbm closing db (%s)\n",
                                       li->li_dbcache[i].dbc_name, 0, 0 );
+#endif
+
                                ldap_pvt_thread_cond_signal( &li->li_dbcache_cv );
                                ldbm_close( li->li_dbcache[i].dbc_db );
                                free( li->li_dbcache[i].dbc_name );
@@ -234,6 +298,24 @@ ldbm_cache_flush_all( Backend *be )
        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,
@@ -294,3 +376,35 @@ ldbm_cache_delete(
 
        return( rc );
 }
+
+void *
+ldbm_cache_sync_daemon(
+       void *be_ptr
+)
+{
+       Backend *be = (Backend *)be_ptr;
+       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
+
+       Debug( LDAP_DEBUG_ANY, "synchronizer starting for %s\n", li->li_directory, 0, 0 );
+  
+       while (!li->li_dbshutdown) {
+               int i = li->li_dbsyncwaitn;
+
+               sleep( li->li_dbsyncfreq );
+
+               while (i && ldap_pvt_thread_pool_backload(&connection_pool) != 0) {
+                       Debug( LDAP_DEBUG_TRACE, "delay syncing %s\n", li->li_directory, 0, 0 );
+                       sleep(li->li_dbsyncwaitinterval);
+                       i--;
+               }
+
+               if (!li->li_dbshutdown) {
+                       Debug( LDAP_DEBUG_TRACE, "syncing %s\n", li->li_directory, 0, 0 );
+                       ldbm_cache_sync( be );
+               }
+       }
+
+       Debug( LDAP_DEBUG_ANY, "synchronizer stopping\n", 0, 0, 0 );
+  
+       return NULL;
+}
index 43fa087664db8d9581086a34bef0b02d44a4e8ca..f369e31bd4e9e1797e03e91784847b560d791189 100644 (file)
@@ -118,7 +118,6 @@ ldbm_back_close(
 {
        /* terminate the underlying database system */
        ldbm_shutdown();
-
        return 0;
 }
 
@@ -153,6 +152,24 @@ ldbm_back_db_init(
        /* default database directory */
        li->li_directory = ch_strdup( DEFAULT_DB_DIRECTORY );
 
+       /* DB_ENV environment pointer for DB3 */
+       li->li_dbenv = 0;
+
+       /* envdirok is turned on by ldbm_initialize_env if DB3 */
+       li->li_envdirok = 0;
+
+       /* syncfreq is 0 if disabled, or # seconds */
+       li->li_dbsyncfreq = 0;
+
+       /* wait up to dbsyncwaitn times if server is busy */
+       li->li_dbsyncwaitn = 12;
+
+       /* delay interval */
+       li->li_dbsyncwaitinterval = 5;
+
+       /* flag to notify ldbm_cache_sync_daemon to shut down */
+       li->li_dbshutdown = 0;
+
        /* initialize various mutex locks & condition variables */
        ldap_pvt_thread_mutex_init( &li->li_root_mutex );
        ldap_pvt_thread_mutex_init( &li->li_add_mutex );
@@ -171,6 +188,25 @@ ldbm_back_db_open(
     BackendDB  *be
 )
 {
+       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
+       li->li_dbenv = ldbm_initialize_env( li->li_directory,
+               li->li_dbcachesize, &li->li_envdirok );
+
+       /* sync thread */
+       if ( li->li_dbsyncfreq > 0 )
+       {
+               int rc;
+               rc = ldap_pvt_thread_create( &li->li_dbsynctid,
+                       0, ldbm_cache_sync_daemon, (void*)be );
+
+               if ( rc != 0 )
+               {
+                       Debug(  LDAP_DEBUG_ANY,
+                               "sync ldap_pvt_thread_create failed (%d)\n", rc, 0, 0 );
+                       return 1;
+               }
+       }
+
        return 0;
 }
 
@@ -181,6 +217,10 @@ ldbm_back_db_destroy(
 {
        /* should free/destroy every in be_private */
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
+
+       if (li->li_dbenv)
+           ldbm_shutdown_env(li->li_dbenv);
+
        free( li->li_directory );
        attr_index_destroy( li->li_attrs );
 
index 3d3e22b87e4ee73c9c26dba75869b5391b47b0e1..d3bc641cc80608c6874c9290638009d7827ee0db 100644 (file)
@@ -68,6 +68,7 @@ DBCache * ldbm_cache_open LDAP_P(( Backend *be,
 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 ));