Imported Upstream version 5.3.21
[platform/upstream/libdb.git] / build_vxworks / db_int.h
1 /* DO NOT EDIT: automatically built by dist/s_vxworks. */
2 /*-
3  * See the file LICENSE for redistribution information.
4  *
5  * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
6  *
7  * $Id$
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(HAVE_REPLICATION_THREADS)
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(HAVE_REPLICATION_THREADS)
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 #endif /* !HAVE_SYSTEM_INCLUDE_FILES */
77 #include "clib_port.h"
78 #include "db.h"
79
80 #ifdef DB_WIN32
81 #include "dbinc/win_db.h"
82 #endif
83
84 #ifdef HAVE_DBM
85 #undef  DB_DBM_HSEARCH
86 #define DB_DBM_HSEARCH 1
87 #endif
88
89 #include "db.h"
90 #include "clib_port.h"
91
92 #include "dbinc/queue.h"
93 #include "dbinc/shqueue.h"
94 #include "dbinc/perfmon.h"
95
96 #if defined(__cplusplus)
97 extern "C" {
98 #endif
99
100 /*
101  * The Windows compiler needs to be told about structures that are available
102  * outside a dll.
103  */
104 #if defined(DB_WIN32) && defined(_MSC_VER) && \
105     !defined(DB_CREATE_DLL) && !defined(_LIB)
106 #define __DB_IMPORT __declspec(dllimport)
107 #else
108 #define __DB_IMPORT
109 #endif
110
111 /*******************************************************
112  * Forward structure declarations.
113  *******************************************************/
114 struct __db_commit_info; typedef struct __db_commit_info DB_COMMIT_INFO;
115 struct __db_reginfo_t;  typedef struct __db_reginfo_t REGINFO;
116 struct __db_txnhead;    typedef struct __db_txnhead DB_TXNHEAD;
117 struct __db_txnlist;    typedef struct __db_txnlist DB_TXNLIST;
118 struct __vrfy_childinfo;typedef struct __vrfy_childinfo VRFY_CHILDINFO;
119 struct __vrfy_dbinfo;   typedef struct __vrfy_dbinfo VRFY_DBINFO;
120 struct __vrfy_pageinfo; typedef struct __vrfy_pageinfo VRFY_PAGEINFO;
121
122 struct __db_log_verify_info;
123 struct __txn_verify_info;
124 struct __lv_filereg_info;
125 struct __lv_ckp_info;
126 struct __lv_timestamp_info;
127 typedef struct __db_log_verify_info DB_LOG_VRFY_INFO;
128 typedef struct __txn_verify_info VRFY_TXN_INFO;
129 typedef struct __lv_filereg_info VRFY_FILEREG_INFO;
130 typedef struct __lv_filelife VRFY_FILELIFE;
131 typedef struct __lv_ckp_info VRFY_CKP_INFO;
132 typedef struct __lv_timestamp_info VRFY_TIMESTAMP_INFO;
133
134 /*
135  * TXNINFO_HANDLER --
136  *      Callback function pointer type for __iterate_txninfo.
137  */
138 typedef int (*TXNINFO_HANDLER) __P((DB_LOG_VRFY_INFO *, VRFY_TXN_INFO *, void *));
139
140 typedef SH_TAILQ_HEAD(__hash_head) DB_HASHTAB;
141
142 /*******************************************************
143  * General purpose constants and macros.
144  *******************************************************/
145 #undef  FALSE
146 #define FALSE           0
147 #undef  TRUE
148 #define TRUE            (!FALSE)
149
150 #define MEGABYTE        1048576
151 #define GIGABYTE        1073741824
152
153 #define NS_PER_MS       1000000         /* Nanoseconds in a millisecond */
154 #define NS_PER_US       1000            /* Nanoseconds in a microsecond */
155 #define NS_PER_SEC      1000000000      /* Nanoseconds in a second */
156 #define US_PER_MS       1000            /* Microseconds in a millisecond */
157 #define US_PER_SEC      1000000         /* Microseconds in a second */
158 #define MS_PER_SEC      1000            /* Milliseconds in a second */
159
160 #define RECNO_OOB       0               /* Illegal record number. */
161
162 /*
163  * Define a macro which has no runtime effect, yet avoids triggering empty
164  * statement compiler warnings. Use it as the text of conditionally-null macros.
165  */
166 #define NOP_STATEMENT   do { } while (0)
167
168 /* Test for a power-of-two (tests true for zero, which doesn't matter here). */
169 #define POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0)
170
171 /* Test for valid page sizes. */
172 #define DB_MIN_PGSIZE   0x000200        /* Minimum page size (512). */
173 #define DB_MAX_PGSIZE   0x010000        /* Maximum page size (65536). */
174 #define IS_VALID_PAGESIZE(x)                                            \
175         (POWER_OF_TWO(x) && (x) >= DB_MIN_PGSIZE && ((x) <= DB_MAX_PGSIZE))
176
177 /* Minimum number of pages cached, by default. */
178 #define DB_MINPAGECACHE 16
179
180 /*
181  * If we are unable to determine the underlying filesystem block size, use
182  * 8K on the grounds that most OS's use less than 8K for a VM page size.
183  */
184 #define DB_DEF_IOSIZE   (8 * 1024)
185
186 /* Align an integer to a specific boundary. */
187 #undef  DB_ALIGN
188 #define DB_ALIGN(v, bound)                                              \
189         (((v) + (bound) - 1) & ~(((uintmax_t)(bound)) - 1))
190
191 /* Increment a pointer to a specific boundary. */
192 #undef  ALIGNP_INC
193 #define ALIGNP_INC(p, bound)                                            \
194         (void *)(((uintptr_t)(p) + (bound) - 1) & ~(((uintptr_t)(bound)) - 1))
195
196 /*
197  * DB_ALIGN8 adjusts structure alignments to make sure shared structures have
198  * fixed size and filed offset on both 32bit and 64bit platforms when
199  * HAVE_MIXED_SIZE_ADDRESSING is defined.
200  */
201 #ifdef HAVE_MIXED_SIZE_ADDRESSING
202 #define DB_ALIGN8 
203 #else
204 #define DB_ALIGN8
205 #endif
206
207 /*
208  * Berkeley DB uses the va_copy macro from C99, not all compilers include
209  * it, so add a dumb implementation compatible with pre C99 implementations.
210  */
211 #ifndef va_copy
212 #define va_copy(d, s)   ((d) = (s))
213 #endif
214
215 /*
216  * Print an address as a u_long (a u_long is the largest type we can print
217  * portably).  Most 64-bit systems have made longs 64-bits, so this should
218  * work.
219  */
220 #define P_TO_ULONG(p)   ((u_long)(uintptr_t)(p))
221
222 /*
223  * Convert a pointer to an integral value.
224  *
225  * The (u_int16_t)(uintptr_t) cast avoids warnings: the (uintptr_t) cast
226  * converts the value to an integral type, and the (u_int16_t) cast converts
227  * it to a small integral type so we don't get complaints when we assign the
228  * final result to an integral type smaller than uintptr_t.
229  */
230 #define P_TO_UINT32(p)  ((u_int32_t)(uintptr_t)(p))
231 #define P_TO_UINT16(p)  ((u_int16_t)(uintptr_t)(p))
232 #define P_TO_ROFF(p)    ((roff_t)(uintptr_t)(p))
233
234 /* The converse of P_TO_ROFF() above. */
235 #define ROFF_TO_P(roff) ((void *)(uintptr_t)(roff))
236
237 /*
238  * There are several on-page structures that are declared to have a number of
239  * fields followed by a variable length array of items.  The structure size
240  * without including the variable length array or the address of the first of
241  * those elements can be found using SSZ.
242  *
243  * This macro can also be used to find the offset of a structure element in a
244  * structure.  This is used in various places to copy structure elements from
245  * unaligned memory references, e.g., pointers into a packed page.
246  *
247  * There are two versions because compilers object if you take the address of
248  * an array.
249  */
250 #undef  SSZ
251 #define SSZ(name, field)  P_TO_UINT16(&(((name *)0)->field))
252
253 #undef  SSZA
254 #define SSZA(name, field) P_TO_UINT16(&(((name *)0)->field[0]))
255
256 /* Structure used to print flag values. */
257 typedef struct __fn {
258         u_int32_t mask;                 /* Flag value. */
259         const char *name;               /* Flag name. */
260 } FN;
261
262 /* Set, clear and test flags. */
263 #define FLD_CLR(fld, f)         (fld) &= ~(f)
264 #define FLD_ISSET(fld, f)       ((fld) & (f))
265 #define FLD_SET(fld, f)         (fld) |= (f)
266 #define F_CLR(p, f)             (p)->flags &= ~(f)
267 #define F_ISSET(p, f)           ((p)->flags & (f))
268 #define F_SET(p, f)             (p)->flags |= (f)
269 #define F2_CLR(p, f)            ((p)->flags2 &= ~(f))
270 #define F2_ISSET(p, f)          ((p)->flags2 & (f))
271 #define F2_SET(p, f)            ((p)->flags2 |= (f))
272 #define LF_CLR(f)               ((flags) &= ~(f))
273 #define LF_ISSET(f)             ((flags) & (f))
274 #define LF_SET(f)               ((flags) |= (f))
275
276 /*
277  * Calculate a percentage.  The values can overflow 32-bit integer arithmetic
278  * so we use floating point.
279  *
280  * When calculating a bytes-vs-page size percentage, we're getting the inverse
281  * of the percentage in all cases, that is, we want 100 minus the percentage we
282  * calculate.
283  */
284 #define DB_PCT(v, total)                                                \
285         ((int)((total) == 0 ? 0 : ((double)(v) * 100) / (total)))
286 #define DB_PCT_PG(v, total, pgsize)                                     \
287         ((int)((total) == 0 ? 0 :                                       \
288             100 - ((double)(v) * 100) / (((double)total) * (pgsize))))
289
290 /*
291  * Statistics update shared memory and so are expensive -- don't update the
292  * values unless we're going to display the results.
293  * When performance monitoring is enabled, the changed value can be published
294  * (via DTrace or SystemTap) along with another associated value or two.
295  */
296 #undef  STAT
297 #ifdef  HAVE_STATISTICS
298 #define STAT(x) x
299 #define STAT_ADJUST(env, cat, subcat, val, amount, id)                  \
300         do {                                                            \
301                 (val) += (amount);                                      \
302                 STAT_PERFMON2((env), cat, subcat, (val), (id));         \
303         } while (0)
304 #define STAT_ADJUST_VERB(env, cat, subcat, val, amount, id1, id2)       \
305         do {                                                            \
306                 (val) += (amount);                                      \
307                 STAT_PERFMON3((env), cat, subcat, (val), (id1), (id2)); \
308         } while (0)
309 #define STAT_INC(env, cat, subcat, val, id)                             \
310         STAT_ADJUST(env, cat, subcat, (val), 1, (id))
311 #define STAT_INC_VERB(env, cat, subcat, val, id1, id2)                  \
312         STAT_ADJUST_VERB((env), cat, subcat, (val), 1, (id1), (id2))
313 /*
314  * STAT_DEC() subtracts one rather than adding (-1) with STAT_ADJUST(); the
315  * latter might generate a compilation warning for an unsigned value.
316  */
317 #define STAT_DEC(env, cat, subcat, val, id)                             \
318         do {                                                            \
319                 (val)--;                                                \
320                 STAT_PERFMON2((env), cat, subcat, (val), (id));         \
321         } while (0)
322 /* N.B.: Add a verbose version of STAT_DEC() when needed. */
323
324 #define STAT_SET(env, cat, subcat, val, newval, id)                     \
325         do {                                                            \
326                 (val) = (newval);                                       \
327                 STAT_PERFMON2((env), cat, subcat, (val), (id));         \
328         } while (0)
329 #define STAT_SET_VERB(env, cat, subcat, val, newval, id1, id2)          \
330         do {                                                            \
331                 (val) = (newval);                                       \
332                 STAT_PERFMON3((env), cat, subcat, (val), (id1), (id2)); \
333         } while (0)
334 #else
335 #define STAT(x)                                                 NOP_STATEMENT
336 #define STAT_ADJUST(env, cat, subcat, val, amt, id)             NOP_STATEMENT
337 #define STAT_ADJUST_VERB(env, cat, subcat, val, amt, id1, id2)  NOP_STATEMENT
338 #define STAT_INC(env, cat, subcat, val, id)                     NOP_STATEMENT
339 #define STAT_INC_VERB(env, cat, subcat, val, id1, id2)          NOP_STATEMENT
340 #define STAT_DEC(env, cat, subcat, val, id)                     NOP_STATEMENT
341 #define STAT_SET(env, cat, subcat, val, newval, id)             NOP_STATEMENT
342 #define STAT_SET_VERB(env, cat, subcat, val, newval, id1, id2)  NOP_STATEMENT
343 #endif
344
345 #if defined HAVE_SIMPLE_THREAD_TYPE
346 #define DB_THREADID_INIT(t)     COMPQUIET((t), 0)
347 #else
348 #define DB_THREADID_INIT(t)     memset(&(t), 0, sizeof(t))
349 #endif
350
351 /*
352  * These macros are used when an error condition is first noticed. They allow
353  * one to be notified (via e.g. DTrace, SystemTap, ...) when an error occurs
354  * deep inside DB, rather than when it is returned back through the API.
355  *
356  * The second actual argument to these is the second part of the error or
357  * warning event name. They work when 'errcode' is a symbolic name e.g.
358  * EINVAL or DB_LOCK_DEALOCK, not a variable.  Noticing system call failures
359  * would be handled by tracing on syscall exit; when e.g., it returns < 0.
360  */
361 #define ERR_ORIGIN(env, errcode)                                        \
362         (PERFMON0(env, error, errcode), errcode)
363
364 #define ERR_ORIGIN_MSG(env, errcode, msg)                               \
365         (PERFMON1(env, error, errcode, msg), errcode)
366
367 #define WARNING_ORIGIN(env, errcode)                                    \
368         (PERFMON0(env, warning, errcode), errcode)
369
370 /*
371  * Structure used for callback message aggregation.
372  *
373  * Display values in XXX_stat_print calls.
374  */
375 typedef struct __db_msgbuf {
376         char *buf;                      /* Heap allocated buffer. */
377         char *cur;                      /* Current end of message. */
378         size_t len;                     /* Allocated length of buffer. */
379 } DB_MSGBUF;
380 #define DB_MSGBUF_INIT(a) do {                                          \
381         (a)->buf = (a)->cur = NULL;                                     \
382         (a)->len = 0;                                                   \
383 } while (0)
384 #define DB_MSGBUF_FLUSH(env, a) do {                                    \
385         if ((a)->buf != NULL) {                                         \
386                 if ((a)->cur != (a)->buf)                               \
387                         __db_msg(env, "%s", (a)->buf);                  \
388                 __os_free(env, (a)->buf);                               \
389                 DB_MSGBUF_INIT(a);                                      \
390         }                                                               \
391 } while (0)
392 #define DB_MSGBUF_REP_FLUSH(env, a, diag_msg, regular_msg) do {         \
393         if ((a)->buf != NULL) {                                         \
394                 if ((a)->cur != (a)->buf && diag_msg)                   \
395                         __db_repmsg(env, "%s", (a)->buf);               \
396                 if (regular_msg)                                        \
397                         DB_MSGBUF_FLUSH(env, a);                        \
398                 else {                                                  \
399                         __os_free(env, (a)->buf);                       \
400                         DB_MSGBUF_INIT(a);                              \
401                 }                                                       \
402         }                                                               \
403 } while (0)
404 #define STAT_FMT(msg, fmt, type, v) do {                                \
405         DB_MSGBUF __mb;                                                 \
406         DB_MSGBUF_INIT(&__mb);                                          \
407         __db_msgadd(env, &__mb, fmt, (type)(v));                        \
408         __db_msgadd(env, &__mb, "\t%s", msg);                           \
409         DB_MSGBUF_FLUSH(env, &__mb);                                    \
410 } while (0)
411 #define STAT_HEX(msg, v)                                                \
412         __db_msg(env, "%#lx\t%s", (u_long)(v), msg)
413 #define STAT_ISSET(msg, p)                                              \
414         __db_msg(env, "%sSet\t%s", (p) == NULL ? "!" : " ", msg)
415 #define STAT_LONG(msg, v)                                               \
416         __db_msg(env, "%ld\t%s", (long)(v), msg)
417 #define STAT_LSN(msg, lsnp)                                             \
418         __db_msg(env, "%lu/%lu\t%s",                                    \
419             (u_long)(lsnp)->file, (u_long)(lsnp)->offset, msg)
420 #define STAT_POINTER(msg, v)                                            \
421         __db_msg(env, "%#lx\t%s", P_TO_ULONG(v), msg)
422 #define STAT_STRING(msg, p) do {                                        \
423         const char *__p = p;    /* p may be a function call. */         \
424         __db_msg(env, "%s\t%s", __p == NULL ? "!Set" : __p, msg);       \
425 } while (0)
426 #define STAT_ULONG(msg, v)                                              \
427         __db_msg(env, "%lu\t%s", (u_long)(v), msg)
428
429 /*
430  * The following macros are used to control how error and message strings are
431  * output by Berkeley DB. There are essentially three different controls
432  * available:
433  *  - Default behavior is to output error strings with its unique identifier.
434  *  - If HAVE_STRIPPED_MESSAGES is enabled, a unique identifier along with any
435  *    parameters to the error string will be output.
436  *  - If HAVE_LOCALIZATION is defined, and the '_()' macro is implemented, a
437  *    gettext or ICU style translation will be done.
438  *
439  * Each new string that will be output should be wrapped in a DB_STR* macro.
440  * There are three versions of this macro for different scenarions:
441  *  - DB_STR for strings that need an identifier, and don't have any argument.
442  *  - DB_STR_A for strings that need an identifier, and have argument(s).
443  *  - DB_STR_P for strings that don't need an identifier, and don't have
444  *    arguments.
445  *
446  * Error message IDs are automatically assigned by dist/s_message_id script.
447  */
448 #ifdef HAVE_LOCALIZATION
449 #define _(msg)  msg     /* Replace with localization function. */
450 #else
451 #define _(msg)  msg
452 #endif
453
454 #ifdef HAVE_STRIPPED_MESSAGES
455 #define DB_STR_C(msg, fmt)      fmt
456 #else
457 #define DB_STR_C(msg, fmt)      _(msg)
458 #endif
459
460 #define DB_MSGID(id)            "BDB" id
461
462 #define DB_STR(id, msg)         DB_MSGID(id) " " DB_STR_C(msg, "")
463
464 #define DB_STR_A(id, msg, fmt)  DB_MSGID(id) " " DB_STR_C(msg, fmt)
465
466 #define DB_STR_P(msg)           _(msg)
467
468 /*
469  * There are quite a few places in Berkeley DB where we want to initialize
470  * a DBT from a string or other random pointer type, using a length typed
471  * to size_t in most cases.  This macro avoids a lot of casting.  The macro
472  * comes in two flavors because we often want to clear the DBT first.
473  */
474 #define DB_SET_DBT(dbt, d, s)  do {                                     \
475         (dbt).data = (void *)(d);                                       \
476         (dbt).size = (u_int32_t)(s);                                    \
477 } while (0)
478 #define DB_INIT_DBT(dbt, d, s)  do {                                    \
479         memset(&(dbt), 0, sizeof(dbt));                                 \
480         DB_SET_DBT(dbt, d, s);                                          \
481 } while (0)
482
483 /*******************************************************
484  * API return values
485  *******************************************************/
486 /*
487  * Return values that are OK for each different call.  Most calls have a
488  * standard 'return of 0 is only OK value', but some, like db->get have
489  * DB_NOTFOUND as a return value, but it really isn't an error.
490  */
491 #define DB_RETOK_STD(ret)       ((ret) == 0)
492 #define DB_RETOK_DBCDEL(ret)    ((ret) == 0 || (ret) == DB_KEYEMPTY || \
493                                     (ret) == DB_NOTFOUND)
494 #define DB_RETOK_DBCGET(ret)    ((ret) == 0 || (ret) == DB_KEYEMPTY || \
495                                     (ret) == DB_NOTFOUND)
496 #define DB_RETOK_DBCPUT(ret)    ((ret) == 0 || (ret) == DB_KEYEXIST || \
497                                     (ret) == DB_NOTFOUND)
498 #define DB_RETOK_DBDEL(ret)     DB_RETOK_DBCDEL(ret)
499 #define DB_RETOK_DBGET(ret)     DB_RETOK_DBCGET(ret)
500 #define DB_RETOK_DBPUT(ret)     ((ret) == 0 || (ret) == DB_KEYEXIST)
501 #define DB_RETOK_EXISTS(ret)    DB_RETOK_DBCGET(ret)
502 #define DB_RETOK_LGGET(ret)     ((ret) == 0 || (ret) == DB_NOTFOUND)
503 #define DB_RETOK_MPGET(ret)     ((ret) == 0 || (ret) == DB_PAGE_NOTFOUND)
504 #define DB_RETOK_REPPMSG(ret)   ((ret) == 0 || \
505                                     (ret) == DB_REP_IGNORE || \
506                                     (ret) == DB_REP_ISPERM || \
507                                     (ret) == DB_REP_NEWMASTER || \
508                                     (ret) == DB_REP_NEWSITE || \
509                                     (ret) == DB_REP_NOTPERM || \
510                                     (ret) == DB_REP_WOULDROLLBACK)
511 #define DB_RETOK_REPMGR_LOCALSITE(ret)  ((ret) == 0 || (ret) == DB_NOTFOUND)
512 #define DB_RETOK_REPMGR_START(ret) ((ret) == 0 || (ret) == DB_REP_IGNORE)
513 #define DB_RETOK_TXNAPPLIED(ret) ((ret) == 0 || \
514                                     (ret) == DB_NOTFOUND ||             \
515                                     (ret) == DB_TIMEOUT ||              \
516                                     (ret) == DB_KEYEMPTY)
517
518 /* Find a reasonable operation-not-supported error. */
519 #ifdef  EOPNOTSUPP
520 #define DB_OPNOTSUP     EOPNOTSUPP
521 #else
522 #ifdef  ENOTSUP
523 #define DB_OPNOTSUP     ENOTSUP
524 #else
525 #define DB_OPNOTSUP     EINVAL
526 #endif
527 #endif
528
529 /*******************************************************
530  * Files.
531  *******************************************************/
532 /*
533  * We use 1024 as the maximum path length.  It's too hard to figure out what
534  * the real path length is, as it was traditionally stored in <sys/param.h>,
535  * and that file isn't always available.
536  */
537 #define DB_MAXPATHLEN   1024
538
539 #define PATH_DOT        "."     /* Current working directory. */
540                                 /* Path separator character(s). */
541 #define PATH_SEPARATOR  "/\\"
542
543 /*******************************************************
544  * Environment.
545  *******************************************************/
546 /* Type passed to __db_appname(). */
547 typedef enum {
548         DB_APP_NONE=0,                  /* No type (region). */
549         DB_APP_DATA,                    /* Data file. */
550         DB_APP_LOG,                     /* Log file. */
551         DB_APP_META,                    /* Persistent metadata file. */
552         DB_APP_RECOVER,                 /* We are in recovery. */
553         DB_APP_TMP                      /* Temporary file. */
554 } APPNAME;
555
556 /*
557  * A set of macros to check if various functionality has been configured.
558  *
559  * ALIVE_ON     The is_alive function is configured.
560  * CDB_LOCKING  CDB product locking.
561  * CRYPTO_ON    Security has been configured.
562  * LOCKING_ON   Locking has been configured.
563  * LOGGING_ON   Logging has been configured.
564  * MUTEX_ON     Mutexes have been configured.
565  * MPOOL_ON     Memory pool has been configured.
566  * REP_ON       Replication has been configured.
567  * TXN_ON       Transactions have been configured.
568  *
569  * REP_ON is more complex than most: if the BDB library was compiled without
570  * replication support, ENV->rep_handle will be NULL; if the BDB library has
571  * replication support, but it was not configured, the region reference will
572  * be NULL.
573  */
574 #define ALIVE_ON(env)           ((env)->dbenv->is_alive != NULL)
575 #define CDB_LOCKING(env)        F_ISSET(env, ENV_CDB)
576 #define CRYPTO_ON(env)          ((env)->crypto_handle != NULL)
577 #define LOCKING_ON(env)         ((env)->lk_handle != NULL)
578 #define LOGGING_ON(env)         ((env)->lg_handle != NULL)
579 #define MPOOL_ON(env)           ((env)->mp_handle != NULL)
580 #define MUTEX_ON(env)           ((env)->mutex_handle != NULL)
581 #define REP_ON(env)                                                     \
582         ((env)->rep_handle != NULL && (env)->rep_handle->region != NULL)
583 #define TXN_ON(env)             ((env)->tx_handle != NULL)
584
585 /*
586  * STD_LOCKING  Standard locking, that is, locking was configured and CDB
587  *              was not.  We do not do locking in off-page duplicate trees,
588  *              so we check for that in the cursor first.
589  */
590 #define STD_LOCKING(dbc)                                                \
591         (!F_ISSET(dbc, DBC_OPD) &&                                      \
592             !CDB_LOCKING((dbc)->env) && LOCKING_ON((dbc)->env))
593
594 /*
595  * IS_RECOVERING: The system is running recovery.
596  */
597 #define IS_RECOVERING(env)                                              \
598         (LOGGING_ON(env) && F_ISSET((env)->lg_handle, DBLOG_RECOVER))
599
600 /* Initialization methods are often illegal before/after open is called. */
601 #define ENV_ILLEGAL_AFTER_OPEN(env, name)                               \
602         if (F_ISSET((env), ENV_OPEN_CALLED))                            \
603                 return (__db_mi_open(env, name, 1));
604 #define ENV_ILLEGAL_BEFORE_OPEN(env, name)                              \
605         if (!F_ISSET((env), ENV_OPEN_CALLED))                           \
606                 return (__db_mi_open(env, name, 0));
607
608 /* We're not actually user hostile, honest. */
609 #define ENV_REQUIRES_CONFIG(env, handle, i, flags)                      \
610         if (handle == NULL)                                             \
611                 return (__env_not_config(env, i, flags));
612 #define ENV_REQUIRES_CONFIG_XX(env, handle, i, flags)                   \
613         if ((env)->handle->region == NULL)                              \
614                 return (__env_not_config(env, i, flags));
615 #define ENV_NOT_CONFIGURED(env, handle, i, flags)                       \
616         if (F_ISSET((env), ENV_OPEN_CALLED))                            \
617                 ENV_REQUIRES_CONFIG(env, handle, i, flags)
618
619 #define ENV_ENTER_RET(env, ip, ret) do {                                \
620         ret = 0;                                                        \
621         PANIC_CHECK_RET(env, ret);                                      \
622         if (ret == 0) {                                                 \
623                 if ((env)->thr_hashtab == NULL)                         \
624                         ip = NULL;                                      \
625                 else                                                    \
626                         ret = __env_set_state(env, &(ip), THREAD_ACTIVE);\
627         }                                                               \
628 } while (0)
629
630 #define ENV_ENTER(env, ip) do {                                         \
631         int __ret;                                                      \
632         ip = NULL;                                                      \
633         ENV_ENTER_RET(env, ip, __ret);                                  \
634         if (__ret != 0)                                                 \
635                 return (__ret);                                         \
636 } while (0)
637
638 #define FAILCHK_THREAD(env, ip) do {                                    \
639         if ((ip) != NULL)                                               \
640                 (ip)->dbth_state = THREAD_FAILCHK;                      \
641 } while (0)
642
643 #define ENV_GET_THREAD_INFO(env, ip) ENV_ENTER(env, ip)
644
645 #ifdef DIAGNOSTIC
646 #define ENV_LEAVE(env, ip) do {                                         \
647         if ((ip) != NULL) {                                             \
648                 DB_ASSERT(env, ((ip)->dbth_state == THREAD_ACTIVE  ||   \
649                     (ip)->dbth_state == THREAD_FAILCHK));               \
650                 (ip)->dbth_state = THREAD_OUT;                          \
651         }                                                               \
652 } while (0)
653 #else
654 #define ENV_LEAVE(env, ip) do {                                         \
655         if ((ip) != NULL)                                               \
656                 (ip)->dbth_state = THREAD_OUT;                          \
657 } while (0)
658 #endif
659 #ifdef DIAGNOSTIC
660 #define CHECK_THREAD(env) do {                                          \
661         if ((env)->thr_hashtab != NULL)                                 \
662                 (void)__env_set_state(env, NULL, THREAD_VERIFY);        \
663 } while (0)
664 #ifdef HAVE_STATISTICS
665 #define CHECK_MTX_THREAD(env, mtx) do {                                 \
666         if (mtx->alloc_id != MTX_MUTEX_REGION &&                        \
667             mtx->alloc_id != MTX_ENV_REGION &&                          \
668             mtx->alloc_id != MTX_APPLICATION)                           \
669                 CHECK_THREAD(env);                                      \
670 } while (0)
671 #else
672 #define CHECK_MTX_THREAD(env, mtx)      NOP_STATEMENT
673 #endif
674 #else
675 #define CHECK_THREAD(env)               NOP_STATEMENT
676 #define CHECK_MTX_THREAD(env, mtx)      NOP_STATEMENT
677 #endif
678
679 typedef enum {
680         THREAD_SLOT_NOT_IN_USE=0,
681         THREAD_OUT,
682         THREAD_ACTIVE,
683         THREAD_BLOCKED,
684         THREAD_BLOCKED_DEAD,
685         THREAD_FAILCHK,
686         THREAD_VERIFY
687 } DB_THREAD_STATE;
688
689 typedef struct __pin_list {
690         roff_t b_ref;           /* offset to buffer. */
691         int region;             /* region containing buffer. */
692 } PIN_LIST;
693 #define PINMAX 4
694
695 struct __db_thread_info { /* SHARED */
696         pid_t           dbth_pid;
697         db_threadid_t   dbth_tid;
698         DB_THREAD_STATE dbth_state;
699         SH_TAILQ_ENTRY  dbth_links;
700         /*
701          * The next field contains the (process local) reference to the XA
702          * transaction currently associated with this thread of control.
703          */
704         SH_TAILQ_HEAD(__dbth_xatxn) dbth_xatxn;
705         u_int32_t       dbth_xa_status;
706         /*
707          * The following fields track which buffers this thread of
708          * control has pinned in the mpool buffer cache.
709          */
710         u_int16_t       dbth_pincount;  /* Number of pins for this thread. */
711         u_int16_t       dbth_pinmax;    /* Number of slots allocated. */
712         roff_t          dbth_pinlist;   /* List of pins. */
713         PIN_LIST        dbth_pinarray[PINMAX];  /* Initial array of slots. */
714 #ifdef DIAGNOSTIC
715         roff_t          dbth_locker;    /* Current locker for this thread. */
716         u_int32_t       dbth_check_off; /* Count of number of LOCK_OFF calls. */
717 #endif
718 };
719 #ifdef DIAGNOSTIC
720 #define LOCK_CHECK_OFF(ip) if ((ip) != NULL)                            \
721         (ip)->dbth_check_off++
722
723 #define LOCK_CHECK_ON(ip) if ((ip) != NULL)                             \
724         (ip)->dbth_check_off--
725
726 #define LOCK_CHECK(dbc, pgno, mode, type)                               \
727         DB_ASSERT((dbc)->dbp->env, (dbc)->locker == NULL ||             \
728              __db_haslock((dbc)->dbp->env,                              \
729             (dbc)->locker, (dbc)->dbp->mpf, pgno, mode, type) == 0)
730 #else
731 #define LOCK_CHECK_OFF(ip)      NOP_STATEMENT
732 #define LOCK_CHECK_ON(ip)       NOP_STATEMENT
733 #define LOCK_CHECK(dbc, pgno, mode)     NOP_STATEMENT
734 #endif
735
736 typedef struct __env_thread_info {
737         u_int32_t       thr_count;
738         u_int32_t       thr_init;
739         u_int32_t       thr_max;
740         u_int32_t       thr_nbucket;
741         roff_t          thr_hashoff;
742 } THREAD_INFO;
743
744 #define DB_EVENT(env, e, einfo) do {                                    \
745         DB_ENV *__dbenv = (env)->dbenv;                                 \
746         if (__dbenv->db_event_func != NULL)                             \
747                 __dbenv->db_event_func(__dbenv, e, einfo);              \
748 } while (0)
749
750 typedef struct __flag_map {
751         u_int32_t inflag, outflag;
752 } FLAG_MAP;
753
754 typedef struct __db_backup_handle {
755         int     (*open) __P((DB_ENV *, const char *, const char *, void **));
756         int     (*write) __P((DB_ENV *,
757                     u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *));
758         int     (*close) __P((DB_ENV *, const char *, void *));
759         u_int32_t       size;
760         u_int32_t       read_count;
761         u_int32_t       read_sleep;
762 #define BACKUP_WRITE_DIRECT     0x0001
763         int     flags;
764 } DB_BACKUP;
765
766 /*
767  * Internal database environment structure.
768  *
769  * This is the private database environment handle.  The public environment
770  * handle is the DB_ENV structure.   The library owns this structure, the user
771  * owns the DB_ENV structure.  The reason there are two structures is because
772  * the user's configuration outlives any particular DB_ENV->open call, and
773  * separate structures allows us to easily discard internal information without
774  * discarding the user's configuration.
775  */
776 struct __env {
777         DB_ENV *dbenv;                  /* Linked DB_ENV structure */
778
779         /*
780          * The ENV structure can be used concurrently, so field access is
781          * protected.
782          */
783         db_mutex_t mtx_env;             /* ENV structure mutex */
784
785         /*
786          * Some fields are included in the ENV structure rather than in the
787          * DB_ENV structure because they are only set as arguments to the
788          * DB_ENV->open method.  In other words, because of the historic API,
789          * not for any rational reason.
790          *
791          * Arguments to DB_ENV->open.
792          */
793         char     *db_home;              /* Database home */
794         u_int32_t open_flags;           /* Flags */
795         int       db_mode;              /* Default open permissions */
796
797         pid_t   pid_cache;              /* Cached process ID */
798
799         DB_FH   *lockfhp;               /* fcntl(2) locking file handle */
800
801         DB_LOCKER *env_lref;            /* Locker in non-threaded handles */
802
803         DB_DISTAB   recover_dtab;       /* Dispatch table for recover funcs */
804
805         int dir_mode;                   /* Intermediate directory perms. */
806
807 #define ENV_DEF_DATA_LEN                100
808         u_int32_t data_len;             /* Data length in __db_prbytes. */
809
810         /* Thread tracking */
811         u_int32_t        thr_nbucket;   /* Number of hash buckets */
812         DB_HASHTAB      *thr_hashtab;   /* Hash table of DB_THREAD_INFO */
813
814         /*
815          * List of open DB handles for this ENV, used for cursor
816          * adjustment.  Must be protected for multi-threaded support.
817          */
818         db_mutex_t mtx_dblist;
819         int        db_ref;              /* DB handle reference count */
820         TAILQ_HEAD(__dblist, __db) dblist;
821
822         /*
823          * List of open file handles for this ENV.  Must be protected
824          * for multi-threaded support.
825          */
826         TAILQ_HEAD(__fdlist, __fh_t) fdlist;
827
828         db_mutex_t       mtx_mt;        /* Mersenne Twister mutex */
829         int              mti;           /* Mersenne Twister index */
830         u_long          *mt;            /* Mersenne Twister state vector */
831
832         DB_CIPHER       *crypto_handle; /* Crypto handle */
833         DB_LOCKTAB      *lk_handle;     /* Lock handle */
834         DB_LOG          *lg_handle;     /* Log handle */
835         DB_MPOOL        *mp_handle;     /* Mpool handle */
836         DB_MUTEXMGR     *mutex_handle;  /* Mutex handle */
837         DB_REP          *rep_handle;    /* Replication handle */
838         DB_TXNMGR       *tx_handle;     /* Txn handle */
839
840         DB_BACKUP       *backup_handle; /* database copy configuration. */
841
842         /*
843          * XA support.
844          */
845         int              xa_rmid;       /* XA Resource Manager ID */
846         int              xa_ref;        /* XA Reference count */
847         TAILQ_ENTRY(__env) links;       /* XA environments */
848
849         /* Application callback to copy data to/from a custom data source */
850 #define DB_USERCOPY_GETDATA     0x0001
851 #define DB_USERCOPY_SETDATA     0x0002
852         int (*dbt_usercopy)
853             __P((DBT *, u_int32_t, void *, u_int32_t, u_int32_t));
854
855         int (*log_verify_wrap) __P((ENV *, const char *, u_int32_t,
856             const char *, const char *, time_t, time_t, u_int32_t,  u_int32_t,
857             u_int32_t, u_int32_t, int, int));
858
859         REGINFO *reginfo;               /* REGINFO structure reference */
860
861 #define DB_TEST_ELECTINIT        1      /* after __rep_elect_init */
862 #define DB_TEST_ELECTVOTE1       2      /* after sending VOTE1 */
863 #define DB_TEST_NO_PAGES         3      /* before sending PAGE */
864 #define DB_TEST_POSTDESTROY      4      /* after destroy op */
865 #define DB_TEST_POSTLOG          5      /* after logging all pages */
866 #define DB_TEST_POSTLOGMETA      6      /* after logging meta in btree */
867 #define DB_TEST_POSTOPEN         7      /* after __os_open */
868 #define DB_TEST_POSTSYNC         8      /* after syncing the log */
869 #define DB_TEST_PREDESTROY       9      /* before destroy op */
870 #define DB_TEST_PREOPEN          10     /* before __os_open */
871 #define DB_TEST_REPMGR_PERM      11     /* repmgr perm/archiving tests */
872 #define DB_TEST_SUBDB_LOCKS      12     /* subdb locking tests */
873         int     test_abort;             /* Abort value for testing */
874         int     test_check;             /* Checkpoint value for testing */
875         int     test_copy;              /* Copy value for testing */
876
877 #define ENV_CDB                 0x00000001 /* DB_INIT_CDB */
878 #define ENV_DBLOCAL             0x00000002 /* Environment for a private DB */
879 #define ENV_LITTLEENDIAN        0x00000004 /* Little endian system. */
880 #define ENV_LOCKDOWN            0x00000008 /* DB_LOCKDOWN set */
881 #define ENV_NO_OUTPUT_SET       0x00000010 /* No output channel set */
882 #define ENV_OPEN_CALLED         0x00000020 /* DB_ENV->open called */
883 #define ENV_PRIVATE             0x00000040 /* DB_PRIVATE set */
884 #define ENV_RECOVER_FATAL       0x00000080 /* Doing fatal recovery in env */
885 #define ENV_REF_COUNTED         0x00000100 /* Region references this handle */
886 #define ENV_SYSTEM_MEM          0x00000200 /* DB_SYSTEM_MEM set */
887 #define ENV_THREAD              0x00000400 /* DB_THREAD set */
888 #define ENV_FORCE_TXN_BULK      0x00000800 /* Txns use bulk mode-for testing */
889         u_int32_t flags;
890 };
891
892 /*******************************************************
893  * Database Access Methods.
894  *******************************************************/
895 /*
896  * DB_IS_THREADED --
897  *      The database handle is free-threaded (was opened with DB_THREAD).
898  */
899 #define DB_IS_THREADED(dbp)                                             \
900         ((dbp)->mutex != MUTEX_INVALID)
901
902 /* Initialization methods are often illegal before/after open is called. */
903 #define DB_ILLEGAL_AFTER_OPEN(dbp, name)                                \
904         if (F_ISSET((dbp), DB_AM_OPEN_CALLED))                          \
905                 return (__db_mi_open((dbp)->env, name, 1));
906 #define DB_ILLEGAL_BEFORE_OPEN(dbp, name)                               \
907         if (!F_ISSET((dbp), DB_AM_OPEN_CALLED))                         \
908                 return (__db_mi_open((dbp)->env, name, 0));
909 /* Some initialization methods are illegal if environment isn't local. */
910 #define DB_ILLEGAL_IN_ENV(dbp, name)                                    \
911         if (!F_ISSET((dbp)->env, ENV_DBLOCAL))                          \
912                 return (__db_mi_env((dbp)->env, name));
913 #define DB_ILLEGAL_METHOD(dbp, flags) {                                 \
914         int __ret;                                                      \
915         if ((__ret = __dbh_am_chk(dbp, flags)) != 0)                    \
916                 return (__ret);                                         \
917 }
918
919 /*
920  * Common DBC->internal fields.  Each access method adds additional fields
921  * to this list, but the initial fields are common.
922  */
923 #define __DBC_INTERNAL                                                  \
924         DBC      *opd;                  /* Off-page duplicate cursor. */\
925         DBC      *pdbc;                 /* Pointer to parent cursor. */ \
926                                                                         \
927         void     *page;                 /* Referenced page. */          \
928         u_int32_t part;                 /* Partition number. */         \
929         db_pgno_t root;                 /* Tree root. */                \
930         db_pgno_t pgno;                 /* Referenced page number. */   \
931         db_indx_t indx;                 /* Referenced key item index. */\
932                                                                         \
933         /* Streaming -- cache last position. */                         \
934         db_pgno_t stream_start_pgno;    /* Last start pgno. */          \
935         u_int32_t stream_off;           /* Current offset. */           \
936         db_pgno_t stream_curr_pgno;     /* Current overflow page. */    \
937                                                                         \
938         DB_LOCK         lock;           /* Cursor lock. */              \
939         db_lockmode_t   lock_mode;      /* Lock mode. */
940
941 struct __dbc_internal {
942         __DBC_INTERNAL
943 };
944
945 /* Actions that __db_master_update can take. */
946 typedef enum { MU_REMOVE, MU_RENAME, MU_OPEN, MU_MOVE } mu_action;
947
948 /*
949  * Access-method-common macro for determining whether a cursor
950  * has been initialized.
951  */
952 #ifdef HAVE_PARTITION
953 #define IS_INITIALIZED(dbc)     (DB_IS_PARTITIONED((dbc)->dbp) ?        \
954                 ((PART_CURSOR *)(dbc)->internal)->sub_cursor != NULL && \
955                 ((PART_CURSOR *)(dbc)->internal)->sub_cursor->          \
956                     internal->pgno != PGNO_INVALID :                    \
957                 (dbc)->internal->pgno != PGNO_INVALID)
958 #else
959 #define IS_INITIALIZED(dbc)     ((dbc)->internal->pgno != PGNO_INVALID)
960 #endif
961
962 /* Free the callback-allocated buffer, if necessary, hanging off of a DBT. */
963 #define FREE_IF_NEEDED(env, dbt)                                        \
964         if (F_ISSET((dbt), DB_DBT_APPMALLOC)) {                         \
965                 __os_ufree((env), (dbt)->data);                         \
966                 F_CLR((dbt), DB_DBT_APPMALLOC);                         \
967         }
968
969 /*
970  * Use memory belonging to object "owner" to return the results of
971  * any no-DBT-flag get ops on cursor "dbc".
972  */
973 #define SET_RET_MEM(dbc, owner)                         \
974         do {                                            \
975                 (dbc)->rskey = &(owner)->my_rskey;      \
976                 (dbc)->rkey = &(owner)->my_rkey;        \
977                 (dbc)->rdata = &(owner)->my_rdata;      \
978         } while (0)
979
980 /* Use the return-data memory src is currently set to use in dest as well. */
981 #define COPY_RET_MEM(src, dest)                         \
982         do {                                            \
983                 (dest)->rskey = (src)->rskey;           \
984                 (dest)->rkey = (src)->rkey;             \
985                 (dest)->rdata = (src)->rdata;           \
986         } while (0)
987
988 /* Reset the returned-memory pointers to their defaults. */
989 #define RESET_RET_MEM(dbc)                              \
990         do {                                            \
991                 (dbc)->rskey = &(dbc)->my_rskey;        \
992                 (dbc)->rkey = &(dbc)->my_rkey;          \
993                 (dbc)->rdata = &(dbc)->my_rdata;        \
994         } while (0)
995
996 #define COMPACT_TRUNCATE(c_data) do {                   \
997         if (c_data->compact_truncate > 1)               \
998                 c_data->compact_truncate--;             \
999 } while (0)
1000
1001 /*******************************************************
1002  * Mpool.
1003  *******************************************************/
1004 /*
1005  * File types for DB access methods.  Negative numbers are reserved to DB.
1006  */
1007 #define DB_FTYPE_SET            -1              /* Call pgin/pgout functions. */
1008 #define DB_FTYPE_NOTSET          0              /* Don't call... */
1009 #define DB_LSN_OFF_NOTSET       -1              /* Not yet set. */
1010 #define DB_CLEARLEN_NOTSET      UINT32_MAX      /* Not yet set. */
1011
1012 /* Structure used as the DB pgin/pgout pgcookie. */
1013 typedef struct __dbpginfo {
1014         u_int32_t db_pagesize;          /* Underlying page size. */
1015         u_int32_t flags;                /* Some DB_AM flags needed. */
1016         DBTYPE  type;                   /* DB type */
1017 } DB_PGINFO;
1018
1019 /*******************************************************
1020  * Log.
1021  *******************************************************/
1022 /* Initialize an LSN to 'zero'. */
1023 #define ZERO_LSN(LSN) do {                                              \
1024         (LSN).file = 0;                                                 \
1025         (LSN).offset = 0;                                               \
1026 } while (0)
1027 #define IS_ZERO_LSN(LSN)        ((LSN).file == 0 && (LSN).offset == 0)
1028
1029 #define IS_INIT_LSN(LSN)        ((LSN).file == 1 && (LSN).offset == 0)
1030 #define INIT_LSN(LSN)           do {                                    \
1031         (LSN).file = 1;                                                 \
1032         (LSN).offset = 0;                                               \
1033 } while (0)
1034
1035 #define MAX_LSN(LSN) do {                                               \
1036         (LSN).file = UINT32_MAX;                                        \
1037         (LSN).offset = UINT32_MAX;                                      \
1038 } while (0)
1039 #define IS_MAX_LSN(LSN) \
1040         ((LSN).file == UINT32_MAX && (LSN).offset == UINT32_MAX)
1041
1042 /* If logging is turned off, smash the lsn. */
1043 #define LSN_NOT_LOGGED(LSN) do {                                        \
1044         (LSN).file = 0;                                                 \
1045         (LSN).offset = 1;                                               \
1046 } while (0)
1047 #define IS_NOT_LOGGED_LSN(LSN) \
1048         ((LSN).file == 0 && (LSN).offset == 1)
1049
1050 /*
1051  * LOG_COMPARE -- compare two LSNs.
1052  */
1053
1054 #define LOG_COMPARE(lsn0, lsn1)                                         \
1055         ((lsn0)->file != (lsn1)->file ?                                 \
1056         ((lsn0)->file < (lsn1)->file ? -1 : 1) :                        \
1057         ((lsn0)->offset != (lsn1)->offset ?                             \
1058         ((lsn0)->offset < (lsn1)->offset ? -1 : 1) : 0))
1059
1060 /*******************************************************
1061  * Txn.
1062  *******************************************************/
1063 #define DB_NONBLOCK(C)  ((C)->txn != NULL && F_ISSET((C)->txn, TXN_NOWAIT))
1064 #define NOWAIT_FLAG(txn) \
1065         ((txn) != NULL && F_ISSET((txn), TXN_NOWAIT) ? DB_LOCK_NOWAIT : 0)
1066 #define IS_REAL_TXN(txn)                                                \
1067         ((txn) != NULL && !F_ISSET(txn, TXN_FAMILY))
1068 #define IS_SUBTRANSACTION(txn)                                          \
1069         ((txn) != NULL && (txn)->parent != NULL)
1070
1071 /* Checks for existence of an XA transaction in access method interfaces. */
1072 #define XA_CHECK_TXN(ip, txn)                                           \
1073         if ((ip) != NULL && (txn) == NULL) {                            \
1074                 (txn) = SH_TAILQ_FIRST(&(ip)->dbth_xatxn, __db_txn);    \
1075                 DB_ASSERT(env, txn == NULL ||                           \
1076                     txn->xa_thr_status == TXN_XA_THREAD_ASSOCIATED);    \
1077         }
1078
1079 /* Ensure that there is no XA transaction active. */
1080 #define XA_NO_TXN(ip, retval) {                                         \
1081         DB_TXN *__txn;                                                  \
1082         retval = 0;                                                     \
1083         if ((ip) != NULL) {                                             \
1084                 __txn = SH_TAILQ_FIRST(&(ip)->dbth_xatxn, __db_txn);    \
1085                 if (__txn != NULL &&                                    \
1086                     __txn->xa_thr_status == TXN_XA_THREAD_ASSOCIATED)   \
1087                         retval = EINVAL;                                \
1088         }                                                               \
1089 }
1090
1091 /*******************************************************
1092  * Crypto.
1093  *******************************************************/
1094 #define DB_IV_BYTES     16              /* Bytes per IV */
1095 #define DB_MAC_KEY      20              /* Bytes per MAC checksum */
1096
1097 /*******************************************************
1098  * Compression
1099  *******************************************************/
1100 #define CMP_INT_SPARE_VAL       0xFC    /* Smallest byte value that the integer
1101                                            compression algorithm doesn't use */
1102
1103 #if defined(__cplusplus)
1104 }
1105 #endif
1106
1107 /*******************************************************
1108  * Remaining general DB includes.
1109  *******************************************************/
1110
1111
1112 #include "dbinc/globals.h"
1113 #include "dbinc/clock.h"
1114 #include "dbinc/debug.h"
1115 #include "dbinc/region.h"
1116 #include "dbinc_auto/env_ext.h"
1117 #include "dbinc/mutex.h"
1118 #ifdef HAVE_REPLICATION_THREADS
1119 #include "dbinc/repmgr.h"
1120 #endif
1121 #include "dbinc/rep.h"
1122 #include "dbinc/os.h"
1123 #include "dbinc_auto/clib_ext.h"
1124 #include "dbinc_auto/common_ext.h"
1125
1126 /*******************************************************
1127  * Remaining Log.
1128  * These need to be defined after the general includes
1129  * because they need rep.h from above.
1130  *******************************************************/
1131 /*
1132  * Test if the environment is currently logging changes.  If we're in recovery
1133  * or we're a replication client, we don't need to log changes because they're
1134  * already in the log, even though we have a fully functional log system.
1135  */
1136 #define DBENV_LOGGING(env)                                              \
1137         (LOGGING_ON(env) && !IS_REP_CLIENT(env) && (!IS_RECOVERING(env)))
1138
1139 /*
1140  * Test if we need to log a change.  By default, we don't log operations without
1141  * associated transactions, unless DIAGNOSTIC, DEBUG_ROP or DEBUG_WOP are on.
1142  * This is because we want to get log records for read/write operations, and, if
1143  * we are trying to debug something, more information is always better.
1144  *
1145  * The DBC_RECOVER flag is set when we're in abort, as well as during recovery;
1146  * thus DBC_LOGGING may be false for a particular dbc even when DBENV_LOGGING
1147  * is true.
1148  *
1149  * We explicitly use LOGGING_ON/IS_REP_CLIENT here because we don't want to pull
1150  * in the log headers, which IS_RECOVERING (and thus DBENV_LOGGING) rely on, and
1151  * because DBC_RECOVER should be set anytime IS_RECOVERING would be true.
1152  *
1153  * If we're not in recovery (master - doing an abort or a client applying
1154  * a txn), then a client's only path through here is on an internal
1155  * operation, and a master's only path through here is a transactional
1156  * operation.  Detect if either is not the case.
1157  */
1158 #if defined(DIAGNOSTIC) || defined(DEBUG_ROP)  || defined(DEBUG_WOP)
1159 #define DBC_LOGGING(dbc)        __dbc_logging(dbc)
1160 #else
1161 #define DBC_LOGGING(dbc)                                                \
1162         ((dbc)->txn != NULL && LOGGING_ON((dbc)->env) &&                \
1163             !F_ISSET((dbc), DBC_RECOVER) && !IS_REP_CLIENT((dbc)->env))
1164 #endif
1165
1166 #endif /* !_DB_INT_H_ */