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