version 1.43, 2004/11/25 20:16:56
|
version 1.43.2.3, 2005/03/14 22:24:59
|
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.42 2004/11/13 12:23:33 hyc Exp $ */ |
/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/config.c,v 1.43.2.2 2005/01/28 17:29:49 kurt 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-2004 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 21
|
Line 21
|
|
|
#include "back-bdb.h" |
#include "back-bdb.h" |
|
|
|
#include "config.h" |
|
|
#ifdef DB_DIRTY_READ |
#ifdef DB_DIRTY_READ |
# define SLAP_BDB_ALLOW_DIRTY_READ |
# define SLAP_BDB_ALLOW_DIRTY_READ |
#endif |
#endif |
|
|
int |
static ObjectClass *bdb_oc; |
bdb_db_config( |
|
BackendDB *be, |
|
const char *fname, |
|
int lineno, |
|
int argc, |
|
char **argv ) |
|
{ |
|
struct bdb_info *bdb = (struct bdb_info *) be->be_private; |
|
|
|
if ( bdb == NULL ) { |
|
fprintf( stderr, "%s: line %d: " |
|
"bdb database info is null!\n", |
|
fname, lineno ); |
|
return 1; |
|
} |
|
|
|
/* directory is the DB_HOME */ |
static ConfigDriver bdb_cf_oc, bdb_cf_gen; |
if ( strcasecmp( argv[0], "directory" ) == 0 ) { |
|
if ( argc < 2 ) { |
|
fprintf( stderr, "%s: line %d: " |
|
"missing dir in \"directory <dir>\" line\n", |
|
fname, lineno ); |
|
return 1; |
|
} |
|
if ( bdb->bi_dbenv_home ) { |
|
free( bdb->bi_dbenv_home ); |
|
} |
|
bdb->bi_dbenv_home = ch_strdup( argv[1] ); |
|
|
|
|
enum { |
|
BDB_CHKPT = 1, |
|
BDB_NOSYNC, |
|
BDB_DIRTYR, |
|
BDB_INDEX, |
|
BDB_LOCKD, |
|
BDB_SSTACK |
|
}; |
|
|
|
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' " |
|
"DESC 'Directory for database content' " |
|
"EQUALITY caseIgnoreMatch " |
|
"SYNTAX OMsDirectoryString )", 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 }, |
|
{ "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 )",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 }, |
|
{ "dirtyread", NULL, 1, 2, 0, |
#ifdef SLAP_BDB_ALLOW_DIRTY_READ |
#ifdef SLAP_BDB_ALLOW_DIRTY_READ |
} else if ( strcasecmp( argv[0], "dirtyread" ) == 0 ) { |
ARG_ON_OFF|ARG_MAGIC|BDB_DIRTYR, bdb_cf_gen, |
bdb->bi_db_opflags |= DB_DIRTY_READ; |
|
#endif |
|
/* transaction logging configuration */ |
|
} 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 |
#else |
bdb->bi_dbenv_xflags |= DB_TXN_NOT_DURABLE; |
ARG_IGNORED, NULL, |
#endif |
#endif |
|
"( OLcfgAt:1.5 NAME 'dbDirtyRead' " |
|
"DESC 'Allow reads of uncommitted data' " |
|
"SYNTAX OMsBoolean )", 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 }, |
|
{ "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' " |
|
"SYNTAX OMsDirectoryString )", NULL, NULL }, |
|
{ "linearindex", NULL, 1, 2, 0, ARG_ON_OFF|ARG_OFFSET, |
|
(void *)offsetof(struct bdb_info, bi_linear_index), |
|
"( OLcfgAt:1.8 NAME 'dbLinearIndex' " |
|
"DESC 'Index attributes one at a time' " |
|
"SYNTAX OMsBoolean )", 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 }, |
|
{ "mode", "mode", 2, 2, 0, ARG_LONG|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 }, |
|
{ "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 }, |
|
{ "shm_key", "key", 2, 2, 0, ARG_INT|ARG_NONZERO|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 }, |
|
{ NULL, NULL, 0, 0, 0, ARG_IGNORED, |
|
NULL, NULL, NULL, NULL } |
|
}; |
|
|
|
static ConfigOCs bdbocs[] = { |
|
{ "( OLcfgOc:1.1 " |
|
"NAME 'bdbConfig' " |
|
"DESC 'BDB backend configuration' " |
|
"AUXILIARY " |
|
"MAY ( dbDirectory $ dbCacheSize $ dbCheckpoint $ dbNoSync $ " |
|
"dbDirtyRead $ dbIDLcacheSize $ dbIndex $ dbLinearIndex $ " |
|
"dbLockDetect $ dbMode $ dbSearchStack $ dbShmKey ) )", |
|
&bdb_oc }, |
|
{ NULL, NULL } |
|
}; |
|
|
/* slapindex algorithm tuning */ |
static int |
} else if ( strcasecmp( argv[0], "linearindex" ) == 0 ) { |
bdb_cf_oc(ConfigArgs *c) |
bdb->bi_linear_index = 1; |
{ |
|
if ( c->emit ) { |
/* transaction checkpoint configuration */ |
value_add_one( &c->rvalue_vals, &bdb_oc->soc_cname ); |
} else if ( strcasecmp( argv[0], "checkpoint" ) == 0 ) { |
return 0; |
if ( argc < 3 ) { |
} |
fprintf( stderr, "%s: line %d: " |
return 1; |
"missing parameters in \"checkpoint <kbyte> <min>\" line\n", |
} |
fname, lineno ); |
|
return 1; |
|
} |
|
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 ); |
|
|
|
/* lock detect configuration */ |
|
} else if ( strcasecmp( argv[0], "lockdetect" ) == 0 ) { |
|
if ( argc < 2 ) { |
|
fprintf( stderr, "%s: line %d: " |
|
"missing parameters in \"lockDetect <policy>\" line\n", |
|
fname, lineno ); |
|
return 1; |
|
} |
|
|
|
if( strcasecmp( argv[1], "default" ) == 0 ) { |
|
bdb->bi_lock_detect = DB_LOCK_DEFAULT; |
|
|
|
} else if( strcasecmp( argv[1], "oldest" ) == 0 ) { |
|
bdb->bi_lock_detect = DB_LOCK_OLDEST; |
|
|
|
} else if( strcasecmp( argv[1], "random" ) == 0 ) { |
|
bdb->bi_lock_detect = DB_LOCK_RANDOM; |
|
|
|
} else if( strcasecmp( argv[1], "youngest" ) == 0 ) { |
static slap_verbmasks bdb_lockd[] = { |
bdb->bi_lock_detect = DB_LOCK_YOUNGEST; |
{ 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 } |
|
}; |
|
|
} else if( strcasecmp( argv[1], "fewest" ) == 0 ) { |
static int |
bdb->bi_lock_detect = DB_LOCK_MINLOCKS; |
bdb_cf_gen(ConfigArgs *c) |
|
{ |
|
struct bdb_info *bdb = c->be->be_private; |
|
int rc; |
|
|
} else { |
if ( c->emit ) { |
fprintf( stderr, "%s: line %d: " |
rc = 0; |
"bad policy (%s) in \"lockDetect <policy>\" line\n", |
switch( c->type ) { |
fname, lineno, argv[1] ); |
case BDB_CHKPT: |
return 1; |
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; |
|
|
/* mode with which to create new database files */ |
case BDB_NOSYNC: |
} else if ( strcasecmp( argv[0], "mode" ) == 0 ) { |
if ( bdb->bi_dbenv_xflags & DB_TXN_NOSYNC ) |
if ( argc < 2 ) { |
c->value_int = 1; |
fprintf( stderr, "%s: line %d: " |
break; |
"missing mode in \"mode <mode>\" line\n", |
|
fname, lineno ); |
case BDB_INDEX: |
return 1; |
bdb_attr_index_unparse( bdb, &c->rvalue_vals ); |
} |
if ( !c->rvalue_vals ) rc = 1; |
bdb->bi_dbenv_mode = strtol( argv[1], NULL, 0 ); |
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; |
|
|
/* attribute to index */ |
case BDB_SSTACK: |
} else if ( strcasecmp( argv[0], "index" ) == 0 ) { |
c->value_int = bdb->bi_search_stack_depth; |
int rc; |
break; |
if ( argc < 2 ) { |
|
fprintf( stderr, "%s: line %d: " |
|
"missing attr in \"index <attr> [pres,eq,approx,sub]\" line\n", |
|
fname, lineno ); |
|
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 ); |
|
} |
} |
rc = bdb_attr_index_config( bdb, fname, lineno, argc - 1, &argv[1] ); |
return rc; |
|
} |
|
switch( c->type ) { |
|
case BDB_CHKPT: |
|
bdb->bi_txn_cp = 1; |
|
bdb->bi_txn_cp_kbyte = strtol( c->argv[1], NULL, 0 ); |
|
bdb->bi_txn_cp_min = strtol( c->argv[2], NULL, 0 ); |
|
break; |
|
|
|
case BDB_NOSYNC: |
|
if ( c->value_int ) |
|
bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC; |
|
else |
|
bdb->bi_dbenv_xflags &= ~DB_TXN_NOSYNC; |
|
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( rc != LDAP_SUCCESS ) return 1; |
|
break; |
|
|
/* unique key for shared memory regions */ |
case BDB_LOCKD: |
} else if ( strcasecmp( argv[0], "shm_key" ) == 0 ) { |
rc = verb_to_mask( c->argv[1], bdb_lockd ); |
if ( argc < 2 ) { |
if ( BER_BVISNULL(&bdb_lockd[rc].word) ) { |
fprintf( stderr, |
fprintf( stderr, "%s: " |
"%s: line %d: missing key in \"shm_key <key>\" line\n", |
"bad policy (%s) in \"lockDetect <policy>\" line\n", |
fname, lineno ); |
c->log, c->argv[1] ); |
return( 1 ); |
return 1; |
} |
|
bdb->bi_shm_key = atoi( argv[1] ); |
|
|
|
/* size of the cache in entries */ |
|
} else if ( strcasecmp( argv[0], "cachesize" ) == 0 ) { |
|
if ( argc < 2 ) { |
|
fprintf( stderr, |
|
"%s: line %d: missing size in \"cachesize <size>\" line\n", |
|
fname, lineno ); |
|
return( 1 ); |
|
} |
|
bdb->bi_cache.c_maxsize = atoi( argv[1] ); |
|
|
|
/* 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 ); |
|
} |
|
bdb->bi_search_stack_depth = atoi( argv[1] ); |
|
if ( bdb->bi_search_stack_depth < MINIMUM_SEARCH_STACK_DEPTH ) { |
|
fprintf( stderr, |
|
"%s: line %d: depth %d too small, using %d\n", |
|
fname, lineno, bdb->bi_search_stack_depth, |
|
MINIMUM_SEARCH_STACK_DEPTH ); |
|
bdb->bi_search_stack_depth = MINIMUM_SEARCH_STACK_DEPTH; |
|
} |
} |
|
bdb->bi_lock_detect = rc; |
|
break; |
|
|
/* size of the IDL cache in entries */ |
case BDB_SSTACK: |
} else if ( strcasecmp( argv[0], "idlcachesize" ) == 0 ) { |
if ( c->value_int < MINIMUM_SEARCH_STACK_DEPTH ) { |
if ( argc < 2 ) { |
|
fprintf( stderr, |
fprintf( stderr, |
"%s: line %d: missing size in \"idlcachesize <size>\" line\n", |
"%s: depth %d too small, using %d\n", |
fname, lineno ); |
c->log, c->value_int, MINIMUM_SEARCH_STACK_DEPTH ); |
return( 1 ); |
c->value_int = MINIMUM_SEARCH_STACK_DEPTH; |
} |
} |
if ( !( slapMode & SLAP_TOOL_MODE ) ) |
bdb->bi_search_stack_depth = c->value_int; |
bdb->bi_idl_cache_max_size = atoi( argv[1] ); |
break; |
#ifdef BDB_PSEARCH |
} |
} else if ( strcasecmp( argv[0], "sessionlog" ) == 0 ) { |
return 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 ) { |
int bdb_back_init_cf( BackendInfo *bi ) |
Debug( LDAP_DEBUG_ANY, |
{ |
"%s: line %d: session log id %d is out of range [0..999]\n", |
int rc; |
fname, lineno , se_id ); |
bi->bi_cf_table = bdbcfg; |
return( 1 ); |
|
} |
|
|
|
se_size = atoi( argv[2] ); |
rc = init_config_attrs( bdbcfg ); |
if ( se_size < 0 ) { |
if ( rc ) return rc; |
Debug( LDAP_DEBUG_ANY, |
bdbcfg[0].ad = slap_schema.si_ad_objectClass; |
"%s: line %d: session log size %d is negative\n", |
rc = init_config_ocs( bdbocs ); |
fname, lineno , se_size ); |
return rc; |
return( 1 ); |
} |
} |
|
|
|
LDAP_LIST_FOREACH( sent, &bdb->bi_session_list, se_link ) { |
int bdb_db_config( Backend *be, const char *fname, int lineno, int argc, |
if ( sent->se_id == se_id ) { |
char **argv ) |
Debug( LDAP_DEBUG_ANY, |
{ |
"%s: line %d: session %d already exists\n", |
ConfigArgs c = { 0 }; |
fname, lineno , se_id ); |
int rc; |
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; |
c.be = be; |
|
c.fname = fname; |
|
c.lineno = lineno; |
|
c.argc = argc; |
|
c.argv = argv; |
|
sprintf( c.log, "%s: line %lu", fname, lineno ); |
|
|
|
rc = parse_config_table( bdbcfg, &c ); |
|
if ( rc == ARG_UNKNOWN ) |
|
rc = SLAP_CONF_UNKNOWN; |
|
return rc; |
} |
} |