resetting manifest requested domain to floor
[platform/upstream/db4.git] / common / db_err.c
1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 1996-2009 Oracle.  All rights reserved.
5  *
6  * $Id$
7  */
8
9 #include "db_config.h"
10
11 #include "db_int.h"
12 #include "dbinc/db_page.h"
13 #include "dbinc/db_am.h"
14 #include "dbinc/lock.h"
15 #include "dbinc/log.h"
16 #include "dbinc/mp.h"
17 #include "dbinc/txn.h"
18
19 static void __db_msgcall __P((const DB_ENV *, const char *, va_list));
20 static void __db_msgfile __P((const DB_ENV *, const char *, va_list));
21
22 /*
23  * __db_fchk --
24  *      General flags checking routine.
25  *
26  * PUBLIC: int __db_fchk __P((ENV *, const char *, u_int32_t, u_int32_t));
27  */
28 int
29 __db_fchk(env, name, flags, ok_flags)
30         ENV *env;
31         const char *name;
32         u_int32_t flags, ok_flags;
33 {
34         return (LF_ISSET(~ok_flags) ? __db_ferr(env, name, 0) : 0);
35 }
36
37 /*
38  * __db_fcchk --
39  *      General combination flags checking routine.
40  *
41  * PUBLIC: int __db_fcchk
42  * PUBLIC:    __P((ENV *, const char *, u_int32_t, u_int32_t, u_int32_t));
43  */
44 int
45 __db_fcchk(env, name, flags, flag1, flag2)
46         ENV *env;
47         const char *name;
48         u_int32_t flags, flag1, flag2;
49 {
50         return (LF_ISSET(flag1) &&
51             LF_ISSET(flag2) ? __db_ferr(env, name, 1) : 0);
52 }
53
54 /*
55  * __db_ferr --
56  *      Common flag errors.
57  *
58  * PUBLIC: int __db_ferr __P((const ENV *, const char *, int));
59  */
60 int
61 __db_ferr(env, name, iscombo)
62         const ENV *env;
63         const char *name;
64         int iscombo;
65 {
66         __db_errx(env, "illegal flag %sspecified to %s",
67             iscombo ? "combination " : "", name);
68         return (EINVAL);
69 }
70
71 /*
72  * __db_fnl --
73  *      Common flag-needs-locking message.
74  *
75  * PUBLIC: int __db_fnl __P((const ENV *, const char *));
76  */
77 int
78 __db_fnl(env, name)
79         const ENV *env;
80         const char *name;
81 {
82         __db_errx(env,
83     "%s: DB_READ_COMMITTED, DB_READ_UNCOMMITTED and DB_RMW require locking",
84             name);
85         return (EINVAL);
86 }
87
88 /*
89  * __db_pgerr --
90  *      Error when unable to retrieve a specified page.
91  *
92  * PUBLIC: int __db_pgerr __P((DB *, db_pgno_t, int));
93  */
94 int
95 __db_pgerr(dbp, pgno, errval)
96         DB *dbp;
97         db_pgno_t pgno;
98         int errval;
99 {
100         /*
101          * Three things are certain:
102          * Death, taxes, and lost data.
103          * Guess which has occurred.
104          */
105         __db_errx(dbp->env,
106             "unable to create/retrieve page %lu", (u_long)pgno);
107         return (__env_panic(dbp->env, errval));
108 }
109
110 /*
111  * __db_pgfmt --
112  *      Error when a page has the wrong format.
113  *
114  * PUBLIC: int __db_pgfmt __P((ENV *, db_pgno_t));
115  */
116 int
117 __db_pgfmt(env, pgno)
118         ENV *env;
119         db_pgno_t pgno;
120 {
121         __db_errx(env, "page %lu: illegal page type or format", (u_long)pgno);
122         return (__env_panic(env, EINVAL));
123 }
124
125 #ifdef DIAGNOSTIC
126 /*
127  * __db_assert --
128  *      Error when an assertion fails.  Only checked if #DIAGNOSTIC defined.
129  *
130  * PUBLIC: #ifdef DIAGNOSTIC
131  * PUBLIC: void __db_assert __P((ENV *, const char *, const char *, int));
132  * PUBLIC: #endif
133  */
134 void
135 __db_assert(env, e, file, line)
136         ENV *env;
137         const char *e, *file;
138         int line;
139 {
140         __db_errx(env, "assert failure: %s/%d: \"%s\"", file, line, e);
141
142         __os_abort(env);
143         /* NOTREACHED */
144 }
145 #endif
146
147 /*
148  * __env_panic_msg --
149  *      Just report that someone else paniced.
150  *
151  * PUBLIC: int __env_panic_msg __P((ENV *));
152  */
153 int
154 __env_panic_msg(env)
155         ENV *env;
156 {
157         DB_ENV *dbenv;
158         int ret;
159
160         dbenv = env->dbenv;
161
162         ret = DB_RUNRECOVERY;
163
164         __db_errx(env, "PANIC: fatal region error detected; run recovery");
165
166         if (dbenv->db_paniccall != NULL)                /* Deprecated */
167                 dbenv->db_paniccall(dbenv, ret);
168
169         /* Must check for DB_EVENT_REG_PANIC panic first because it is never
170          * set by itself.  If set, it means panic came from DB_REGISTER code
171          * only, otherwise it could be from many possible places in the code.
172          */
173         if ((env->reginfo != NULL) &&
174             (((REGENV *)env->reginfo->primary)->reg_panic))
175                 DB_EVENT(env, DB_EVENT_REG_PANIC, &ret);
176         else
177                 DB_EVENT(env, DB_EVENT_PANIC, &ret);
178
179         return (ret);
180 }
181
182 /*
183  * __env_panic --
184  *      Lock out the database environment due to unrecoverable error.
185  *
186  * PUBLIC: int __env_panic __P((ENV *, int));
187  */
188 int
189 __env_panic(env, errval)
190         ENV *env;
191         int errval;
192 {
193         DB_ENV *dbenv;
194
195         dbenv = env->dbenv;
196
197         if (env != NULL) {
198                 __env_panic_set(env, 1);
199
200                 __db_err(env, errval, "PANIC");
201
202                 if (dbenv->db_paniccall != NULL)        /* Deprecated */
203                         dbenv->db_paniccall(dbenv, errval);
204
205                 /* Must check for DB_EVENT_REG_PANIC first because it is never
206                  * set by itself.  If set, it means panic came from DB_REGISTER
207                  * code only, otherwise it could be from many possible places
208                  * in the code.
209                  */
210                 if ((env->reginfo != NULL) &&
211                     (((REGENV *)env->reginfo->primary)->reg_panic))
212                         DB_EVENT(env, DB_EVENT_REG_PANIC, &errval);
213                 else
214                         DB_EVENT(env, DB_EVENT_PANIC, &errval);
215         }
216
217 #if defined(DIAGNOSTIC) && !defined(CONFIG_TEST)
218         /*
219          * We want a stack trace of how this could possibly happen.
220          *
221          * Don't drop core if it's the test suite -- it's reasonable for the
222          * test suite to check to make sure that DB_RUNRECOVERY is returned
223          * under certain conditions.
224          */
225         __os_abort(env);
226         /* NOTREACHED */
227 #endif
228
229         /*
230          * Chaos reigns within.
231          * Reflect, repent, and reboot.
232          * Order shall return.
233          */
234         return (DB_RUNRECOVERY);
235 }
236
237 /*
238  * db_strerror --
239  *      ANSI C strerror(3) for DB.
240  *
241  * EXTERN: char *db_strerror __P((int));
242  */
243 char *
244 db_strerror(error)
245         int error;
246 {
247         char *p;
248
249         if (error == 0)
250                 return ("Successful return: 0");
251         if (error > 0) {
252                 if ((p = strerror(error)) != NULL)
253                         return (p);
254                 return (__db_unknown_error(error));
255         }
256
257         /*
258          * !!!
259          * The Tcl API requires that some of these return strings be compared
260          * against strings stored in application scripts.  So, any of these
261          * errors that do not invariably result in a Tcl exception may not be
262          * altered.
263          */
264         switch (error) {
265         case DB_BUFFER_SMALL:
266                 return
267                     ("DB_BUFFER_SMALL: User memory too small for return value");
268         case DB_DONOTINDEX:
269                 return ("DB_DONOTINDEX: Secondary index callback returns null");
270         case DB_FOREIGN_CONFLICT:
271                 return
272        ("DB_FOREIGN_CONFLICT: A foreign database constraint has been violated");
273         case DB_KEYEMPTY:
274                 return ("DB_KEYEMPTY: Non-existent key/data pair");
275         case DB_KEYEXIST:
276                 return ("DB_KEYEXIST: Key/data pair already exists");
277         case DB_LOCK_DEADLOCK:
278                 return
279                     ("DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock");
280         case DB_LOCK_NOTGRANTED:
281                 return ("DB_LOCK_NOTGRANTED: Lock not granted");
282         case DB_LOG_BUFFER_FULL:
283                 return ("DB_LOG_BUFFER_FULL: In-memory log buffer is full");
284         case DB_NOSERVER:
285                 return ("DB_NOSERVER: Fatal error, no RPC server");
286         case DB_NOSERVER_HOME:
287                 return ("DB_NOSERVER_HOME: Home unrecognized at server");
288         case DB_NOSERVER_ID:
289                 return ("DB_NOSERVER_ID: Identifier unrecognized at server");
290         case DB_NOTFOUND:
291                 return ("DB_NOTFOUND: No matching key/data pair found");
292         case DB_OLD_VERSION:
293                 return ("DB_OLDVERSION: Database requires a version upgrade");
294         case DB_PAGE_NOTFOUND:
295                 return ("DB_PAGE_NOTFOUND: Requested page not found");
296         case DB_REP_DUPMASTER:
297                 return ("DB_REP_DUPMASTER: A second master site appeared");
298         case DB_REP_HANDLE_DEAD:
299                 return ("DB_REP_HANDLE_DEAD: Handle is no longer valid");
300         case DB_REP_HOLDELECTION:
301                 return ("DB_REP_HOLDELECTION: Need to hold an election");
302         case DB_REP_IGNORE:
303                 return ("DB_REP_IGNORE: Replication record/operation ignored");
304         case DB_REP_ISPERM:
305                 return ("DB_REP_ISPERM: Permanent record written");
306         case DB_REP_JOIN_FAILURE:
307                 return
308             ("DB_REP_JOIN_FAILURE: Unable to join replication group");
309         case DB_REP_LEASE_EXPIRED:
310                 return
311             ("DB_REP_LEASE_EXPIRED: Replication leases have expired");
312         case DB_REP_LOCKOUT:
313                 return
314             ("DB_REP_LOCKOUT: Waiting for replication recovery to complete");
315         case DB_REP_NEWSITE:
316                 return ("DB_REP_NEWSITE: A new site has entered the system");
317         case DB_REP_NOTPERM:
318                 return ("DB_REP_NOTPERM: Permanent log record not written");
319         case DB_REP_UNAVAIL:
320                 return ("DB_REP_UNAVAIL: Unable to elect a master");
321         case DB_RUNRECOVERY:
322                 return ("DB_RUNRECOVERY: Fatal error, run database recovery");
323         case DB_SECONDARY_BAD:
324                 return
325             ("DB_SECONDARY_BAD: Secondary index inconsistent with primary");
326         case DB_VERIFY_BAD:
327                 return ("DB_VERIFY_BAD: Database verification failed");
328         case DB_VERSION_MISMATCH:
329                 return
330             ("DB_VERSION_MISMATCH: Database environment version mismatch");
331         default:
332                 break;
333         }
334
335         return (__db_unknown_error(error));
336 }
337
338 /*
339  * __db_unknown_error --
340  *      Format an unknown error value into a static buffer.
341  *
342  * PUBLIC: char *__db_unknown_error __P((int));
343  */
344 char *
345 __db_unknown_error(error)
346         int error;
347 {
348         /*
349          * !!!
350          * Room for a 64-bit number + slop.  This buffer is only used
351          * if we're given an unknown error number, which should never
352          * happen.
353          *
354          * We're no longer thread-safe if it does happen, but the worst
355          * result is a corrupted error string because there will always
356          * be a trailing nul byte since the error buffer is nul filled
357          * and longer than any error message.
358          */
359         (void)snprintf(DB_GLOBAL(error_buf),
360             sizeof(DB_GLOBAL(error_buf)), "Unknown error: %d", error);
361         return (DB_GLOBAL(error_buf));
362 }
363
364 /*
365  * __db_syserr --
366  *      Standard error routine.
367  *
368  * PUBLIC: void __db_syserr __P((const ENV *, int, const char *, ...))
369  * PUBLIC:    __attribute__ ((__format__ (__printf__, 3, 4)));
370  */
371 void
372 #ifdef STDC_HEADERS
373 __db_syserr(const ENV *env, int error, const char *fmt, ...)
374 #else
375 __db_syserr(env, error, fmt, va_alist)
376         const ENV *env;
377         int error;
378         const char *fmt;
379         va_dcl
380 #endif
381 {
382         DB_ENV *dbenv;
383
384         dbenv = env == NULL ? NULL : env->dbenv;
385
386         /*
387          * The same as DB->err, except we don't default to writing to stderr
388          * after any output channel has been configured, and we use a system-
389          * specific function to translate errors to strings.
390          */
391         DB_REAL_ERR(dbenv, error, DB_ERROR_SYSTEM, 0, fmt);
392 }
393
394 /*
395  * __db_err --
396  *      Standard error routine.
397  *
398  * PUBLIC: void __db_err __P((const ENV *, int, const char *, ...))
399  * PUBLIC:    __attribute__ ((__format__ (__printf__, 3, 4)));
400  */
401 void
402 #ifdef STDC_HEADERS
403 __db_err(const ENV *env, int error, const char *fmt, ...)
404 #else
405 __db_err(env, error, fmt, va_alist)
406         const ENV *env;
407         int error;
408         const char *fmt;
409         va_dcl
410 #endif
411 {
412         DB_ENV *dbenv;
413
414         dbenv = env == NULL ? NULL : env->dbenv;
415
416         /*
417          * The same as DB->err, except we don't default to writing to stderr
418          * once an output channel has been configured.
419          */
420         DB_REAL_ERR(dbenv, error, DB_ERROR_SET, 0, fmt);
421 }
422
423 /*
424  * __db_errx --
425  *      Standard error routine.
426  *
427  * PUBLIC: void __db_errx __P((const ENV *, const char *, ...))
428  * PUBLIC:    __attribute__ ((__format__ (__printf__, 2, 3)));
429  */
430 void
431 #ifdef STDC_HEADERS
432 __db_errx(const ENV *env, const char *fmt, ...)
433 #else
434 __db_errx(env, fmt, va_alist)
435         const ENV *env;
436         const char *fmt;
437         va_dcl
438 #endif
439 {
440         DB_ENV *dbenv;
441
442         dbenv = env == NULL ? NULL : env->dbenv;
443
444         /*
445          * The same as DB->errx, except we don't default to writing to stderr
446          * once an output channel has been configured.
447          */
448         DB_REAL_ERR(dbenv, 0, DB_ERROR_NOT_SET, 0, fmt);
449 }
450
451 /*
452  * __db_errcall --
453  *      Do the error message work for callback functions.
454  *
455  * PUBLIC: void __db_errcall
456  * PUBLIC:    __P((const DB_ENV *, int, db_error_set_t, const char *, va_list));
457  */
458 void
459 __db_errcall(dbenv, error, error_set, fmt, ap)
460         const DB_ENV *dbenv;
461         int error;
462         db_error_set_t error_set;
463         const char *fmt;
464         va_list ap;
465 {
466         char *p;
467         char buf[2048];         /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
468         char sysbuf[1024];      /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
469
470         p = buf;
471         if (fmt != NULL)
472                 p += vsnprintf(buf, sizeof(buf), fmt, ap);
473         if (error_set != DB_ERROR_NOT_SET)
474                 p += snprintf(p,
475                     sizeof(buf) - (size_t)(p - buf), ": %s",
476                     error_set == DB_ERROR_SET ? db_strerror(error) :
477                     __os_strerror(error, sysbuf, sizeof(sysbuf)));
478
479         dbenv->db_errcall(dbenv, dbenv->db_errpfx, buf);
480 }
481
482 /*
483  * __db_errfile --
484  *      Do the error message work for FILE *s.
485  *
486  * PUBLIC: void __db_errfile
487  * PUBLIC:    __P((const DB_ENV *, int, db_error_set_t, const char *, va_list));
488  */
489 void
490 __db_errfile(dbenv, error, error_set, fmt, ap)
491         const DB_ENV *dbenv;
492         int error;
493         db_error_set_t error_set;
494         const char *fmt;
495         va_list ap;
496 {
497         FILE *fp;
498         int need_sep;
499         char sysbuf[1024];      /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
500
501         fp = dbenv == NULL ||
502             dbenv->db_errfile == NULL ? stderr : dbenv->db_errfile;
503         need_sep = 0;
504
505         if (dbenv != NULL && dbenv->db_errpfx != NULL) {
506                 (void)fprintf(fp, "%s", dbenv->db_errpfx);
507                 need_sep = 1;
508         }
509         if (fmt != NULL && fmt[0] != '\0') {
510                 if (need_sep)
511                         (void)fprintf(fp, ": ");
512                 need_sep = 1;
513                 (void)vfprintf(fp, fmt, ap);
514         }
515         if (error_set != DB_ERROR_NOT_SET)
516                 (void)fprintf(fp, "%s%s",
517                     need_sep ? ": " : "",
518                     error_set == DB_ERROR_SET ? db_strerror(error) :
519                     __os_strerror(error, sysbuf, sizeof(sysbuf)));
520         (void)fprintf(fp, "\n");
521         (void)fflush(fp);
522 }
523
524 /*
525  * __db_msgadd --
526  *      Aggregate a set of strings into a buffer for the callback API.
527  *
528  * PUBLIC: void __db_msgadd __P((ENV *, DB_MSGBUF *, const char *, ...))
529  * PUBLIC:    __attribute__ ((__format__ (__printf__, 3, 4)));
530  */
531 void
532 #ifdef STDC_HEADERS
533 __db_msgadd(ENV *env, DB_MSGBUF *mbp, const char *fmt, ...)
534 #else
535 __db_msgadd(env, mbp, fmt, va_alist)
536         ENV *env;
537         DB_MSGBUF *mbp;
538         const char *fmt;
539         va_dcl
540 #endif
541 {
542         va_list ap;
543
544 #ifdef STDC_HEADERS
545         va_start(ap, fmt);
546 #else
547         va_start(ap);
548 #endif
549         __db_msgadd_ap(env, mbp, fmt, ap);
550         va_end(ap);
551 }
552
553 /*
554  * __db_msgadd_ap --
555  *      Aggregate a set of strings into a buffer for the callback API.
556  *
557  * PUBLIC: void __db_msgadd_ap
558  * PUBLIC:     __P((ENV *, DB_MSGBUF *, const char *, va_list));
559  */
560 void
561 __db_msgadd_ap(env, mbp, fmt, ap)
562         ENV *env;
563         DB_MSGBUF *mbp;
564         const char *fmt;
565         va_list ap;
566 {
567         size_t len, olen;
568         char buf[2048];         /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
569
570         len = (size_t)vsnprintf(buf, sizeof(buf), fmt, ap);
571
572         /*
573          * There's a heap buffer in the ENV handle we use to aggregate the
574          * message chunks.  We maintain a pointer to the buffer, the next slot
575          * to be filled in in the buffer, and a total buffer length.
576          */
577         olen = (size_t)(mbp->cur - mbp->buf);
578         if (olen + len >= mbp->len) {
579                 if (__os_realloc(env, mbp->len + len + 256, &mbp->buf))
580                         return;
581                 mbp->len += (len + 256);
582                 mbp->cur = mbp->buf + olen;
583         }
584
585         memcpy(mbp->cur, buf, len + 1);
586         mbp->cur += len;
587 }
588
589 /*
590  * __db_msg --
591  *      Standard DB stat message routine.
592  *
593  * PUBLIC: void __db_msg __P((const ENV *, const char *, ...))
594  * PUBLIC:    __attribute__ ((__format__ (__printf__, 2, 3)));
595  */
596 void
597 #ifdef STDC_HEADERS
598 __db_msg(const ENV *env, const char *fmt, ...)
599 #else
600 __db_msg(env, fmt, va_alist)
601         const ENV *env;
602         const char *fmt;
603         va_dcl
604 #endif
605 {
606         DB_ENV *dbenv;
607
608         dbenv = env == NULL ? NULL : env->dbenv;
609
610         DB_REAL_MSG(dbenv, fmt);
611 }
612
613 /*
614  * __db_msgcall --
615  *      Do the message work for callback functions.
616  */
617 static void
618 __db_msgcall(dbenv, fmt, ap)
619         const DB_ENV *dbenv;
620         const char *fmt;
621         va_list ap;
622 {
623         char buf[2048];         /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
624
625         (void)vsnprintf(buf, sizeof(buf), fmt, ap);
626
627         dbenv->db_msgcall(dbenv, buf);
628 }
629
630 /*
631  * __db_msgfile --
632  *      Do the message work for FILE *s.
633  */
634 static void
635 __db_msgfile(dbenv, fmt, ap)
636         const DB_ENV *dbenv;
637         const char *fmt;
638         va_list ap;
639 {
640         FILE *fp;
641
642         fp = dbenv == NULL ||
643             dbenv->db_msgfile == NULL ? stdout : dbenv->db_msgfile;
644         (void)vfprintf(fp, fmt, ap);
645
646         (void)fprintf(fp, "\n");
647         (void)fflush(fp);
648 }
649
650 /*
651  * __db_unknown_flag -- report internal error
652  *
653  * PUBLIC: int __db_unknown_flag __P((ENV *, char *, u_int32_t));
654  */
655 int
656 __db_unknown_flag(env, routine, flag)
657         ENV *env;
658         char *routine;
659         u_int32_t flag;
660 {
661         __db_errx(env, "%s: Unknown flag: %#x", routine, (u_int)flag);
662
663 #ifdef DIAGNOSTIC
664         __os_abort(env);
665         /* NOTREACHED */
666 #endif
667         return (EINVAL);
668 }
669
670 /*
671  * __db_unknown_type -- report internal database type error
672  *
673  * PUBLIC: int __db_unknown_type __P((ENV *, char *, DBTYPE));
674  */
675 int
676 __db_unknown_type(env, routine, type)
677         ENV *env;
678         char *routine;
679         DBTYPE type;
680 {
681         __db_errx(env,
682             "%s: Unexpected database type: %s",
683             routine, __db_dbtype_to_string(type));
684
685 #ifdef DIAGNOSTIC
686         __os_abort(env);
687         /* NOTREACHED */
688 #endif
689         return (EINVAL);
690 }
691
692 /*
693  * __db_unknown_path -- report unexpected database code path error.
694  *
695  * PUBLIC: int __db_unknown_path __P((ENV *, char *));
696  */
697 int
698 __db_unknown_path(env, routine)
699         ENV *env;
700         char *routine;
701 {
702         __db_errx(env, "%s: Unexpected code path error", routine);
703
704 #ifdef DIAGNOSTIC
705         __os_abort(env);
706         /* NOTREACHED */
707 #endif
708         return (EINVAL);
709 }
710
711 /*
712  * __db_check_txn --
713  *      Check for common transaction errors.
714  *
715  * PUBLIC: int __db_check_txn __P((DB *, DB_TXN *, DB_LOCKER *, int));
716  */
717 int
718 __db_check_txn(dbp, txn, assoc_locker, read_op)
719         DB *dbp;
720         DB_TXN *txn;
721         DB_LOCKER *assoc_locker;
722         int read_op;
723 {
724         ENV *env;
725         int isp, ret;
726
727         env = dbp->env;
728
729         /*
730          * If we are in recovery or aborting a transaction, then we
731          * don't need to enforce the rules about dbp's not allowing
732          * transactional operations in non-transactional dbps and
733          * vica-versa.  This happens all the time as the dbp during
734          * an abort may be transactional, but we undo operations
735          * outside a transaction since we're aborting.
736          */
737         if (IS_RECOVERING(env) || F_ISSET(dbp, DB_AM_RECOVER))
738                 return (0);
739
740         /*
741          * Check for common transaction errors:
742          *      an operation on a handle whose open commit hasn't completed.
743          *      a transaction handle in a non-transactional environment
744          *      a transaction handle for a non-transactional database
745          */
746         if (txn == NULL || F_ISSET(txn, TXN_PRIVATE)) {
747                 if (dbp->cur_locker != NULL &&
748                     dbp->cur_locker->id >= TXN_MINIMUM)
749                         goto open_err;
750
751                 if (!read_op && F_ISSET(dbp, DB_AM_TXN)) {
752                         __db_errx(env,
753                     "Transaction not specified for a transactional database");
754                         return (EINVAL);
755                 }
756         } else if (F_ISSET(txn, TXN_CDSGROUP)) {
757                 if (!CDB_LOCKING(env)) {
758                         __db_errx(env,
759                             "CDS groups can only be used in a CDS environment");
760                         return (EINVAL);
761                 }
762                 /*
763                  * CDS group handles can be passed to any method, since they
764                  * only determine locker IDs.
765                  */
766                 return (0);
767         } else {
768                 if (!TXN_ON(env))
769                          return (__db_not_txn_env(env));
770
771                 if (!F_ISSET(dbp, DB_AM_TXN)) {
772                         __db_errx(env,
773                     "Transaction specified for a non-transactional database");
774                         return (EINVAL);
775                 }
776
777                 if (F_ISSET(txn, TXN_DEADLOCK))
778                         return (__db_txn_deadlock_err(env, txn));
779                 if (dbp->cur_locker != NULL &&
780                     dbp->cur_locker->id >= TXN_MINIMUM &&
781                      dbp->cur_locker->id != txn->txnid) {
782                         if ((ret = __lock_locker_is_parent(env,
783                              dbp->cur_locker, txn->locker, &isp)) != 0)
784                                 return (ret);
785                         if (!isp)
786                                 goto open_err;
787                 }
788         }
789
790         /*
791          * If dbp->associate_locker is not NULL, that means we're in
792          * the middle of a DB->associate with DB_CREATE (i.e., a secondary index
793          * creation).
794          *
795          * In addition to the usual transaction rules, we need to lock out
796          * non-transactional updates that aren't part of the associate (and
797          * thus are using some other locker ID).
798          *
799          * Transactional updates should simply block;  from the time we
800          * decide to build the secondary until commit, we'll hold a write
801          * lock on all of its pages, so it should be safe to attempt to update
802          * the secondary in another transaction (presumably by updating the
803          * primary).
804          */
805         if (!read_op && dbp->associate_locker != NULL &&
806             txn != NULL && dbp->associate_locker != assoc_locker) {
807                 __db_errx(env,
808             "Operation forbidden while secondary index is being created");
809                 return (EINVAL);
810         }
811
812         /*
813          * Check the txn and dbp are from the same env.
814          */
815         if (txn != NULL && env != txn->mgrp->env) {
816                 __db_errx(env,
817             "Transaction and database from different environments");
818                 return (EINVAL);
819         }
820
821         return (0);
822 open_err:
823         __db_errx(env,
824             "Transaction that opened the DB handle is still active");
825         return (EINVAL);
826 }
827
828 /*
829  * __db_txn_deadlock_err --
830  *      Transaction has allready been deadlocked.
831  *
832  * PUBLIC: int __db_txn_deadlock_err __P((ENV *, DB_TXN *));
833  */
834 int
835 __db_txn_deadlock_err(env, txn)
836         ENV *env;
837         DB_TXN *txn;
838 {
839         const char *name;
840
841         name = NULL;
842         (void)__txn_get_name(txn, &name);
843
844         __db_errx(env,
845             "%s%sprevious transaction deadlock return not resolved",
846             name == NULL ? "" : name, name == NULL ? "" : ": ");
847
848         return (EINVAL);
849 }
850
851 /*
852  * __db_not_txn_env --
853  *      DB handle must be in an environment that supports transactions.
854  *
855  * PUBLIC: int __db_not_txn_env __P((ENV *));
856  */
857 int
858 __db_not_txn_env(env)
859         ENV *env;
860 {
861         __db_errx(env, "DB environment not configured for transactions");
862         return (EINVAL);
863 }
864
865 /*
866  * __db_rec_toobig --
867  *      Fixed record length exceeded error message.
868  *
869  * PUBLIC: int __db_rec_toobig __P((ENV *, u_int32_t, u_int32_t));
870  */
871 int
872 __db_rec_toobig(env, data_len, fixed_rec_len)
873         ENV *env;
874         u_int32_t data_len, fixed_rec_len;
875 {
876         __db_errx(env,
877             "%lu larger than database's maximum record length %lu",
878             (u_long)data_len, (u_long)fixed_rec_len);
879         return (EINVAL);
880 }
881
882 /*
883  * __db_rec_repl --
884  *      Fixed record replacement length error message.
885  *
886  * PUBLIC: int __db_rec_repl __P((ENV *, u_int32_t, u_int32_t));
887  */
888 int
889 __db_rec_repl(env, data_size, data_dlen)
890         ENV *env;
891         u_int32_t data_size, data_dlen;
892 {
893         __db_errx(env,
894             "%s: replacement length %lu differs from replaced length %lu",
895             "Record length error", (u_long)data_size, (u_long)data_dlen);
896         return (EINVAL);
897 }
898
899 #if defined(DIAGNOSTIC) || defined(DEBUG_ROP)  || defined(DEBUG_WOP)
900 /*
901  * __dbc_logging --
902  *      In DIAGNOSTIC mode, check for bad replication combinations.
903  *
904  * PUBLIC: int __dbc_logging __P((DBC *));
905  */
906 int
907 __dbc_logging(dbc)
908         DBC *dbc;
909 {
910         DB_REP *db_rep;
911         ENV *env;
912         int ret;
913
914         env = dbc->env;
915         db_rep = env->rep_handle;
916
917         ret = LOGGING_ON(env) &&
918             !F_ISSET(dbc, DBC_RECOVER) && !IS_REP_CLIENT(env);
919
920         /*
921          * If we're not using replication or running recovery, return.
922          */
923         if (db_rep == NULL || F_ISSET(dbc, DBC_RECOVER))
924                 return (ret);
925
926 #ifndef DEBUG_ROP
927         /*
928          *  Only check when DEBUG_ROP is not configured.  People often do
929          * non-transactional reads, and debug_rop is going to write
930          * a log record.
931          */
932         {
933         REP *rep;
934
935         rep = db_rep->region;
936
937         /*
938          * If we're a client and not running recovery or non durably, error.
939          */
940         if (IS_REP_CLIENT(env) && !F_ISSET(dbc->dbp, DB_AM_NOT_DURABLE)) {
941                 __db_errx(env, "dbc_logging: Client update");
942                 goto err;
943         }
944
945 #ifndef DEBUG_WOP
946         /*
947          * If DEBUG_WOP is enabled, then we'll generate debugging log records
948          * that are non-transactional.  This is OK.
949          */
950         if (IS_REP_MASTER(env) &&
951             dbc->txn == NULL && !F_ISSET(dbc->dbp, DB_AM_NOT_DURABLE)) {
952                 __db_errx(env, "Dbc_logging: Master non-txn update");
953                 goto err;
954         }
955 #endif
956
957         if (0) {
958 err:            __db_errx(env, "Rep: flags 0x%lx msg_th %lu",
959                     (u_long)rep->flags, (u_long)rep->msg_th);
960                 __db_errx(env, "Rep: handle %lu, opcnt %lu",
961                     (u_long)rep->handle_cnt, (u_long)rep->op_cnt);
962                 __os_abort(env);
963                 /* NOTREACHED */
964         }
965         }
966 #endif
967         return (ret);
968 }
969 #endif
970
971 /*
972  * __db_check_lsn --
973  *      Display the log sequence error message.
974  *
975  * PUBLIC: int __db_check_lsn __P((ENV *, DB_LSN *, DB_LSN *));
976  */
977 int
978 __db_check_lsn(env, lsn, prev)
979         ENV *env;
980         DB_LSN *lsn, *prev;
981 {
982         __db_errx(env,
983             "Log sequence error: page LSN %lu %lu; previous LSN %lu %lu",
984             (u_long)(lsn)->file, (u_long)(lsn)->offset,
985             (u_long)(prev)->file, (u_long)(prev)->offset);
986         return (EINVAL);
987 }
988
989 /*
990  * __db_rdonly --
991  *      Common readonly message.
992  * PUBLIC: int __db_rdonly __P((const ENV *, const char *));
993  */
994 int
995 __db_rdonly(env, name)
996         const ENV *env;
997         const char *name;
998 {
999         __db_errx(env, "%s: attempt to modify a read-only database", name);
1000         return (EACCES);
1001 }
1002
1003 /*
1004  * __db_space_err --
1005  *      Common out of space message.
1006  * PUBLIC: int __db_space_err __P((const DB *));
1007  */
1008 int
1009 __db_space_err(dbp)
1010         const DB *dbp;
1011 {
1012         __db_errx(dbp->env,
1013             "%s: file limited to %lu pages",
1014             dbp->fname, (u_long)dbp->mpf->mfp->maxpgno);
1015         return (ENOSPC);
1016 }
1017
1018 /*
1019  * __db_failed --
1020  *      Common failed thread  message.
1021  *
1022  * PUBLIC: int __db_failed __P((const ENV *,
1023  * PUBLIC:      const char *, pid_t, db_threadid_t));
1024  */
1025 int
1026 __db_failed(env, msg, pid, tid)
1027         const ENV *env;
1028         const char *msg;
1029         pid_t pid;
1030         db_threadid_t tid;
1031 {
1032         DB_ENV *dbenv;
1033         char buf[DB_THREADID_STRLEN];
1034
1035         dbenv = env->dbenv;
1036
1037         __db_errx(env, "Thread/process %s failed: %s",
1038             dbenv->thread_id_string(dbenv, pid, tid, buf),  msg);
1039         return (DB_RUNRECOVERY);
1040 }