1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1999,2008 Oracle. All rights reserved. 5 * 6 * $Id: env_method.c,v 12.87 2008/02/18 20:06:07 bostic Exp $ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12#include "dbinc/crypto.h" 13#include "dbinc/hmac.h" 14#include "dbinc/db_page.h" 15#include "dbinc/db_am.h" 16#include "dbinc/lock.h" 17#include "dbinc/log.h" 18#include "dbinc/mp.h" 19#include "dbinc/txn.h" 20 21#ifdef HAVE_RPC 22#ifdef HAVE_SYSTEM_INCLUDE_FILES 23#include <rpc/rpc.h> 24#endif 25#include "db_server.h" 26#include "dbinc_auto/rpc_client_ext.h" 27#endif 28 29static int __db_env_init __P((DB_ENV *)); 30static void __env_err __P((const DB_ENV *, int, const char *, ...)); 31static void __env_errx __P((const DB_ENV *, const char *, ...)); 32static int __env_get_data_dirs __P((DB_ENV *, const char ***)); 33static int __env_get_flags __P((DB_ENV *, u_int32_t *)); 34static int __env_get_home __P((DB_ENV *, const char **)); 35static int __env_get_intermediate_dir_mode __P((DB_ENV *, const char **)); 36static int __env_get_shm_key __P((DB_ENV *, long *)); 37static int __env_get_thread_count __P((DB_ENV *, u_int32_t *)); 38static int __env_get_tmp_dir __P((DB_ENV *, const char **)); 39static int __env_get_verbose __P((DB_ENV *, u_int32_t, int *)); 40static int __env_set_app_dispatch 41 __P((DB_ENV *, int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops))); 42static int __env_set_event_notify 43 __P((DB_ENV *, void (*)(DB_ENV *, u_int32_t, void *))); 44static int __env_set_feedback __P((DB_ENV *, void (*)(DB_ENV *, int, int))); 45static int __env_set_isalive __P((DB_ENV *, 46 int (*)(DB_ENV *, pid_t, db_threadid_t, u_int32_t))); 47static int __env_set_thread_id __P((DB_ENV *, void (*)(DB_ENV *, 48 pid_t *, db_threadid_t *))); 49static int __env_set_thread_id_string __P((DB_ENV *, 50 char * (*)(DB_ENV *, pid_t, db_threadid_t, char *))); 51static int __env_set_thread_count __P((DB_ENV *, u_int32_t)); 52static int __env_set_rpc_server 53 __P((DB_ENV *, void *, const char *, long, long, u_int32_t)); 54 55/* 56 * db_env_create -- 57 * DB_ENV constructor. 58 * 59 * EXTERN: int db_env_create __P((DB_ENV **, u_int32_t)); 60 */ 61int 62db_env_create(dbenvpp, flags) 63 DB_ENV **dbenvpp; 64 u_int32_t flags; 65{ 66 DB_ENV *dbenv; 67 ENV *env; 68 int ret; 69 70 /* 71 * !!! 72 * Our caller has not yet had the opportunity to reset the panic 73 * state or turn off mutex locking, and so we can neither check 74 * the panic state or acquire a mutex in the DB_ENV create path. 75 * 76 * !!! 77 * We can't call the flags-checking routines, we don't have an 78 * environment yet. 79 */ 80 if (flags != 0 && !LF_ISSET(DB_RPCCLIENT)) 81 return (EINVAL); 82 83 /* Allocate the DB_ENV and ENV structures -- we always have both. */ 84 if ((ret = __os_calloc(NULL, 1, sizeof(DB_ENV), &dbenv)) != 0) 85 return (ret); 86 if ((ret = __os_calloc(NULL, 1, sizeof(ENV), &env)) != 0) 87 goto err; 88 dbenv->env = env; 89 env->dbenv = dbenv; 90 91#ifdef HAVE_RPC 92 if (LF_ISSET(DB_RPCCLIENT)) 93 F_SET(dbenv, DB_ENV_RPCCLIENT); 94#endif 95 if ((ret = __db_env_init(dbenv)) != 0 || 96 (ret = __lock_env_create(dbenv)) != 0 || 97 (ret = __log_env_create(dbenv)) != 0 || 98 (ret = __memp_env_create(dbenv)) != 0 || 99#ifdef HAVE_REPLICATION 100 (ret = __rep_env_create(dbenv)) != 0 || 101#endif 102 (ret = __txn_env_create(dbenv))) 103 goto err; 104 105#ifdef HAVE_RPC 106 /* 107 * RPC specific: must be last, as we replace methods set by the 108 * access methods. 109 */ 110 if (F_ISSET(dbenv, DB_ENV_RPCCLIENT)) { 111 __dbcl_dbenv_init(dbenv); 112 /* 113 * !!! 114 * We wrap the DB_ENV->open and close methods for RPC, and 115 * the rpc.src file can't handle that. 116 */ 117 dbenv->open = __dbcl_env_open_wrap; 118 dbenv->close = __dbcl_env_close_wrap; 119 } 120#endif 121 122 *dbenvpp = dbenv; 123 return (0); 124 125err: __db_env_destroy(dbenv); 126 return (ret); 127} 128 129/* 130 * __db_env_destroy -- 131 * DB_ENV destructor. 132 * 133 * PUBLIC: void __db_env_destroy __P((DB_ENV *)); 134 */ 135void 136__db_env_destroy(dbenv) 137 DB_ENV *dbenv; 138{ 139 __lock_env_destroy(dbenv); 140 __log_env_destroy(dbenv); 141 __memp_env_destroy(dbenv); 142#ifdef HAVE_REPLICATION 143 __rep_env_destroy(dbenv); 144#endif 145 __txn_env_destroy(dbenv); 146 147 /* 148 * Discard the underlying ENV structure. 149 * 150 * XXX 151 * This is wrong, but can't be fixed until we finish the work of 152 * splitting up the DB_ENV and ENV structures so that we don't 153 * touch anything in the ENV as part of the above calls to subsystem 154 * DB_ENV cleanup routines. 155 */ 156 memset(dbenv->env, CLEAR_BYTE, sizeof(ENV)); 157 __os_free(NULL, dbenv->env); 158 159 memset(dbenv, CLEAR_BYTE, sizeof(DB_ENV)); 160 __os_free(NULL, dbenv); 161} 162 163/* 164 * __db_env_init -- 165 * Initialize a DB_ENV structure. 166 */ 167static int 168__db_env_init(dbenv) 169 DB_ENV *dbenv; 170{ 171 ENV *env; 172 /* 173 * !!! 174 * Our caller has not yet had the opportunity to reset the panic 175 * state or turn off mutex locking, and so we can neither check 176 * the panic state or acquire a mutex in the DB_ENV create path. 177 * 178 * Initialize the method handles. 179 */ 180 /* DB_ENV PUBLIC HANDLE LIST BEGIN */ 181 dbenv->cdsgroup_begin = __cdsgroup_begin; 182 dbenv->close = __env_close_pp; 183 dbenv->dbremove = __env_dbremove_pp; 184 dbenv->dbrename = __env_dbrename_pp; 185 dbenv->err = __env_err; 186 dbenv->errx = __env_errx; 187 dbenv->failchk = __env_failchk_pp; 188 dbenv->fileid_reset = __env_fileid_reset_pp; 189 dbenv->get_cache_max = __memp_get_cache_max; 190 dbenv->get_cachesize = __memp_get_cachesize; 191 dbenv->get_data_dirs = __env_get_data_dirs; 192 dbenv->get_encrypt_flags = __env_get_encrypt_flags; 193 dbenv->get_errcall = __env_get_errcall; 194 dbenv->get_errfile = __env_get_errfile; 195 dbenv->get_errpfx = __env_get_errpfx; 196 dbenv->get_flags = __env_get_flags; 197 dbenv->get_home = __env_get_home; 198 dbenv->get_intermediate_dir_mode = __env_get_intermediate_dir_mode; 199 dbenv->get_lg_bsize = __log_get_lg_bsize; 200 dbenv->get_lg_dir = __log_get_lg_dir; 201 dbenv->get_lg_filemode = __log_get_lg_filemode; 202 dbenv->get_lg_max = __log_get_lg_max; 203 dbenv->get_lg_regionmax = __log_get_lg_regionmax; 204 dbenv->get_lk_conflicts = __lock_get_lk_conflicts; 205 dbenv->get_lk_detect = __lock_get_lk_detect; 206 dbenv->get_lk_max_lockers = __lock_get_lk_max_lockers; 207 dbenv->get_lk_max_locks = __lock_get_lk_max_locks; 208 dbenv->get_lk_max_objects = __lock_get_lk_max_objects; 209 dbenv->get_lk_partitions = __lock_get_lk_partitions; 210 dbenv->get_mp_max_openfd = __memp_get_mp_max_openfd; 211 dbenv->get_mp_max_write = __memp_get_mp_max_write; 212 dbenv->get_mp_mmapsize = __memp_get_mp_mmapsize; 213 dbenv->get_msgfile = __env_get_msgfile; 214 dbenv->get_open_flags = __env_get_open_flags; 215 dbenv->get_shm_key = __env_get_shm_key; 216 dbenv->get_thread_count = __env_get_thread_count; 217 dbenv->get_timeout = __lock_get_env_timeout; 218 dbenv->get_tmp_dir = __env_get_tmp_dir; 219 dbenv->get_tx_max = __txn_get_tx_max; 220 dbenv->get_tx_timestamp = __txn_get_tx_timestamp; 221 dbenv->get_verbose = __env_get_verbose; 222 dbenv->is_bigendian = __db_isbigendian; 223 dbenv->lock_detect = __lock_detect_pp; 224 dbenv->lock_get = __lock_get_pp; 225 dbenv->lock_id = __lock_id_pp; 226 dbenv->lock_id_free = __lock_id_free_pp; 227 dbenv->lock_put = __lock_put_pp; 228 dbenv->lock_stat = __lock_stat_pp; 229 dbenv->lock_stat_print = __lock_stat_print_pp; 230 dbenv->lock_vec = __lock_vec_pp; 231 dbenv->log_archive = __log_archive_pp; 232 dbenv->log_cursor = __log_cursor_pp; 233 dbenv->log_file = __log_file_pp; 234 dbenv->log_flush = __log_flush_pp; 235 dbenv->log_get_config = __log_get_config; 236 dbenv->log_printf = __log_printf_capi; 237 dbenv->log_put = __log_put_pp; 238 dbenv->log_set_config = __log_set_config; 239 dbenv->log_stat = __log_stat_pp; 240 dbenv->log_stat_print = __log_stat_print_pp; 241 dbenv->lsn_reset = __env_lsn_reset_pp; 242 dbenv->memp_fcreate = __memp_fcreate_pp; 243 dbenv->memp_register = __memp_register_pp; 244 dbenv->memp_stat = __memp_stat_pp; 245 dbenv->memp_stat_print = __memp_stat_print_pp; 246 dbenv->memp_sync = __memp_sync_pp; 247 dbenv->memp_trickle = __memp_trickle_pp; 248 dbenv->mutex_alloc = __mutex_alloc_pp; 249 dbenv->mutex_free = __mutex_free_pp; 250 dbenv->mutex_get_align = __mutex_get_align; 251 dbenv->mutex_get_increment = __mutex_get_increment; 252 dbenv->mutex_get_max = __mutex_get_max; 253 dbenv->mutex_get_tas_spins = __mutex_get_tas_spins; 254 dbenv->mutex_lock = __mutex_lock_pp; 255 dbenv->mutex_set_align = __mutex_set_align; 256 dbenv->mutex_set_increment = __mutex_set_increment; 257 dbenv->mutex_set_max = __mutex_set_max; 258 dbenv->mutex_set_tas_spins = __mutex_set_tas_spins; 259 dbenv->mutex_stat = __mutex_stat_pp; 260 dbenv->mutex_stat_print = __mutex_stat_print_pp; 261 dbenv->mutex_unlock = __mutex_unlock_pp; 262 dbenv->open = __env_open_pp; 263 dbenv->remove = __env_remove; 264 dbenv->rep_elect = __rep_elect; 265 dbenv->rep_flush = __rep_flush; 266 dbenv->rep_get_clockskew = __rep_get_clockskew; 267 dbenv->rep_get_config = __rep_get_config; 268 dbenv->rep_get_limit = __rep_get_limit; 269 dbenv->rep_get_nsites = __rep_get_nsites; 270 dbenv->rep_get_priority = __rep_get_priority; 271 dbenv->rep_get_request = __rep_get_request; 272 dbenv->rep_get_timeout = __rep_get_timeout; 273 dbenv->rep_process_message = __rep_process_message; 274 dbenv->rep_set_clockskew = __rep_set_clockskew; 275 dbenv->rep_set_config = __rep_set_config; 276 dbenv->rep_set_limit = __rep_set_limit; 277 dbenv->rep_set_nsites = __rep_set_nsites; 278 dbenv->rep_set_priority = __rep_set_priority; 279 dbenv->rep_set_request = __rep_set_request; 280 dbenv->rep_set_timeout = __rep_set_timeout; 281 dbenv->rep_set_transport = __rep_set_transport; 282 dbenv->rep_start = __rep_start; 283 dbenv->rep_stat = __rep_stat_pp; 284 dbenv->rep_stat_print = __rep_stat_print_pp; 285 dbenv->rep_sync = __rep_sync; 286 dbenv->repmgr_add_remote_site = __repmgr_add_remote_site; 287 dbenv->repmgr_get_ack_policy = __repmgr_get_ack_policy; 288 dbenv->repmgr_set_ack_policy = __repmgr_set_ack_policy; 289 dbenv->repmgr_set_local_site = __repmgr_set_local_site; 290 dbenv->repmgr_site_list = __repmgr_site_list; 291 dbenv->repmgr_start = __repmgr_start; 292 dbenv->repmgr_stat = __repmgr_stat_pp; 293 dbenv->repmgr_stat_print = __repmgr_stat_print_pp; 294 dbenv->set_alloc = __env_set_alloc; 295 dbenv->set_app_dispatch = __env_set_app_dispatch; 296 dbenv->set_cache_max = __memp_set_cache_max; 297 dbenv->set_cachesize = __memp_set_cachesize; 298 dbenv->set_data_dir = __env_set_data_dir; 299 dbenv->set_encrypt = __env_set_encrypt; 300 dbenv->set_errcall = __env_set_errcall; 301 dbenv->set_errfile = __env_set_errfile; 302 dbenv->set_errpfx = __env_set_errpfx; 303 dbenv->set_event_notify = __env_set_event_notify; 304 dbenv->set_feedback = __env_set_feedback; 305 dbenv->set_flags = __env_set_flags; 306 dbenv->set_intermediate_dir_mode = __env_set_intermediate_dir_mode; 307 dbenv->set_isalive = __env_set_isalive; 308 dbenv->set_lg_bsize = __log_set_lg_bsize; 309 dbenv->set_lg_dir = __log_set_lg_dir; 310 dbenv->set_lg_filemode = __log_set_lg_filemode; 311 dbenv->set_lg_max = __log_set_lg_max; 312 dbenv->set_lg_regionmax = __log_set_lg_regionmax; 313 dbenv->set_lk_conflicts = __lock_set_lk_conflicts; 314 dbenv->set_lk_detect = __lock_set_lk_detect; 315 dbenv->set_lk_max_lockers = __lock_set_lk_max_lockers; 316 dbenv->set_lk_max_locks = __lock_set_lk_max_locks; 317 dbenv->set_lk_max_objects = __lock_set_lk_max_objects; 318 dbenv->set_lk_partitions = __lock_set_lk_partitions; 319 dbenv->set_mp_max_openfd = __memp_set_mp_max_openfd; 320 dbenv->set_mp_max_write = __memp_set_mp_max_write; 321 dbenv->set_mp_mmapsize = __memp_set_mp_mmapsize; 322 dbenv->set_msgcall = __env_set_msgcall; 323 dbenv->set_msgfile = __env_set_msgfile; 324 dbenv->set_paniccall = __env_set_paniccall; 325 dbenv->set_rpc_server = __env_set_rpc_server; 326 dbenv->set_shm_key = __env_set_shm_key; 327 dbenv->set_thread_count = __env_set_thread_count; 328 dbenv->set_thread_id = __env_set_thread_id; 329 dbenv->set_thread_id_string = __env_set_thread_id_string; 330 dbenv->set_timeout = __lock_set_env_timeout; 331 dbenv->set_tmp_dir = __env_set_tmp_dir; 332 dbenv->set_tx_max = __txn_set_tx_max; 333 dbenv->set_tx_timestamp = __txn_set_tx_timestamp; 334 dbenv->set_verbose = __env_set_verbose; 335 dbenv->stat_print = __env_stat_print_pp; 336 dbenv->txn_begin = __txn_begin_pp; 337 dbenv->txn_checkpoint = __txn_checkpoint_pp; 338 dbenv->txn_recover = __txn_recover_pp; 339 dbenv->txn_stat = __txn_stat_pp; 340 dbenv->txn_stat_print = __txn_stat_print_pp; 341 /* DB_ENV PUBLIC HANDLE LIST END */ 342 343 /* DB_ENV PRIVATE HANDLE LIST BEGIN */ 344 dbenv->prdbt = __db_prdbt; 345 /* DB_ENV PRIVATE HANDLE LIST END */ 346 347 dbenv->shm_key = INVALID_REGION_SEGID; 348 dbenv->thread_id = __os_id; 349 dbenv->thread_id_string = __env_thread_id_string; 350 351 env = dbenv->env; 352 __os_id(NULL, &env->pid_cache, NULL); 353 354 env->db_ref = 0; 355 TAILQ_INIT(&env->fdlist); 356 357 if (!__db_isbigendian()) 358 F_SET(env, ENV_LITTLEENDIAN); 359 F_SET(env, ENV_NO_OUTPUT_SET); 360 361 return (0); 362} 363 364/* 365 * __env_err -- 366 * DbEnv.err method. 367 */ 368static void 369#ifdef STDC_HEADERS 370__env_err(const DB_ENV *dbenv, int error, const char *fmt, ...) 371#else 372__env_err(dbenv, error, fmt, va_alist) 373 const DB_ENV *dbenv; 374 int error; 375 const char *fmt; 376 va_dcl 377#endif 378{ 379 /* Message with error string, to stderr by default. */ 380 DB_REAL_ERR(dbenv, error, DB_ERROR_SET, 1, fmt); 381} 382 383/* 384 * __env_errx -- 385 * DbEnv.errx method. 386 */ 387static void 388#ifdef STDC_HEADERS 389__env_errx(const DB_ENV *dbenv, const char *fmt, ...) 390#else 391__env_errx(dbenv, fmt, va_alist) 392 const DB_ENV *dbenv; 393 const char *fmt; 394 va_dcl 395#endif 396{ 397 /* Message without error string, to stderr by default. */ 398 DB_REAL_ERR(dbenv, 0, DB_ERROR_NOT_SET, 1, fmt); 399} 400 401static int 402__env_get_home(dbenv, homep) 403 DB_ENV *dbenv; 404 const char **homep; 405{ 406 ENV *env; 407 408 env = dbenv->env; 409 410 ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->get_home"); 411 *homep = env->db_home; 412 413 return (0); 414} 415 416/* 417 * __env_set_alloc -- 418 * {DB_ENV,DB}->set_alloc. 419 * 420 * PUBLIC: int __env_set_alloc __P((DB_ENV *, void *(*)(size_t), 421 * PUBLIC: void *(*)(void *, size_t), void (*)(void *))); 422 */ 423int 424__env_set_alloc(dbenv, mal_func, real_func, free_func) 425 DB_ENV *dbenv; 426 void *(*mal_func) __P((size_t)); 427 void *(*real_func) __P((void *, size_t)); 428 void (*free_func) __P((void *)); 429{ 430 ENV *env; 431 432 env = dbenv->env; 433 434 ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_alloc"); 435 436 dbenv->db_malloc = mal_func; 437 dbenv->db_realloc = real_func; 438 dbenv->db_free = free_func; 439 return (0); 440} 441 442/* 443 * __env_set_app_dispatch -- 444 * Set the transaction abort recover function. 445 */ 446static int 447__env_set_app_dispatch(dbenv, app_dispatch) 448 DB_ENV *dbenv; 449 int (*app_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); 450{ 451 ENV *env; 452 453 env = dbenv->env; 454 455 ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_app_dispatch"); 456 457 dbenv->app_dispatch = app_dispatch; 458 return (0); 459} 460 461/* 462 * __env_get_encrypt_flags -- 463 * {DB_ENV,DB}->get_encrypt_flags. 464 * 465 * PUBLIC: int __env_get_encrypt_flags __P((DB_ENV *, u_int32_t *)); 466 */ 467int 468__env_get_encrypt_flags(dbenv, flagsp) 469 DB_ENV *dbenv; 470 u_int32_t *flagsp; 471{ 472#ifdef HAVE_CRYPTO 473 DB_CIPHER *db_cipher; 474#endif 475 ENV *env; 476 477 env = dbenv->env; 478 479#ifdef HAVE_CRYPTO 480 db_cipher = env->crypto_handle; 481 if (db_cipher != NULL && db_cipher->alg == CIPHER_AES) 482 *flagsp = DB_ENCRYPT_AES; 483 else 484 *flagsp = 0; 485 return (0); 486#else 487 COMPQUIET(flagsp, 0); 488 __db_errx(env, 489 "library build did not include support for cryptography"); 490 return (DB_OPNOTSUP); 491#endif 492} 493 494/* 495 * __env_set_encrypt -- 496 * DB_ENV->set_encrypt. 497 * 498 * PUBLIC: int __env_set_encrypt __P((DB_ENV *, const char *, u_int32_t)); 499 */ 500int 501__env_set_encrypt(dbenv, passwd, flags) 502 DB_ENV *dbenv; 503 const char *passwd; 504 u_int32_t flags; 505{ 506#ifdef HAVE_CRYPTO 507 DB_CIPHER *db_cipher; 508 ENV *env; 509 int ret; 510 511 env = dbenv->env; 512 513 ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_encrypt"); 514#define OK_CRYPTO_FLAGS (DB_ENCRYPT_AES) 515 516 if (flags != 0 && LF_ISSET(~OK_CRYPTO_FLAGS)) 517 return (__db_ferr(env, "DB_ENV->set_encrypt", 0)); 518 519 if (passwd == NULL || strlen(passwd) == 0) { 520 __db_errx(env, "Empty password specified to set_encrypt"); 521 return (EINVAL); 522 } 523 if (!CRYPTO_ON(env)) { 524 if ((ret = __os_calloc(env, 1, sizeof(DB_CIPHER), &db_cipher)) 525 != 0) 526 goto err; 527 env->crypto_handle = db_cipher; 528 } else 529 db_cipher = env->crypto_handle; 530 531 if (dbenv->passwd != NULL) 532 __os_free(env, dbenv->passwd); 533 if ((ret = __os_strdup(env, passwd, &dbenv->passwd)) != 0) { 534 __os_free(env, db_cipher); 535 goto err; 536 } 537 /* 538 * We're going to need this often enough to keep around 539 */ 540 dbenv->passwd_len = strlen(dbenv->passwd) + 1; 541 /* 542 * The MAC key is for checksumming, and is separate from 543 * the algorithm. So initialize it here, even if they 544 * are using CIPHER_ANY. 545 */ 546 __db_derive_mac( 547 (u_int8_t *)dbenv->passwd, dbenv->passwd_len, db_cipher->mac_key); 548 switch (flags) { 549 case 0: 550 F_SET(db_cipher, CIPHER_ANY); 551 break; 552 case DB_ENCRYPT_AES: 553 if ((ret = 554 __crypto_algsetup(env, db_cipher, CIPHER_AES, 0)) != 0) 555 goto err1; 556 break; 557 default: /* Impossible. */ 558 break; 559 } 560 return (0); 561 562err1: 563 __os_free(env, dbenv->passwd); 564 __os_free(env, db_cipher); 565 env->crypto_handle = NULL; 566err: 567 return (ret); 568#else 569 COMPQUIET(passwd, NULL); 570 COMPQUIET(flags, 0); 571 572 __db_errx(dbenv->env, 573 "library build did not include support for cryptography"); 574 return (DB_OPNOTSUP); 575#endif 576} 577#ifndef HAVE_BREW 578static 579#endif 580const FLAG_MAP EnvMap[] = { 581 { DB_AUTO_COMMIT, DB_ENV_AUTO_COMMIT }, 582 { DB_CDB_ALLDB, DB_ENV_CDB_ALLDB }, 583 { DB_DIRECT_DB, DB_ENV_DIRECT_DB }, 584 { DB_DSYNC_DB, DB_ENV_DSYNC_DB }, 585 { DB_MULTIVERSION, DB_ENV_MULTIVERSION }, 586 { DB_NOLOCKING, DB_ENV_NOLOCKING }, 587 { DB_NOMMAP, DB_ENV_NOMMAP }, 588 { DB_NOPANIC, DB_ENV_NOPANIC }, 589 { DB_OVERWRITE, DB_ENV_OVERWRITE }, 590 { DB_REGION_INIT, DB_ENV_REGION_INIT }, 591 { DB_TIME_NOTGRANTED, DB_ENV_TIME_NOTGRANTED }, 592 { DB_TXN_NOSYNC, DB_ENV_TXN_NOSYNC }, 593 { DB_TXN_NOWAIT, DB_ENV_TXN_NOWAIT }, 594 { DB_TXN_SNAPSHOT, DB_ENV_TXN_SNAPSHOT }, 595 { DB_TXN_WRITE_NOSYNC, DB_ENV_TXN_WRITE_NOSYNC }, 596 { DB_YIELDCPU, DB_ENV_YIELDCPU } 597}; 598 599/* 600 * __env_map_flags -- map from external to internal flags. 601 * PUBLIC: void __env_map_flags __P((const FLAG_MAP *, 602 * PUBLIC: u_int, u_int32_t *, u_int32_t *)); 603 */ 604void 605__env_map_flags(flagmap, mapsize, inflagsp, outflagsp) 606 const FLAG_MAP *flagmap; 607 u_int mapsize; 608 u_int32_t *inflagsp, *outflagsp; 609{ 610 611 const FLAG_MAP *fmp; 612 u_int i; 613 614 for (i = 0, fmp = flagmap; 615 i < mapsize / sizeof(flagmap[0]); ++i, ++fmp) 616 if (FLD_ISSET(*inflagsp, fmp->inflag)) { 617 FLD_SET(*outflagsp, fmp->outflag); 618 FLD_CLR(*inflagsp, fmp->inflag); 619 if (*inflagsp == 0) 620 break; 621 } 622} 623 624/* 625 * __env_fetch_flags -- map from internal to external flags. 626 * PUBLIC: void __env_fetch_flags __P((const FLAG_MAP *, 627 * PUBLIC: u_int, u_int32_t *, u_int32_t *)); 628 */ 629void 630__env_fetch_flags(flagmap, mapsize, inflagsp, outflagsp) 631 const FLAG_MAP *flagmap; 632 u_int mapsize; 633 u_int32_t *inflagsp, *outflagsp; 634{ 635 const FLAG_MAP *fmp; 636 u_int32_t i; 637 638 *outflagsp = 0; 639 for (i = 0, fmp = flagmap; 640 i < mapsize / sizeof(flagmap[0]); ++i, ++fmp) 641 if (FLD_ISSET(*inflagsp, fmp->outflag)) 642 FLD_SET(*outflagsp, fmp->inflag); 643} 644 645static int 646__env_get_flags(dbenv, flagsp) 647 DB_ENV *dbenv; 648 u_int32_t *flagsp; 649{ 650 ENV *env; 651 652 __env_fetch_flags(EnvMap, sizeof(EnvMap), &dbenv->flags, flagsp); 653 654 env = dbenv->env; 655 /* Some flags are persisted in the regions. */ 656 if (env->reginfo != NULL && 657 ((REGENV *)env->reginfo->primary)->panic != 0) 658 FLD_SET(*flagsp, DB_PANIC_ENVIRONMENT); 659 660 return (0); 661} 662 663/* 664 * __env_set_flags -- 665 * DB_ENV->set_flags. 666 * 667 * PUBLIC: int __env_set_flags __P((DB_ENV *, u_int32_t, int)); 668 */ 669int 670__env_set_flags(dbenv, flags, on) 671 DB_ENV *dbenv; 672 u_int32_t flags; 673 int on; 674{ 675 ENV *env; 676 u_int32_t mapped_flags; 677 int ret; 678 679 env = dbenv->env; 680 681#define OK_FLAGS \ 682 (DB_AUTO_COMMIT | DB_CDB_ALLDB | DB_DIRECT_DB | \ 683 DB_DSYNC_DB | DB_MULTIVERSION | DB_NOLOCKING | \ 684 DB_NOMMAP | DB_NOPANIC | DB_OVERWRITE | \ 685 DB_PANIC_ENVIRONMENT | DB_REGION_INIT | \ 686 DB_TIME_NOTGRANTED | DB_TXN_NOSYNC | DB_TXN_NOWAIT | \ 687 DB_TXN_SNAPSHOT | DB_TXN_WRITE_NOSYNC | DB_YIELDCPU) 688 689 if (LF_ISSET(~OK_FLAGS)) 690 return (__db_ferr(env, "DB_ENV->set_flags", 0)); 691 if (on) { 692 if ((ret = __db_fcchk(env, "DB_ENV->set_flags", 693 flags, DB_TXN_NOSYNC, DB_TXN_WRITE_NOSYNC)) != 0) 694 return (ret); 695 if (LF_ISSET(DB_DIRECT_DB) && __os_support_direct_io() == 0) { 696 __db_errx(env, 697 "DB_ENV->set_flags: direct I/O either not configured or not supported"); 698 return (EINVAL); 699 } 700 } 701 702 if (LF_ISSET(DB_CDB_ALLDB)) 703 ENV_ILLEGAL_AFTER_OPEN(env, 704 "DB_ENV->set_flags: DB_CDB_ALLDB"); 705 if (LF_ISSET(DB_PANIC_ENVIRONMENT)) { 706 ENV_ILLEGAL_BEFORE_OPEN(env, 707 "DB_ENV->set_flags: DB_PANIC_ENVIRONMENT"); 708 if (on) { 709 __db_errx(env, "Environment panic set"); 710 (void)__env_panic(env, DB_RUNRECOVERY); 711 } else 712 __env_panic_set(env, 0); 713 } 714 if (LF_ISSET(DB_REGION_INIT)) 715 ENV_ILLEGAL_AFTER_OPEN(env, 716 "DB_ENV->set_flags: DB_REGION_INIT"); 717 718 /* 719 * DB_LOG_IN_MEMORY, DB_TXN_NOSYNC and DB_TXN_WRITE_NOSYNC are 720 * mutually incompatible. If we're setting one of them, clear all 721 * current settings. 722 */ 723 if (LF_ISSET(DB_TXN_NOSYNC | DB_TXN_WRITE_NOSYNC)) { 724 F_CLR(dbenv, DB_ENV_TXN_NOSYNC | DB_ENV_TXN_WRITE_NOSYNC); 725 if ((LOGGING_ON(env) || !F_ISSET(env, ENV_OPEN_CALLED)) && 726 (ret = __log_set_config(dbenv, DB_LOG_IN_MEMORY, 0)) != 0) 727 return (ret); 728 } 729 730 mapped_flags = 0; 731 __env_map_flags(EnvMap, sizeof(EnvMap), &flags, &mapped_flags); 732 if (on) 733 F_SET(dbenv, mapped_flags); 734 else 735 F_CLR(dbenv, mapped_flags); 736 737 return (0); 738} 739 740static int 741__env_get_data_dirs(dbenv, dirpp) 742 DB_ENV *dbenv; 743 const char ***dirpp; 744{ 745 *dirpp = (const char **)dbenv->db_data_dir; 746 return (0); 747} 748 749/* 750 * __env_set_data_dir -- 751 * DB_ENV->set_data_dir. 752 * 753 * PUBLIC: int __env_set_data_dir __P((DB_ENV *, const char *)); 754 */ 755int 756__env_set_data_dir(dbenv, dir) 757 DB_ENV *dbenv; 758 const char *dir; 759{ 760 ENV *env; 761 int ret; 762 763 env = dbenv->env; 764 765 /* 766 * The array is NULL-terminated so it can be returned by get_data_dirs 767 * without a length. 768 */ 769 770#define DATA_INIT_CNT 20 /* Start with 20 data slots. */ 771 if (dbenv->db_data_dir == NULL) { 772 if ((ret = __os_calloc(env, DATA_INIT_CNT, 773 sizeof(char **), &dbenv->db_data_dir)) != 0) 774 return (ret); 775 dbenv->data_cnt = DATA_INIT_CNT; 776 } else if (dbenv->data_next == dbenv->data_cnt - 2) { 777 dbenv->data_cnt *= 2; 778 if ((ret = __os_realloc(env, 779 (u_int)dbenv->data_cnt * sizeof(char **), 780 &dbenv->db_data_dir)) != 0) 781 return (ret); 782 } 783 784 ret = __os_strdup(env, 785 dir, &dbenv->db_data_dir[dbenv->data_next++]); 786 dbenv->db_data_dir[dbenv->data_next] = NULL; 787 return (ret); 788} 789 790static int 791__env_get_intermediate_dir_mode(dbenv, modep) 792 DB_ENV *dbenv; 793 const char **modep; 794{ 795 *modep = dbenv->intermediate_dir_mode; 796 return (0); 797} 798 799/* 800 * __env_set_intermediate_dir_mode -- 801 * DB_ENV->set_intermediate_dir_mode. 802 * 803 * PUBLIC: int __env_set_intermediate_dir_mode __P((DB_ENV *, const char *)); 804 */ 805int 806__env_set_intermediate_dir_mode(dbenv, mode) 807 DB_ENV *dbenv; 808 const char *mode; 809{ 810 ENV *env; 811 u_int t; 812 int ret; 813 814 env = dbenv->env; 815 816 ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_intermediate_dir_mode"); 817 818#define __SETMODE(offset, valid_ch, mask) { \ 819 if (mode[offset] == (valid_ch)) \ 820 t |= (mask); \ 821 else if (mode[offset] != '-') \ 822 goto format_err; \ 823} 824 t = 0; 825 __SETMODE(0, 'r', S_IRUSR); 826 __SETMODE(1, 'w', S_IWUSR); 827 __SETMODE(2, 'x', S_IXUSR); 828 __SETMODE(3, 'r', S_IRGRP); 829 __SETMODE(4, 'w', S_IWGRP); 830 __SETMODE(5, 'x', S_IXGRP); 831 __SETMODE(6, 'r', S_IROTH); 832 __SETMODE(7, 'w', S_IWOTH); 833 __SETMODE(8, 'x', S_IXOTH); 834 if (mode[9] != '\0' || t == 0) { 835 /* 836 * We disallow modes of 0 -- we use 0 to decide the application 837 * never configured intermediate directory permissions, and we 838 * shouldn't create intermediate directories. Besides, setting 839 * the permissions to 0 makes no sense. 840 */ 841format_err: __db_errx(env, 842 "DB_ENV->set_intermediate_dir_mode: illegal mode \"%s\"", mode); 843 return (EINVAL); 844 } 845 846 if (dbenv->intermediate_dir_mode != NULL) 847 __os_free(env, dbenv->intermediate_dir_mode); 848 if ((ret = __os_strdup(env, mode, &dbenv->intermediate_dir_mode)) != 0) 849 return (ret); 850 851 env->dir_mode = (int)t; 852 return (0); 853} 854 855/* 856 * __env_get_errcall -- 857 * {DB_ENV,DB}->get_errcall. 858 * 859 * PUBLIC: void __env_get_errcall __P((DB_ENV *, 860 * PUBLIC: void (**)(const DB_ENV *, const char *, const char *))); 861 */ 862void 863__env_get_errcall(dbenv, errcallp) 864 DB_ENV *dbenv; 865 void (**errcallp) __P((const DB_ENV *, const char *, const char *)); 866{ 867 *errcallp = dbenv->db_errcall; 868} 869 870/* 871 * __env_set_errcall -- 872 * {DB_ENV,DB}->set_errcall. 873 * 874 * PUBLIC: void __env_set_errcall __P((DB_ENV *, 875 * PUBLIC: void (*)(const DB_ENV *, const char *, const char *))); 876 */ 877void 878__env_set_errcall(dbenv, errcall) 879 DB_ENV *dbenv; 880 void (*errcall) __P((const DB_ENV *, const char *, const char *)); 881{ 882 ENV *env; 883 884 env = dbenv->env; 885 886 F_CLR(env, ENV_NO_OUTPUT_SET); 887 dbenv->db_errcall = errcall; 888} 889 890/* 891 * __env_get_errfile -- 892 * {DB_ENV,DB}->get_errfile. 893 * 894 * PUBLIC: void __env_get_errfile __P((DB_ENV *, FILE **)); 895 */ 896void 897__env_get_errfile(dbenv, errfilep) 898 DB_ENV *dbenv; 899 FILE **errfilep; 900{ 901 *errfilep = dbenv->db_errfile; 902} 903 904/* 905 * __env_set_errfile -- 906 * {DB_ENV,DB}->set_errfile. 907 * 908 * PUBLIC: void __env_set_errfile __P((DB_ENV *, FILE *)); 909 */ 910void 911__env_set_errfile(dbenv, errfile) 912 DB_ENV *dbenv; 913 FILE *errfile; 914{ 915 ENV *env; 916 917 env = dbenv->env; 918 919 F_CLR(env, ENV_NO_OUTPUT_SET); 920 dbenv->db_errfile = errfile; 921} 922 923/* 924 * __env_get_errpfx -- 925 * {DB_ENV,DB}->get_errpfx. 926 * 927 * PUBLIC: void __env_get_errpfx __P((DB_ENV *, const char **)); 928 */ 929void 930__env_get_errpfx(dbenv, errpfxp) 931 DB_ENV *dbenv; 932 const char **errpfxp; 933{ 934 *errpfxp = dbenv->db_errpfx; 935} 936 937/* 938 * __env_set_errpfx -- 939 * {DB_ENV,DB}->set_errpfx. 940 * 941 * PUBLIC: void __env_set_errpfx __P((DB_ENV *, const char *)); 942 */ 943void 944__env_set_errpfx(dbenv, errpfx) 945 DB_ENV *dbenv; 946 const char *errpfx; 947{ 948 dbenv->db_errpfx = errpfx; 949} 950 951static int 952__env_set_feedback(dbenv, feedback) 953 DB_ENV *dbenv; 954 void (*feedback) __P((DB_ENV *, int, int)); 955{ 956 dbenv->db_feedback = feedback; 957 return (0); 958} 959 960/* 961 * __env_set_thread_id -- 962 * DB_ENV->set_thread_id 963 */ 964static int 965__env_set_thread_id(dbenv, id) 966 DB_ENV *dbenv; 967 void (*id) __P((DB_ENV *, pid_t *, db_threadid_t *)); 968{ 969 dbenv->thread_id = id; 970 return (0); 971} 972 973/* 974 * __env_set_threadid_string -- 975 * DB_ENV->set_threadid_string 976 */ 977static int 978__env_set_thread_id_string(dbenv, thread_id_string) 979 DB_ENV *dbenv; 980 char *(*thread_id_string) __P((DB_ENV *, pid_t, db_threadid_t, char *)); 981{ 982 dbenv->thread_id_string = thread_id_string; 983 return (0); 984} 985 986/* 987 * __env_set_isalive -- 988 * DB_ENV->set_isalive 989 */ 990static int 991__env_set_isalive(dbenv, is_alive) 992 DB_ENV *dbenv; 993 int (*is_alive) __P((DB_ENV *, pid_t, db_threadid_t, u_int32_t)); 994{ 995 ENV *env; 996 997 env = dbenv->env; 998 999 if (F_ISSET(env, ENV_OPEN_CALLED) && env->thr_nbucket == 0) { 1000 __db_errx(env, 1001 "is_alive method specified but no thread region allocated"); 1002 return (EINVAL); 1003 } 1004 dbenv->is_alive = is_alive; 1005 return (0); 1006} 1007 1008/* 1009 * __env_get_thread_count -- 1010 * DB_ENV->get_thread_count 1011 */ 1012static int 1013__env_get_thread_count(dbenv, countp) 1014 DB_ENV *dbenv; 1015 u_int32_t *countp; 1016{ 1017 *countp = dbenv->thr_max; 1018 return (0); 1019} 1020 1021/* 1022 * __env_set_thread_count -- 1023 * DB_ENV->set_thread_count 1024 */ 1025static int 1026__env_set_thread_count(dbenv, count) 1027 DB_ENV *dbenv; 1028 u_int32_t count; 1029{ 1030 ENV *env; 1031 1032 env = dbenv->env; 1033 1034 ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_thread_count"); 1035 dbenv->thr_max = count; 1036 1037 return (0); 1038} 1039 1040/* 1041 * __env_set_msgcall -- 1042 * {DB_ENV,DB}->set_msgcall. 1043 * 1044 * PUBLIC: void __env_set_msgcall 1045 * PUBLIC: __P((DB_ENV *, void (*)(const DB_ENV *, const char *))); 1046 */ 1047void 1048__env_set_msgcall(dbenv, msgcall) 1049 DB_ENV *dbenv; 1050 void (*msgcall) __P((const DB_ENV *, const char *)); 1051{ 1052 dbenv->db_msgcall = msgcall; 1053} 1054 1055/* 1056 * __env_get_msgfile -- 1057 * {DB_ENV,DB}->get_msgfile. 1058 * 1059 * PUBLIC: void __env_get_msgfile __P((DB_ENV *, FILE **)); 1060 */ 1061void 1062__env_get_msgfile(dbenv, msgfilep) 1063 DB_ENV *dbenv; 1064 FILE **msgfilep; 1065{ 1066 *msgfilep = dbenv->db_msgfile; 1067} 1068 1069/* 1070 * __env_set_msgfile -- 1071 * {DB_ENV,DB}->set_msgfile. 1072 * 1073 * PUBLIC: void __env_set_msgfile __P((DB_ENV *, FILE *)); 1074 */ 1075void 1076__env_set_msgfile(dbenv, msgfile) 1077 DB_ENV *dbenv; 1078 FILE *msgfile; 1079{ 1080 dbenv->db_msgfile = msgfile; 1081} 1082 1083/* 1084 * __env_set_paniccall -- 1085 * {DB_ENV,DB}->set_paniccall. 1086 * 1087 * PUBLIC: int __env_set_paniccall __P((DB_ENV *, void (*)(DB_ENV *, int))); 1088 */ 1089int 1090__env_set_paniccall(dbenv, paniccall) 1091 DB_ENV *dbenv; 1092 void (*paniccall) __P((DB_ENV *, int)); 1093{ 1094 dbenv->db_paniccall = paniccall; 1095 return (0); 1096} 1097 1098/* 1099 * __env_set_event_notify -- 1100 * DB_ENV->set_event_notify. 1101 */ 1102static int 1103__env_set_event_notify(dbenv, event_func) 1104 DB_ENV *dbenv; 1105 void (*event_func) __P((DB_ENV *, u_int32_t, void *)); 1106{ 1107 dbenv->db_event_func = event_func; 1108 return (0); 1109} 1110 1111static int 1112__env_get_shm_key(dbenv, shm_keyp) 1113 DB_ENV *dbenv; 1114 long *shm_keyp; /* !!!: really a key_t *. */ 1115{ 1116 *shm_keyp = dbenv->shm_key; 1117 return (0); 1118} 1119 1120/* 1121 * __env_set_shm_key -- 1122 * DB_ENV->set_shm_key. 1123 * 1124 * PUBLIC: int __env_set_shm_key __P((DB_ENV *, long)); 1125 */ 1126int 1127__env_set_shm_key(dbenv, shm_key) 1128 DB_ENV *dbenv; 1129 long shm_key; /* !!!: really a key_t. */ 1130{ 1131 ENV *env; 1132 1133 env = dbenv->env; 1134 1135 ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_shm_key"); 1136 1137 dbenv->shm_key = shm_key; 1138 return (0); 1139} 1140 1141static int 1142__env_get_tmp_dir(dbenv, dirp) 1143 DB_ENV *dbenv; 1144 const char **dirp; 1145{ 1146 *dirp = dbenv->db_tmp_dir; 1147 return (0); 1148} 1149 1150/* 1151 * __env_set_tmp_dir -- 1152 * DB_ENV->set_tmp_dir. 1153 * 1154 * PUBLIC: int __env_set_tmp_dir __P((DB_ENV *, const char *)); 1155 */ 1156int 1157__env_set_tmp_dir(dbenv, dir) 1158 DB_ENV *dbenv; 1159 const char *dir; 1160{ 1161 ENV *env; 1162 1163 env = dbenv->env; 1164 1165 if (dbenv->db_tmp_dir != NULL) 1166 __os_free(env, dbenv->db_tmp_dir); 1167 return (__os_strdup(env, dir, &dbenv->db_tmp_dir)); 1168} 1169 1170static int 1171__env_get_verbose(dbenv, which, onoffp) 1172 DB_ENV *dbenv; 1173 u_int32_t which; 1174 int *onoffp; 1175{ 1176 switch (which) { 1177 case DB_VERB_DEADLOCK: 1178 case DB_VERB_FILEOPS: 1179 case DB_VERB_FILEOPS_ALL: 1180 case DB_VERB_RECOVERY: 1181 case DB_VERB_REGISTER: 1182 case DB_VERB_REPLICATION: 1183 case DB_VERB_REP_ELECT: 1184 case DB_VERB_REP_LEASE: 1185 case DB_VERB_REP_MISC: 1186 case DB_VERB_REP_MSGS: 1187 case DB_VERB_REP_SYNC: 1188 case DB_VERB_REPMGR_CONNFAIL: 1189 case DB_VERB_REPMGR_MISC: 1190 case DB_VERB_WAITSFOR: 1191 *onoffp = FLD_ISSET(dbenv->verbose, which) ? 1 : 0; 1192 break; 1193 default: 1194 return (EINVAL); 1195 } 1196 return (0); 1197} 1198 1199/* 1200 * __env_set_verbose -- 1201 * DB_ENV->set_verbose. 1202 * 1203 * PUBLIC: int __env_set_verbose __P((DB_ENV *, u_int32_t, int)); 1204 */ 1205int 1206__env_set_verbose(dbenv, which, on) 1207 DB_ENV *dbenv; 1208 u_int32_t which; 1209 int on; 1210{ 1211 switch (which) { 1212 case DB_VERB_DEADLOCK: 1213 case DB_VERB_FILEOPS: 1214 case DB_VERB_FILEOPS_ALL: 1215 case DB_VERB_RECOVERY: 1216 case DB_VERB_REGISTER: 1217 case DB_VERB_REPLICATION: 1218 case DB_VERB_REP_ELECT: 1219 case DB_VERB_REP_LEASE: 1220 case DB_VERB_REP_MISC: 1221 case DB_VERB_REP_MSGS: 1222 case DB_VERB_REP_SYNC: 1223 case DB_VERB_REPMGR_CONNFAIL: 1224 case DB_VERB_REPMGR_MISC: 1225 case DB_VERB_WAITSFOR: 1226 if (on) 1227 FLD_SET(dbenv->verbose, which); 1228 else 1229 FLD_CLR(dbenv->verbose, which); 1230 break; 1231 default: 1232 return (EINVAL); 1233 } 1234 return (0); 1235} 1236 1237/* 1238 * __db_mi_env -- 1239 * Method illegally called with public environment. 1240 * 1241 * PUBLIC: int __db_mi_env __P((ENV *, const char *)); 1242 */ 1243int 1244__db_mi_env(env, name) 1245 ENV *env; 1246 const char *name; 1247{ 1248 __db_errx(env, 1249 "%s: method not permitted when environment specified", name); 1250 return (EINVAL); 1251} 1252 1253/* 1254 * __db_mi_open -- 1255 * Method illegally called after open. 1256 * 1257 * PUBLIC: int __db_mi_open __P((ENV *, const char *, int)); 1258 */ 1259int 1260__db_mi_open(env, name, after) 1261 ENV *env; 1262 const char *name; 1263 int after; 1264{ 1265 __db_errx(env, "%s: method not permitted %s handle's open method", 1266 name, after ? "after" : "before"); 1267 return (EINVAL); 1268} 1269 1270/* 1271 * __env_not_config -- 1272 * Method or function called without required configuration. 1273 * 1274 * PUBLIC: int __env_not_config __P((ENV *, char *, u_int32_t)); 1275 */ 1276int 1277__env_not_config(env, i, flags) 1278 ENV *env; 1279 char *i; 1280 u_int32_t flags; 1281{ 1282 char *sub; 1283 1284 switch (flags) { 1285 case DB_INIT_LOCK: 1286 sub = "locking"; 1287 break; 1288 case DB_INIT_LOG: 1289 sub = "logging"; 1290 break; 1291 case DB_INIT_MPOOL: 1292 sub = "memory pool"; 1293 break; 1294 case DB_INIT_REP: 1295 sub = "replication"; 1296 break; 1297 case DB_INIT_TXN: 1298 sub = "transaction"; 1299 break; 1300 default: 1301 sub = "<unspecified>"; 1302 break; 1303 } 1304 __db_errx(env, 1305 "%s interface requires an environment configured for the %s subsystem", 1306 i, sub); 1307 return (EINVAL); 1308} 1309 1310static int 1311__env_set_rpc_server(dbenv, cl, host, tsec, ssec, flags) 1312 DB_ENV *dbenv; 1313 void *cl; 1314 const char *host; 1315 long tsec, ssec; 1316 u_int32_t flags; 1317{ 1318 ENV *env; 1319 1320 env = dbenv->env; 1321 1322 COMPQUIET(host, NULL); 1323 COMPQUIET(cl, NULL); 1324 COMPQUIET(tsec, 0); 1325 COMPQUIET(ssec, 0); 1326 COMPQUIET(flags, 0); 1327 1328 __db_errx(env, "Berkeley DB was not configured for RPC support"); 1329 return (DB_OPNOTSUP); 1330} 1331