Diff for /servers/slapd/back-bdb/config.c between versions 1.43.2.20 and 1.44

version 1.43.2.20, 2008/02/11 23:24:19 version 1.44, 2005/01/01 19:49:51
Line 1 Line 1
 /* config.c - bdb backend configuration file routine */  /* config.c - bdb backend configuration file routine */
 /* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/config.c,v 1.43.2.19 2007/09/02 21:57:35 hyc Exp $ */  /* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/config.c,v 1.43 2004/11/25 20:16:56 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.  /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *   *
  * Copyright 2000-2008 The OpenLDAP Foundation.   * Copyright 2000-2005 The OpenLDAP Foundation.
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 17 Line 17
 #include "portable.h"  #include "portable.h"
   
 #include <stdio.h>  #include <stdio.h>
 #include <ac/ctype.h>  
 #include <ac/string.h>  #include <ac/string.h>
   
 #include "back-bdb.h"  #include "back-bdb.h"
   
 #include "config.h"  
   
 #include "lutil.h"  
 #include "ldap_rq.h"  
   
 #ifdef DB_DIRTY_READ  #ifdef DB_DIRTY_READ
 #       define  SLAP_BDB_ALLOW_DIRTY_READ  #       define  SLAP_BDB_ALLOW_DIRTY_READ
 #endif  #endif
   
 #define bdb_cf_gen                      BDB_SYMBOL(cf_gen)  int
 #define bdb_cf_cleanup          BDB_SYMBOL(cf_cleanup)  bdb_db_config(
 #define bdb_checkpoint          BDB_SYMBOL(checkpoint)          BackendDB       *be,
 #define bdb_online_index        BDB_SYMBOL(online_index)          const char      *fname,
           int             lineno,
 static ConfigDriver bdb_cf_gen;          int             argc,
           char    **argv )
 enum {  
         BDB_CHKPT = 1,  
         BDB_CONFIG,  
         BDB_DIRECTORY,  
         BDB_NOSYNC,  
         BDB_DIRTYR,  
         BDB_INDEX,  
         BDB_LOCKD,  
         BDB_SSTACK  
 };  
   
 static ConfigTable bdbcfg[] = {  
         { "directory", "dir", 2, 2, 0, ARG_STRING|ARG_MAGIC|BDB_DIRECTORY,  
                 bdb_cf_gen, "( OLcfgDbAt:0.1 NAME 'olcDbDirectory' "  
                         "DESC 'Directory for database content' "  
                         "EQUALITY caseIgnoreMatch "  
                         "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },  
         { "cachefree", "size", 2, 2, 0, ARG_INT|ARG_OFFSET,  
                 (void *)offsetof(struct bdb_info, bi_cache.c_minfree),  
                 "( OLcfgDbAt:1.11 NAME 'olcDbCacheFree' "  
                         "DESC 'Number of extra entries to free when max is reached' "  
                         "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },  
         { "cachesize", "size", 2, 2, 0, ARG_INT|ARG_OFFSET,  
                 (void *)offsetof(struct bdb_info, bi_cache.c_maxsize),  
                 "( OLcfgDbAt:1.1 NAME 'olcDbCacheSize' "  
                         "DESC 'Entry cache size in entries' "  
                         "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },  
         { "checkpoint", "kbyte> <min", 3, 3, 0, ARG_MAGIC|BDB_CHKPT,  
                 bdb_cf_gen, "( OLcfgDbAt:1.2 NAME 'olcDbCheckpoint' "  
                         "DESC 'Database checkpoint interval in kbytes and minutes' "  
                         "SYNTAX OMsDirectoryString SINGLE-VALUE )",NULL, NULL },  
         { "dbconfig", "DB_CONFIG setting", 1, 0, 0, ARG_MAGIC|BDB_CONFIG,  
                 bdb_cf_gen, "( OLcfgDbAt:1.3 NAME 'olcDbConfig' "  
                         "DESC 'BerkeleyDB DB_CONFIG configuration directives' "  
                         "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },  
         { "dbnosync", NULL, 1, 2, 0, ARG_ON_OFF|ARG_MAGIC|BDB_NOSYNC,  
                 bdb_cf_gen, "( OLcfgDbAt:1.4 NAME 'olcDbNoSync' "  
                         "DESC 'Disable synchronous database writes' "  
                         "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },  
         { "dirtyread", NULL, 1, 2, 0,  
 #ifdef SLAP_BDB_ALLOW_DIRTY_READ  
                 ARG_ON_OFF|ARG_MAGIC|BDB_DIRTYR, bdb_cf_gen,  
 #else  
                 ARG_IGNORED, NULL,  
 #endif  
                 "( OLcfgDbAt:1.5 NAME 'olcDbDirtyRead' "  
                 "DESC 'Allow reads of uncommitted data' "  
                 "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },  
         { "idlcachesize", "size", 2, 2, 0, ARG_INT|ARG_OFFSET,  
                 (void *)offsetof(struct bdb_info,bi_idl_cache_max_size),  
                 "( OLcfgDbAt:1.6 NAME 'olcDbIDLcacheSize' "  
                 "DESC 'IDL cache size in IDLs' "  
                 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },  
         { "index", "attr> <[pres,eq,approx,sub]", 2, 3, 0, ARG_MAGIC|BDB_INDEX,  
                 bdb_cf_gen, "( OLcfgDbAt:0.2 NAME 'olcDbIndex' "  
                 "DESC 'Attribute index parameters' "  
                 "EQUALITY caseIgnoreMatch "  
                 "SYNTAX OMsDirectoryString )", NULL, NULL },  
         { "linearindex", NULL, 1, 2, 0, ARG_ON_OFF|ARG_OFFSET,  
                 (void *)offsetof(struct bdb_info, bi_linear_index),   
                 "( OLcfgDbAt:1.7 NAME 'olcDbLinearIndex' "  
                 "DESC 'Index attributes one at a time' "  
                 "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },  
         { "lockdetect", "policy", 2, 2, 0, ARG_MAGIC|BDB_LOCKD,  
                 bdb_cf_gen, "( OLcfgDbAt:1.8 NAME 'olcDbLockDetect' "  
                 "DESC 'Deadlock detection algorithm' "  
                 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },  
         { "mode", "mode", 2, 2, 0, ARG_INT|ARG_OFFSET,  
                 (void *)offsetof(struct bdb_info, bi_dbenv_mode),  
                 "( OLcfgDbAt:0.3 NAME 'olcDbMode' "  
                 "DESC 'Unix permissions of database files' "  
                 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },  
         { "searchstack", "depth", 2, 2, 0, ARG_INT|ARG_MAGIC|BDB_SSTACK,  
                 bdb_cf_gen, "( OLcfgDbAt:1.9 NAME 'olcDbSearchStack' "  
                 "DESC 'Depth of search stack in IDLs' "  
                 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },  
         { "shm_key", "key", 2, 2, 0, ARG_INT|ARG_OFFSET,  
                 (void *)offsetof(struct bdb_info, bi_shm_key),   
                 "( OLcfgDbAt:1.10 NAME 'olcDbShmKey' "  
                 "DESC 'Key for shared memory region' "  
                 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },  
         { NULL, NULL, 0, 0, 0, ARG_IGNORED,  
                 NULL, NULL, NULL, NULL }  
 };  
   
 static ConfigOCs bdbocs[] = {  
         {  
 #ifdef BDB_HIER  
                 "( OLcfgDbOc:1.2 "  
                 "NAME 'olcHdbConfig' "  
                 "DESC 'HDB backend configuration' "  
 #else  
                 "( OLcfgDbOc:1.1 "  
                 "NAME 'olcBdbConfig' "  
                 "DESC 'BDB backend configuration' "  
 #endif  
                 "SUP olcDatabaseConfig "  
                 "MUST olcDbDirectory "  
                 "MAY ( olcDbCacheSize $ olcDbCheckpoint $ olcDbConfig $ "  
                 "olcDbNoSync $ olcDbDirtyRead $ olcDbIDLcacheSize $ "  
                 "olcDbIndex $ olcDbLinearIndex $ olcDbLockDetect $ "  
                 "olcDbMode $ olcDbSearchStack $ olcDbShmKey $ "  
                 " olcDbCacheFree ) )",  
                         Cft_Database, bdbcfg },  
         { NULL, 0, NULL }  
 };  
   
 static slap_verbmasks bdb_lockd[] = {  
         { BER_BVC("default"), DB_LOCK_DEFAULT },  
         { BER_BVC("oldest"), DB_LOCK_OLDEST },  
         { BER_BVC("random"), DB_LOCK_RANDOM },  
         { BER_BVC("youngest"), DB_LOCK_YOUNGEST },  
         { BER_BVC("fewest"), DB_LOCK_MINLOCKS },  
         { BER_BVNULL, 0 }  
 };  
   
 /* perform periodic checkpoints */  
 static void *  
 bdb_checkpoint( void *ctx, void *arg )  
 {  
         struct re_s *rtask = arg;  
         struct bdb_info *bdb = rtask->arg;  
           
         TXN_CHECKPOINT( bdb->bi_dbenv, bdb->bi_txn_cp_kbyte,  
                 bdb->bi_txn_cp_min, 0 );  
         ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );  
         ldap_pvt_runqueue_stoptask( &slapd_rq, rtask );  
         ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );  
         return NULL;  
 }  
   
 /* reindex entries on the fly */  
 static void *  
 bdb_online_index( void *ctx, void *arg )  
 {  {
         struct re_s *rtask = arg;          struct bdb_info *bdb = (struct bdb_info *) be->be_private;
         BackendDB *be = rtask->arg;  
         struct bdb_info *bdb = be->be_private;  
   
         Connection conn = {0};  
         OperationBuffer opbuf;  
         Operation *op = (Operation *) &opbuf;  
   
         DBC *curs;  
         DBT key, data;  
         DB_TXN *txn;  
         DB_LOCK lock;  
         u_int32_t locker;  
         ID id, nid;  
         EntryInfo *ei;  
         int rc, getnext = 1;  
         int i;  
   
         connection_fake_init( &conn, op, ctx );  
   
         op->o_bd = be;  
   
         DBTzero( &key );  
         DBTzero( &data );  
           
         id = 1;  
         key.data = &nid;  
         key.size = key.ulen = sizeof(ID);  
         key.flags = DB_DBT_USERMEM;  
   
         data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;  
         data.dlen = data.ulen = 0;  
   
         while ( 1 ) {  
                 if ( slapd_shutdown )  
                         break;  
   
                 rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &txn, bdb->bi_db_opflags );  
                 if ( rc )   
                         break;  
                 locker = TXN_ID( txn );  
                 if ( getnext ) {  
                         getnext = 0;  
                         BDB_ID2DISK( id, &nid );  
                         rc = bdb->bi_id2entry->bdi_db->cursor(  
                                 bdb->bi_id2entry->bdi_db, txn, &curs, bdb->bi_db_opflags );  
                         if ( rc ) {  
                                 TXN_ABORT( txn );  
                                 break;  
                         }  
                         rc = curs->c_get( curs, &key, &data, DB_SET_RANGE );  
                         curs->c_close( curs );  
                         if ( rc ) {  
                                 TXN_ABORT( txn );  
                                 if ( rc == DB_NOTFOUND )  
                                         rc = 0;  
                                 if ( rc == DB_LOCK_DEADLOCK ) {  
                                         ldap_pvt_thread_yield();  
                                         continue;  
                                 }  
                                 break;  
                         }  
                         BDB_DISK2ID( &nid, &id );  
                 }  
   
                 ei = NULL;          if ( bdb == NULL ) {
                 rc = bdb_cache_find_id( op, txn, id, &ei, 0, locker, &lock );                  fprintf( stderr, "%s: line %d: "
                 if ( rc ) {                          "bdb database info is null!\n",
                         TXN_ABORT( txn );                          fname, lineno );
                         if ( rc == DB_LOCK_DEADLOCK ) {                  return 1;
                                 ldap_pvt_thread_yield();  
                                 continue;  
                         }  
                         if ( rc == DB_NOTFOUND ) {  
                                 id++;  
                                 getnext = 1;  
                                 continue;  
                         }  
                         break;  
                 }  
                 if ( ei->bei_e ) {  
                         rc = bdb_index_entry( op, txn, BDB_INDEX_UPDATE_OP, ei->bei_e );  
                         if ( rc == DB_LOCK_DEADLOCK ) {  
                                 TXN_ABORT( txn );  
                                 ldap_pvt_thread_yield();  
                                 continue;  
                         }  
                         if ( rc == 0 ) {  
                                 rc = TXN_COMMIT( txn, 0 );  
                                 txn = NULL;  
                         }  
                         if ( rc )  
                                 break;  
                 }  
                 id++;  
                 getnext = 1;  
         }          }
   
         for ( i = 0; i < bdb->bi_nattrs; i++ ) {          /* directory is the DB_HOME */
                 if ( bdb->bi_attrs[ i ]->ai_indexmask & BDB_INDEX_DELETING          if ( strcasecmp( argv[0], "directory" ) == 0 ) {
                         || bdb->bi_attrs[ i ]->ai_newmask == 0 )                  if ( argc < 2 ) {
                 {                          fprintf( stderr, "%s: line %d: "
                         continue;                                  "missing dir in \"directory <dir>\" line\n",
                                   fname, lineno );
                           return 1;
                 }                  }
                 bdb->bi_attrs[ i ]->ai_indexmask = bdb->bi_attrs[ i ]->ai_newmask;                  if ( bdb->bi_dbenv_home ) {
                 bdb->bi_attrs[ i ]->ai_newmask = 0;                          free( bdb->bi_dbenv_home );
         }                  }
                   bdb->bi_dbenv_home = ch_strdup( argv[1] );
         ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );  
         ldap_pvt_runqueue_stoptask( &slapd_rq, rtask );  
         bdb->bi_index_task = NULL;  
         ldap_pvt_runqueue_remove( &slapd_rq, rtask );  
         ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );  
   
         return NULL;  
 }  
   
 /* Cleanup loose ends after Modify completes */  #ifdef SLAP_BDB_ALLOW_DIRTY_READ
 static int          } else if ( strcasecmp( argv[0], "dirtyread" ) == 0 ) {
 bdb_cf_cleanup( ConfigArgs *c )                  bdb->bi_db_opflags |= DB_DIRTY_READ;
 {  #endif
         struct bdb_info *bdb = c->be->be_private;          /* transaction logging configuration */
         int rc = 0;          } else if ( strcasecmp( argv[0], "dbnosync" ) == 0 ) {
                   bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC;
   
           /* slapadd/slapindex logging configuration */
           } else if ( strcasecmp( argv[0], "fasttool" ) == 0 ) {
                   if ( slapMode & SLAP_TOOL_MODE )
   #if DB_VERSION_FULL >= 0x04030015
                   bdb->bi_dbenv_xflags |= DB_LOG_INMEMORY;
   #else
                   bdb->bi_dbenv_xflags |= DB_TXN_NOT_DURABLE;
   #endif
   
         if ( bdb->bi_flags & BDB_UPD_CONFIG ) {          /* slapindex algorithm tuning */
                 if ( bdb->bi_db_config ) {          } else if ( strcasecmp( argv[0], "linearindex" ) == 0 ) {
                         int i;                  bdb->bi_linear_index = 1;
                         FILE *f = fopen( bdb->bi_db_config_path, "w" );  
                         if ( f ) {          /* transaction checkpoint configuration */
                                 for (i=0; bdb->bi_db_config[i].bv_val; i++)          } else if ( strcasecmp( argv[0], "checkpoint" ) == 0 ) {
                                         fprintf( f, "%s\n", bdb->bi_db_config[i].bv_val );                  if ( argc < 3 ) {
                                 fclose( f );                          fprintf( stderr, "%s: line %d: "
                         }                                  "missing parameters in \"checkpoint <kbyte> <min>\" line\n",
                 } else {                                  fname, lineno );
                         unlink( bdb->bi_db_config_path );                          return 1;
                 }                  }
                 bdb->bi_flags ^= BDB_UPD_CONFIG;                  bdb->bi_txn_cp = 1;
         }                  bdb->bi_txn_cp_kbyte = strtol( argv[1], NULL, 0 );
                   bdb->bi_txn_cp_min = strtol( argv[2], NULL, 0 );
   
         if ( bdb->bi_flags & BDB_DEL_INDEX ) {          /* lock detect configuration */
                 bdb_attr_flush( bdb );          } else if ( strcasecmp( argv[0], "lockdetect" ) == 0 ) {
                 bdb->bi_flags ^= BDB_DEL_INDEX;                  if ( argc < 2 ) {
         }                          fprintf( stderr, "%s: line %d: "
                                           "missing parameters in \"lockDetect <policy>\" line\n",
         if ( bdb->bi_flags & BDB_RE_OPEN ) {                                  fname, lineno );
                 bdb->bi_flags ^= BDB_RE_OPEN;                          return 1;
                 rc = c->be->bd_info->bi_db_close( c->be );  
                 if ( rc == 0 )  
                         rc = c->be->bd_info->bi_db_open( c->be );  
                 /* If this fails, we need to restart */  
                 if ( rc ) {  
                         slapd_shutdown = 2;  
                         Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_cf_cleanup)  
                                 ": failed to reopen database, rc=%d", rc, 0, 0 );  
                 }                  }
         }  
         return rc;  
 }  
   
 static int                  if( strcasecmp( argv[1], "default" ) == 0 ) {
 bdb_cf_gen(ConfigArgs *c)                          bdb->bi_lock_detect = DB_LOCK_DEFAULT;
 {  
         struct bdb_info *bdb = c->be->be_private;  
         int rc;  
   
         if ( c->op == SLAP_CONFIG_EMIT ) {                  } else if( strcasecmp( argv[1], "oldest" ) == 0 ) {
                 rc = 0;                          bdb->bi_lock_detect = DB_LOCK_OLDEST;
                 switch( c->type ) {  
                 case BDB_CHKPT:  
                         if (bdb->bi_txn_cp ) {  
                                 char buf[64];  
                                 struct berval bv;  
                                 bv.bv_len = sprintf( buf, "%d %d", bdb->bi_txn_cp_kbyte,  
                                         bdb->bi_txn_cp_min );  
                                 bv.bv_val = buf;  
                                 value_add_one( &c->rvalue_vals, &bv );  
                         } else{  
                                 rc = 1;  
                         }  
                         break;  
   
                 case BDB_DIRECTORY:                  } else if( strcasecmp( argv[1], "random" ) == 0 ) {
                         if ( bdb->bi_dbenv_home ) {                          bdb->bi_lock_detect = DB_LOCK_RANDOM;
                                 c->value_string = ch_strdup( bdb->bi_dbenv_home );  
                         } else {  
                                 rc = 1;  
                         }  
                         break;  
   
                 case BDB_CONFIG:                  } else if( strcasecmp( argv[1], "youngest" ) == 0 ) {
                         if ( !( bdb->bi_flags & BDB_IS_OPEN )                          bdb->bi_lock_detect = DB_LOCK_YOUNGEST;
                                 && !bdb->bi_db_config ) {  
                                 char    buf[SLAP_TEXT_BUFLEN];  
                                 FILE *f = fopen( bdb->bi_db_config_path, "r" );  
                                 struct berval bv;  
   
                                 if ( f ) {  
                                         bdb->bi_flags |= BDB_HAS_CONFIG;  
                                         while ( fgets( buf, sizeof(buf), f )) {  
                                                 ber_str2bv( buf, 0, 1, &bv );  
                                                 if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\n' ) {  
                                                         bv.bv_len--;  
                                                         bv.bv_val[bv.bv_len] = '\0';  
                                                 }  
                                                 /* shouldn't need this, but ... */  
                                                 if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\r' ) {  
                                                         bv.bv_len--;  
                                                         bv.bv_val[bv.bv_len] = '\0';  
                                                 }  
                                                 ber_bvarray_add( &bdb->bi_db_config, &bv );  
                                         }  
                                         fclose( f );  
                                 }  
                         }  
                         if ( bdb->bi_db_config ) {  
                                 int i;  
                                 struct berval bv;  
   
                                 bv.bv_val = c->log;  
                                 for (i=0; !BER_BVISNULL(&bdb->bi_db_config[i]); i++) {  
                                         bv.bv_len = sprintf( bv.bv_val, "{%d}%s", i,  
                                                 bdb->bi_db_config[i].bv_val );  
                                         value_add_one( &c->rvalue_vals, &bv );  
                                 }  
                         }  
                         if ( !c->rvalue_vals ) rc = 1;  
                         break;  
   
                 case BDB_NOSYNC:                  } else if( strcasecmp( argv[1], "fewest" ) == 0 ) {
                         if ( bdb->bi_dbenv_xflags & DB_TXN_NOSYNC )                          bdb->bi_lock_detect = DB_LOCK_MINLOCKS;
                                 c->value_int = 1;  
                         break;  
                           
                 case BDB_INDEX:  
                         bdb_attr_index_unparse( bdb, &c->rvalue_vals );  
                         if ( !c->rvalue_vals ) rc = 1;  
                         break;  
   
                 case BDB_LOCKD:  
                         rc = 1;  
                         if ( bdb->bi_lock_detect != DB_LOCK_DEFAULT ) {  
                                 int i;  
                                 for (i=0; !BER_BVISNULL(&bdb_lockd[i].word); i++) {  
                                         if ( bdb->bi_lock_detect == bdb_lockd[i].mask ) {  
                                                 value_add_one( &c->rvalue_vals, &bdb_lockd[i].word );  
                                                 rc = 0;  
                                                 break;  
                                         }  
                                 }  
                         }  
                         break;  
   
                 case BDB_SSTACK:                  } else {
                         c->value_int = bdb->bi_search_stack_depth;                          fprintf( stderr, "%s: line %d: "
                         break;                                  "bad policy (%s) in \"lockDetect <policy>\" line\n",
                 }                                  fname, lineno, argv[1] );
                 return rc;                          return 1;
         } else if ( c->op == LDAP_MOD_DELETE ) {  
                 rc = 0;  
                 switch( c->type ) {  
                 /* single-valued no-ops */  
                 case BDB_LOCKD:  
                 case BDB_SSTACK:  
                         break;  
   
                 case BDB_CHKPT:  
                         if ( bdb->bi_txn_cp_task ) {  
                                 struct re_s *re = bdb->bi_txn_cp_task;  
                                 bdb->bi_txn_cp_task = NULL;  
                                 if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ))  
                                         ldap_pvt_runqueue_stoptask( &slapd_rq, re );  
                                 ldap_pvt_runqueue_remove( &slapd_rq, re );  
                         }  
                         bdb->bi_txn_cp = 0;  
                         break;  
                 case BDB_CONFIG:  
                         if ( c->valx < 0 ) {  
                                 ber_bvarray_free( bdb->bi_db_config );  
                                 bdb->bi_db_config = NULL;  
                         } else {  
                                 int i = c->valx;  
                                 ch_free( bdb->bi_db_config[i].bv_val );  
                                 for (; bdb->bi_db_config[i].bv_val; i++)  
                                         bdb->bi_db_config[i] = bdb->bi_db_config[i+1];  
                         }  
                         bdb->bi_flags |= BDB_UPD_CONFIG;  
                         c->cleanup = bdb_cf_cleanup;  
                         break;  
                 case BDB_DIRECTORY:  
                         bdb->bi_flags |= BDB_RE_OPEN;  
                         bdb->bi_flags ^= BDB_HAS_CONFIG;  
                         ch_free( bdb->bi_dbenv_home );  
                         bdb->bi_dbenv_home = NULL;  
                         ch_free( bdb->bi_db_config_path );  
                         bdb->bi_db_config_path = NULL;  
                         c->cleanup = bdb_cf_cleanup;  
                         ldap_pvt_thread_pool_purgekey( bdb->bi_dbenv );  
                         break;  
                 case BDB_NOSYNC:  
                         bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC, 0 );  
                         break;  
                 case BDB_INDEX:  
                         if ( c->valx == -1 ) {  
                                 int i;  
   
                                 /* delete all (FIXME) */  
                                 for ( i = 0; i < bdb->bi_nattrs; i++ ) {  
                                         bdb->bi_attrs[i]->ai_indexmask |= BDB_INDEX_DELETING;  
                                 }  
                                 bdb->bi_flags |= BDB_DEL_INDEX;  
                                 c->cleanup = bdb_cf_cleanup;  
   
                         } else {  
                                 struct berval bv, def = BER_BVC("default");  
                                 char *ptr;  
   
                                 for (ptr = c->line; !isspace( *ptr ); ptr++);  
   
                                 bv.bv_val = c->line;  
                                 bv.bv_len = ptr - bv.bv_val;  
                                 if ( bvmatch( &bv, &def )) {  
                                         bdb->bi_defaultmask = 0;  
   
                                 } else {  
                                         int i;  
                                         char **attrs;  
                                         char sep;  
   
                                         sep = bv.bv_val[ bv.bv_len ];  
                                         bv.bv_val[ bv.bv_len ] = '\0';  
                                         attrs = ldap_str2charray( bv.bv_val, "," );  
   
                                         for ( i = 0; attrs[ i ]; i++ ) {  
                                                 AttributeDescription *ad = NULL;  
                                                 const char *text;  
                                                 AttrInfo *ai;  
   
                                                 slap_str2ad( attrs[ i ], &ad, &text );  
                                                 /* if we got here... */  
                                                 assert( ad != NULL );  
   
                                                 ai = bdb_attr_mask( bdb, ad );  
                                                 /* if we got here... */  
                                                 assert( ai != NULL );  
   
                                                 ai->ai_indexmask |= BDB_INDEX_DELETING;  
                                                 bdb->bi_flags |= BDB_DEL_INDEX;  
                                                 c->cleanup = bdb_cf_cleanup;  
                                         }  
   
                                         bv.bv_val[ bv.bv_len ] = sep;  
                                         ldap_charray_free( attrs );  
                                 }  
                         }  
                         break;  
                 }                  }
                 return rc;  
         }  
   
         switch( c->type ) {          /* mode with which to create new database files */
         case BDB_CHKPT: {          } else if ( strcasecmp( argv[0], "mode" ) == 0 ) {
                 long    l;                  if ( argc < 2 ) {
                 bdb->bi_txn_cp = 1;                          fprintf( stderr, "%s: line %d: "
                 if ( lutil_atolx( &l, c->argv[1], 0 ) != 0 ) {                                  "missing mode in \"mode <mode>\" line\n",
                         fprintf( stderr, "%s: "                                  fname, lineno );
                                 "invalid kbyte \"%s\" in \"checkpoint\".\n",  
                                 c->log, c->argv[1] );  
                         return 1;                          return 1;
                 }                  }
                 bdb->bi_txn_cp_kbyte = l;                  bdb->bi_dbenv_mode = strtol( argv[1], NULL, 0 );
                 if ( lutil_atolx( &l, c->argv[2], 0 ) != 0 ) {  
                         fprintf( stderr, "%s: "          /* attribute to index */
                                 "invalid minutes \"%s\" in \"checkpoint\".\n",          } else if ( strcasecmp( argv[0], "index" ) == 0 ) {
                                 c->log, c->argv[2] );                  int rc;
                   if ( argc < 2 ) {
                           fprintf( stderr, "%s: line %d: "
                                   "missing attr in \"index <attr> [pres,eq,approx,sub]\" line\n",
                                   fname, lineno );
                         return 1;                          return 1;
                   } else if ( argc > 3 ) {
                           fprintf( stderr, "%s: line %d: "
                                   "extra junk after \"index <attr> [pres,eq,approx,sub]\" "
                                   "line (ignored)\n",
                                   fname, lineno );
                 }                  }
                 bdb->bi_txn_cp_min = l;                  rc = bdb_attr_index_config( bdb, fname, lineno, argc - 1, &argv[1] );
                 /* If we're in server mode and time-based checkpointing is enabled,  
                  * submit a task to perform periodic checkpoints.  
                  */  
                 if ((slapMode & SLAP_SERVER_MODE) && bdb->bi_txn_cp_min ) {  
                         struct re_s *re = bdb->bi_txn_cp_task;  
                         if ( re ) {  
                                 re->interval.tv_sec = bdb->bi_txn_cp_min * 60;  
                         } else {  
                                 if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) {  
                                         fprintf( stderr, "%s: "  
                                                 "\"checkpoint\" must occur after \"suffix\".\n",  
                                                 c->log );  
                                         return 1;  
                                 }  
                                 bdb->bi_txn_cp_task = ldap_pvt_runqueue_insert( &slapd_rq,  
                                         bdb->bi_txn_cp_min * 60, bdb_checkpoint, bdb,  
                                         LDAP_XSTRING(bdb_checkpoint), c->be->be_suffix[0].bv_val );  
                         }  
                 }  
                 } break;  
   
         case BDB_CONFIG: {                  if( rc != LDAP_SUCCESS ) return 1;
                 char *ptr = c->line;  
                 struct berval bv;  
   
                 if ( c->op == SLAP_CONFIG_ADD ) {  
                         ptr += STRLENOF("dbconfig");  
                         while (!isspace(*ptr)) ptr++;  
                         while (isspace(*ptr)) ptr++;  
                 }  
   
                 if ( bdb->bi_flags & BDB_IS_OPEN ) {          /* unique key for shared memory regions */
                         bdb->bi_flags |= BDB_UPD_CONFIG;          } else if ( strcasecmp( argv[0], "shm_key" ) == 0 ) {
                         c->cleanup = bdb_cf_cleanup;                  if ( argc < 2 ) {
                 } else {                          fprintf( stderr,
                 /* If we're just starting up...                                  "%s: line %d: missing key in \"shm_key <key>\" line\n",
                  */                                  fname, lineno );
                         FILE *f;                          return( 1 );
                         /* If a DB_CONFIG file exists, or we don't know the path                  }
                          * to the DB_CONFIG file, ignore these directives                  bdb->bi_shm_key = atoi( argv[1] );
                          */  
                         if (( bdb->bi_flags & BDB_HAS_CONFIG ) || !bdb->bi_db_config_path )          /* size of the cache in entries */
                                 break;          } else if ( strcasecmp( argv[0], "cachesize" ) == 0 ) {
                         f = fopen( bdb->bi_db_config_path, "a" );                  if ( argc < 2 ) {
                         if ( f ) {                          fprintf( stderr,
                                 /* FIXME: EBCDIC probably needs special handling */                                  "%s: line %d: missing size in \"cachesize <size>\" line\n",
                                 fprintf( f, "%s\n", ptr );                                  fname, lineno );
                                 fclose( f );                          return( 1 );
                         }                  }
                 }                  bdb->bi_cache.c_maxsize = atoi( argv[1] );
                 ber_str2bv( ptr, 0, 1, &bv );  
                 ber_bvarray_add( &bdb->bi_db_config, &bv );          /* depth of search stack cache in units of (IDL)s */
           } else if ( strcasecmp( argv[0], "searchstack" ) == 0 ) {
                   if ( argc < 2 ) {
                           fprintf( stderr,
                                   "%s: line %d: missing depth in \"searchstack <depth>\" line\n",
                                   fname, lineno );
                           return( 1 );
                 }                  }
                 break;                  bdb->bi_search_stack_depth = atoi( argv[1] );
                   if ( bdb->bi_search_stack_depth < MINIMUM_SEARCH_STACK_DEPTH ) {
         case BDB_DIRECTORY: {                          fprintf( stderr,
                 FILE *f;                  "%s: line %d: depth %d too small, using %d\n",
                 char *ptr;                          fname, lineno, bdb->bi_search_stack_depth,
                           MINIMUM_SEARCH_STACK_DEPTH );
                 if ( bdb->bi_dbenv_home )                          bdb->bi_search_stack_depth = MINIMUM_SEARCH_STACK_DEPTH;
                         ch_free( bdb->bi_dbenv_home );  
                 bdb->bi_dbenv_home = c->value_string;  
   
                 /* See if a DB_CONFIG file already exists here */  
                 if ( bdb->bi_db_config_path )  
                         ch_free( bdb->bi_db_config_path );  
                 bdb->bi_db_config_path = ch_malloc( strlen( bdb->bi_dbenv_home ) +  
                         STRLENOF(LDAP_DIRSEP) + STRLENOF("DB_CONFIG") + 1 );  
                 ptr = lutil_strcopy( bdb->bi_db_config_path, bdb->bi_dbenv_home );  
                 *ptr++ = LDAP_DIRSEP[0];  
                 strcpy( ptr, "DB_CONFIG" );  
   
                 f = fopen( bdb->bi_db_config_path, "r" );  
                 if ( f ) {  
                         bdb->bi_flags |= BDB_HAS_CONFIG;  
                         fclose(f);  
                 }  
                 }  
                 break;  
   
         case BDB_NOSYNC:  
                 if ( c->value_int )  
                         bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC;  
                 else  
                         bdb->bi_dbenv_xflags &= ~DB_TXN_NOSYNC;  
                 if ( bdb->bi_flags & BDB_IS_OPEN ) {  
                         bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC,  
                                 c->value_int );  
                 }  
                 break;  
   
         case BDB_INDEX:  
                 rc = bdb_attr_index_config( bdb, c->fname, c->lineno,  
                         c->argc - 1, &c->argv[1] );  
   
                 if( rc != LDAP_SUCCESS ) return 1;  
                 if (( bdb->bi_flags & BDB_IS_OPEN ) && !bdb->bi_index_task ) {  
                         /* Start the task as soon as we finish here. Set a long  
                          * interval (10 hours) so that it only gets scheduled once.  
                          */  
                         if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) {  
                                 fprintf( stderr, "%s: "  
                                         "\"index\" must occur after \"suffix\".\n",  
                                         c->log );  
                                 return 1;  
                         }  
                         bdb->bi_index_task = ldap_pvt_runqueue_insert( &slapd_rq, 36000,  
                                 bdb_online_index, c->be,  
                                 LDAP_XSTRING(bdb_online_index), c->be->be_suffix[0].bv_val );  
                 }  
                 break;  
   
         case BDB_LOCKD:  
                 rc = verb_to_mask( c->argv[1], bdb_lockd );  
                 if ( BER_BVISNULL(&bdb_lockd[rc].word) ) {  
                         fprintf( stderr, "%s: "  
                                 "bad policy (%s) in \"lockDetect <policy>\" line\n",  
                                 c->log, c->argv[1] );  
                         return 1;  
                 }                  }
                 bdb->bi_lock_detect = rc;  
                 break;  
   
         case BDB_SSTACK:          /* size of the IDL cache in entries */
                 if ( c->value_int < MINIMUM_SEARCH_STACK_DEPTH ) {          } else if ( strcasecmp( argv[0], "idlcachesize" ) == 0 ) {
                   if ( argc < 2 ) {
                         fprintf( stderr,                          fprintf( stderr,
                 "%s: depth %d too small, using %d\n",                                  "%s: line %d: missing size in \"idlcachesize <size>\" line\n",
                         c->log, c->value_int, MINIMUM_SEARCH_STACK_DEPTH );                                  fname, lineno );
                         c->value_int = MINIMUM_SEARCH_STACK_DEPTH;                          return( 1 );
                 }                  }
                 bdb->bi_search_stack_depth = c->value_int;                  if ( !( slapMode & SLAP_TOOL_MODE ) )
                 break;                          bdb->bi_idl_cache_max_size = atoi( argv[1] );
   #ifdef BDB_PSEARCH
           } else if ( strcasecmp( argv[0], "sessionlog" ) == 0 ) {
                   int se_id = 0, se_size = 0;
                   struct slap_session_entry *sent;
                   if ( argc < 3 ) {
                           Debug( LDAP_DEBUG_ANY,
                                   "%s: line %d: missing arguments in \"sessionlog <id> <size>\""
                                   " line\n", fname, lineno, 0 );
                           return( 1 );
                   }
   
                   se_id = atoi( argv[1] );
   
                   if ( se_id < 0 || se_id > 999 ) {
                           Debug( LDAP_DEBUG_ANY,
                                   "%s: line %d: session log id %d is out of range [0..999]\n",
                                   fname, lineno , se_id );
                           return( 1 );
                   }
   
                   se_size = atoi( argv[2] );
                   if ( se_size < 0 ) {
                           Debug( LDAP_DEBUG_ANY,
                                   "%s: line %d: session log size %d is negative\n",
                                   fname, lineno , se_size );
                           return( 1 );
                   }
   
                   LDAP_LIST_FOREACH( sent, &bdb->bi_session_list, se_link ) {
                           if ( sent->se_id == se_id ) {
                                   Debug( LDAP_DEBUG_ANY,
                                           "%s: line %d: session %d already exists\n",
                                           fname, lineno , se_id );
                                   return( 1 );
                           }
                   }
                   sent = (struct slap_session_entry *) ch_calloc( 1,
                                                   sizeof( struct slap_session_entry ));
                   sent->se_id = se_id;
                   sent->se_size = se_size;
                   LDAP_LIST_INSERT_HEAD( &bdb->bi_session_list, sent, se_link );
   #endif /* BDB_PSEARCH */
           /* anything else */
           } else {
                   return SLAP_CONF_UNKNOWN;
         }          }
         return 0;  
 }  
   
 int bdb_back_init_cf( BackendInfo *bi )  
 {  
         int rc;  
         bi->bi_cf_ocs = bdbocs;  
   
         rc = config_register_schema( bdbcfg, bdbocs );  
         if ( rc ) return rc;  
         return 0;          return 0;
 }  }

Removed from v.1.43.2.20  
changed lines
  Added in v.1.44


______________
© Copyright 1998-2020, OpenLDAP Foundation, info@OpenLDAP.org