#include "config.h"
+#include "lutil.h"
+
#ifdef DB_DIRTY_READ
# define SLAP_BDB_ALLOW_DIRTY_READ
#endif
enum {
BDB_CHKPT = 1,
+ BDB_CONFIG,
+ BDB_DIRECTORY,
BDB_NOSYNC,
BDB_DIRTYR,
BDB_INDEX,
static ConfigTable bdbcfg[] = {
{ "", "", 0, 0, 0, ARG_MAGIC,
bdb_cf_oc, NULL, NULL, NULL },
- { "directory", "dir", 2, 2, 0, ARG_STRING|ARG_OFFSET,
- (void *)offsetof(struct bdb_info, bi_dbenv_home),
- "( OLcfgAt:1.1 NAME 'dbDirectory' "
+ { "directory", "dir", 2, 2, 0, ARG_STRING|ARG_MAGIC|BDB_DIRECTORY,
+ bdb_cf_gen, "( OLcfgAt:1.1 NAME 'dbDirectory' "
"DESC 'Directory for database content' "
"EQUALITY caseIgnoreMatch "
- "SYNTAX OMsDirectoryString )", NULL, NULL },
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "cachesize", "size", 2, 2, 0, ARG_INT|ARG_OFFSET,
(void *)offsetof(struct bdb_info, bi_cache.c_maxsize),
"( OLcfgAt:1.2 NAME 'dbCacheSize' "
"DESC 'Entry cache size in entries' "
- "SYNTAX OMsInteger )", NULL, NULL },
+ "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "checkpoint", "kbyte> <min", 3, 3, 0, ARG_MAGIC|BDB_CHKPT,
bdb_cf_gen, "( OLcfgAt:1.3 NAME 'dbCheckpoint' "
"DESC 'Database checkpoint interval in kbytes and minutes' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )",NULL, NULL },
+ { "dbconfig", "DB_CONFIG setting", 3, 0, 0, ARG_MAGIC|BDB_CONFIG,
+ bdb_cf_gen, "( OLcfgAt:1.13 NAME 'dbConfig' "
+ "DESC 'BerkeleyDB DB_CONFIG configuration directives' "
"SYNTAX OMsDirectoryString )",NULL, NULL },
{ "dbnosync", NULL, 1, 2, 0, ARG_ON_OFF|ARG_MAGIC|BDB_NOSYNC,
bdb_cf_gen, "( OLcfgAt:1.4 NAME 'dbNoSync' "
"DESC 'Disable synchronous database writes' "
- "SYNTAX OMsBoolean )", NULL, NULL },
+ "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,
#endif
"( OLcfgAt:1.5 NAME 'dbDirtyRead' "
"DESC 'Allow reads of uncommitted data' "
- "SYNTAX OMsBoolean )", NULL, NULL },
+ "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),
"( OLcfgAt:1.6 NAME 'dbIDLcacheSize' "
"DESC 'IDL cache size in IDLs' "
- "SYNTAX OMsInteger )", NULL, NULL },
+ "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "index", "attr> <[pres,eq,approx,sub]", 3, 3, 0, ARG_MAGIC|BDB_INDEX,
bdb_cf_gen, "( OLcfgAt:1.7 NAME 'dbIndex' "
"DESC 'Attribute index parameters' "
(void *)offsetof(struct bdb_info, bi_linear_index),
"( OLcfgAt:1.8 NAME 'dbLinearIndex' "
"DESC 'Index attributes one at a time' "
- "SYNTAX OMsBoolean )", NULL, NULL },
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
{ "lockdetect", "policy", 2, 2, 0, ARG_MAGIC|BDB_LOCKD,
bdb_cf_gen, "( OLcfgAt:1.9 NAME 'dbLockDetect' "
"DESC 'Deadlock detection algorithm' "
- "SYNTAX OMsDirectoryString )", NULL, NULL },
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "mode", "mode", 2, 2, 0, ARG_INT|ARG_OFFSET,
(void *)offsetof(struct bdb_info, bi_dbenv_mode),
"( OLcfgAt:1.10 NAME 'dbMode' "
"DESC 'Unix permissions of database files' "
- "SYNTAX OMsInteger )", NULL, NULL },
+ "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "searchstack", "depth", 2, 2, 0, ARG_INT|ARG_MAGIC|BDB_SSTACK,
bdb_cf_gen, "( OLcfgAt:1.11 NAME 'dbSearchStack' "
"DESC 'Depth of search stack in IDLs' "
- "SYNTAX OMsInteger )", NULL, NULL },
+ "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "shm_key", "key", 2, 2, 0, ARG_INT|ARG_OFFSET,
(void *)offsetof(struct bdb_info, bi_shm_key),
"( OLcfgAt:1.12 NAME 'dbShmKey' "
"DESC 'Key for shared memory region' "
- "SYNTAX OMsInteger )", NULL, NULL },
+ "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ NULL, NULL, 0, 0, 0, ARG_IGNORED,
NULL, NULL, NULL, NULL }
};
"DESC 'BDB backend configuration' "
"SUP olcDatabaseConfig "
"MUST dbDirectory "
- "MAY ( dbCacheSize $ dbCheckpoint $ dbNoSync $ "
+ "MAY ( dbCacheSize $ dbCheckpoint $ dbConfig $ dbNoSync $ "
"dbDirtyRead $ dbIDLcacheSize $ dbIndex $ dbLinearIndex $ "
"dbLockDetect $ dbMode $ dbSearchStack $ dbShmKey ) )",
Cft_Database, &bdb_oc },
}
break;
+ case BDB_DIRECTORY:
+ if ( bdb->bi_dbenv_home ) {
+ c->value_string = ch_strdup( bdb->bi_dbenv_home );
+ } else {
+ rc = 1;
+ }
+ break;
+
+ case BDB_CONFIG:
+ 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:
if ( bdb->bi_dbenv_xflags & DB_TXN_NOSYNC )
c->value_int = 1;
bdb->bi_txn_cp_min = strtol( c->argv[2], NULL, 0 );
break;
+ case BDB_CONFIG: {
+ char *ptr = c->line + STRLENOF("dbconfig");
+ struct berval bv;
+ while (!isspace(*ptr)) ptr++;
+ while (isspace(*ptr)) ptr++;
+
+ /* If we're just starting up...
+ */
+ if ( !bdb->bi_db_is_open ) {
+ FILE *f;
+ /* If a DB_CONFIG file exists, or we don't know the path
+ * to the DB_CONFIG file, ignore these directives
+ */
+ if ( bdb->bi_db_has_config || !bdb->bi_db_config_path )
+ break;
+ f = fopen( bdb->bi_db_config_path, "a" );
+ if ( f ) {
+ /* FIXME: EBCDIC probably needs special handling */
+ fprintf( f, "%s\n", ptr );
+ fclose( f );
+ }
+ }
+ ber_str2bv( ptr, 0, 1, &bv );
+ ber_bvarray_add( &bdb->bi_db_config, &bv );
+ }
+ break;
+
+ case BDB_DIRECTORY: {
+ FILE *f;
+ char *ptr;
+
+ bdb->bi_dbenv_home = c->value_string;
+
+ /* See if a DB_CONFIG file already exists here */
+ bdb->bi_db_config_path = ch_malloc( strlen( bdb->bi_dbenv_home ) +
+ STRLENOF(LDAP_DIRSEP) + STRLENOF("DB_CONFIG"));
+ 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_db_has_config = 1;
+ fclose(f);
+ }
+ }
+ break;
+
case BDB_NOSYNC:
if ( c->value_int )
bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC;