00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014
00015 #ifdef HAVE_RPC
00016 #include <rpc/rpc.h>
00017 #endif
00018
00019 #include <string.h>
00020 #endif
00021
00022 #ifdef HAVE_RPC
00023 #include "db_server.h"
00024 #endif
00025
00026
00027
00028
00029
00030
00031 #define DB_INITIALIZE_DB_GLOBALS 1
00032
00033 #include "db_int.h"
00034 #include "dbinc/crypto.h"
00035 #include "dbinc/hmac.h"
00036 #include "dbinc/db_shash.h"
00037 #include "dbinc/db_page.h"
00038 #include "dbinc/db_am.h"
00039 #include "dbinc/lock.h"
00040 #include "dbinc/log.h"
00041 #include "dbinc/mp.h"
00042 #include "dbinc/txn.h"
00043
00044 #ifdef HAVE_RPC
00045 #include "dbinc_auto/rpc_client_ext.h"
00046 #endif
00047
00048 static void __env_err __P((const DB_ENV *, int, const char *, ...));
00049 static void __env_errx __P((const DB_ENV *, const char *, ...));
00050 static int __env_get_data_dirs __P((DB_ENV *, const char ***));
00051 static int __env_get_flags __P((DB_ENV *, u_int32_t *));
00052 static int __env_get_home __P((DB_ENV *, const char **));
00053 static int __env_get_shm_key __P((DB_ENV *, long *));
00054 static int __env_get_tmp_dir __P((DB_ENV *, const char **));
00055 static int __env_get_verbose __P((DB_ENV *, u_int32_t, int *));
00056 static int __env_init __P((DB_ENV *));
00057 static void __env_map_flags __P((DB_ENV *, u_int32_t *, u_int32_t *));
00058 static int __env_set_app_dispatch
00059 __P((DB_ENV *, int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops)));
00060 static int __env_set_feedback __P((DB_ENV *, void (*)(DB_ENV *, int, int)));
00061 static int __env_set_isalive __P((DB_ENV *, int (*)(DB_ENV *,
00062 pid_t, db_threadid_t)));
00063 static int __env_set_thread_id __P((DB_ENV *, void (*)(DB_ENV *,
00064 pid_t *, db_threadid_t *)));
00065 static int __env_set_thread_id_string __P((DB_ENV *,
00066 char * (*)(DB_ENV *, pid_t, db_threadid_t, char *)));
00067 static int __env_set_thread_count __P((DB_ENV *, u_int32_t));
00068 static int __env_set_rpc_server
00069 __P((DB_ENV *, void *, const char *, long, long, u_int32_t));
00070
00071
00072
00073
00074
00075
00076
00077 int
00078 db_env_create(dbenvpp, flags)
00079 DB_ENV **dbenvpp;
00080 u_int32_t flags;
00081 {
00082 DB_ENV *dbenv;
00083 int ret;
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 if (flags != 0 && !LF_ISSET(DB_RPCCLIENT))
00096 return (EINVAL);
00097 if ((ret = __os_calloc(NULL, 1, sizeof(*dbenv), &dbenv)) != 0)
00098 return (ret);
00099
00100 #ifdef HAVE_RPC
00101 if (LF_ISSET(DB_RPCCLIENT))
00102 F_SET(dbenv, DB_ENV_RPCCLIENT);
00103 #endif
00104 if ((ret = __env_init(dbenv)) != 0) {
00105 __os_free(NULL, dbenv);
00106 return (ret);
00107 }
00108
00109 *dbenvpp = dbenv;
00110 return (0);
00111 }
00112
00113
00114
00115
00116
00117 static int
00118 __env_init(dbenv)
00119 DB_ENV *dbenv;
00120 {
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 dbenv->close = __env_close_pp;
00131 dbenv->dbremove = __env_dbremove_pp;
00132 dbenv->dbrename = __env_dbrename_pp;
00133 dbenv->err = __env_err;
00134 dbenv->errx = __env_errx;
00135 dbenv->failchk = __env_failchk_pp;
00136 dbenv->fileid_reset = __env_fileid_reset_pp;
00137 dbenv->get_cachesize = __memp_get_cachesize;
00138 dbenv->get_data_dirs = __env_get_data_dirs;
00139 dbenv->get_encrypt_flags = __env_get_encrypt_flags;
00140 dbenv->get_errfile = __env_get_errfile;
00141 dbenv->get_errpfx = __env_get_errpfx;
00142 dbenv->get_flags = __env_get_flags;
00143 dbenv->get_home = __env_get_home;
00144 dbenv->get_lg_bsize = __log_get_lg_bsize;
00145 dbenv->get_lg_dir = __log_get_lg_dir;
00146 dbenv->get_lg_filemode = __log_get_lg_filemode;
00147 dbenv->get_lg_max = __log_get_lg_max;
00148 dbenv->get_lg_regionmax = __log_get_lg_regionmax;
00149 dbenv->get_lk_conflicts = __lock_get_lk_conflicts;
00150 dbenv->get_lk_detect = __lock_get_lk_detect;
00151 dbenv->get_lk_max_lockers = __lock_get_lk_max_lockers;
00152 dbenv->get_lk_max_locks = __lock_get_lk_max_locks;
00153 dbenv->get_lk_max_objects = __lock_get_lk_max_objects;
00154 dbenv->get_mp_max_openfd = __memp_get_mp_max_openfd;
00155 dbenv->get_mp_max_write = __memp_get_mp_max_write;
00156 dbenv->get_mp_mmapsize = __memp_get_mp_mmapsize;
00157 dbenv->get_msgfile = __env_get_msgfile;
00158 dbenv->get_open_flags = __env_get_open_flags;
00159 dbenv->get_rep_limit = __rep_get_limit;
00160 dbenv->get_shm_key = __env_get_shm_key;
00161 dbenv->get_timeout = __lock_get_env_timeout;
00162 dbenv->get_tmp_dir = __env_get_tmp_dir;
00163 dbenv->get_tx_max = __txn_get_tx_max;
00164 dbenv->get_tx_timestamp = __txn_get_tx_timestamp;
00165 dbenv->get_verbose = __env_get_verbose;
00166 dbenv->is_bigendian = __db_isbigendian;
00167 dbenv->lock_detect = __lock_detect_pp;
00168 dbenv->lock_get = __lock_get_pp;
00169 dbenv->lock_id = __lock_id_pp;
00170 dbenv->lock_id_free = __lock_id_free_pp;
00171 dbenv->lock_put = __lock_put_pp;
00172 dbenv->lock_stat = __lock_stat_pp;
00173 dbenv->lock_stat_print = __lock_stat_print_pp;
00174 dbenv->lock_vec = __lock_vec_pp;
00175 dbenv->log_archive = __log_archive_pp;
00176 dbenv->log_cursor = __log_cursor_pp;
00177 dbenv->log_file = __log_file_pp;
00178 dbenv->log_flush = __log_flush_pp;
00179 dbenv->log_printf = __log_printf_capi;
00180 dbenv->log_put = __log_put_pp;
00181 dbenv->log_stat = __log_stat_pp;
00182 dbenv->log_stat_print = __log_stat_print_pp;
00183 dbenv->lsn_reset = __env_lsn_reset_pp;
00184 dbenv->memp_fcreate = __memp_fcreate_pp;
00185 dbenv->memp_register = __memp_register_pp;
00186 dbenv->memp_stat = __memp_stat_pp;
00187 dbenv->memp_stat_print = __memp_stat_print_pp;
00188 dbenv->memp_sync = __memp_sync_pp;
00189 dbenv->memp_trickle = __memp_trickle_pp;
00190 dbenv->mutex_alloc = __mutex_alloc_pp;
00191 dbenv->mutex_free = __mutex_free_pp;
00192 dbenv->mutex_get_align = __mutex_get_align;
00193 dbenv->mutex_get_increment = __mutex_get_increment;
00194 dbenv->mutex_get_max = __mutex_get_max;
00195 dbenv->mutex_get_tas_spins = __mutex_get_tas_spins;
00196 dbenv->mutex_lock = __mutex_lock_pp;
00197 dbenv->mutex_set_align = __mutex_set_align;
00198 dbenv->mutex_set_increment = __mutex_set_increment;
00199 dbenv->mutex_set_max = __mutex_set_max;
00200 dbenv->mutex_set_tas_spins = __mutex_set_tas_spins;
00201 dbenv->mutex_stat = __mutex_stat;
00202 dbenv->mutex_stat_print = __mutex_stat_print;
00203 dbenv->mutex_unlock = __mutex_unlock_pp;
00204 dbenv->open = __env_open_pp;
00205 dbenv->remove = __env_remove;
00206 dbenv->rep_elect = __rep_elect;
00207 dbenv->rep_flush = __rep_flush;
00208 dbenv->rep_get_config = __rep_get_config;
00209 dbenv->rep_process_message = __rep_process_message;
00210 dbenv->rep_set_config = __rep_set_config;
00211 dbenv->rep_start = __rep_start;
00212 dbenv->rep_stat = __rep_stat_pp;
00213 dbenv->rep_stat_print = __rep_stat_print_pp;
00214 dbenv->rep_sync = __rep_sync;
00215 dbenv->set_alloc = __env_set_alloc;
00216 dbenv->set_app_dispatch = __env_set_app_dispatch;
00217 dbenv->set_cachesize = __memp_set_cachesize;
00218 dbenv->set_data_dir = __env_set_data_dir;
00219 dbenv->set_encrypt = __env_set_encrypt;
00220 dbenv->set_errcall = __env_set_errcall;
00221 dbenv->set_errfile = __env_set_errfile;
00222 dbenv->set_errpfx = __env_set_errpfx;
00223 dbenv->set_feedback = __env_set_feedback;
00224 dbenv->set_flags = __env_set_flags;
00225 dbenv->set_intermediate_dir = __env_set_intermediate_dir;
00226 dbenv->set_isalive = __env_set_isalive;
00227 dbenv->set_lg_bsize = __log_set_lg_bsize;
00228 dbenv->set_lg_dir = __log_set_lg_dir;
00229 dbenv->set_lg_filemode = __log_set_lg_filemode;
00230 dbenv->set_lg_max = __log_set_lg_max;
00231 dbenv->set_lg_regionmax = __log_set_lg_regionmax;
00232 dbenv->set_lk_conflicts = __lock_set_lk_conflicts;
00233 dbenv->set_lk_detect = __lock_set_lk_detect;
00234 dbenv->set_lk_max = __lock_set_lk_max;
00235 dbenv->set_lk_max_lockers = __lock_set_lk_max_lockers;
00236 dbenv->set_lk_max_locks = __lock_set_lk_max_locks;
00237 dbenv->set_lk_max_objects = __lock_set_lk_max_objects;
00238 dbenv->set_mp_max_openfd = __memp_set_mp_max_openfd;
00239 dbenv->set_mp_max_write = __memp_set_mp_max_write;
00240 dbenv->set_mp_mmapsize = __memp_set_mp_mmapsize;
00241 dbenv->set_msgcall = __env_set_msgcall;
00242 dbenv->set_msgfile = __env_set_msgfile;
00243 dbenv->set_paniccall = __env_set_paniccall;
00244 dbenv->set_rep_limit = __rep_set_limit;
00245 dbenv->set_rep_request = __rep_set_request;
00246 dbenv->set_rep_transport = __rep_set_rep_transport;
00247 dbenv->set_rpc_server = __env_set_rpc_server;
00248 dbenv->set_shm_key = __env_set_shm_key;
00249 dbenv->set_thread_count = __env_set_thread_count;
00250 dbenv->set_thread_id = __env_set_thread_id;
00251 dbenv->set_thread_id_string = __env_set_thread_id_string;
00252 dbenv->set_timeout = __lock_set_env_timeout;
00253 dbenv->set_tmp_dir = __env_set_tmp_dir;
00254 dbenv->set_tx_max = __txn_set_tx_max;
00255 dbenv->set_tx_timestamp = __txn_set_tx_timestamp;
00256 dbenv->set_verbose = __env_set_verbose;
00257 dbenv->stat_print = __env_stat_print_pp;
00258 dbenv->txn_begin = __txn_begin_pp;
00259 dbenv->txn_checkpoint = __txn_checkpoint_pp;
00260 dbenv->txn_recover = __txn_recover_pp;
00261 dbenv->txn_stat = __txn_stat_pp;
00262 dbenv->txn_stat_print = __txn_stat_print_pp;
00263
00264
00265
00266 dbenv->prdbt = __db_prdbt;
00267
00268
00269 __os_id(NULL, &dbenv->pid_cache, NULL);
00270 dbenv->thread_id = __os_id;
00271 dbenv->thread_id_string = __env_thread_id_string;
00272 dbenv->db_ref = 0;
00273 dbenv->shm_key = INVALID_REGION_SEGID;
00274
00275 __lock_dbenv_create(dbenv);
00276 __log_dbenv_create(dbenv);
00277 __memp_dbenv_create(dbenv);
00278 __txn_dbenv_create(dbenv);
00279
00280 #ifdef HAVE_RPC
00281
00282
00283
00284
00285 if (F_ISSET(dbenv, DB_ENV_RPCCLIENT)) {
00286 __dbcl_dbenv_init(dbenv);
00287
00288
00289
00290
00291
00292 dbenv->open = __dbcl_env_open_wrap;
00293 dbenv->close = __dbcl_env_close_wrap;
00294 }
00295 #endif
00296
00297 return (0);
00298 }
00299
00300
00301
00302
00303
00304 static void
00305 #ifdef STDC_HEADERS
00306 __env_err(const DB_ENV *dbenv, int error, const char *fmt, ...)
00307 #else
00308 __env_err(dbenv, error, fmt, va_alist)
00309 const DB_ENV *dbenv;
00310 int error;
00311 const char *fmt;
00312 va_dcl
00313 #endif
00314 {
00315 DB_REAL_ERR(dbenv, error, 1, 1, fmt);
00316 }
00317
00318
00319
00320
00321
00322 static void
00323 #ifdef STDC_HEADERS
00324 __env_errx(const DB_ENV *dbenv, const char *fmt, ...)
00325 #else
00326 __env_errx(dbenv, fmt, va_alist)
00327 const DB_ENV *dbenv;
00328 const char *fmt;
00329 va_dcl
00330 #endif
00331 {
00332 DB_REAL_ERR(dbenv, 0, 0, 1, fmt);
00333 }
00334
00335 static int
00336 __env_get_home(dbenv, homep)
00337 DB_ENV *dbenv;
00338 const char **homep;
00339 {
00340 ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->get_home");
00341 *homep = dbenv->db_home;
00342 return (0);
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352 int
00353 __env_set_alloc(dbenv, mal_func, real_func, free_func)
00354 DB_ENV *dbenv;
00355 void *(*mal_func) __P((size_t));
00356 void *(*real_func) __P((void *, size_t));
00357 void (*free_func) __P((void *));
00358 {
00359 ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_alloc");
00360
00361 dbenv->db_malloc = mal_func;
00362 dbenv->db_realloc = real_func;
00363 dbenv->db_free = free_func;
00364 return (0);
00365 }
00366
00367
00368
00369
00370
00371 static int
00372 __env_set_app_dispatch(dbenv, app_dispatch)
00373 DB_ENV *dbenv;
00374 int (*app_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops));
00375 {
00376 ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_app_dispatch");
00377
00378 dbenv->app_dispatch = app_dispatch;
00379 return (0);
00380 }
00381
00382
00383
00384
00385
00386
00387
00388 int
00389 __env_get_encrypt_flags(dbenv, flagsp)
00390 DB_ENV *dbenv;
00391 u_int32_t *flagsp;
00392 {
00393 #ifdef HAVE_CRYPTO
00394 DB_CIPHER *db_cipher;
00395
00396 db_cipher = dbenv->crypto_handle;
00397 if (db_cipher != NULL && db_cipher->alg == CIPHER_AES)
00398 *flagsp = DB_ENCRYPT_AES;
00399 else
00400 *flagsp = 0;
00401 return (0);
00402 #else
00403 COMPQUIET(flagsp, 0);
00404 __db_err(dbenv,
00405 "library build did not include support for cryptography");
00406 return (DB_OPNOTSUP);
00407 #endif
00408 }
00409
00410
00411
00412
00413
00414
00415
00416 int
00417 __env_set_encrypt(dbenv, passwd, flags)
00418 DB_ENV *dbenv;
00419 const char *passwd;
00420 u_int32_t flags;
00421 {
00422 #ifdef HAVE_CRYPTO
00423 DB_CIPHER *db_cipher;
00424 int ret;
00425
00426 ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_encrypt");
00427 #define OK_CRYPTO_FLAGS (DB_ENCRYPT_AES)
00428
00429 if (flags != 0 && LF_ISSET(~OK_CRYPTO_FLAGS))
00430 return (__db_ferr(dbenv, "DB_ENV->set_encrypt", 0));
00431
00432 if (passwd == NULL || strlen(passwd) == 0) {
00433 __db_err(dbenv, "Empty password specified to set_encrypt");
00434 return (EINVAL);
00435 }
00436 if (!CRYPTO_ON(dbenv)) {
00437 if ((ret = __os_calloc(dbenv, 1, sizeof(DB_CIPHER), &db_cipher))
00438 != 0)
00439 goto err;
00440 dbenv->crypto_handle = db_cipher;
00441 } else
00442 db_cipher = (DB_CIPHER *)dbenv->crypto_handle;
00443
00444 if (dbenv->passwd != NULL)
00445 __os_free(dbenv, dbenv->passwd);
00446 if ((ret = __os_strdup(dbenv, passwd, &dbenv->passwd)) != 0) {
00447 __os_free(dbenv, db_cipher);
00448 goto err;
00449 }
00450
00451
00452
00453 dbenv->passwd_len = strlen(dbenv->passwd) + 1;
00454
00455
00456
00457
00458
00459 __db_derive_mac((u_int8_t *)dbenv->passwd,
00460 dbenv->passwd_len, db_cipher->mac_key);
00461 switch (flags) {
00462 case 0:
00463 F_SET(db_cipher, CIPHER_ANY);
00464 break;
00465 case DB_ENCRYPT_AES:
00466 if ((ret = __crypto_algsetup(dbenv, db_cipher, CIPHER_AES, 0))
00467 != 0)
00468 goto err1;
00469 break;
00470 default:
00471 break;
00472 }
00473 return (0);
00474
00475 err1:
00476 __os_free(dbenv, dbenv->passwd);
00477 __os_free(dbenv, db_cipher);
00478 dbenv->crypto_handle = NULL;
00479 err:
00480 return (ret);
00481 #else
00482 COMPQUIET(passwd, NULL);
00483 COMPQUIET(flags, 0);
00484
00485 __db_err(dbenv,
00486 "library build did not include support for cryptography");
00487 return (DB_OPNOTSUP);
00488 #endif
00489 }
00490
00491 static void
00492 __env_map_flags(dbenv, inflagsp, outflagsp)
00493 DB_ENV *dbenv;
00494 u_int32_t *inflagsp, *outflagsp;
00495 {
00496 COMPQUIET(dbenv, NULL);
00497
00498 if (FLD_ISSET(*inflagsp, DB_AUTO_COMMIT)) {
00499 FLD_SET(*outflagsp, DB_ENV_AUTO_COMMIT);
00500 FLD_CLR(*inflagsp, DB_AUTO_COMMIT);
00501 }
00502 if (FLD_ISSET(*inflagsp, DB_CDB_ALLDB)) {
00503 FLD_SET(*outflagsp, DB_ENV_CDB_ALLDB);
00504 FLD_CLR(*inflagsp, DB_CDB_ALLDB);
00505 }
00506 if (FLD_ISSET(*inflagsp, DB_DIRECT_DB)) {
00507 FLD_SET(*outflagsp, DB_ENV_DIRECT_DB);
00508 FLD_CLR(*inflagsp, DB_DIRECT_DB);
00509 }
00510 if (FLD_ISSET(*inflagsp, DB_DIRECT_LOG)) {
00511 FLD_SET(*outflagsp, DB_ENV_DIRECT_LOG);
00512 FLD_CLR(*inflagsp, DB_DIRECT_LOG);
00513 }
00514 if (FLD_ISSET(*inflagsp, DB_DSYNC_DB)) {
00515 FLD_SET(*outflagsp, DB_ENV_DSYNC_DB);
00516 FLD_CLR(*inflagsp, DB_DSYNC_DB);
00517 }
00518 if (FLD_ISSET(*inflagsp, DB_DSYNC_LOG)) {
00519 FLD_SET(*outflagsp, DB_ENV_DSYNC_LOG);
00520 FLD_CLR(*inflagsp, DB_DSYNC_LOG);
00521 }
00522 if (FLD_ISSET(*inflagsp, DB_LOG_AUTOREMOVE)) {
00523 FLD_SET(*outflagsp, DB_ENV_LOG_AUTOREMOVE);
00524 FLD_CLR(*inflagsp, DB_LOG_AUTOREMOVE);
00525 }
00526 if (FLD_ISSET(*inflagsp, DB_LOG_INMEMORY)) {
00527 FLD_SET(*outflagsp, DB_ENV_LOG_INMEMORY);
00528 FLD_CLR(*inflagsp, DB_LOG_INMEMORY);
00529 }
00530 if (FLD_ISSET(*inflagsp, DB_NOLOCKING)) {
00531 FLD_SET(*outflagsp, DB_ENV_NOLOCKING);
00532 FLD_CLR(*inflagsp, DB_NOLOCKING);
00533 }
00534 if (FLD_ISSET(*inflagsp, DB_NOMMAP)) {
00535 FLD_SET(*outflagsp, DB_ENV_NOMMAP);
00536 FLD_CLR(*inflagsp, DB_NOMMAP);
00537 }
00538 if (FLD_ISSET(*inflagsp, DB_NOPANIC)) {
00539 FLD_SET(*outflagsp, DB_ENV_NOPANIC);
00540 FLD_CLR(*inflagsp, DB_NOPANIC);
00541 }
00542 if (FLD_ISSET(*inflagsp, DB_OVERWRITE)) {
00543 FLD_SET(*outflagsp, DB_ENV_OVERWRITE);
00544 FLD_CLR(*inflagsp, DB_OVERWRITE);
00545 }
00546 if (FLD_ISSET(*inflagsp, DB_REGION_INIT)) {
00547 FLD_SET(*outflagsp, DB_ENV_REGION_INIT);
00548 FLD_CLR(*inflagsp, DB_REGION_INIT);
00549 }
00550 if (FLD_ISSET(*inflagsp, DB_TIME_NOTGRANTED)) {
00551 FLD_SET(*outflagsp, DB_ENV_TIME_NOTGRANTED);
00552 FLD_CLR(*inflagsp, DB_TIME_NOTGRANTED);
00553 }
00554 if (FLD_ISSET(*inflagsp, DB_TXN_NOSYNC)) {
00555 FLD_SET(*outflagsp, DB_ENV_TXN_NOSYNC);
00556 FLD_CLR(*inflagsp, DB_TXN_NOSYNC);
00557 }
00558 if (FLD_ISSET(*inflagsp, DB_TXN_WRITE_NOSYNC)) {
00559 FLD_SET(*outflagsp, DB_ENV_TXN_WRITE_NOSYNC);
00560 FLD_CLR(*inflagsp, DB_TXN_WRITE_NOSYNC);
00561 }
00562 if (FLD_ISSET(*inflagsp, DB_YIELDCPU)) {
00563 FLD_SET(*outflagsp, DB_ENV_YIELDCPU);
00564 FLD_CLR(*inflagsp, DB_YIELDCPU);
00565 }
00566 }
00567
00568 static int
00569 __env_get_flags(dbenv, flagsp)
00570 DB_ENV *dbenv;
00571 u_int32_t *flagsp;
00572 {
00573 static const u_int32_t env_flags[] = {
00574 DB_AUTO_COMMIT,
00575 DB_CDB_ALLDB,
00576 DB_DIRECT_DB,
00577 DB_DIRECT_LOG,
00578 DB_DSYNC_DB,
00579 DB_DSYNC_LOG,
00580 DB_LOG_AUTOREMOVE,
00581 DB_LOG_INMEMORY,
00582 DB_NOLOCKING,
00583 DB_NOMMAP,
00584 DB_NOPANIC,
00585 DB_OVERWRITE,
00586 DB_REGION_INIT,
00587 DB_TIME_NOTGRANTED,
00588 DB_TXN_NOSYNC,
00589 DB_TXN_WRITE_NOSYNC,
00590 DB_YIELDCPU,
00591 0
00592 };
00593 u_int32_t f, flags, mapped_flag;
00594 int i;
00595
00596 flags = 0;
00597 for (i = 0; (f = env_flags[i]) != 0; i++) {
00598 mapped_flag = 0;
00599 __env_map_flags(dbenv, &f, &mapped_flag);
00600 DB_ASSERT(f == 0);
00601 if (F_ISSET(dbenv, mapped_flag) == mapped_flag)
00602 LF_SET(env_flags[i]);
00603 }
00604
00605
00606 if (dbenv->reginfo != NULL &&
00607 ((REGENV *)((REGINFO *)dbenv->reginfo)->primary)->panic != 0) {
00608 LF_SET(DB_PANIC_ENVIRONMENT);
00609 }
00610 __log_get_flags(dbenv, &flags);
00611
00612 *flagsp = flags;
00613 return (0);
00614 }
00615
00616
00617
00618
00619
00620
00621
00622 int
00623 __env_set_flags(dbenv, flags, on)
00624 DB_ENV *dbenv;
00625 u_int32_t flags;
00626 int on;
00627 {
00628 u_int32_t mapped_flags;
00629 int ret;
00630
00631 #define OK_FLAGS \
00632 (DB_AUTO_COMMIT | DB_CDB_ALLDB | DB_DIRECT_DB | DB_DIRECT_LOG | \
00633 DB_DSYNC_DB | DB_DSYNC_LOG | DB_LOG_AUTOREMOVE | \
00634 DB_LOG_INMEMORY | DB_NOLOCKING | DB_NOMMAP | DB_NOPANIC | \
00635 DB_OVERWRITE | DB_PANIC_ENVIRONMENT | DB_REGION_INIT | \
00636 DB_TIME_NOTGRANTED | DB_TXN_NOSYNC | DB_TXN_WRITE_NOSYNC | \
00637 DB_YIELDCPU)
00638
00639 if (LF_ISSET(~OK_FLAGS))
00640 return (__db_ferr(dbenv, "DB_ENV->set_flags", 0));
00641 if (on) {
00642 if ((ret = __db_fcchk(dbenv, "DB_ENV->set_flags",
00643 flags, DB_LOG_INMEMORY, DB_TXN_NOSYNC)) != 0)
00644 return (ret);
00645 if ((ret = __db_fcchk(dbenv, "DB_ENV->set_flags",
00646 flags, DB_LOG_INMEMORY, DB_TXN_WRITE_NOSYNC)) != 0)
00647 return (ret);
00648 if ((ret = __db_fcchk(dbenv, "DB_ENV->set_flags",
00649 flags, DB_TXN_NOSYNC, DB_TXN_WRITE_NOSYNC)) != 0)
00650 return (ret);
00651 if (LF_ISSET(DB_DIRECT_DB |
00652 DB_DIRECT_LOG) && __os_have_direct() == 0) {
00653 __db_err(dbenv,
00654 "DB_ENV->set_flags: direct I/O either not configured or not supported");
00655 return (EINVAL);
00656 }
00657 }
00658
00659 if (LF_ISSET(DB_CDB_ALLDB))
00660 ENV_ILLEGAL_AFTER_OPEN(dbenv,
00661 "DB_ENV->set_flags: DB_CDB_ALLDB");
00662 if (LF_ISSET(DB_PANIC_ENVIRONMENT)) {
00663 ENV_ILLEGAL_BEFORE_OPEN(dbenv,
00664 "DB_ENV->set_flags: DB_PANIC_ENVIRONMENT");
00665 if (on) {
00666 __db_err(dbenv, "Environment panic set");
00667 (void)__db_panic(dbenv, EACCES);
00668 } else
00669 __db_panic_set(dbenv, 0);
00670 }
00671 if (LF_ISSET(DB_REGION_INIT))
00672 ENV_ILLEGAL_AFTER_OPEN(dbenv,
00673 "DB_ENV->set_flags: DB_REGION_INIT");
00674 if (LF_ISSET(DB_LOG_INMEMORY))
00675 ENV_ILLEGAL_AFTER_OPEN(dbenv,
00676 "DB_ENV->set_flags: DB_LOG_INMEMORY");
00677
00678
00679
00680
00681
00682
00683 if (LF_ISSET(
00684 DB_LOG_INMEMORY | DB_TXN_NOSYNC | DB_TXN_WRITE_NOSYNC))
00685 F_CLR(dbenv,
00686 DB_ENV_LOG_INMEMORY |
00687 DB_ENV_TXN_NOSYNC | DB_ENV_TXN_WRITE_NOSYNC);
00688
00689
00690 __log_set_flags(dbenv, flags, on);
00691
00692 mapped_flags = 0;
00693 __env_map_flags(dbenv, &flags, &mapped_flags);
00694 if (on)
00695 F_SET(dbenv, mapped_flags);
00696 else
00697 F_CLR(dbenv, mapped_flags);
00698
00699 return (0);
00700 }
00701
00702 static int
00703 __env_get_data_dirs(dbenv, dirpp)
00704 DB_ENV *dbenv;
00705 const char ***dirpp;
00706 {
00707 *dirpp = (const char **)dbenv->db_data_dir;
00708 return (0);
00709 }
00710
00711
00712
00713
00714
00715
00716
00717 int
00718 __env_set_data_dir(dbenv, dir)
00719 DB_ENV *dbenv;
00720 const char *dir;
00721 {
00722 int ret;
00723
00724
00725
00726
00727
00728
00729 #define DATA_INIT_CNT 20
00730 if (dbenv->db_data_dir == NULL) {
00731 if ((ret = __os_calloc(dbenv, DATA_INIT_CNT,
00732 sizeof(char **), &dbenv->db_data_dir)) != 0)
00733 return (ret);
00734 dbenv->data_cnt = DATA_INIT_CNT;
00735 } else if (dbenv->data_next == dbenv->data_cnt - 2) {
00736 dbenv->data_cnt *= 2;
00737 if ((ret = __os_realloc(dbenv,
00738 (u_int)dbenv->data_cnt * sizeof(char **),
00739 &dbenv->db_data_dir)) != 0)
00740 return (ret);
00741 }
00742
00743 ret = __os_strdup(dbenv,
00744 dir, &dbenv->db_data_dir[dbenv->data_next++]);
00745 dbenv->db_data_dir[dbenv->data_next] = NULL;
00746 return (ret);
00747 }
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 int
00760 __env_set_intermediate_dir(dbenv, mode, flags)
00761 DB_ENV *dbenv;
00762 int mode;
00763 u_int32_t flags;
00764 {
00765 if (flags != 0)
00766 return (__db_ferr(dbenv, "DB_ENV->set_intermediate_dir", 0));
00767 if (mode == 0) {
00768 __db_err(dbenv,
00769 "DB_ENV->set_intermediate_dir: mode may not be set to 0");
00770 return (EINVAL);
00771 }
00772
00773 dbenv->dir_mode = mode;
00774 return (0);
00775 }
00776
00777
00778
00779
00780
00781
00782
00783
00784 void
00785 __env_set_errcall(dbenv, errcall)
00786 DB_ENV *dbenv;
00787 void (*errcall) __P((const DB_ENV *, const char *, const char *));
00788 {
00789 dbenv->db_errcall = errcall;
00790 }
00791
00792
00793
00794
00795
00796
00797
00798 void
00799 __env_get_errfile(dbenv, errfilep)
00800 DB_ENV *dbenv;
00801 FILE **errfilep;
00802 {
00803 *errfilep = dbenv->db_errfile;
00804 }
00805
00806
00807
00808
00809
00810
00811
00812 void
00813 __env_set_errfile(dbenv, errfile)
00814 DB_ENV *dbenv;
00815 FILE *errfile;
00816 {
00817 dbenv->db_errfile = errfile;
00818 }
00819
00820
00821
00822
00823
00824
00825
00826 void
00827 __env_get_errpfx(dbenv, errpfxp)
00828 DB_ENV *dbenv;
00829 const char **errpfxp;
00830 {
00831 *errpfxp = dbenv->db_errpfx;
00832 }
00833
00834
00835
00836
00837
00838
00839
00840 void
00841 __env_set_errpfx(dbenv, errpfx)
00842 DB_ENV *dbenv;
00843 const char *errpfx;
00844 {
00845 dbenv->db_errpfx = errpfx;
00846 }
00847
00848 static int
00849 __env_set_feedback(dbenv, feedback)
00850 DB_ENV *dbenv;
00851 void (*feedback) __P((DB_ENV *, int, int));
00852 {
00853 dbenv->db_feedback = feedback;
00854 return (0);
00855 }
00856
00857
00858
00859
00860
00861 static int
00862 __env_set_thread_id(dbenv, id)
00863 DB_ENV *dbenv;
00864 void (*id) __P((DB_ENV *, pid_t *, db_threadid_t *));
00865 {
00866 dbenv->thread_id = id;
00867 return (0);
00868 }
00869
00870
00871
00872
00873
00874 static int
00875 __env_set_thread_id_string(dbenv, thread_id_string)
00876 DB_ENV *dbenv;
00877 char *(*thread_id_string) __P((DB_ENV *, pid_t, db_threadid_t, char *));
00878 {
00879 dbenv->thread_id_string = thread_id_string;
00880 return (0);
00881 }
00882
00883
00884
00885
00886
00887 static int
00888 __env_set_isalive(dbenv, is_alive)
00889 DB_ENV *dbenv;
00890 int (*is_alive) __P((DB_ENV *, pid_t, db_threadid_t));
00891 {
00892 if (F_ISSET((dbenv), DB_ENV_OPEN_CALLED) &&
00893 dbenv->thr_nbucket == 0) {
00894 __db_err(dbenv,
00895 "is_alive method specified but no thread region allocated");
00896 return (EINVAL);
00897 }
00898 dbenv->is_alive = is_alive;
00899 return (0);
00900 }
00901
00902
00903
00904
00905
00906 static int
00907 __env_set_thread_count(dbenv, count)
00908 DB_ENV *dbenv;
00909 u_int32_t count;
00910 {
00911 ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_thread_count");
00912 dbenv->thr_max = count;
00913
00914
00915
00916
00917
00918
00919 dbenv->thr_nbucket = count / 8;
00920 return (0);
00921 }
00922
00923
00924
00925
00926
00927
00928
00929
00930 void
00931 __env_set_msgcall(dbenv, msgcall)
00932 DB_ENV *dbenv;
00933 void (*msgcall) __P((const DB_ENV *, const char *));
00934 {
00935 dbenv->db_msgcall = msgcall;
00936 }
00937
00938
00939
00940
00941
00942
00943
00944 void
00945 __env_get_msgfile(dbenv, msgfilep)
00946 DB_ENV *dbenv;
00947 FILE **msgfilep;
00948 {
00949 *msgfilep = dbenv->db_msgfile;
00950 }
00951
00952
00953
00954
00955
00956
00957
00958 void
00959 __env_set_msgfile(dbenv, msgfile)
00960 DB_ENV *dbenv;
00961 FILE *msgfile;
00962 {
00963 dbenv->db_msgfile = msgfile;
00964 }
00965
00966
00967
00968
00969
00970
00971
00972 int
00973 __env_set_paniccall(dbenv, paniccall)
00974 DB_ENV *dbenv;
00975 void (*paniccall) __P((DB_ENV *, int));
00976 {
00977 dbenv->db_paniccall = paniccall;
00978 return (0);
00979 }
00980
00981 static int
00982 __env_get_shm_key(dbenv, shm_keyp)
00983 DB_ENV *dbenv;
00984 long *shm_keyp;
00985 {
00986 *shm_keyp = dbenv->shm_key;
00987 return (0);
00988 }
00989
00990
00991
00992
00993
00994
00995
00996 int
00997 __env_set_shm_key(dbenv, shm_key)
00998 DB_ENV *dbenv;
00999 long shm_key;
01000 {
01001 ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_shm_key");
01002
01003 dbenv->shm_key = shm_key;
01004 return (0);
01005 }
01006
01007 static int
01008 __env_get_tmp_dir(dbenv, dirp)
01009 DB_ENV *dbenv;
01010 const char **dirp;
01011 {
01012 *dirp = dbenv->db_tmp_dir;
01013 return (0);
01014 }
01015
01016
01017
01018
01019
01020
01021
01022 int
01023 __env_set_tmp_dir(dbenv, dir)
01024 DB_ENV *dbenv;
01025 const char *dir;
01026 {
01027 if (dbenv->db_tmp_dir != NULL)
01028 __os_free(dbenv, dbenv->db_tmp_dir);
01029 return (__os_strdup(dbenv, dir, &dbenv->db_tmp_dir));
01030 }
01031
01032 static int
01033 __env_get_verbose(dbenv, which, onoffp)
01034 DB_ENV *dbenv;
01035 u_int32_t which;
01036 int *onoffp;
01037 {
01038 switch (which) {
01039 case DB_VERB_DEADLOCK:
01040 case DB_VERB_RECOVERY:
01041 case DB_VERB_REGISTER:
01042 case DB_VERB_REPLICATION:
01043 case DB_VERB_WAITSFOR:
01044 *onoffp = FLD_ISSET(dbenv->verbose, which) ? 1 : 0;
01045 break;
01046 default:
01047 return (EINVAL);
01048 }
01049 return (0);
01050 }
01051
01052
01053
01054
01055
01056
01057
01058 int
01059 __env_set_verbose(dbenv, which, on)
01060 DB_ENV *dbenv;
01061 u_int32_t which;
01062 int on;
01063 {
01064 switch (which) {
01065 case DB_VERB_DEADLOCK:
01066 case DB_VERB_RECOVERY:
01067 case DB_VERB_REGISTER:
01068 case DB_VERB_REPLICATION:
01069 case DB_VERB_WAITSFOR:
01070 if (on)
01071 FLD_SET(dbenv->verbose, which);
01072 else
01073 FLD_CLR(dbenv->verbose, which);
01074 break;
01075 default:
01076 return (EINVAL);
01077 }
01078 return (0);
01079 }
01080
01081
01082
01083
01084
01085
01086
01087 int
01088 __db_mi_env(dbenv, name)
01089 DB_ENV *dbenv;
01090 const char *name;
01091 {
01092 __db_err(dbenv, "%s: method not permitted when environment specified",
01093 name);
01094 return (EINVAL);
01095 }
01096
01097
01098
01099
01100
01101
01102
01103 int
01104 __db_mi_open(dbenv, name, after)
01105 DB_ENV *dbenv;
01106 const char *name;
01107 int after;
01108 {
01109 __db_err(dbenv, "%s: method not permitted %s handle's open method",
01110 name, after ? "after" : "before");
01111 return (EINVAL);
01112 }
01113
01114
01115
01116
01117
01118
01119
01120 int
01121 __db_env_config(dbenv, i, flags)
01122 DB_ENV *dbenv;
01123 char *i;
01124 u_int32_t flags;
01125 {
01126 char *sub;
01127
01128 switch (flags) {
01129 case DB_INIT_LOCK:
01130 sub = "locking";
01131 break;
01132 case DB_INIT_LOG:
01133 sub = "logging";
01134 break;
01135 case DB_INIT_MPOOL:
01136 sub = "memory pool";
01137 break;
01138 case DB_INIT_REP:
01139 sub = "replication";
01140 break;
01141 case DB_INIT_TXN:
01142 sub = "transaction";
01143 break;
01144 default:
01145 sub = "<unspecified>";
01146 break;
01147 }
01148 __db_err(dbenv,
01149 "%s interface requires an environment configured for the %s subsystem",
01150 i, sub);
01151 return (EINVAL);
01152 }
01153
01154 static int
01155 __env_set_rpc_server(dbenv, cl, host, tsec, ssec, flags)
01156 DB_ENV *dbenv;
01157 void *cl;
01158 const char *host;
01159 long tsec, ssec;
01160 u_int32_t flags;
01161 {
01162 COMPQUIET(host, NULL);
01163 COMPQUIET(cl, NULL);
01164 COMPQUIET(tsec, 0);
01165 COMPQUIET(ssec, 0);
01166 COMPQUIET(flags, 0);
01167
01168 __db_err(dbenv, "Berkeley DB was not configured for RPC support");
01169 return (DB_OPNOTSUP);
01170 }