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 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 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 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__ 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 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 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 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