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 #include <ctype.h>
00016 #include <limits.h>
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #endif
00020
00021 #include "db_int.h"
00022 #include "dbinc/crypto.h"
00023 #include "dbinc/db_page.h"
00024 #include "dbinc/db_shash.h"
00025 #include "dbinc/btree.h"
00026 #include "dbinc/hash.h"
00027 #include "dbinc/fop.h"
00028 #include "dbinc/lock.h"
00029 #include "dbinc/log.h"
00030 #include "dbinc/mp.h"
00031 #include "dbinc/qam.h"
00032 #include "dbinc/txn.h"
00033
00034 static int __db_parse __P((DB_ENV *, char *));
00035 static int __db_tmp_open __P((DB_ENV *, u_int32_t, char *, DB_FH **));
00036 static int __env_config __P((DB_ENV *, const char *, u_int32_t));
00037 static int __env_refresh __P((DB_ENV *, u_int32_t, int));
00038 static int __env_remove_int __P((DB_ENV *, const char *, u_int32_t));
00039
00040
00041
00042
00043
00044
00045
00046 char *
00047 db_version(majverp, minverp, patchp)
00048 int *majverp, *minverp, *patchp;
00049 {
00050 if (majverp != NULL)
00051 *majverp = DB_VERSION_MAJOR;
00052 if (minverp != NULL)
00053 *minverp = DB_VERSION_MINOR;
00054 if (patchp != NULL)
00055 *patchp = DB_VERSION_PATCH;
00056 return ((char *)DB_VERSION_STRING);
00057 }
00058
00059
00060
00061
00062
00063
00064
00065 int
00066 __env_open_pp(dbenv, db_home, flags, mode)
00067 DB_ENV *dbenv;
00068 const char *db_home;
00069 u_int32_t flags;
00070 int mode;
00071 {
00072 DB_THREAD_INFO *ip;
00073 u_int32_t orig_flags;
00074 int need_recovery, ret, t_ret;
00075
00076 need_recovery = 0;
00077
00078 #undef OKFLAGS
00079 #define OKFLAGS \
00080 (DB_CREATE | DB_INIT_CDB | DB_INIT_LOCK | DB_INIT_LOG | \
00081 DB_INIT_MPOOL | DB_INIT_REP | DB_INIT_TXN | DB_LOCKDOWN | \
00082 DB_PRIVATE | DB_RECOVER | DB_RECOVER_FATAL | DB_REGISTER | \
00083 DB_SYSTEM_MEM | DB_THREAD | DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)
00084 #undef OKFLAGS_CDB
00085 #define OKFLAGS_CDB \
00086 (DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL | DB_LOCKDOWN | \
00087 DB_PRIVATE | DB_SYSTEM_MEM | DB_THREAD | \
00088 DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)
00089
00090 if ((ret = __db_fchk(dbenv, "DB_ENV->open", flags, OKFLAGS)) != 0)
00091 return (ret);
00092 if ((ret = __db_fcchk(
00093 dbenv, "DB_ENV->open", flags, DB_INIT_CDB, ~OKFLAGS_CDB)) != 0)
00094 return (ret);
00095 if ((ret = __db_fcchk(dbenv, "DB_ENV->open", flags,
00096 DB_PRIVATE, DB_REGISTER | DB_SYSTEM_MEM)) != 0)
00097 return (ret);
00098 if (LF_ISSET(DB_INIT_REP)) {
00099 if (!LF_ISSET(DB_INIT_LOCK)) {
00100 __db_err(dbenv, "replication requires locking support");
00101 return (EINVAL);
00102 }
00103 if (!LF_ISSET(DB_INIT_TXN)) {
00104 __db_err(
00105 dbenv, "replication requires transaction support");
00106 return (EINVAL);
00107 }
00108 }
00109 if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL)) {
00110 if ((ret = __db_fcchk(dbenv,
00111 "DB_ENV->open", flags, DB_RECOVER, DB_RECOVER_FATAL)) != 0)
00112 return (ret);
00113 if (!LF_ISSET(DB_CREATE)) {
00114 __db_err(dbenv, "recovery requires the create flag");
00115 return (EINVAL);
00116 }
00117 if (!LF_ISSET(DB_INIT_TXN)) {
00118 __db_err(
00119 dbenv, "recovery requires transaction support");
00120 return (EINVAL);
00121 }
00122 }
00123
00124
00125
00126
00127
00128
00129 #ifdef HAVE_MUTEX_THREAD_ONLY
00130 if (!LF_ISSET(DB_PRIVATE)) {
00131 __db_err(dbenv,
00132 "Berkeley DB library configured to support only private environments");
00133 return (EINVAL);
00134 }
00135 #endif
00136
00137 #if defined(HAVE_MUTEX_FCNTL)
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 if (F_ISSET(dbenv, DB_ENV_THREAD)) {
00156 __db_err(dbenv,
00157 "architecture lacks fast mutexes: applications cannot be threaded");
00158 return (EINVAL);
00159 }
00160 #endif
00161
00162 if (LF_ISSET(DB_INIT_REP) && !__os_support_replication()) {
00163 __db_err(dbenv,
00164 "Berkeley DB library does not support replication on this system");
00165 return (EINVAL);
00166 }
00167
00168
00169
00170
00171
00172 if (LF_ISSET(DB_REGISTER)) {
00173 if (!__os_support_db_register()) {
00174 __db_err(dbenv,
00175 "Berkeley DB library does not support DB_REGISTER on this system");
00176 return (EINVAL);
00177 }
00178
00179 if ((ret =
00180 __envreg_register(dbenv, db_home, &need_recovery)) != 0)
00181 return (ret);
00182 if (need_recovery) {
00183 if (!LF_ISSET(DB_RECOVER)) {
00184 __db_err(dbenv,
00185 "No recovery flag was specified, and recovery is needed");
00186 ret = DB_RUNRECOVERY;
00187 goto err;
00188 }
00189 } else
00190 LF_CLR(DB_RECOVER | DB_RECOVER_FATAL);
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL)) {
00206 orig_flags = dbenv->flags;
00207 if ((ret = __env_remove_int(dbenv, db_home, DB_FORCE)) != 0 ||
00208 (ret = __env_refresh(dbenv, orig_flags, 0)) != 0)
00209 goto err;
00210 }
00211
00212 ret = __env_open(dbenv, db_home, flags, mode);
00213 if (ret == 0 && dbenv->thr_hashtab != NULL &&
00214 (t_ret = __env_set_state(dbenv, &ip, THREAD_OUT)) != 0)
00215 ret = t_ret;
00216
00217 err: if (need_recovery) {
00218
00219
00220
00221
00222
00223
00224 if (ret == 0 && (t_ret = __envreg_xunlock(dbenv)) != 0)
00225 ret = t_ret;
00226 if (ret != 0)
00227 (void)__envreg_unregister(dbenv, 1);
00228 }
00229
00230 return (ret);
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 int
00240 __env_open(dbenv, db_home, flags, mode)
00241 DB_ENV *dbenv;
00242 const char *db_home;
00243 u_int32_t flags;
00244 int mode;
00245 {
00246 DB_THREAD_INFO *ip;
00247 REGINFO *infop;
00248 u_int32_t init_flags, orig_flags;
00249 int rep_check, ret;
00250
00251 orig_flags = dbenv->flags;
00252 rep_check = 0;
00253 ip = NULL;
00254
00255
00256 if ((ret = __env_config(dbenv, db_home, flags)) != 0)
00257 goto err;
00258
00259
00260 if (LF_ISSET(DB_CREATE))
00261 F_SET(dbenv, DB_ENV_CREATE);
00262 if (LF_ISSET(DB_LOCKDOWN))
00263 F_SET(dbenv, DB_ENV_LOCKDOWN);
00264 if (LF_ISSET(DB_PRIVATE))
00265 F_SET(dbenv, DB_ENV_PRIVATE);
00266 if (LF_ISSET(DB_RECOVER_FATAL))
00267 F_SET(dbenv, DB_ENV_FATAL);
00268 if (LF_ISSET(DB_SYSTEM_MEM))
00269 F_SET(dbenv, DB_ENV_SYSTEM_MEM);
00270 if (LF_ISSET(DB_THREAD))
00271 F_SET(dbenv, DB_ENV_THREAD);
00272
00273
00274 dbenv->db_mode = mode == 0 ? __db_omode("rw-rw----") : mode;
00275
00276
00277
00278
00279
00280 #define DB_INITENV_CDB 0x0001
00281 #define DB_INITENV_CDB_ALLDB 0x0002
00282 #define DB_INITENV_LOCK 0x0004
00283 #define DB_INITENV_LOG 0x0008
00284 #define DB_INITENV_MPOOL 0x0010
00285 #define DB_INITENV_REP 0x0020
00286 #define DB_INITENV_TXN 0x0040
00287
00288
00289
00290
00291
00292
00293
00294 init_flags = 0;
00295 if (LF_ISSET(DB_INIT_CDB))
00296 FLD_SET(init_flags, DB_INITENV_CDB);
00297 if (LF_ISSET(DB_INIT_LOCK))
00298 FLD_SET(init_flags, DB_INITENV_LOCK);
00299 if (LF_ISSET(DB_INIT_LOG))
00300 FLD_SET(init_flags, DB_INITENV_LOG);
00301 if (LF_ISSET(DB_INIT_MPOOL))
00302 FLD_SET(init_flags, DB_INITENV_MPOOL);
00303 if (LF_ISSET(DB_INIT_REP))
00304 FLD_SET(init_flags, DB_INITENV_REP);
00305 if (LF_ISSET(DB_INIT_TXN))
00306 FLD_SET(init_flags, DB_INITENV_TXN);
00307 if (F_ISSET(dbenv, DB_ENV_CDB_ALLDB))
00308 FLD_SET(init_flags, DB_INITENV_CDB_ALLDB);
00309 if ((ret = __db_e_attach(dbenv, &init_flags)) != 0)
00310 goto err;
00311
00312
00313
00314
00315
00316
00317
00318
00319 if (FLD_ISSET(init_flags, DB_INITENV_CDB))
00320 LF_SET(DB_INIT_CDB);
00321 if (FLD_ISSET(init_flags, DB_INITENV_LOCK))
00322 LF_SET(DB_INIT_LOCK);
00323 if (FLD_ISSET(init_flags, DB_INITENV_LOG))
00324 LF_SET(DB_INIT_LOG);
00325 if (FLD_ISSET(init_flags, DB_INITENV_MPOOL))
00326 LF_SET(DB_INIT_MPOOL);
00327 if (FLD_ISSET(init_flags, DB_INITENV_REP))
00328 LF_SET(DB_INIT_REP);
00329 if (FLD_ISSET(init_flags, DB_INITENV_TXN))
00330 LF_SET(DB_INIT_TXN);
00331 if (FLD_ISSET(init_flags, DB_INITENV_CDB_ALLDB) &&
00332 (ret = __env_set_flags(dbenv, DB_CDB_ALLDB, 1)) != 0)
00333 goto err;
00334
00335
00336
00337
00338
00339
00340 dbenv->open_flags = flags;
00341
00342
00343 if (LF_ISSET(DB_INIT_CDB)) {
00344 LF_SET(DB_INIT_LOCK);
00345 F_SET(dbenv, DB_ENV_CDB);
00346 }
00347
00348
00349
00350
00351
00352
00353 F_SET(dbenv, DB_ENV_OPEN_CALLED);
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 if ((ret = __mutex_open(dbenv)) != 0)
00364 goto err;
00365
00366
00367 ENV_ENTER(dbenv, ip);
00368
00369
00370
00371
00372
00373 if (LF_ISSET(DB_INIT_REP) && (ret = __rep_open(dbenv)) != 0)
00374 goto err;
00375
00376 rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0;
00377 if (rep_check && (ret = __env_rep_enter(dbenv, 0)) != 0)
00378 goto err;
00379
00380 if (LF_ISSET(DB_INIT_MPOOL))
00381 if ((ret = __memp_open(dbenv)) != 0)
00382 goto err;
00383
00384
00385
00386
00387
00388
00389
00390
00391 if (LF_ISSET(DB_INIT_MPOOL | DB_INIT_LOG | DB_INIT_TXN) &&
00392 (ret = __crypto_region_init(dbenv)) != 0)
00393 goto err;
00394
00395
00396
00397
00398
00399
00400
00401 if (LF_ISSET(DB_INIT_LOG | DB_INIT_TXN))
00402 if ((ret = __log_open(dbenv)) != 0)
00403 goto err;
00404 if (LF_ISSET(DB_INIT_LOCK))
00405 if ((ret = __lock_open(dbenv)) != 0)
00406 goto err;
00407
00408 if (LF_ISSET(DB_INIT_TXN)) {
00409 if ((ret = __txn_open(dbenv)) != 0)
00410 goto err;
00411
00412
00413
00414
00415
00416 if ((ret = __bam_init_recover(dbenv, &dbenv->recover_dtab,
00417 &dbenv->recover_dtab_size)) != 0)
00418 goto err;
00419 if ((ret = __crdel_init_recover(dbenv, &dbenv->recover_dtab,
00420 &dbenv->recover_dtab_size)) != 0)
00421 goto err;
00422 if ((ret = __db_init_recover(dbenv, &dbenv->recover_dtab,
00423 &dbenv->recover_dtab_size)) != 0)
00424 goto err;
00425 if ((ret = __dbreg_init_recover(dbenv, &dbenv->recover_dtab,
00426 &dbenv->recover_dtab_size)) != 0)
00427 goto err;
00428 if ((ret = __fop_init_recover(dbenv, &dbenv->recover_dtab,
00429 &dbenv->recover_dtab_size)) != 0)
00430 goto err;
00431 if ((ret = __ham_init_recover(dbenv, &dbenv->recover_dtab,
00432 &dbenv->recover_dtab_size)) != 0)
00433 goto err;
00434 if ((ret = __qam_init_recover(dbenv, &dbenv->recover_dtab,
00435 &dbenv->recover_dtab_size)) != 0)
00436 goto err;
00437 if ((ret = __txn_init_recover(dbenv, &dbenv->recover_dtab,
00438 &dbenv->recover_dtab_size)) != 0)
00439 goto err;
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 LIST_INIT(&dbenv->dblist);
00458 if (LF_ISSET(DB_INIT_MPOOL)) {
00459 if ((ret = __mutex_alloc(dbenv, MTX_ENV_DBLIST,
00460 DB_MUTEX_THREAD, &dbenv->mtx_dblist)) != 0)
00461 goto err;
00462 if ((ret = __mutex_alloc(dbenv,
00463 MTX_TWISTER, DB_MUTEX_THREAD, &dbenv->mtx_mt)) != 0)
00464 goto err;
00465
00466
00467 if ((ret = __memp_register(
00468 dbenv, DB_FTYPE_SET, __db_pgin, __db_pgout)) != 0)
00469 goto err;
00470 }
00471
00472
00473 if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) &&
00474 (ret = __db_apprec(dbenv, NULL, NULL, 1,
00475 LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL))) != 0)
00476 goto err;
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 infop = dbenv->reginfo;
00489 if (TXN_ON(dbenv) &&
00490 !F_ISSET(dbenv, DB_ENV_LOG_INMEMORY) &&
00491 F_ISSET(infop, REGION_CREATE) &&
00492 !LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) &&
00493 (ret = __txn_reset(dbenv)) != 0)
00494 goto err;
00495
00496
00497 if ((ret = __db_e_golive(dbenv)) != 0)
00498 goto err;
00499
00500 if (rep_check && (ret = __env_db_rep_exit(dbenv)) != 0)
00501 goto err;
00502
00503 ENV_LEAVE(dbenv, ip);
00504 return (0);
00505
00506 err:
00507
00508
00509
00510
00511
00512
00513 infop = dbenv->reginfo;
00514 if (infop != NULL && F_ISSET(infop, REGION_CREATE)) {
00515 ret = __db_panic(dbenv, ret);
00516
00517
00518 (void)__env_refresh(dbenv, orig_flags, rep_check);
00519 (void)__env_remove_int(dbenv, db_home, DB_FORCE);
00520 (void)__env_refresh(dbenv, orig_flags, 0);
00521 } else
00522 (void)__env_refresh(dbenv, orig_flags, rep_check);
00523
00524 if (ip != NULL)
00525 ENV_LEAVE(dbenv, ip);
00526 return (ret);
00527 }
00528
00529
00530
00531
00532
00533
00534
00535 int
00536 __env_remove(dbenv, db_home, flags)
00537 DB_ENV *dbenv;
00538 const char *db_home;
00539 u_int32_t flags;
00540 {
00541 int ret, t_ret;
00542
00543 #undef OKFLAGS
00544 #define OKFLAGS \
00545 (DB_FORCE | DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)
00546
00547
00548 if ((ret = __db_fchk(dbenv, "DB_ENV->remove", flags, OKFLAGS)) != 0)
00549 return (ret);
00550
00551 ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->remove");
00552
00553 ret = __env_remove_int(dbenv, db_home, flags);
00554
00555 if ((t_ret = __env_close(dbenv, 0)) != 0 && ret == 0)
00556 ret = t_ret;
00557
00558 return (ret);
00559 }
00560
00561
00562
00563
00564
00565 static int
00566 __env_remove_int(dbenv, db_home, flags)
00567 DB_ENV *dbenv;
00568 const char *db_home;
00569 u_int32_t flags;
00570 {
00571 int ret;
00572
00573
00574 if ((ret = __env_config(dbenv, db_home, flags)) != 0)
00575 return (ret);
00576
00577
00578 F_SET(dbenv, DB_ENV_OPEN_CALLED);
00579
00580
00581 return (__db_e_remove(dbenv, flags));
00582 }
00583
00584
00585
00586
00587
00588 static int
00589 __env_config(dbenv, db_home, flags)
00590 DB_ENV *dbenv;
00591 const char *db_home;
00592 u_int32_t flags;
00593 {
00594 FILE *fp;
00595 int ret;
00596 char *p, buf[256];
00597
00598
00599
00600
00601
00602 if ((ret = __db_home(dbenv, db_home, flags)) != 0)
00603 return (ret);
00604
00605
00606 p = NULL;
00607 if ((ret =
00608 __db_appname(dbenv, DB_APP_NONE, "DB_CONFIG", 0, NULL, &p)) != 0)
00609 return (ret);
00610 if (p == NULL)
00611 fp = NULL;
00612 else {
00613 fp = fopen(p, "r");
00614 __os_free(dbenv, p);
00615 }
00616
00617 if (fp != NULL) {
00618 while (fgets(buf, sizeof(buf), fp) != NULL) {
00619 if ((p = strchr(buf, '\n')) != NULL)
00620 *p = '\0';
00621 else if (strlen(buf) + 1 == sizeof(buf)) {
00622 __db_err(dbenv, "DB_CONFIG: line too long");
00623 (void)fclose(fp);
00624 return (EINVAL);
00625 }
00626 if (buf[0] == '\0' ||
00627 buf[0] == '#' || isspace((int)buf[0]))
00628 continue;
00629
00630 if ((ret = __db_parse(dbenv, buf)) != 0) {
00631 (void)fclose(fp);
00632 return (ret);
00633 }
00634 }
00635 (void)fclose(fp);
00636 }
00637
00638
00639
00640
00641
00642 if (dbenv->db_tmp_dir == NULL && (ret = __os_tmpdir(dbenv, flags)) != 0)
00643 return (ret);
00644
00645 return (0);
00646 }
00647
00648
00649
00650
00651
00652
00653
00654 int
00655 __env_close_pp(dbenv, flags)
00656 DB_ENV *dbenv;
00657 u_int32_t flags;
00658 {
00659 DB_THREAD_INFO *ip;
00660 int rep_check, ret, t_ret;
00661
00662 ret = 0;
00663
00664 PANIC_CHECK(dbenv);
00665
00666 ENV_ENTER(dbenv, ip);
00667
00668
00669
00670
00671 if (flags != 0 &&
00672 (t_ret = __db_ferr(dbenv, "DB_ENV->close", 0)) != 0 && ret == 0)
00673 ret = t_ret;
00674
00675 rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0;
00676 if (rep_check && (t_ret = __env_rep_enter(dbenv, 0)) != 0 && ret == 0)
00677 ret = t_ret;
00678
00679 if ((t_ret = __env_close(dbenv, rep_check)) != 0 && ret == 0)
00680 ret = t_ret;
00681
00682
00683 return (ret);
00684 }
00685
00686
00687
00688
00689
00690
00691
00692 int
00693 __env_close(dbenv, rep_check)
00694 DB_ENV *dbenv;
00695 int rep_check;
00696 {
00697 int ret, t_ret;
00698 char **p;
00699
00700 ret = 0;
00701
00702
00703
00704
00705
00706
00707 if (TXN_ON(dbenv) && (t_ret = __txn_preclose(dbenv)) != 0 && ret == 0)
00708 ret = t_ret;
00709
00710 if (REP_ON(dbenv) &&
00711 (t_ret = __rep_preclose(dbenv)) != 0 && ret == 0)
00712 ret = t_ret;
00713
00714
00715
00716
00717
00718 if ((t_ret = __env_refresh(dbenv, 0, rep_check)) != 0 && ret == 0)
00719 ret = t_ret;
00720
00721
00722 if ((t_ret = __lock_dbenv_close(dbenv)) != 0 && ret == 0)
00723 ret = t_ret;
00724
00725 if ((t_ret = __rep_dbenv_close(dbenv)) != 0 && ret == 0)
00726 ret = t_ret;
00727
00728 #ifdef HAVE_CRYPTO
00729
00730
00731
00732
00733 if ((t_ret = __crypto_dbenv_close(dbenv)) != 0 && ret == 0)
00734 ret = t_ret;
00735 #endif
00736
00737
00738 if (dbenv->db_log_dir != NULL)
00739 __os_free(dbenv, dbenv->db_log_dir);
00740 if (dbenv->db_tmp_dir != NULL)
00741 __os_free(dbenv, dbenv->db_tmp_dir);
00742 if (dbenv->db_data_dir != NULL) {
00743 for (p = dbenv->db_data_dir; *p != NULL; ++p)
00744 __os_free(dbenv, *p);
00745 __os_free(dbenv, dbenv->db_data_dir);
00746 }
00747
00748
00749 if (dbenv->registry != NULL) {
00750 (void)__envreg_unregister(dbenv, 0);
00751 dbenv->registry = NULL;
00752 }
00753
00754
00755 memset(dbenv, CLEAR_BYTE, sizeof(DB_ENV));
00756 __os_free(NULL, dbenv);
00757
00758 return (ret);
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
00768 static int
00769 __env_refresh(dbenv, orig_flags, rep_check)
00770 DB_ENV *dbenv;
00771 u_int32_t orig_flags;
00772 int rep_check;
00773 {
00774 DB *ldbp;
00775 DB_THREAD_INFO *ip;
00776 int ret, t_ret;
00777
00778 ret = 0;
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790 if (TXN_ON(dbenv) &&
00791 (t_ret = __txn_dbenv_refresh(dbenv)) != 0 && ret == 0)
00792 ret = t_ret;
00793
00794 if (LOGGING_ON(dbenv) &&
00795 (t_ret = __log_dbenv_refresh(dbenv)) != 0 && ret == 0)
00796 ret = t_ret;
00797
00798
00799
00800
00801
00802 if (LOCKING_ON(dbenv)) {
00803 if (!F_ISSET(dbenv, DB_ENV_THREAD) &&
00804 dbenv->env_lref != NULL && (t_ret = __lock_id_free(dbenv,
00805 ((DB_LOCKER *)dbenv->env_lref)->id)) != 0 && ret == 0)
00806 ret = t_ret;
00807 dbenv->env_lref = NULL;
00808
00809 if ((t_ret = __lock_dbenv_refresh(dbenv)) != 0 && ret == 0)
00810 ret = t_ret;
00811 }
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 if (dbenv->db_ref != 0) {
00825 __db_err(dbenv,
00826 "Database handles still open at environment close");
00827 for (ldbp = LIST_FIRST(&dbenv->dblist);
00828 ldbp != NULL; ldbp = LIST_NEXT(ldbp, dblistlinks))
00829 __db_err(dbenv, "Open database handle: %s%s%s",
00830 ldbp->fname == NULL ? "unnamed" : ldbp->fname,
00831 ldbp->dname == NULL ? "" : "/",
00832 ldbp->dname == NULL ? "" : ldbp->dname);
00833 if (ret == 0)
00834 ret = EINVAL;
00835 }
00836 LIST_INIT(&dbenv->dblist);
00837
00838 if ((t_ret = __mutex_free(dbenv, &dbenv->mtx_dblist)) != 0 && ret == 0)
00839 ret = t_ret;
00840 if ((t_ret = __mutex_free(dbenv, &dbenv->mtx_mt)) != 0 && ret == 0)
00841 ret = t_ret;
00842
00843 if (dbenv->mt != NULL) {
00844 __os_free(dbenv, dbenv->mt);
00845 dbenv->mt = NULL;
00846 }
00847
00848 if (MPOOL_ON(dbenv)) {
00849
00850
00851
00852
00853
00854 if (F_ISSET(dbenv, DB_ENV_PRIVATE) &&
00855 (t_ret = __memp_sync(dbenv, NULL)) != 0 && ret == 0)
00856 ret = t_ret;
00857 if ((t_ret = __memp_dbenv_refresh(dbenv)) != 0 && ret == 0)
00858 ret = t_ret;
00859 }
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872 if (rep_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
00873 ret = t_ret;
00874
00875
00876
00877
00878
00879
00880 __rep_dbenv_refresh(dbenv);
00881
00882
00883
00884
00885
00886 if (dbenv->thr_hashtab != NULL &&
00887 (t_ret = __env_set_state(dbenv, &ip, THREAD_OUT)) != 0 && ret == 0)
00888 ret = t_ret;
00889
00890 if (MUTEX_ON(dbenv) &&
00891 (t_ret = __mutex_dbenv_refresh(dbenv)) != 0 && ret == 0)
00892 ret = t_ret;
00893
00894 if (dbenv->reginfo != NULL) {
00895 if ((t_ret = __db_e_detach(dbenv, 0)) != 0 && ret == 0)
00896 ret = t_ret;
00897
00898
00899
00900
00901
00902 }
00903
00904
00905 if (dbenv->db_home != NULL) {
00906 __os_free(dbenv, dbenv->db_home);
00907 dbenv->db_home = NULL;
00908 }
00909 if (dbenv->db_abshome != NULL) {
00910 __os_free(dbenv, dbenv->db_abshome);
00911 dbenv->db_abshome = NULL;
00912 }
00913 if (dbenv->mutex_iq != NULL) {
00914 __os_free(dbenv, dbenv->mutex_iq);
00915 dbenv->mutex_iq = NULL;
00916 }
00917
00918 dbenv->open_flags = 0;
00919 dbenv->db_mode = 0;
00920
00921 if (dbenv->recover_dtab != NULL) {
00922 __os_free(dbenv, dbenv->recover_dtab);
00923 dbenv->recover_dtab = NULL;
00924 dbenv->recover_dtab_size = 0;
00925 }
00926
00927 dbenv->flags = orig_flags;
00928
00929 return (ret);
00930 }
00931
00932 #define DB_ADDSTR(add) { \
00933
00934
00935
00936 \
00937 if ((add) != NULL && (add)[0] != '\0') { \
00938 \
00939 if (__os_abspath(add)) { \
00940 p = str; \
00941 slash = 0; \
00942 } \
00943 \
00944 len = strlen(add); \
00945 if (slash) \
00946 *p++ = PATH_SEPARATOR[0]; \
00947 memcpy(p, add, len); \
00948 p += len; \
00949 slash = strchr(PATH_SEPARATOR, p[-1]) == NULL; \
00950 } \
00951 }
00952
00953
00954
00955
00956
00957
00958
00959 int
00960 __env_get_open_flags(dbenv, flagsp)
00961 DB_ENV *dbenv;
00962 u_int32_t *flagsp;
00963 {
00964 ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->get_open_flags");
00965
00966 *flagsp = dbenv->open_flags;
00967 return (0);
00968 }
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979 int
00980 __db_appname(dbenv, appname, file, tmp_oflags, fhpp, namep)
00981 DB_ENV *dbenv;
00982 APPNAME appname;
00983 const char *file;
00984 u_int32_t tmp_oflags;
00985 DB_FH **fhpp;
00986 char **namep;
00987 {
00988 size_t len, str_len;
00989 int data_entry, ret, slash, tmp_create;
00990 const char *a, *b;
00991 char *p, *str;
00992
00993 a = b = NULL;
00994 data_entry = -1;
00995 tmp_create = 0;
00996
00997
00998
00999
01000
01001 if (fhpp != NULL)
01002 *fhpp = NULL;
01003 if (namep != NULL)
01004 *namep = NULL;
01005
01006
01007
01008
01009
01010 if (file != NULL && __os_abspath(file))
01011 return (__os_strdup(dbenv, file, namep));
01012
01013
01014 if (dbenv != NULL)
01015 a = dbenv->db_home;
01016
01017 retry:
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027 switch (appname) {
01028 case DB_APP_NONE:
01029 break;
01030 case DB_APP_DATA:
01031 if (dbenv != NULL && dbenv->db_data_dir != NULL &&
01032 (b = dbenv->db_data_dir[++data_entry]) == NULL) {
01033 data_entry = -1;
01034 b = dbenv->db_data_dir[0];
01035 }
01036 break;
01037 case DB_APP_LOG:
01038 if (dbenv != NULL)
01039 b = dbenv->db_log_dir;
01040 break;
01041 case DB_APP_TMP:
01042 if (dbenv != NULL)
01043 b = dbenv->db_tmp_dir;
01044 tmp_create = 1;
01045 break;
01046 }
01047
01048 len =
01049 (a == NULL ? 0 : strlen(a) + 1) +
01050 (b == NULL ? 0 : strlen(b) + 1) +
01051 (file == NULL ? 0 : strlen(file) + 1);
01052
01053
01054
01055
01056
01057
01058 #define DB_TRAIL "BDBXXXXX"
01059 str_len = len + sizeof(DB_TRAIL) + 10;
01060 if ((ret = __os_malloc(dbenv, str_len, &str)) != 0)
01061 return (ret);
01062
01063 slash = 0;
01064 p = str;
01065 DB_ADDSTR(a);
01066 DB_ADDSTR(b);
01067 DB_ADDSTR(file);
01068 *p = '\0';
01069
01070
01071
01072
01073
01074 if (__os_exists(str, NULL) != 0 && data_entry != -1) {
01075 __os_free(dbenv, str);
01076 b = NULL;
01077 goto retry;
01078 }
01079
01080
01081 if (tmp_create &&
01082 (ret = __db_tmp_open(dbenv, tmp_oflags, str, fhpp)) != 0) {
01083 __os_free(dbenv, str);
01084 return (ret);
01085 }
01086
01087 if (namep == NULL)
01088 __os_free(dbenv, str);
01089 else
01090 *namep = str;
01091 return (0);
01092 }
01093
01094
01095
01096
01097
01098
01099
01100 int
01101 __db_home(dbenv, db_home, flags)
01102 DB_ENV *dbenv;
01103 const char *db_home;
01104 u_int32_t flags;
01105 {
01106 int ret;
01107 const char *p;
01108 char path[MAXPATHLEN];
01109
01110
01111
01112
01113
01114
01115
01116 if ((p = db_home) == NULL &&
01117 (LF_ISSET(DB_USE_ENVIRON) ||
01118 (LF_ISSET(DB_USE_ENVIRON_ROOT) && __os_isroot())) &&
01119 (p = getenv("DB_HOME")) != NULL && p[0] == '\0') {
01120 __db_err(dbenv, "illegal DB_HOME environment variable");
01121 return (EINVAL);
01122 }
01123 if (p != NULL && (ret = __os_strdup(dbenv, p, &dbenv->db_home)) != 0)
01124 return (ret);
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136 __os_set_errno(0);
01137 if ((p = getcwd(path, sizeof(path))) == NULL) {
01138 if ((ret = __os_get_errno()) == 0) {
01139 __db_err(dbenv,
01140 "no absolute path for the current directory");
01141 ret = EAGAIN;
01142 } else
01143 __db_err(dbenv,
01144 "no absolute path for the current directory: %s",
01145 db_strerror(ret));
01146 return (ret);
01147 }
01148 if (p != NULL && (ret = __os_strdup(dbenv, p, &dbenv->db_abshome)) != 0)
01149 return (ret);
01150
01151 return (0);
01152 }
01153
01154 #define __DB_OVFL(v, max) \
01155 if (v > max) { \
01156 __v = v; \
01157 __max = max; \
01158 goto toobig; \
01159 }
01160
01161
01162
01163
01164
01165 static int
01166 __db_parse(dbenv, s)
01167 DB_ENV *dbenv;
01168 char *s;
01169 {
01170 u_long __max, __v, v1, v2, v3;
01171 u_int32_t flags;
01172 char *name, *p, *value, v4;
01173
01174
01175
01176
01177
01178
01179
01180
01181 char arg[40 + 5];
01182
01183
01184
01185
01186
01187
01188
01189
01190 name = s;
01191 for (p = name; *p != '\0' && !isspace((int)*p); ++p)
01192 ;
01193 if (*p == '\0' || p == name)
01194 goto illegal;
01195 *p = '\0';
01196 for (++p; isspace((int)*p); ++p)
01197 ;
01198 if (*p == '\0')
01199 goto illegal;
01200 value = p;
01201 for (++p; *p != '\0'; ++p)
01202 ;
01203 for (--p; isspace((int)*p); --p)
01204 ;
01205 ++p;
01206 if (p == value) {
01207 illegal: __db_err(dbenv, "mis-formatted name-value pair: %s", s);
01208 return (EINVAL);
01209 }
01210 *p = '\0';
01211
01212 if (strcasecmp(name, "mutex_set_align") == 0) {
01213 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01214 goto badarg;
01215 __DB_OVFL(v1, UINT32_MAX);
01216 return (__mutex_set_align(dbenv, (u_int32_t)v1));
01217 }
01218
01219 if (strcasecmp(name, "mutex_set_increment") == 0) {
01220 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01221 goto badarg;
01222 __DB_OVFL(v1, UINT32_MAX);
01223 return (__mutex_set_increment(dbenv, (u_int32_t)v1));
01224 }
01225
01226 if (strcasecmp(name, "mutex_set_max") == 0) {
01227 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01228 goto badarg;
01229 __DB_OVFL(v1, UINT32_MAX);
01230 return (__mutex_set_max(dbenv, (u_int32_t)v1));
01231 }
01232
01233 if (strcasecmp(name, "mutex_set_tas_spins") == 0) {
01234 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01235 goto badarg;
01236 __DB_OVFL(v1, UINT32_MAX);
01237 return (__mutex_set_tas_spins(dbenv, (u_int32_t)v1));
01238 }
01239
01240 if (strcasecmp(name, "rep_set_config") == 0) {
01241 if (sscanf(value, "%40s %c", arg, &v4) != 1)
01242 goto badarg;
01243
01244 if (strcasecmp(value, "rep_bulk") == 0)
01245 return (__rep_set_config(dbenv,
01246 DB_REP_CONF_BULK, 1));
01247 if (strcasecmp(value, "rep_delayclient") == 0)
01248 return (__rep_set_config(dbenv,
01249 DB_REP_CONF_DELAYCLIENT, 1));
01250 if (strcasecmp(value, "rep_noautoinit") == 0)
01251 return (__rep_set_config(dbenv,
01252 DB_REP_CONF_NOAUTOINIT, 1));
01253 if (strcasecmp(value, "rep_nowait") == 0)
01254 return (__rep_set_config(dbenv, DB_REP_CONF_NOWAIT, 1));
01255 goto badarg;
01256 }
01257
01258 if (strcasecmp(name, "set_cachesize") == 0) {
01259 if (sscanf(value, "%lu %lu %lu %c", &v1, &v2, &v3, &v4) != 3)
01260 goto badarg;
01261 __DB_OVFL(v1, UINT32_MAX);
01262 __DB_OVFL(v2, UINT32_MAX);
01263 __DB_OVFL(v3, 10000);
01264 return (__memp_set_cachesize(
01265 dbenv, (u_int32_t)v1, (u_int32_t)v2, (int)v3));
01266 }
01267
01268 if (strcasecmp(name, "set_data_dir") == 0 ||
01269 strcasecmp(name, "db_data_dir") == 0)
01270 return (__env_set_data_dir(dbenv, value));
01271
01272
01273 if (strcasecmp(name, "set_intermediate_dir") == 0) {
01274 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01275 goto badarg;
01276 #ifdef INT_MAX
01277 __DB_OVFL(v1, INT_MAX);
01278 #endif
01279 return (__env_set_intermediate_dir(dbenv, (int)v1, 0));
01280 }
01281
01282 if (strcasecmp(name, "set_flags") == 0) {
01283 if (sscanf(value, "%40s %c", arg, &v4) != 1)
01284 goto badarg;
01285
01286 if (strcasecmp(value, "db_auto_commit") == 0)
01287 return (__env_set_flags(dbenv, DB_AUTO_COMMIT, 1));
01288 if (strcasecmp(value, "db_cdb_alldb") == 0)
01289 return (__env_set_flags(dbenv, DB_CDB_ALLDB, 1));
01290 if (strcasecmp(value, "db_direct_db") == 0)
01291 return (__env_set_flags(dbenv, DB_DIRECT_DB, 1));
01292 if (strcasecmp(value, "db_direct_log") == 0)
01293 return (__env_set_flags(dbenv, DB_DIRECT_LOG, 1));
01294 if (strcasecmp(value, "db_dsync_db") == 0)
01295 return (__env_set_flags(dbenv, DB_DSYNC_DB, 1));
01296 if (strcasecmp(value, "db_dsync_log") == 0)
01297 return (__env_set_flags(dbenv, DB_DSYNC_LOG, 1));
01298 if (strcasecmp(value, "db_log_autoremove") == 0)
01299 return (__env_set_flags(dbenv, DB_LOG_AUTOREMOVE, 1));
01300 if (strcasecmp(value, "db_log_inmemory") == 0)
01301 return (__env_set_flags(dbenv, DB_LOG_INMEMORY, 1));
01302 if (strcasecmp(value, "db_nolocking") == 0)
01303 return (__env_set_flags(dbenv, DB_NOLOCKING, 1));
01304 if (strcasecmp(value, "db_nommap") == 0)
01305 return (__env_set_flags(dbenv, DB_NOMMAP, 1));
01306 if (strcasecmp(value, "db_nopanic") == 0)
01307 return (__env_set_flags(dbenv, DB_NOPANIC, 1));
01308 if (strcasecmp(value, "db_overwrite") == 0)
01309 return (__env_set_flags(dbenv, DB_OVERWRITE, 1));
01310 if (strcasecmp(value, "db_region_init") == 0)
01311 return (__env_set_flags(dbenv, DB_REGION_INIT, 1));
01312 if (strcasecmp(value, "db_txn_nosync") == 0)
01313 return (__env_set_flags(dbenv, DB_TXN_NOSYNC, 1));
01314 if (strcasecmp(value, "db_txn_write_nosync") == 0)
01315 return (
01316 __env_set_flags(dbenv, DB_TXN_WRITE_NOSYNC, 1));
01317 if (strcasecmp(value, "db_yieldcpu") == 0)
01318 return (__env_set_flags(dbenv, DB_YIELDCPU, 1));
01319 goto badarg;
01320 }
01321
01322 if (strcasecmp(name, "set_lg_bsize") == 0) {
01323 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01324 goto badarg;
01325 __DB_OVFL(v1, UINT32_MAX);
01326 return (__log_set_lg_bsize(dbenv, (u_int32_t)v1));
01327 }
01328
01329 if (strcasecmp(name, "set_lg_filemode") == 0) {
01330 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01331 goto badarg;
01332 __DB_OVFL(v1, INT_MAX);
01333 return (__log_set_lg_filemode(dbenv, (int)v1));
01334 }
01335
01336 if (strcasecmp(name, "set_lg_max") == 0) {
01337 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01338 goto badarg;
01339 __DB_OVFL(v1, UINT32_MAX);
01340 return (__log_set_lg_max(dbenv, (u_int32_t)v1));
01341 }
01342
01343 if (strcasecmp(name, "set_lg_regionmax") == 0) {
01344 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01345 goto badarg;
01346 __DB_OVFL(v1, UINT32_MAX);
01347 return (__log_set_lg_regionmax(dbenv, (u_int32_t)v1));
01348 }
01349
01350 if (strcasecmp(name, "set_lg_dir") == 0 ||
01351 strcasecmp(name, "db_log_dir") == 0)
01352 return (__log_set_lg_dir(dbenv, value));
01353
01354 if (strcasecmp(name, "set_lk_detect") == 0) {
01355 if (sscanf(value, "%40s %c", arg, &v4) != 1)
01356 goto badarg;
01357 if (strcasecmp(value, "db_lock_default") == 0)
01358 flags = DB_LOCK_DEFAULT;
01359 else if (strcasecmp(value, "db_lock_expire") == 0)
01360 flags = DB_LOCK_EXPIRE;
01361 else if (strcasecmp(value, "db_lock_maxlocks") == 0)
01362 flags = DB_LOCK_MAXLOCKS;
01363 else if (strcasecmp(value, "db_lock_maxwrite") == 0)
01364 flags = DB_LOCK_MAXWRITE;
01365 else if (strcasecmp(value, "db_lock_minlocks") == 0)
01366 flags = DB_LOCK_MINLOCKS;
01367 else if (strcasecmp(value, "db_lock_minwrite") == 0)
01368 flags = DB_LOCK_MINWRITE;
01369 else if (strcasecmp(value, "db_lock_oldest") == 0)
01370 flags = DB_LOCK_OLDEST;
01371 else if (strcasecmp(value, "db_lock_random") == 0)
01372 flags = DB_LOCK_RANDOM;
01373 else if (strcasecmp(value, "db_lock_youngest") == 0)
01374 flags = DB_LOCK_YOUNGEST;
01375 else
01376 goto badarg;
01377 return (__lock_set_lk_detect(dbenv, flags));
01378 }
01379
01380 if (strcasecmp(name, "set_lk_max") == 0) {
01381 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01382 goto badarg;
01383 __DB_OVFL(v1, UINT32_MAX);
01384 return (__lock_set_lk_max(dbenv, (u_int32_t)v1));
01385 }
01386
01387 if (strcasecmp(name, "set_lk_max_locks") == 0) {
01388 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01389 goto badarg;
01390 __DB_OVFL(v1, UINT32_MAX);
01391 return (__lock_set_lk_max_locks(dbenv, (u_int32_t)v1));
01392 }
01393
01394 if (strcasecmp(name, "set_lk_max_lockers") == 0) {
01395 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01396 goto badarg;
01397 __DB_OVFL(v1, UINT32_MAX);
01398 return (__lock_set_lk_max_lockers(dbenv, (u_int32_t)v1));
01399 }
01400
01401 if (strcasecmp(name, "set_lk_max_objects") == 0) {
01402 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01403 goto badarg;
01404 __DB_OVFL(v1, UINT32_MAX);
01405 return (__lock_set_lk_max_objects(dbenv, (u_int32_t)v1));
01406 }
01407
01408 if (strcasecmp(name, "set_lock_timeout") == 0) {
01409 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01410 goto badarg;
01411 __DB_OVFL(v1, UINT32_MAX);
01412 return (__lock_set_env_timeout(
01413 dbenv, (u_int32_t)v1, DB_SET_LOCK_TIMEOUT));
01414 }
01415
01416 if (strcasecmp(name, "set_mp_max_openfd") == 0) {
01417 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01418 goto badarg;
01419 __DB_OVFL(v1, INT_MAX);
01420 return (__memp_set_mp_max_openfd(dbenv, (int)v1));
01421 }
01422
01423 if (strcasecmp(name, "set_mp_max_write") == 0) {
01424 if (sscanf(value, "%lu %lu %c", &v1, &v2, &v4) != 2)
01425 goto badarg;
01426 __DB_OVFL(v1, INT_MAX);
01427 __DB_OVFL(v2, INT_MAX);
01428 return (__memp_set_mp_max_write(dbenv, (int)v1, (int)v2));
01429 }
01430
01431 if (strcasecmp(name, "set_mp_mmapsize") == 0) {
01432 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01433 goto badarg;
01434 __DB_OVFL(v1, UINT32_MAX);
01435 return (__memp_set_mp_mmapsize(dbenv, (u_int32_t)v1));
01436 }
01437
01438 if (strcasecmp(name, "set_region_init") == 0) {
01439 if (sscanf(value, "%lu %c", &v1, &v4) != 1 || v1 != 1)
01440 goto badarg;
01441 return (__env_set_flags(
01442 dbenv, DB_REGION_INIT, v1 == 0 ? 0 : 1));
01443 }
01444
01445 if (strcasecmp(name, "set_shm_key") == 0) {
01446 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01447 goto badarg;
01448 return (__env_set_shm_key(dbenv, (long)v1));
01449 }
01450
01451
01452
01453
01454
01455 if (strcasecmp(name, "set_tas_spins") == 0) {
01456 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01457 goto badarg;
01458 __DB_OVFL(v1, UINT32_MAX);
01459 return (__mutex_set_tas_spins(dbenv, (u_int32_t)v1));
01460 }
01461
01462 if (strcasecmp(name, "set_tmp_dir") == 0 ||
01463 strcasecmp(name, "db_tmp_dir") == 0)
01464 return (__env_set_tmp_dir(dbenv, value));
01465
01466 if (strcasecmp(name, "set_tx_max") == 0) {
01467 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01468 goto badarg;
01469 __DB_OVFL(v1, UINT32_MAX);
01470 return (__txn_set_tx_max(dbenv, (u_int32_t)v1));
01471 }
01472
01473 if (strcasecmp(name, "set_txn_timeout") == 0) {
01474 if (sscanf(value, "%lu %c", &v1, &v4) != 1)
01475 goto badarg;
01476 __DB_OVFL(v1, UINT32_MAX);
01477 return (__lock_set_env_timeout(
01478 dbenv, (u_int32_t)v1, DB_SET_TXN_TIMEOUT));
01479 }
01480
01481 if (strcasecmp(name, "set_verbose") == 0) {
01482 if (sscanf(value, "%40s %c", arg, &v4) != 1)
01483 goto badarg;
01484
01485 else if (strcasecmp(value, "db_verb_deadlock") == 0)
01486 flags = DB_VERB_DEADLOCK;
01487 else if (strcasecmp(value, "db_verb_recovery") == 0)
01488 flags = DB_VERB_RECOVERY;
01489 else if (strcasecmp(value, "db_verb_register") == 0)
01490 flags = DB_VERB_REGISTER;
01491 else if (strcasecmp(value, "db_verb_replication") == 0)
01492 flags = DB_VERB_REPLICATION;
01493 else if (strcasecmp(value, "db_verb_waitsfor") == 0)
01494 flags = DB_VERB_WAITSFOR;
01495 else
01496 goto badarg;
01497 return (__env_set_verbose(dbenv, flags, 1));
01498 }
01499
01500 __db_err(dbenv, "unrecognized name-value pair: %s", s);
01501 return (EINVAL);
01502
01503 badarg: __db_err(dbenv, "incorrect arguments for name-value pair: %s", s);
01504 return (EINVAL);
01505
01506 toobig: __db_err(dbenv,
01507 "%s: %lu larger than maximum value %lu", s, __v, __max);
01508 return (EINVAL);
01509 }
01510
01511
01512
01513
01514
01515 static int
01516 __db_tmp_open(dbenv, tmp_oflags, path, fhpp)
01517 DB_ENV *dbenv;
01518 u_int32_t tmp_oflags;
01519 char *path;
01520 DB_FH **fhpp;
01521 {
01522 pid_t pid;
01523 db_threadid_t tid;
01524 int filenum, i, isdir, ret;
01525 char *firstx, *trv;
01526
01527
01528
01529
01530
01531 if ((ret = __os_exists(path, &isdir)) != 0) {
01532 __db_err(dbenv, "%s: %s", path, db_strerror(ret));
01533 return (ret);
01534 }
01535 if (!isdir) {
01536 __db_err(dbenv, "%s: %s", path, db_strerror(EINVAL));
01537 return (EINVAL);
01538 }
01539
01540
01541 (void)strncat(path, PATH_SEPARATOR, 1);
01542 (void)strcat(path, DB_TRAIL);
01543
01544
01545 __os_id(dbenv, &pid, &tid);
01546 for (trv = path + strlen(path); *--trv == 'X'; pid /= 10)
01547 *trv = '0' + (u_char)(pid % 10);
01548 firstx = trv + 1;
01549
01550
01551 for (filenum = 1;; filenum++) {
01552 if ((ret = __os_open(dbenv, path,
01553 tmp_oflags | DB_OSO_CREATE | DB_OSO_EXCL | DB_OSO_TEMP,
01554 __db_omode(OWNER_RW), fhpp)) == 0)
01555 return (0);
01556
01557
01558
01559
01560
01561
01562
01563
01564 if (ret != EEXIST) {
01565 __db_err(dbenv,
01566 "tmp_open: %s: %s", path, db_strerror(ret));
01567 return (ret);
01568 }
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585 for (i = filenum, trv = firstx; i > 0; i = (i - 1) / 26)
01586 if (*trv++ == '\0')
01587 return (EINVAL);
01588
01589 for (i = filenum; i > 0; i = (i - 1) / 26)
01590 *--trv = 'a' + ((i - 1) % 26);
01591 }
01592
01593 }