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