1 /*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1996, 1997, 1998
5 * Sleepycat Software. All rights reserved.
6 */
7
8 #include "config.h"
9
10 #ifndef lint
11 static const char sccsid[] = "@(#)db_err.c 10.42 (Sleepycat) 11/24/98";
12 #endif /* not lint */
13
14 #ifndef NO_SYSTEM_INCLUDES
15 #include <sys/types.h>
16
17 #include <errno.h>
18 #include <stdio.h>
19 #include <string.h>
20
21 #ifdef __STDC__
22 #include <stdarg.h>
23 #else
24 #include <varargs.h>
25 #endif
26 #endif
27
28 #include "db_int.h"
29 #include "shqueue.h"
30 #include "db_shash.h"
31 #include "lock.h"
32 #include "lock_ext.h"
33 #include "log.h"
34 #include "log_ext.h"
35 #include "mp.h"
36 #include "mp_ext.h"
37 #include "txn.h"
38 #include "txn_ext.h"
39 #include "common_ext.h"
40 #include "clib_ext.h"
41
42 /*
43 * __db_fchk --
44 * General flags checking routine.
45 *
46 * PUBLIC: int __db_fchk __P((DB_ENV *, const char *, u_int32_t, u_int32_t));
47 */
48 int
__db_fchk(dbenv,name,flags,ok_flags)49 __db_fchk(dbenv, name, flags, ok_flags)
50 DB_ENV *dbenv;
51 const char *name;
52 u_int32_t flags, ok_flags;
53 {
54 return (flags & ~ok_flags ? __db_ferr(dbenv, name, 0) : 0);
55 }
56
57 /*
58 * __db_fcchk --
59 * General combination flags checking routine.
60 *
61 * PUBLIC: int __db_fcchk
62 * PUBLIC: __P((DB_ENV *, const char *, u_int32_t, u_int32_t, u_int32_t));
63 */
64 int
__db_fcchk(dbenv,name,flags,flag1,flag2)65 __db_fcchk(dbenv, name, flags, flag1, flag2)
66 DB_ENV *dbenv;
67 const char *name;
68 u_int32_t flags, flag1, flag2;
69 {
70 return ((flags & flag1) &&
71 (flags & flag2) ? __db_ferr(dbenv, name, 1) : 0);
72 }
73
74 /*
75 * __db_ferr --
76 * Common flag errors.
77 *
78 * PUBLIC: int __db_ferr __P((const DB_ENV *, const char *, int));
79 */
80 int
__db_ferr(dbenv,name,iscombo)81 __db_ferr(dbenv, name, iscombo)
82 const DB_ENV *dbenv;
83 const char *name;
84 int iscombo;
85 {
86 __db_err(dbenv, "illegal flag %sspecified to %s",
87 iscombo ? "combination " : "", name);
88 return (EINVAL);
89 }
90
91 /*
92 * __db_err --
93 * Standard DB error routine.
94 *
95 * PUBLIC: #ifdef __STDC__
96 * PUBLIC: void __db_err __P((const DB_ENV *dbenv, const char *fmt, ...));
97 * PUBLIC: #else
98 * PUBLIC: void __db_err();
99 * PUBLIC: #endif
100 */
101 void
102 #ifdef __STDC__
__db_err(const DB_ENV * dbenv,const char * fmt,...)103 __db_err(const DB_ENV *dbenv, const char *fmt, ...)
104 #else
105 __db_err(dbenv, fmt, va_alist)
106 const DB_ENV *dbenv;
107 const char *fmt;
108 va_dcl
109 #endif
110 {
111 va_list ap;
112 char errbuf[2048]; /* XXX: END OF THE STACK DON'T TRUST SPRINTF. */
113
114 if (dbenv == NULL)
115 return;
116
117 if (dbenv->db_errcall != NULL) {
118 #ifdef __STDC__
119 va_start(ap, fmt);
120 #else
121 va_start(ap);
122 #endif
123 (void)vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
124 dbenv->db_errcall(dbenv->db_errpfx, errbuf);
125 va_end(ap);
126 }
127 if (dbenv->db_errfile != NULL) {
128 if (dbenv->db_errpfx != NULL)
129 (void)fprintf(dbenv->db_errfile, "%s: ",
130 dbenv->db_errpfx);
131 #ifdef __STDC__
132 va_start(ap, fmt);
133 #else
134 va_start(ap);
135 #endif
136 (void)vfprintf(dbenv->db_errfile, fmt, ap);
137 (void)fprintf(dbenv->db_errfile, "\n");
138 (void)fflush(dbenv->db_errfile);
139 va_end(ap);
140 }
141 }
142
143 /*
144 * __db_pgerr --
145 * Error when unable to retrieve a specified page.
146 *
147 * PUBLIC: int __db_pgerr __P((DB *, db_pgno_t));
148 */
149 int
__db_pgerr(dbp,pgno)150 __db_pgerr(dbp, pgno)
151 DB *dbp;
152 db_pgno_t pgno;
153 {
154 /*
155 * Three things are certain:
156 * Death, taxes, and lost data.
157 * Guess which has occurred.
158 */
159 __db_err(dbp->dbenv,
160 "unable to create/retrieve page %lu", (u_long)pgno);
161 return (__db_panic(dbp->dbenv, EIO));
162 }
163
164 /*
165 * __db_pgfmt --
166 * Error when a page has the wrong format.
167 *
168 * PUBLIC: int __db_pgfmt __P((DB *, db_pgno_t));
169 */
170 int
__db_pgfmt(dbp,pgno)171 __db_pgfmt(dbp, pgno)
172 DB *dbp;
173 db_pgno_t pgno;
174 {
175 __db_err(dbp->dbenv,
176 "page %lu: illegal page type or format", (u_long)pgno);
177 return (__db_panic(dbp->dbenv, EINVAL));
178 }
179
180 /*
181 * __db_panic --
182 * Lock out the tree due to unrecoverable error.
183 *
184 * PUBLIC: int __db_panic __P((DB_ENV *, int));
185 */
186 int
__db_panic(dbenv,errval)187 __db_panic(dbenv, errval)
188 DB_ENV *dbenv;
189 int errval;
190 {
191 if (dbenv != NULL) {
192 dbenv->db_panic = errval;
193
194 (void)__log_panic(dbenv);
195 (void)__memp_panic(dbenv);
196 (void)__lock_panic(dbenv);
197 (void)__txn_panic(dbenv);
198
199 __db_err(dbenv, "PANIC: %s", strerror(errval));
200
201 if (dbenv->db_paniccall != NULL)
202 dbenv->db_paniccall(dbenv, errval);
203 }
204
205 /*
206 * Chaos reigns within.
207 * Reflect, repent, and reboot.
208 * Order shall return.
209 */
210 return (DB_RUNRECOVERY);
211 }
212