diff options
Diffstat (limited to 'db/env/env_config.c')
-rw-r--r-- | db/env/env_config.c | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/db/env/env_config.c b/db/env/env_config.c new file mode 100644 index 000000000..1a098e277 --- /dev/null +++ b/db/env/env_config.c @@ -0,0 +1,370 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2006 + * Oracle Corporation. All rights reserved. + * + * $Id: env_config.c,v 12.67 2006/09/19 14:14:07 mjc Exp $ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/txn.h" + +#undef CONFIG_SLOTS +#define CONFIG_SLOTS 10 + +static int __config_parse __P((DB_ENV *, char *, int)); +static int __config_split __P((char *, char *[CONFIG_SLOTS])); + +/* + * __env_read_db_config -- + * Read the DB_CONFIG file. + * + * PUBLIC: int __env_read_db_config __P((DB_ENV *)); + */ +int +__env_read_db_config(dbenv) + DB_ENV *dbenv; +{ + FILE *fp; + int lc, ret; + char *p, buf[256]; + + /* Parse the config file. */ + p = NULL; + if ((ret = + __db_appname(dbenv, DB_APP_NONE, "DB_CONFIG", 0, NULL, &p)) != 0) + return (ret); + if (p == NULL) + fp = NULL; + else { + fp = fopen(p, "r"); + __os_free(dbenv, p); + } + + if (fp == NULL) + return (0); + + for (lc = 1; fgets(buf, sizeof(buf), fp) != NULL; ++lc) { + if ((p = strchr(buf, '\n')) != NULL) + *p = '\0'; + else if (strlen(buf) + 1 == sizeof(buf)) { + __db_errx(dbenv, "DB_CONFIG: line too long"); + ret = EINVAL; + break; + } + for (p = buf; *p != '\0' || isspace((int)*p); ++p) + ; + if (buf[0] == '\0' || buf[0] == '#') + continue; + + if ((ret = __config_parse(dbenv, buf, lc)) != 0) + break; + } + (void)fclose(fp); + + return (ret); +} + +#undef CONFIG_GET_INT +#define CONFIG_GET_INT(s, vp) do { \ + int __ret; \ + if ((__ret = \ + __db_getlong(dbenv, NULL, s, 0, INT_MAX, vp)) != 0) \ + return (__ret); \ +} while (0) +#undef CONFIG_GET_LONG +#define CONFIG_GET_LONG(s, vp) do { \ + int __ret; \ + if ((__ret = \ + __db_getlong(dbenv, NULL, s, 0, LONG_MAX, vp)) != 0) \ + return (__ret); \ +} while (0) +#undef CONFIG_INT +#define CONFIG_INT(s, f) do { \ + if (strcasecmp(s, argv[0]) == 0) { \ + long __v; \ + if (nf != 2) \ + goto format; \ + CONFIG_GET_INT(argv[1], &__v); \ + return (f(dbenv, (int)__v)); \ + } \ +} while (0) +#undef CONFIG_GET_UINT32 +#define CONFIG_GET_UINT32(s, vp) do { \ + if (__db_getulong(dbenv, NULL, s, 0, UINT32_MAX, vp) != 0) \ + return (EINVAL); \ +} while (0) +#undef CONFIG_UINT32 +#define CONFIG_UINT32(s, f) do { \ + if (strcasecmp(s, argv[0]) == 0) { \ + u_long __v; \ + if (nf != 2) \ + goto format; \ + CONFIG_GET_UINT32(argv[1], &__v); \ + return (f(dbenv, (u_int32_t)__v)); \ + } \ +} while (0) + +/* + * __config_parse -- + * Parse a single NAME VALUE pair. + */ +static int +__config_parse(dbenv, s, lc) + DB_ENV *dbenv; + char *s; + int lc; +{ + u_long uv1, uv2; + u_int32_t flags; + long lv1, lv2; + int nf; + char *argv[CONFIG_SLOTS]; + /* Split the line by white-space. */ + if ((nf = __config_split(s, argv)) < 2) { +format: __db_errx(dbenv, + "line %d: %s: incorrect name-value pair", lc, argv[0]); + return (EINVAL); + } + + CONFIG_UINT32("mutex_set_align", __mutex_set_align); + CONFIG_UINT32("mutex_set_increment", __mutex_set_increment); + CONFIG_UINT32("mutex_set_max", __mutex_set_max); + CONFIG_UINT32("mutex_set_tas_spins", __mutex_set_tas_spins); + + if (strcasecmp(argv[0], "rep_set_config") == 0) { + if (nf != 2) + goto format; + if (strcasecmp(argv[1], "rep_bulk") == 0) + return (__rep_set_config(dbenv, + DB_REP_CONF_BULK, 1)); + if (strcasecmp(argv[1], "rep_delayclient") == 0) + return (__rep_set_config(dbenv, + DB_REP_CONF_DELAYCLIENT, 1)); + if (strcasecmp(argv[1], "rep_noautoinit") == 0) + return (__rep_set_config(dbenv, + DB_REP_CONF_NOAUTOINIT, 1)); + if (strcasecmp(argv[1], "rep_nowait") == 0) + return (__rep_set_config(dbenv, DB_REP_CONF_NOWAIT, 1)); + goto format; + } + + if (strcasecmp(argv[0], "set_cachesize") == 0) { + if (nf != 4) + goto format; + CONFIG_GET_UINT32(argv[1], &uv1); + CONFIG_GET_UINT32(argv[2], &uv2); + CONFIG_GET_INT(argv[3], &lv1); + return (__memp_set_cachesize( + dbenv, (u_int32_t)uv1, (u_int32_t)uv2, (int)lv1)); + } + + if (strcasecmp(argv[0], "set_data_dir") == 0 || + strcasecmp(argv[0], "db_data_dir") == 0) { /* Compatibility. */ + if (nf != 2) + goto format; + return (__env_set_data_dir(dbenv, argv[1])); + } + /* Undocumented. */ + if (strcasecmp(argv[0], "set_intermediate_dir") == 0) { + if (nf != 2) + goto format; + CONFIG_GET_INT(argv[1], &lv1); + return (__env_set_intermediate_dir(dbenv, (int)lv1, 0)); + } + + if (strcasecmp(argv[0], "set_flags") == 0) { + if (nf != 2) + goto format; + if (strcasecmp(argv[1], "db_auto_commit") == 0) + return (__env_set_flags(dbenv, DB_AUTO_COMMIT, 1)); + if (strcasecmp(argv[1], "db_cdb_alldb") == 0) + return (__env_set_flags(dbenv, DB_CDB_ALLDB, 1)); + if (strcasecmp(argv[1], "db_direct_db") == 0) + return (__env_set_flags(dbenv, DB_DIRECT_DB, 1)); + if (strcasecmp(argv[1], "db_direct_log") == 0) + return (__env_set_flags(dbenv, DB_DIRECT_LOG, 1)); + if (strcasecmp(argv[1], "db_dsync_db") == 0) + return (__env_set_flags(dbenv, DB_DSYNC_DB, 1)); + if (strcasecmp(argv[1], "db_dsync_log") == 0) + return (__env_set_flags(dbenv, DB_DSYNC_LOG, 1)); + if (strcasecmp(argv[1], "db_log_autoremove") == 0) + return (__env_set_flags(dbenv, DB_LOG_AUTOREMOVE, 1)); + if (strcasecmp(argv[1], "db_log_inmemory") == 0) + return (__env_set_flags(dbenv, DB_LOG_INMEMORY, 1)); + if (strcasecmp(argv[1], "db_multiversion") == 0) + return (__env_set_flags(dbenv, DB_MULTIVERSION, 1)); + if (strcasecmp(argv[1], "db_nolocking") == 0) + return (__env_set_flags(dbenv, DB_NOLOCKING, 1)); + if (strcasecmp(argv[1], "db_nommap") == 0) + return (__env_set_flags(dbenv, DB_NOMMAP, 1)); + if (strcasecmp(argv[1], "db_nopanic") == 0) + return (__env_set_flags(dbenv, DB_NOPANIC, 1)); + if (strcasecmp(argv[1], "db_overwrite") == 0) + return (__env_set_flags(dbenv, DB_OVERWRITE, 1)); + if (strcasecmp(argv[1], "db_region_init") == 0) + return (__env_set_flags(dbenv, DB_REGION_INIT, 1)); + if (strcasecmp(argv[1], "db_txn_nosync") == 0) + return (__env_set_flags(dbenv, DB_TXN_NOSYNC, 1)); + if (strcasecmp(argv[1], "db_txn_snapshot") == 0) + return (__env_set_flags(dbenv, DB_TXN_SNAPSHOT, 1)); + if (strcasecmp(argv[1], "db_txn_write_nosync") == 0) + return ( + __env_set_flags(dbenv, DB_TXN_WRITE_NOSYNC, 1)); + if (strcasecmp(argv[1], "db_yieldcpu") == 0) + return (__env_set_flags(dbenv, DB_YIELDCPU, 1)); + goto format; + } + + CONFIG_UINT32("set_lg_bsize", __log_set_lg_bsize); + CONFIG_INT("set_lg_filemode", __log_set_lg_filemode); + CONFIG_UINT32("set_lg_max", __log_set_lg_max); + CONFIG_UINT32("set_lg_regionmax", __log_set_lg_regionmax); + + if (strcasecmp(argv[0], "set_lg_dir") == 0 || + strcasecmp(argv[0], "db_log_dir") == 0) { /* Compatibility. */ + if (nf != 2) + goto format; + return (__log_set_lg_dir(dbenv, argv[1])); + } + + if (strcasecmp(argv[0], "set_lk_detect") == 0) { + if (nf != 2) + goto format; + if (strcasecmp(argv[1], "db_lock_default") == 0) + flags = DB_LOCK_DEFAULT; + else if (strcasecmp(argv[1], "db_lock_expire") == 0) + flags = DB_LOCK_EXPIRE; + else if (strcasecmp(argv[1], "db_lock_maxlocks") == 0) + flags = DB_LOCK_MAXLOCKS; + else if (strcasecmp(argv[1], "db_lock_maxwrite") == 0) + flags = DB_LOCK_MAXWRITE; + else if (strcasecmp(argv[1], "db_lock_minlocks") == 0) + flags = DB_LOCK_MINLOCKS; + else if (strcasecmp(argv[1], "db_lock_minwrite") == 0) + flags = DB_LOCK_MINWRITE; + else if (strcasecmp(argv[1], "db_lock_oldest") == 0) + flags = DB_LOCK_OLDEST; + else if (strcasecmp(argv[1], "db_lock_random") == 0) + flags = DB_LOCK_RANDOM; + else if (strcasecmp(argv[1], "db_lock_youngest") == 0) + flags = DB_LOCK_YOUNGEST; + else + goto format; + return (__lock_set_lk_detect(dbenv, flags)); + } + + CONFIG_UINT32("set_lk_max_locks", __lock_set_lk_max_locks); + CONFIG_UINT32("set_lk_max_lockers", __lock_set_lk_max_lockers); + CONFIG_UINT32("set_lk_max_objects", __lock_set_lk_max_objects); + + if (strcasecmp(argv[0], "set_lock_timeout") == 0) { + if (nf != 2) + goto format; + CONFIG_GET_UINT32(argv[1], &uv1); + return (__lock_set_env_timeout( + dbenv, (u_int32_t)uv1, DB_SET_LOCK_TIMEOUT)); + } + + CONFIG_INT("set_mp_max_openfd", __memp_set_mp_max_openfd); + + if (strcasecmp(argv[0], "set_mp_max_write") == 0) { + if (nf != 3) + goto format; + CONFIG_GET_INT(argv[1], &lv1); + CONFIG_GET_INT(argv[2], &lv2); + return (__memp_set_mp_max_write(dbenv, (int)lv1, (int)lv2)); + } + + CONFIG_UINT32("set_mp_mmapsize", __memp_set_mp_mmapsize); + + if (strcasecmp(argv[0], "set_region_init") == 0) { + if (nf != 2) + goto format; + CONFIG_GET_INT(argv[1], &lv1); + if (lv1 != 0 && lv1 != 1) + goto format; + return (__env_set_flags( + dbenv, DB_REGION_INIT, lv1 == 0 ? 0 : 1)); + } + + if (strcasecmp(argv[0], "set_shm_key") == 0) { + if (nf != 2) + goto format; + CONFIG_GET_LONG(argv[1], &lv1); + return (__env_set_shm_key(dbenv, lv1)); + } + + /* + * The set_tas_spins method has been replaced by mutex_set_tas_spins. + * The set_tas_spins argv[0] remains for DB_CONFIG compatibility. + */ + CONFIG_UINT32("set_tas_spins", __mutex_set_tas_spins); + + if (strcasecmp(argv[0], "set_tmp_dir") == 0 || + strcasecmp(argv[0], "db_tmp_dir") == 0) { /* Compatibility.*/ + if (nf != 2) + goto format; + return (__env_set_tmp_dir(dbenv, argv[1])); + } + + CONFIG_UINT32("set_tx_max", __txn_set_tx_max); + + if (strcasecmp(argv[0], "set_txn_timeout") == 0) { + if (nf != 2) + goto format; + CONFIG_GET_UINT32(argv[1], &uv1); + return (__lock_set_env_timeout( + dbenv, (u_int32_t)uv1, DB_SET_TXN_TIMEOUT)); + } + + if (strcasecmp(argv[0], "set_verbose") == 0) { + if (nf != 2) + goto format; + if (strcasecmp(argv[1], "db_verb_deadlock") == 0) + flags = DB_VERB_DEADLOCK; + else if (strcasecmp(argv[1], "db_verb_recovery") == 0) + flags = DB_VERB_RECOVERY; + else if (strcasecmp(argv[1], "db_verb_register") == 0) + flags = DB_VERB_REGISTER; + else if (strcasecmp(argv[1], "db_verb_replication") == 0) + flags = DB_VERB_REPLICATION; + else if (strcasecmp(argv[1], "db_verb_waitsfor") == 0) + flags = DB_VERB_WAITSFOR; + else + goto format; + return (__env_set_verbose(dbenv, flags, 1)); + } + + __db_errx(dbenv, "unrecognized name-value pair: %s", s); + return (EINVAL); +} + +/* + * __config_split -- + * Split lines into white-space separated fields, returning the count of + * fields. + */ +static int +__config_split(input, argv) + char *input, *argv[CONFIG_SLOTS]; +{ + int count; + char **ap; + + for (count = 0, ap = argv; (*ap = strsep(&input, " \t\n")) != NULL;) + if (**ap != '\0') { + ++count; + if (++ap == &argv[CONFIG_SLOTS - 1]) { + *ap = NULL; + break; + } + } + return (count); +} |