X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-ldbm%2Fdbcache.c;h=b9407f4d1a8461ea9e3e1c26c4ef1dce26bf596e;hb=4d36fd5a3ed407b0a53004d1431f1669222138b4;hp=ea3c3610c96f0f22d2fece825d06b9b580644f53;hpb=89da861b89b97bf20b428f450a434e3e8978bbe2;p=openldap diff --git a/servers/slapd/back-ldbm/dbcache.c b/servers/slapd/back-ldbm/dbcache.c index ea3c3610c9..b9407f4d1a 100644 --- a/servers/slapd/back-ldbm/dbcache.c +++ b/servers/slapd/back-ldbm/dbcache.c @@ -1,7 +1,7 @@ /* ldbmcache.c - maintain a cache of open ldbm files */ /* $OpenLDAP$ */ /* - * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "slap.h" @@ -28,14 +29,17 @@ ldbm_cache_open( { struct ldbminfo *li = (struct ldbminfo *) be->be_private; int i, lru, empty; - time_t oldtime, curtime; + time_t oldtime; char buf[MAXPATHLEN]; #ifdef HAVE_ST_BLKSIZE 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,20 +53,26 @@ ldbm_cache_open( flags |= LDBM_NOSYNC; } +#ifdef NEW_LOGGING + LDAP_LOG( CACHE, 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; ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex ); do { lru = 0; - oldtime = curtime; + oldtime = 1; for ( i = 0; i < MAXDBCACHE; i++ ) { /* see if this slot is free */ if ( li->li_dbcache[i].dbc_name == NULL) { - empty = i; + if (empty == MAXDBCACHE) + empty = i; continue; } @@ -73,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 @@ -90,15 +100,22 @@ ldbm_cache_open( break; } li->li_dbcache[i].dbc_refcnt++; +#ifdef NEW_LOGGING + LDAP_LOG( CACHE, DETAIL1, + "ldbm_cache_open: cache %d\n", i, 0, 0 ); +#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] ); } /* keep track of lru db */ - if ( li->li_dbcache[i].dbc_lastref < oldtime - && li->li_dbcache[i].dbc_refcnt == 0 ) + if (( li->li_dbcache[i].dbc_refcnt == 0 ) && + (( oldtime == 1 ) || + ( li->li_dbcache[i].dbc_lastref < oldtime )) ) { lru = i; oldtime = li->li_dbcache[i].dbc_lastref; @@ -114,9 +131,16 @@ ldbm_cache_open( free( li->li_dbcache[i].dbc_name ); li->li_dbcache[i].dbc_name = NULL; } else { +#ifdef NEW_LOGGING + LDAP_LOG( CACHE, INFO, + "ldbm_cache_open: no unused db to close - waiting\n", + 0, 0, 0 ); +#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 @@ -127,20 +151,28 @@ 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, 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 ); } li->li_dbcache[i].dbc_name = ch_strdup( buf ); li->li_dbcache[i].dbc_refcnt = 1; - li->li_dbcache[i].dbc_lastref = curtime; + li->li_dbcache[i].dbc_lastref = slap_get_time(); li->li_dbcache[i].dbc_flags = flags; li->li_dbcache[i].dbc_dirty = 0; #ifdef HAVE_ST_BLKSIZE @@ -158,11 +190,26 @@ ldbm_cache_open( assert( li->li_dbcache[i].dbc_maxindirect < 256 ); +#ifdef NEW_LOGGING + LDAP_LOG( CACHE, 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, DETAIL1, "<= ldbm_cache_open: (opened %d)\n", i, 0, 0 ); +#else Debug( LDAP_DEBUG_TRACE, "<= ldbm_cache_open (opened %d)\n", i, 0, 0 ); +#endif + + ldap_pvt_thread_mutex_init( &li->li_dbcache[i].dbc_write_mutex ); + ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex ); return( &li->li_dbcache[i] ); } @@ -197,6 +244,7 @@ ldbm_cache_really_close( Backend *be, DBCache *db ) ldbm_close( db->dbc_db ); free( db->dbc_name ); db->dbc_name = NULL; + ldap_pvt_thread_mutex_destroy( &db->dbc_write_mutex ); } ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex ); } @@ -210,19 +258,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, DETAIL1, + "ldbm_cache_flush_all: flushing db (%s)\n", + li->li_dbcache[i].dbc_name, 0, 0 ); +#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, 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,0); +#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, DETAIL1, + "ldbm_cache_flush_all: ldbm closing db (%s)\n", + li->li_dbcache[i].dbc_name, 0, 0 ); +#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 ); @@ -233,17 +302,36 @@ 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 ) { +#ifdef NEW_LOGGING + LDAP_LOG ( CACHE, DETAIL1, "ldbm_cache_sync: " + "ldbm syncing db (%s)\n", li->li_dbcache[i].dbc_name, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "ldbm syncing 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; + } + } + ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex ); +} + Datum ldbm_cache_fetch( DBCache *db, Datum key ) { - Datum data; - return ldbm_fetch( db->dbc_db, key ); - - return( data ); } int @@ -293,3 +381,55 @@ 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; + +#ifdef NEW_LOGGING + LDAP_LOG ( CACHE, ARGS, "ldbm_cache_sync_daemon:" + " synchronizer starting for %s\n", li->li_directory, 0, 0 ); +#else + Debug( LDAP_DEBUG_ANY, "synchronizer starting for %s\n", li->li_directory, 0, 0 ); +#endif + + while (!li->li_dbshutdown) { + int i = li->li_dbsyncwaitn; + + sleep( li->li_dbsyncfreq ); + + while (i && ldap_pvt_thread_pool_backload(&connection_pool) != 0) { +#ifdef NEW_LOGGING + LDAP_LOG ( CACHE, DETAIL1, "ldbm_cache_sync_daemon:" + " delay syncing %s\n", li->li_directory, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "delay syncing %s\n", li->li_directory, 0, 0 ); +#endif + sleep(li->li_dbsyncwaitinterval); + i--; + } + + if (!li->li_dbshutdown) { +#ifdef NEW_LOGGING + LDAP_LOG ( CACHE, DETAIL1, "ldbm_cache_sync_daemon:" + " syncing %s\n", li->li_directory, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "syncing %s\n", li->li_directory, 0, 0 ); +#endif + ldbm_cache_sync( be ); + } + } + +#ifdef NEW_LOGGING + LDAP_LOG ( CACHE, DETAIL1, "ldbm_cache_sync_daemon:" + " synchronizer stopping\n", 0, 0, 0); +#else + Debug( LDAP_DEBUG_ANY, "synchronizer stopping\n", 0, 0, 0 ); +#endif + + return NULL; +}