1/* DO NOT EDIT: automatically built by dist/s_brew. */ 2/*- 3 * See the file LICENSE for redistribution information. 4 * 5 * Copyright (c) 1996,2008 Oracle. All rights reserved. 6 * 7 * $Id: db_int.in,v 12.76 2008/05/07 12:34:15 bschmeck Exp $ 8 */ 9 10#ifndef _DB_INT_H_ 11#define _DB_INT_H_ 12 13/******************************************************* 14 * Berkeley DB ANSI/POSIX include files. 15 *******************************************************/ 16#ifdef HAVE_SYSTEM_INCLUDE_FILES 17#include <sys/types.h> 18#ifdef DIAG_MVCC 19#include <sys/mman.h> 20#endif 21#include <sys/stat.h> 22 23#if defined(__INCLUDE_SELECT_H) 24#ifdef HAVE_SYS_SELECT_H 25#include <sys/select.h> 26#endif 27#ifdef HAVE_VXWORKS 28#include <selectLib.h> 29#endif 30#endif 31 32#if TIME_WITH_SYS_TIME 33#include <sys/time.h> 34#include <time.h> 35#else 36#if HAVE_SYS_TIME_H 37#include <sys/time.h> 38#else 39#include <time.h> 40#endif 41#endif 42 43#ifdef HAVE_VXWORKS 44#include <net/uio.h> 45#else 46#include <sys/uio.h> 47#endif 48 49#if defined(__INCLUDE_NETWORKING) 50#ifdef HAVE_SYS_SOCKET_H 51#include <sys/socket.h> 52#endif 53#include <netinet/in.h> 54#include <netdb.h> 55#include <arpa/inet.h> 56#endif 57 58#if defined(STDC_HEADERS) || defined(__cplusplus) 59#include <stdarg.h> 60#else 61#include <varargs.h> 62#endif 63 64#include <ctype.h> 65#include <errno.h> 66#include <fcntl.h> 67#include <limits.h> 68#include <signal.h> 69#include <stddef.h> 70#include <stdio.h> 71#include <stdlib.h> 72#include <string.h> 73#include <unistd.h> 74 75#if defined(__INCLUDE_DIRECTORY) 76#if HAVE_DIRENT_H 77# include <dirent.h> 78# define NAMLEN(dirent) strlen((dirent)->d_name) 79#else 80# define dirent direct 81# define NAMLEN(dirent) (dirent)->d_namlen 82# if HAVE_SYS_NDIR_H 83# include <sys/ndir.h> 84# endif 85# if HAVE_SYS_DIR_H 86# include <sys/dir.h> 87# endif 88# if HAVE_NDIR_H 89# include <ndir.h> 90# endif 91#endif 92#endif /* __INCLUDE_DIRECTORY */ 93 94#endif /* !HAVE_SYSTEM_INCLUDE_FILES */ 95#include "brew_db.h" 96 97#ifdef DB_WIN32 98#include "dbinc/win_db.h" 99#endif 100 101#include "db.h" 102#include "clib_port.h" 103 104#include "dbinc/queue.h" 105#include "dbinc/shqueue.h" 106 107#if defined(__cplusplus) 108extern "C" { 109#endif 110 111/******************************************************* 112 * Forward structure declarations. 113 *******************************************************/ 114struct __db_reginfo_t; typedef struct __db_reginfo_t REGINFO; 115struct __db_txnhead; typedef struct __db_txnhead DB_TXNHEAD; 116struct __db_txnlist; typedef struct __db_txnlist DB_TXNLIST; 117struct __vrfy_childinfo;typedef struct __vrfy_childinfo VRFY_CHILDINFO; 118struct __vrfy_dbinfo; typedef struct __vrfy_dbinfo VRFY_DBINFO; 119struct __vrfy_pageinfo; typedef struct __vrfy_pageinfo VRFY_PAGEINFO; 120 121typedef SH_TAILQ_HEAD(__hash_head) DB_HASHTAB; 122 123/******************************************************* 124 * General purpose constants and macros. 125 *******************************************************/ 126#undef FALSE 127#define FALSE 0 128#undef TRUE 129#define TRUE (!FALSE) 130 131#define MEGABYTE 1048576 132#define GIGABYTE 1073741824 133 134#define NS_PER_MS 1000000 /* Nanoseconds in a millisecond */ 135#define NS_PER_US 1000 /* Nanoseconds in a microsecond */ 136#define NS_PER_SEC 1000000000 /* Nanoseconds in a second */ 137#define US_PER_MS 1000 /* Microseconds in a millisecond */ 138#define US_PER_SEC 1000000 /* Microseconds in a second */ 139#define MS_PER_SEC 1000 /* Milliseconds in a second */ 140 141#define RECNO_OOB 0 /* Illegal record number. */ 142 143/* Test for a power-of-two (tests true for zero, which doesn't matter here). */ 144#define POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0) 145 146/* Test for valid page sizes. */ 147#define DB_MIN_PGSIZE 0x000200 /* Minimum page size (512). */ 148#define DB_MAX_PGSIZE 0x010000 /* Maximum page size (65536). */ 149#define IS_VALID_PAGESIZE(x) \ 150 (POWER_OF_TWO(x) && (x) >= DB_MIN_PGSIZE && ((x) <= DB_MAX_PGSIZE)) 151 152/* Minimum number of pages cached, by default. */ 153#define DB_MINPAGECACHE 16 154 155/* 156 * If we are unable to determine the underlying filesystem block size, use 157 * 8K on the grounds that most OS's use less than 8K for a VM page size. 158 */ 159#define DB_DEF_IOSIZE (8 * 1024) 160 161/* Align an integer to a specific boundary. */ 162#undef DB_ALIGN 163#define DB_ALIGN(v, bound) \ 164 (((v) + (bound) - 1) & ~(((uintmax_t)(bound)) - 1)) 165 166/* Increment a pointer to a specific boundary. */ 167#undef ALIGNP_INC 168#define ALIGNP_INC(p, bound) \ 169 (void *)(((uintptr_t)(p) + (bound) - 1) & ~(((uintptr_t)(bound)) - 1)) 170 171/* 172 * Print an address as a u_long (a u_long is the largest type we can print 173 * portably). Most 64-bit systems have made longs 64-bits, so this should 174 * work. 175 */ 176#define P_TO_ULONG(p) ((u_long)(uintptr_t)(p)) 177 178/* 179 * Convert a pointer to a small integral value. 180 * 181 * The (u_int16_t)(uintptr_t) cast avoids warnings: the (uintptr_t) cast 182 * converts the value to an integral type, and the (u_int16_t) cast converts 183 * it to a small integral type so we don't get complaints when we assign the 184 * final result to an integral type smaller than uintptr_t. 185 */ 186#define P_TO_UINT32(p) ((u_int32_t)(uintptr_t)(p)) 187#define P_TO_UINT16(p) ((u_int16_t)(uintptr_t)(p)) 188 189/* 190 * There are several on-page structures that are declared to have a number of 191 * fields followed by a variable length array of items. The structure size 192 * without including the variable length array or the address of the first of 193 * those elements can be found using SSZ. 194 * 195 * This macro can also be used to find the offset of a structure element in a 196 * structure. This is used in various places to copy structure elements from 197 * unaligned memory references, e.g., pointers into a packed page. 198 * 199 * There are two versions because compilers object if you take the address of 200 * an array. 201 */ 202#undef SSZ 203#define SSZ(name, field) P_TO_UINT16(&(((name *)0)->field)) 204 205#undef SSZA 206#define SSZA(name, field) P_TO_UINT16(&(((name *)0)->field[0])) 207 208/* Structure used to print flag values. */ 209typedef struct __fn { 210 u_int32_t mask; /* Flag value. */ 211 const char *name; /* Flag name. */ 212} FN; 213 214/* Set, clear and test flags. */ 215#define FLD_CLR(fld, f) (fld) &= ~(f) 216#define FLD_ISSET(fld, f) ((fld) & (f)) 217#define FLD_SET(fld, f) (fld) |= (f) 218#define F_CLR(p, f) (p)->flags &= ~(f) 219#define F_ISSET(p, f) ((p)->flags & (f)) 220#define F_SET(p, f) (p)->flags |= (f) 221#define LF_CLR(f) ((flags) &= ~(f)) 222#define LF_ISSET(f) ((flags) & (f)) 223#define LF_SET(f) ((flags) |= (f)) 224 225/* 226 * Calculate a percentage. The values can overflow 32-bit integer arithmetic 227 * so we use floating point. 228 * 229 * When calculating a bytes-vs-page size percentage, we're getting the inverse 230 * of the percentage in all cases, that is, we want 100 minus the percentage we 231 * calculate. 232 */ 233#define DB_PCT(v, total) \ 234 ((int)((total) == 0 ? 0 : ((double)(v) * 100) / (total))) 235#define DB_PCT_PG(v, total, pgsize) \ 236 ((int)((total) == 0 ? 0 : \ 237 100 - ((double)(v) * 100) / (((double)total) * (pgsize)))) 238 239/* 240 * Statistics update shared memory and so are expensive -- don't update the 241 * values unless we're going to display the results. 242 */ 243#undef STAT 244#ifdef HAVE_STATISTICS 245#define STAT(x) x 246#else 247#define STAT(x) 248#endif 249 250/* 251 * Structure used for callback message aggregation. 252 * 253 * Display values in XXX_stat_print calls. 254 */ 255typedef struct __db_msgbuf { 256 char *buf; /* Heap allocated buffer. */ 257 char *cur; /* Current end of message. */ 258 size_t len; /* Allocated length of buffer. */ 259} DB_MSGBUF; 260#define DB_MSGBUF_INIT(a) do { \ 261 (a)->buf = (a)->cur = NULL; \ 262 (a)->len = 0; \ 263} while (0) 264#define DB_MSGBUF_FLUSH(env, a) do { \ 265 if ((a)->buf != NULL) { \ 266 if ((a)->cur != (a)->buf) \ 267 __db_msg(env, "%s", (a)->buf); \ 268 __os_free(env, (a)->buf); \ 269 DB_MSGBUF_INIT(a); \ 270 } \ 271} while (0) 272#define STAT_FMT(msg, fmt, type, v) do { \ 273 DB_MSGBUF __mb; \ 274 DB_MSGBUF_INIT(&__mb); \ 275 __db_msgadd(env, &__mb, fmt, (type)(v)); \ 276 __db_msgadd(env, &__mb, "\t%s", msg); \ 277 DB_MSGBUF_FLUSH(env, &__mb); \ 278} while (0) 279#define STAT_HEX(msg, v) \ 280 __db_msg(env, "%#lx\t%s", (u_long)(v), msg) 281#define STAT_ISSET(msg, p) \ 282 __db_msg(env, "%sSet\t%s", (p) == NULL ? "!" : " ", msg) 283#define STAT_LONG(msg, v) \ 284 __db_msg(env, "%ld\t%s", (long)(v), msg) 285#define STAT_LSN(msg, lsnp) \ 286 __db_msg(env, "%lu/%lu\t%s", \ 287 (u_long)(lsnp)->file, (u_long)(lsnp)->offset, msg) 288#define STAT_POINTER(msg, v) \ 289 __db_msg(env, "%#lx\t%s", P_TO_ULONG(v), msg) 290#define STAT_STRING(msg, p) do { \ 291 const char *__p = p; /* p may be a function call. */ \ 292 __db_msg(env, "%s\t%s", __p == NULL ? "!Set" : __p, msg); \ 293} while (0) 294#define STAT_ULONG(msg, v) \ 295 __db_msg(env, "%lu\t%s", (u_long)(v), msg) 296 297/* 298 * There are quite a few places in Berkeley DB where we want to initialize 299 * a DBT from a string or other random pointer type, using a length typed 300 * to size_t in most cases. This macro avoids a lot of casting. The macro 301 * comes in two flavors because we often want to clear the DBT first. 302 */ 303#define DB_SET_DBT(dbt, d, s) do { \ 304 (dbt).data = (void *)(d); \ 305 (dbt).size = (u_int32_t)(s); \ 306} while (0) 307#define DB_INIT_DBT(dbt, d, s) do { \ 308 memset(&(dbt), 0, sizeof(dbt)); \ 309 DB_SET_DBT(dbt, d, s); \ 310} while (0) 311 312/******************************************************* 313 * API return values 314 *******************************************************/ 315/* 316 * Return values that are OK for each different call. Most calls have a 317 * standard 'return of 0 is only OK value', but some, like db->get have 318 * DB_NOTFOUND as a return value, but it really isn't an error. 319 */ 320#define DB_RETOK_STD(ret) ((ret) == 0) 321#define DB_RETOK_DBCDEL(ret) ((ret) == 0 || (ret) == DB_KEYEMPTY || \ 322 (ret) == DB_NOTFOUND) 323#define DB_RETOK_DBCGET(ret) ((ret) == 0 || (ret) == DB_KEYEMPTY || \ 324 (ret) == DB_NOTFOUND) 325#define DB_RETOK_DBCPUT(ret) ((ret) == 0 || (ret) == DB_KEYEXIST || \ 326 (ret) == DB_NOTFOUND) 327#define DB_RETOK_DBDEL(ret) DB_RETOK_DBCDEL(ret) 328#define DB_RETOK_DBGET(ret) DB_RETOK_DBCGET(ret) 329#define DB_RETOK_DBPUT(ret) ((ret) == 0 || (ret) == DB_KEYEXIST) 330#define DB_RETOK_EXISTS(ret) DB_RETOK_DBCGET(ret) 331#define DB_RETOK_LGGET(ret) ((ret) == 0 || (ret) == DB_NOTFOUND) 332#define DB_RETOK_MPGET(ret) ((ret) == 0 || (ret) == DB_PAGE_NOTFOUND) 333#define DB_RETOK_REPPMSG(ret) ((ret) == 0 || \ 334 (ret) == DB_REP_IGNORE || \ 335 (ret) == DB_REP_ISPERM || \ 336 (ret) == DB_REP_NEWMASTER || \ 337 (ret) == DB_REP_NEWSITE || \ 338 (ret) == DB_REP_NOTPERM) 339 340/* Find a reasonable operation-not-supported error. */ 341#ifdef EOPNOTSUPP 342#define DB_OPNOTSUP EOPNOTSUPP 343#else 344#ifdef ENOTSUP 345#define DB_OPNOTSUP ENOTSUP 346#else 347#define DB_OPNOTSUP EINVAL 348#endif 349#endif 350 351/******************************************************* 352 * Files. 353 *******************************************************/ 354/* 355 * We use 1024 as the maximum path length. It's too hard to figure out what 356 * the real path length is, as it was traditionally stored in <sys/param.h>, 357 * and that file isn't always available. 358 */ 359#define DB_MAXPATHLEN 1024 360 361#define PATH_DOT "." /* Current working directory. */ 362 /* Path separator character(s). */ 363#define PATH_SEPARATOR "\\/:" 364 365/******************************************************* 366 * Environment. 367 *******************************************************/ 368/* Type passed to __db_appname(). */ 369typedef enum { 370 DB_APP_NONE=0, /* No type (region). */ 371 DB_APP_DATA, /* Data file. */ 372 DB_APP_LOG, /* Log file. */ 373 DB_APP_TMP /* Temporary file. */ 374} APPNAME; 375 376/* 377 * A set of macros to check if various functionality has been configured. 378 * 379 * ALIVE_ON The is_alive function is configured. 380 * CDB_LOCKING CDB product locking. 381 * CRYPTO_ON Security has been configured. 382 * LOCKING_ON Locking has been configured. 383 * LOGGING_ON Logging has been configured. 384 * MUTEX_ON Mutexes have been configured. 385 * MPOOL_ON Memory pool has been configured. 386 * REP_ON Replication has been configured. 387 * RPC_ON RPC has been configured. 388 * TXN_ON Transactions have been configured. 389 * 390 * REP_ON is more complex than most: if the BDB library was compiled without 391 * replication support, ENV->rep_handle will be NULL; if the BDB library has 392 * replication support, but it was not configured, the region reference will 393 * be NULL. 394 */ 395#define ALIVE_ON(env) ((env)->dbenv->is_alive != NULL) 396#define CDB_LOCKING(env) F_ISSET(env, ENV_CDB) 397#define CRYPTO_ON(env) ((env)->crypto_handle != NULL) 398#define LOCKING_ON(env) ((env)->lk_handle != NULL) 399#define LOGGING_ON(env) ((env)->lg_handle != NULL) 400#define MPOOL_ON(env) ((env)->mp_handle != NULL) 401#define MUTEX_ON(env) ((env)->mutex_handle != NULL) 402#define REP_ON(env) \ 403 ((env)->rep_handle != NULL && (env)->rep_handle->region != NULL) 404#define RPC_ON(dbenv) ((dbenv)->cl_handle != NULL) 405#define TXN_ON(env) ((env)->tx_handle != NULL) 406 407/* 408 * STD_LOCKING Standard locking, that is, locking was configured and CDB 409 * was not. We do not do locking in off-page duplicate trees, 410 * so we check for that in the cursor first. 411 */ 412#define STD_LOCKING(dbc) \ 413 (!F_ISSET(dbc, DBC_OPD) && \ 414 !CDB_LOCKING((dbc)->env) && LOCKING_ON((dbc)->env)) 415 416/* 417 * IS_RECOVERING: The system is running recovery. 418 */ 419#define IS_RECOVERING(env) \ 420 (LOGGING_ON(env) && F_ISSET((env)->lg_handle, DBLOG_RECOVER)) 421 422/* Initialization methods are often illegal before/after open is called. */ 423#define ENV_ILLEGAL_AFTER_OPEN(env, name) \ 424 if (F_ISSET((env), ENV_OPEN_CALLED)) \ 425 return (__db_mi_open(env, name, 1)); 426#define ENV_ILLEGAL_BEFORE_OPEN(env, name) \ 427 if (!F_ISSET((env), ENV_OPEN_CALLED)) \ 428 return (__db_mi_open(env, name, 0)); 429 430/* We're not actually user hostile, honest. */ 431#define ENV_REQUIRES_CONFIG(env, handle, i, flags) \ 432 if (handle == NULL) \ 433 return (__env_not_config(env, i, flags)); 434#define ENV_REQUIRES_CONFIG_XX(env, handle, i, flags) \ 435 if ((env)->handle->region == NULL) \ 436 return (__env_not_config(env, i, flags)); 437#define ENV_NOT_CONFIGURED(env, handle, i, flags) \ 438 if (F_ISSET((env), ENV_OPEN_CALLED)) \ 439 ENV_REQUIRES_CONFIG(env, handle, i, flags) 440 441#define ENV_ENTER(env, ip) do { \ 442 int __ret; \ 443 PANIC_CHECK(env); \ 444 if ((env)->thr_hashtab == NULL) \ 445 ip = NULL; \ 446 else { \ 447 if ((__ret = \ 448 __env_set_state(env, &(ip), THREAD_ACTIVE)) != 0) \ 449 return (__ret); \ 450 } \ 451} while (0) 452 453#define ENV_GET_THREAD_INFO(env, ip) ENV_ENTER(env, ip) 454 455#ifdef DIAGNOSTIC 456#define ENV_LEAVE(env, ip) do { \ 457 if ((ip) != NULL) { \ 458 DB_ASSERT(env, (ip)->dbth_state == THREAD_ACTIVE); \ 459 (ip)->dbth_state = THREAD_OUT; \ 460 } \ 461} while (0) 462#else 463#define ENV_LEAVE(env, ip) do { \ 464 if ((ip) != NULL) \ 465 (ip)->dbth_state = THREAD_OUT; \ 466} while (0) 467#endif 468#ifdef DIAGNOSTIC 469#define CHECK_THREAD(env) do { \ 470 if ((env)->thr_hashtab != NULL) \ 471 (void)__env_set_state(env, NULL, THREAD_VERIFY); \ 472} while (0) 473#ifdef HAVE_STATISTICS 474#define CHECK_MTX_THREAD(env, mtx) do { \ 475 if (mtx->alloc_id != MTX_MUTEX_REGION && \ 476 mtx->alloc_id != MTX_ENV_REGION && \ 477 mtx->alloc_id != MTX_APPLICATION) \ 478 CHECK_THREAD(env); \ 479} while (0) 480#else 481#define CHECK_MTX_THREAD(env, mtx) 482#endif 483#else 484#define CHECK_THREAD(env) 485#define CHECK_MTX_THREAD(env, mtx) 486#endif 487 488typedef enum { 489 THREAD_SLOT_NOT_IN_USE=0, 490 THREAD_OUT, 491 THREAD_ACTIVE, 492 THREAD_BLOCKED, 493 THREAD_BLOCKED_DEAD 494#ifdef DIAGNOSTIC 495 , THREAD_VERIFY 496#endif 497} DB_THREAD_STATE; 498 499typedef struct __pin_list { 500 roff_t b_ref; /* offset to buffer. */ 501 int region; /* region containing buffer. */ 502} PIN_LIST; 503#define PINMAX 4 504 505struct __db_thread_info { 506 pid_t dbth_pid; 507 db_threadid_t dbth_tid; 508 DB_THREAD_STATE dbth_state; 509 SH_TAILQ_ENTRY dbth_links; 510 /* 511 * The following fields track which buffers this thread of 512 * control has pinned in the mpool buffer cache. 513 */ 514 u_int16_t dbth_pincount; /* Number of pins for this thread. */ 515 u_int16_t dbth_pinmax; /* Number of slots allocated. */ 516 roff_t dbth_pinlist; /* List of pins. */ 517 PIN_LIST dbth_pinarray[PINMAX]; /* Initial array of slots. */ 518}; 519 520typedef struct __env_thread_info { 521 u_int32_t thr_count; 522 u_int32_t thr_max; 523 u_int32_t thr_nbucket; 524 roff_t thr_hashoff; 525} THREAD_INFO; 526 527#define DB_EVENT(env, e, einfo) do { \ 528 DB_ENV *__dbenv = (env)->dbenv; \ 529 if (__dbenv->db_event_func != NULL) \ 530 __dbenv->db_event_func(__dbenv, e, einfo); \ 531} while (0) 532 533typedef struct __flag_map { 534 u_int32_t inflag, outflag; 535} FLAG_MAP; 536 537/* 538 * Internal database environment structure. 539 * 540 * This is the private database environment handle. The public environment 541 * handle is the DB_ENV structure. The library owns this structure, the user 542 * owns the DB_ENV structure. The reason there are two structures is because 543 * the user's configuration outlives any particular DB_ENV->open call, and 544 * separate structures allows us to easily discard internal information without 545 * discarding the user's configuration. 546 */ 547struct __env { 548 DB_ENV *dbenv; /* Linked DB_ENV structure */ 549 550 /* 551 * The ENV structure can be used concurrently, so field access is 552 * protected. 553 */ 554 db_mutex_t mtx_env; /* ENV structure mutex */ 555 556 /* 557 * Some fields are included in the ENV structure rather than in the 558 * DB_ENV structure because they are only set as arguments to the 559 * DB_ENV->open method. In other words, because of the historic API, 560 * not for any rational reason. 561 * 562 * Arguments to DB_ENV->open. 563 */ 564 char *db_home; /* Database home */ 565 u_int32_t open_flags; /* Flags */ 566 int db_mode; /* Default open permissions */ 567 568 pid_t pid_cache; /* Cached process ID */ 569 570 DB_FH *lockfhp; /* fcntl(2) locking file handle */ 571 572 DB_LOCKER *env_lref; /* Locker in non-threaded handles */ 573 574 DB_DISTAB recover_dtab; /* Dispatch table for recover funcs */ 575 576 int dir_mode; /* Intermediate directory perms. */ 577 578 /* Thread tracking */ 579 u_int32_t thr_nbucket; /* Number of hash buckets */ 580 DB_HASHTAB *thr_hashtab; /* Hash table of DB_THREAD_INFO */ 581 582 /* Mutex allocation */ 583 struct { 584 int alloc_id; /* Allocation ID argument */ 585 u_int32_t flags; /* Flags argument */ 586 } *mutex_iq; /* Initial mutexes queue */ 587 u_int mutex_iq_next; /* Count of initial mutexes */ 588 u_int mutex_iq_max; /* Maximum initial mutexes */ 589 590 /* 591 * List of open DB handles for this ENV, used for cursor 592 * adjustment. Must be protected for multi-threaded support. 593 */ 594 db_mutex_t mtx_dblist; 595 int db_ref; /* DB handle reference count */ 596 TAILQ_HEAD(__dblist, __db) dblist; 597 598 /* 599 * XA support. 600 */ 601 int xa_rmid; /* XA Resource Manager ID */ 602 TAILQ_ENTRY(__env) links; /* XA environments */ 603 TAILQ_HEAD(__xa_txn, __db_txn) xa_txn; /* XA active transactions */ 604 605 /* 606 * List of open file handles for this ENV. Must be protected 607 * for multi-threaded support. 608 */ 609 TAILQ_HEAD(__fdlist, __fh_t) fdlist; 610 611 db_mutex_t mtx_mt; /* Mersenne Twister mutex */ 612 int mti; /* Mersenne Twister index */ 613 u_long *mt; /* Mersenne Twister state vector */ 614 615 DB_CIPHER *crypto_handle; /* Crypto handle */ 616 DB_LOCKTAB *lk_handle; /* Lock handle */ 617 DB_LOG *lg_handle; /* Log handle */ 618 DB_MPOOL *mp_handle; /* Mpool handle */ 619 DB_MUTEXMGR *mutex_handle; /* Mutex handle */ 620 DB_REP *rep_handle; /* Replication handle */ 621 DB_TXNMGR *tx_handle; /* Txn handle */ 622 623 /* Application callback to copy data to/from a custom data source */ 624#define DB_USERCOPY_GETDATA 0x0001 625#define DB_USERCOPY_SETDATA 0x0002 626 int (*dbt_usercopy) 627 __P((DBT *, u_int32_t, void *, u_int32_t, u_int32_t)); 628 629 REGINFO *reginfo; /* REGINFO structure reference */ 630 631#define DB_TEST_ELECTINIT 1 /* after __rep_elect_init */ 632#define DB_TEST_ELECTVOTE1 2 /* after sending VOTE1 */ 633#define DB_TEST_POSTDESTROY 3 /* after destroy op */ 634#define DB_TEST_POSTLOG 4 /* after logging all pages */ 635#define DB_TEST_POSTLOGMETA 5 /* after logging meta in btree */ 636#define DB_TEST_POSTOPEN 6 /* after __os_open */ 637#define DB_TEST_POSTSYNC 7 /* after syncing the log */ 638#define DB_TEST_PREDESTROY 8 /* before destroy op */ 639#define DB_TEST_PREOPEN 9 /* before __os_open */ 640#define DB_TEST_SUBDB_LOCKS 10 /* subdb locking tests */ 641 int test_abort; /* Abort value for testing */ 642 int test_check; /* Checkpoint value for testing */ 643 int test_copy; /* Copy value for testing */ 644 645#define ENV_CDB 0x00000001 /* DB_INIT_CDB */ 646#define ENV_DBLOCAL 0x00000002 /* Environment for a private DB */ 647#define ENV_LITTLEENDIAN 0x00000004 /* Little endian system. */ 648#define ENV_LOCKDOWN 0x00000008 /* DB_LOCKDOWN set */ 649#define ENV_NO_OUTPUT_SET 0x00000010 /* No output channel set */ 650#define ENV_OPEN_CALLED 0x00000020 /* DB_ENV->open called */ 651#define ENV_PRIVATE 0x00000040 /* DB_PRIVATE set */ 652#define ENV_RECOVER_FATAL 0x00000080 /* Doing fatal recovery in env */ 653#define ENV_REF_COUNTED 0x00000100 /* Region references this handle */ 654#define ENV_SYSTEM_MEM 0x00000200 /* DB_SYSTEM_MEM set */ 655#define ENV_THREAD 0x00000400 /* DB_THREAD set */ 656 u_int32_t flags; 657}; 658 659/******************************************************* 660 * Database Access Methods. 661 *******************************************************/ 662/* 663 * DB_IS_THREADED -- 664 * The database handle is free-threaded (was opened with DB_THREAD). 665 */ 666#define DB_IS_THREADED(dbp) \ 667 ((dbp)->mutex != MUTEX_INVALID) 668 669/* Initialization methods are often illegal before/after open is called. */ 670#define DB_ILLEGAL_AFTER_OPEN(dbp, name) \ 671 if (F_ISSET((dbp), DB_AM_OPEN_CALLED)) \ 672 return (__db_mi_open((dbp)->env, name, 1)); 673#define DB_ILLEGAL_BEFORE_OPEN(dbp, name) \ 674 if (!F_ISSET((dbp), DB_AM_OPEN_CALLED)) \ 675 return (__db_mi_open((dbp)->env, name, 0)); 676/* Some initialization methods are illegal if environment isn't local. */ 677#define DB_ILLEGAL_IN_ENV(dbp, name) \ 678 if (!F_ISSET((dbp)->env, ENV_DBLOCAL)) \ 679 return (__db_mi_env((dbp)->env, name)); 680#define DB_ILLEGAL_METHOD(dbp, flags) { \ 681 int __ret; \ 682 if ((__ret = __dbh_am_chk(dbp, flags)) != 0) \ 683 return (__ret); \ 684} 685 686/* 687 * Common DBC->internal fields. Each access method adds additional fields 688 * to this list, but the initial fields are common. 689 */ 690#define __DBC_INTERNAL \ 691 DBC *opd; /* Off-page duplicate cursor. */\ 692 \ 693 void *page; /* Referenced page. */ \ 694 db_pgno_t root; /* Tree root. */ \ 695 db_pgno_t pgno; /* Referenced page number. */ \ 696 db_indx_t indx; /* Referenced key item index. */\ 697 \ 698 DB_LOCK lock; /* Cursor lock. */ \ 699 db_lockmode_t lock_mode; /* Lock mode. */ 700 701struct __dbc_internal { 702 __DBC_INTERNAL 703}; 704 705/* Actions that __db_master_update can take. */ 706typedef enum { MU_REMOVE, MU_RENAME, MU_OPEN } mu_action; 707 708/* 709 * Access-method-common macro for determining whether a cursor 710 * has been initialized. 711 */ 712#define IS_INITIALIZED(dbc) ((dbc)->internal->pgno != PGNO_INVALID) 713 714/* Free the callback-allocated buffer, if necessary, hanging off of a DBT. */ 715#define FREE_IF_NEEDED(env, dbt) \ 716 if (F_ISSET((dbt), DB_DBT_APPMALLOC)) { \ 717 __os_ufree((env), (dbt)->data); \ 718 F_CLR((dbt), DB_DBT_APPMALLOC); \ 719 } 720 721/* 722 * Use memory belonging to object "owner" to return the results of 723 * any no-DBT-flag get ops on cursor "dbc". 724 */ 725#define SET_RET_MEM(dbc, owner) \ 726 do { \ 727 (dbc)->rskey = &(owner)->my_rskey; \ 728 (dbc)->rkey = &(owner)->my_rkey; \ 729 (dbc)->rdata = &(owner)->my_rdata; \ 730 } while (0) 731 732/* Use the return-data memory src is currently set to use in dest as well. */ 733#define COPY_RET_MEM(src, dest) \ 734 do { \ 735 (dest)->rskey = (src)->rskey; \ 736 (dest)->rkey = (src)->rkey; \ 737 (dest)->rdata = (src)->rdata; \ 738 } while (0) 739 740/* Reset the returned-memory pointers to their defaults. */ 741#define RESET_RET_MEM(dbc) \ 742 do { \ 743 (dbc)->rskey = &(dbc)->my_rskey; \ 744 (dbc)->rkey = &(dbc)->my_rkey; \ 745 (dbc)->rdata = &(dbc)->my_rdata; \ 746 } while (0) 747 748/******************************************************* 749 * Mpool. 750 *******************************************************/ 751/* 752 * File types for DB access methods. Negative numbers are reserved to DB. 753 */ 754#define DB_FTYPE_SET -1 /* Call pgin/pgout functions. */ 755#define DB_FTYPE_NOTSET 0 /* Don't call... */ 756#define DB_LSN_OFF_NOTSET -1 /* Not yet set. */ 757#define DB_CLEARLEN_NOTSET UINT32_MAX /* Not yet set. */ 758 759/* Structure used as the DB pgin/pgout pgcookie. */ 760typedef struct __dbpginfo { 761 size_t db_pagesize; /* Underlying page size. */ 762 u_int32_t flags; /* Some DB_AM flags needed. */ 763 DBTYPE type; /* DB type */ 764} DB_PGINFO; 765 766/******************************************************* 767 * Log. 768 *******************************************************/ 769/* Initialize an LSN to 'zero'. */ 770#define ZERO_LSN(LSN) do { \ 771 (LSN).file = 0; \ 772 (LSN).offset = 0; \ 773} while (0) 774#define IS_ZERO_LSN(LSN) ((LSN).file == 0 && (LSN).offset == 0) 775 776#define IS_INIT_LSN(LSN) ((LSN).file == 1 && (LSN).offset == 0) 777#define INIT_LSN(LSN) do { \ 778 (LSN).file = 1; \ 779 (LSN).offset = 0; \ 780} while (0) 781 782#define MAX_LSN(LSN) do { \ 783 (LSN).file = UINT32_MAX; \ 784 (LSN).offset = UINT32_MAX; \ 785} while (0) 786#define IS_MAX_LSN(LSN) \ 787 ((LSN).file == UINT32_MAX && (LSN).offset == UINT32_MAX) 788 789/* If logging is turned off, smash the lsn. */ 790#define LSN_NOT_LOGGED(LSN) do { \ 791 (LSN).file = 0; \ 792 (LSN).offset = 1; \ 793} while (0) 794#define IS_NOT_LOGGED_LSN(LSN) \ 795 ((LSN).file == 0 && (LSN).offset == 1) 796 797/* 798 * LOG_COMPARE -- compare two LSNs. 799 */ 800 801#define LOG_COMPARE(lsn0, lsn1) \ 802 ((lsn0)->file != (lsn1)->file ? \ 803 ((lsn0)->file < (lsn1)->file ? -1 : 1) : \ 804 ((lsn0)->offset != (lsn1)->offset ? \ 805 ((lsn0)->offset < (lsn1)->offset ? -1 : 1) : 0)) 806 807/******************************************************* 808 * Txn. 809 *******************************************************/ 810#define DB_NONBLOCK(C) ((C)->txn != NULL && F_ISSET((C)->txn, TXN_NOWAIT)) 811#define NOWAIT_FLAG(txn) \ 812 ((txn) != NULL && F_ISSET((txn), TXN_NOWAIT) ? DB_LOCK_NOWAIT : 0) 813#define IS_REAL_TXN(txn) \ 814 ((txn) != NULL && !F_ISSET(txn, TXN_CDSGROUP)) 815#define IS_SUBTRANSACTION(txn) \ 816 ((txn) != NULL && (txn)->parent != NULL) 817 818/******************************************************* 819 * Crypto. 820 *******************************************************/ 821#define DB_IV_BYTES 16 /* Bytes per IV */ 822#define DB_MAC_KEY 20 /* Bytes per MAC checksum */ 823 824/******************************************************* 825 * Secondaries over RPC. 826 *******************************************************/ 827#ifdef CONFIG_TEST 828/* 829 * These are flags passed to DB->associate calls by the Tcl API if running 830 * over RPC. The RPC server will mask out these flags before making the real 831 * DB->associate call. 832 * 833 * These flags must coexist with the valid flags to DB->associate (currently 834 * DB_AUTO_COMMIT and DB_CREATE). DB_AUTO_COMMIT is in the group of 835 * high-order shared flags (0xff000000), and DB_CREATE is in the low-order 836 * group (0x00000fff), so we pick a range in between. 837 */ 838#define DB_RPC2ND_MASK 0x00f00000 /* Reserved bits. */ 839 840#define DB_RPC2ND_REVERSEDATA 0x00100000 /* callback_n(0) _s_reversedata. */ 841#define DB_RPC2ND_NOOP 0x00200000 /* callback_n(1) _s_noop */ 842#define DB_RPC2ND_CONCATKEYDATA 0x00300000 /* callback_n(2) _s_concatkeydata */ 843#define DB_RPC2ND_CONCATDATAKEY 0x00400000 /* callback_n(3) _s_concatdatakey */ 844#define DB_RPC2ND_REVERSECONCAT 0x00500000 /* callback_n(4) _s_reverseconcat */ 845#define DB_RPC2ND_TRUNCDATA 0x00600000 /* callback_n(5) _s_truncdata */ 846#define DB_RPC2ND_CONSTANT 0x00700000 /* callback_n(6) _s_constant */ 847#define DB_RPC2ND_GETZIP 0x00800000 /* sj_getzip */ 848#define DB_RPC2ND_GETNAME 0x00900000 /* sj_getname */ 849#endif 850 851#if defined(__cplusplus) 852} 853#endif 854 855/******************************************************* 856 * Remaining general DB includes. 857 *******************************************************/ 858 859 860#include "dbinc/globals.h" 861#include "dbinc/clock.h" 862#include "dbinc/debug.h" 863#include "dbinc/region.h" 864#include "dbinc_auto/env_ext.h" 865#include "dbinc/mutex.h" 866#ifdef HAVE_REPLICATION_THREADS 867#include "dbinc/repmgr.h" 868#endif 869#include "dbinc/rep.h" 870#include "dbinc/os.h" 871#include "dbinc_auto/clib_ext.h" 872#include "dbinc_auto/common_ext.h" 873 874/******************************************************* 875 * Remaining Log. 876 * These need to be defined after the general includes 877 * because they need rep.h from above. 878 *******************************************************/ 879/* 880 * Test if the environment is currently logging changes. If we're in recovery 881 * or we're a replication client, we don't need to log changes because they're 882 * already in the log, even though we have a fully functional log system. 883 */ 884#define DBENV_LOGGING(env) \ 885 (LOGGING_ON(env) && !IS_REP_CLIENT(env) && (!IS_RECOVERING(env))) 886 887/* 888 * Test if we need to log a change. By default, we don't log operations without 889 * associated transactions, unless DIAGNOSTIC, DEBUG_ROP or DEBUG_WOP are on. 890 * This is because we want to get log records for read/write operations, and, if 891 * we are trying to debug something, more information is always better. 892 * 893 * The DBC_RECOVER flag is set when we're in abort, as well as during recovery; 894 * thus DBC_LOGGING may be false for a particular dbc even when DBENV_LOGGING 895 * is true. 896 * 897 * We explicitly use LOGGING_ON/IS_REP_CLIENT here because we don't want to pull 898 * in the log headers, which IS_RECOVERING (and thus DBENV_LOGGING) rely on, and 899 * because DBC_RECOVER should be set anytime IS_RECOVERING would be true. 900 * 901 * If we're not in recovery (master - doing an abort or a client applying 902 * a txn), then a client's only path through here is on an internal 903 * operation, and a master's only path through here is a transactional 904 * operation. Detect if either is not the case. 905 */ 906#if defined(DIAGNOSTIC) || defined(DEBUG_ROP) || defined(DEBUG_WOP) 907#define DBC_LOGGING(dbc) __dbc_logging(dbc) 908#else 909#define DBC_LOGGING(dbc) \ 910 ((dbc)->txn != NULL && LOGGING_ON((dbc)->env) && \ 911 !F_ISSET((dbc), DBC_RECOVER) && !IS_REP_CLIENT((dbc)->env)) 912#endif 913 914#endif /* !_DB_INT_H_ */ 915