Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

db_err.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: db_err.c,v 12.19 2005/10/19 19:06:29 sue Exp $
00008  */
00009 
00010 #include "db_config.h"
00011 
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 
00015 #include <stdlib.h>
00016 #include <string.h>
00017 #endif
00018 
00019 #include "db_int.h"
00020 #include "dbinc/db_page.h"
00021 #include "dbinc/db_am.h"
00022 #include "dbinc/db_shash.h"
00023 #include "dbinc/lock.h"
00024 #include "dbinc/log.h"
00025 #include "dbinc/mp.h"
00026 #include "dbinc/txn.h"
00027 
00028 static void __db_msgcall __P((const DB_ENV *, const char *, va_list));
00029 static void __db_msgfile __P((const DB_ENV *, const char *, va_list));
00030 
00031 /*
00032  * __db_fchk --
00033  *      General flags checking routine.
00034  *
00035  * PUBLIC: int __db_fchk __P((DB_ENV *, const char *, u_int32_t, u_int32_t));
00036  */
00037 int
00038 __db_fchk(dbenv, name, flags, ok_flags)
00039         DB_ENV *dbenv;
00040         const char *name;
00041         u_int32_t flags, ok_flags;
00042 {
00043         return (LF_ISSET(~ok_flags) ? __db_ferr(dbenv, name, 0) : 0);
00044 }
00045 
00046 /*
00047  * __db_fcchk --
00048  *      General combination flags checking routine.
00049  *
00050  * PUBLIC: int __db_fcchk
00051  * PUBLIC:    __P((DB_ENV *, const char *, u_int32_t, u_int32_t, u_int32_t));
00052  */
00053 int
00054 __db_fcchk(dbenv, name, flags, flag1, flag2)
00055         DB_ENV *dbenv;
00056         const char *name;
00057         u_int32_t flags, flag1, flag2;
00058 {
00059         return (LF_ISSET(flag1) &&
00060             LF_ISSET(flag2) ? __db_ferr(dbenv, name, 1) : 0);
00061 }
00062 
00063 /*
00064  * __db_ferr --
00065  *      Common flag errors.
00066  *
00067  * PUBLIC: int __db_ferr __P((const DB_ENV *, const char *, int));
00068  */
00069 int
00070 __db_ferr(dbenv, name, iscombo)
00071         const DB_ENV *dbenv;
00072         const char *name;
00073         int iscombo;
00074 {
00075         __db_err(dbenv, "illegal flag %sspecified to %s",
00076             iscombo ? "combination " : "", name);
00077         return (EINVAL);
00078 }
00079 
00080 /*
00081  * __db_fnl --
00082  *      Common flag-needs-locking message.
00083  *
00084  * PUBLIC: int __db_fnl __P((const DB_ENV *, const char *));
00085  */
00086 int
00087 __db_fnl(dbenv, name)
00088         const DB_ENV *dbenv;
00089         const char *name;
00090 {
00091         __db_err(dbenv,
00092     "%s: DB_READ_COMMITTED, DB_READ_UNCOMMITTED and DB_RMW require locking",
00093             name);
00094         return (EINVAL);
00095 }
00096 
00097 /*
00098  * __db_pgerr --
00099  *      Error when unable to retrieve a specified page.
00100  *
00101  * PUBLIC: int __db_pgerr __P((DB *, db_pgno_t, int));
00102  */
00103 int
00104 __db_pgerr(dbp, pgno, errval)
00105         DB *dbp;
00106         db_pgno_t pgno;
00107         int errval;
00108 {
00109         /*
00110          * Three things are certain:
00111          * Death, taxes, and lost data.
00112          * Guess which has occurred.
00113          */
00114         __db_err(dbp->dbenv,
00115             "unable to create/retrieve page %lu", (u_long)pgno);
00116         return (__db_panic(dbp->dbenv, errval));
00117 }
00118 
00119 /*
00120  * __db_pgfmt --
00121  *      Error when a page has the wrong format.
00122  *
00123  * PUBLIC: int __db_pgfmt __P((DB_ENV *, db_pgno_t));
00124  */
00125 int
00126 __db_pgfmt(dbenv, pgno)
00127         DB_ENV *dbenv;
00128         db_pgno_t pgno;
00129 {
00130         __db_err(dbenv, "page %lu: illegal page type or format", (u_long)pgno);
00131         return (__db_panic(dbenv, EINVAL));
00132 }
00133 
00134 #ifdef DIAGNOSTIC
00135 /*
00136  * __db_assert --
00137  *      Error when an assertion fails.  Only checked if #DIAGNOSTIC defined.
00138  *
00139  * PUBLIC: #ifdef DIAGNOSTIC
00140  * PUBLIC: void __db_assert __P((const char *, const char *, int));
00141  * PUBLIC: #endif
00142  */
00143 void
00144 __db_assert(failedexpr, file, line)
00145         const char *failedexpr, *file;
00146         int line;
00147 {
00148         (void)fprintf(stderr,
00149             "__db_assert: \"%s\" failed: file \"%s\", line %d\n",
00150             failedexpr, file, line);
00151         (void)fflush(stderr);
00152 
00153         /* We want a stack trace of how this could possibly happen. */
00154         abort();
00155 
00156         /* NOTREACHED */
00157 }
00158 #endif
00159 
00160 /*
00161  * __db_panic_msg --
00162  *      Just report that someone else paniced.
00163  *
00164  * PUBLIC: int __db_panic_msg __P((DB_ENV *));
00165  */
00166 int
00167 __db_panic_msg(dbenv)
00168         DB_ENV *dbenv;
00169 {
00170         __db_err(dbenv, "PANIC: fatal region error detected; run recovery");
00171 
00172         if (dbenv->db_paniccall != NULL)
00173                 dbenv->db_paniccall(dbenv, DB_RUNRECOVERY);
00174 
00175         return (DB_RUNRECOVERY);
00176 }
00177 
00178 /*
00179  * __db_panic --
00180  *      Lock out the tree due to unrecoverable error.
00181  *
00182  * PUBLIC: int __db_panic __P((DB_ENV *, int));
00183  */
00184 int
00185 __db_panic(dbenv, errval)
00186         DB_ENV *dbenv;
00187         int errval;
00188 {
00189         if (dbenv != NULL) {
00190                 __db_panic_set(dbenv, 1);
00191 
00192                 __db_err(dbenv, "PANIC: %s", db_strerror(errval));
00193 
00194                 if (dbenv->db_paniccall != NULL)
00195                         dbenv->db_paniccall(dbenv, errval);
00196         }
00197 
00198 #if defined(DIAGNOSTIC) && !defined(CONFIG_TEST)
00199         /*
00200          * We want a stack trace of how this could possibly happen.
00201          *
00202          * Don't drop core if it's the test suite -- it's reasonable for the
00203          * test suite to check to make sure that DB_RUNRECOVERY is returned
00204          * under certain conditions.
00205          */
00206         abort();
00207 #endif
00208 
00209         /*
00210          * Chaos reigns within.
00211          * Reflect, repent, and reboot.
00212          * Order shall return.
00213          */
00214         return (DB_RUNRECOVERY);
00215 }
00216 
00217 /*
00218  * __db_panic_set --
00219  *      Set/clear unrecoverable error.
00220  *
00221  * PUBLIC: void __db_panic_set __P((DB_ENV *, int));
00222  */
00223 void
00224 __db_panic_set(dbenv, on)
00225         DB_ENV *dbenv;
00226         int on;
00227 {
00228         if (dbenv != NULL && dbenv->reginfo != NULL)
00229                 ((REGENV *)
00230                     ((REGINFO *)dbenv->reginfo)->primary)->panic = on ? 1 : 0;
00231 }
00232 
00233 /*
00234  * db_strerror --
00235  *      ANSI C strerror(3) for DB.
00236  *
00237  * EXTERN: char *db_strerror __P((int));
00238  */
00239 char *
00240 db_strerror(error)
00241         int error;
00242 {
00243         char *p;
00244 
00245         if (error == 0)
00246                 return ("Successful return: 0");
00247         if (error > 0) {
00248                 if ((p = strerror(error)) != NULL)
00249                         return (p);
00250                 goto unknown_err;
00251         }
00252 
00253         /*
00254          * !!!
00255          * The Tcl API requires that some of these return strings be compared
00256          * against strings stored in application scripts.  So, any of these
00257          * errors that do not invariably result in a Tcl exception may not be
00258          * altered.
00259          */
00260         switch (error) {
00261         case DB_BUFFER_SMALL:
00262                 return
00263                     ("DB_BUFFER_SMALL: User memory too small for return value");
00264         case DB_DONOTINDEX:
00265                 return ("DB_DONOTINDEX: Secondary index callback returns null");
00266         case DB_KEYEMPTY:
00267                 return ("DB_KEYEMPTY: Non-existent key/data pair");
00268         case DB_KEYEXIST:
00269                 return ("DB_KEYEXIST: Key/data pair already exists");
00270         case DB_LOCK_DEADLOCK:
00271                 return
00272                     ("DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock");
00273         case DB_LOCK_NOTGRANTED:
00274                 return ("DB_LOCK_NOTGRANTED: Lock not granted");
00275         case DB_LOG_BUFFER_FULL:
00276                 return ("DB_LOG_BUFFER_FULL: In-memory log buffer is full");
00277         case DB_NOSERVER:
00278                 return ("DB_NOSERVER: Fatal error, no RPC server");
00279         case DB_NOSERVER_HOME:
00280                 return ("DB_NOSERVER_HOME: Home unrecognized at server");
00281         case DB_NOSERVER_ID:
00282                 return ("DB_NOSERVER_ID: Identifier unrecognized at server");
00283         case DB_NOTFOUND:
00284                 return ("DB_NOTFOUND: No matching key/data pair found");
00285         case DB_OLD_VERSION:
00286                 return ("DB_OLDVERSION: Database requires a version upgrade");
00287         case DB_PAGE_NOTFOUND:
00288                 return ("DB_PAGE_NOTFOUND: Requested page not found");
00289         case DB_REP_DUPMASTER:
00290                 return ("DB_REP_DUPMASTER: A second master site appeared");
00291         case DB_REP_HANDLE_DEAD:
00292                 return ("DB_REP_HANDLE_DEAD: Handle is no longer valid");
00293         case DB_REP_HOLDELECTION:
00294                 return ("DB_REP_HOLDELECTION: Need to hold an election");
00295         case DB_REP_IGNORE:
00296                 return ("DB_REP_IGNORE: Replication record ignored");
00297         case DB_REP_ISPERM:
00298                 return ("DB_REP_ISPERM: Permanent record written");
00299         case DB_REP_JOIN_FAILURE:
00300                 return
00301             ("DB_REP_JOIN_FAILURE: Unable to join replication group");
00302         case DB_REP_LOCKOUT:
00303                 return
00304             ("DB_REP_LOCKOUT: Waiting for replication recovery to complete"); 
00305         case DB_REP_NEWMASTER:
00306                 return ("DB_REP_NEWMASTER: A new master has declared itself");
00307         case DB_REP_NEWSITE:
00308                 return ("DB_REP_NEWSITE: A new site has entered the system");
00309         case DB_REP_NOTPERM:
00310                 return ("DB_REP_NOTPERM: Permanent log record not written");
00311         case DB_REP_STARTUPDONE:
00312                 return
00313             ("DB_REP_STARTUPDONE: Client completed startup synchronization.");
00314         case DB_REP_UNAVAIL:
00315                 return ("DB_REP_UNAVAIL: Unable to elect a master");
00316         case DB_RUNRECOVERY:
00317                 return ("DB_RUNRECOVERY: Fatal error, run database recovery");
00318         case DB_SECONDARY_BAD:
00319                 return
00320             ("DB_SECONDARY_BAD: Secondary index inconsistent with primary");
00321         case DB_VERIFY_BAD:
00322                 return ("DB_VERIFY_BAD: Database verification failed");
00323         case DB_VERSION_MISMATCH:
00324                 return
00325             ("DB_VERSION_MISMATCH: Database environment version mismatch");
00326         default:
00327                 break;
00328         }
00329 
00330 unknown_err: {
00331                 /*
00332                  * !!!
00333                  * Room for a 64-bit number + slop.  This buffer is only used
00334                  * if we're given an unknown error, which should never happen.
00335                  * Note, however, we're no longer thread-safe if it does.
00336                  */
00337                 static char ebuf[40];
00338 
00339                 (void)snprintf(ebuf, sizeof(ebuf), "Unknown error: %d", error);
00340                 return (ebuf);
00341         }
00342 }
00343 
00344 /*
00345  * __db_err --
00346  *      Standard DB error routine.  The same as errx, except we don't write
00347  *      to stderr if no output mechanism was specified.
00348  *
00349  * PUBLIC: void __db_err __P((const DB_ENV *, const char *, ...))
00350  * PUBLIC:    __attribute__ ((__format__ (__printf__, 2, 3)));
00351  */
00352 void
00353 #ifdef STDC_HEADERS
00354 __db_err(const DB_ENV *dbenv, const char *fmt, ...)
00355 #else
00356 __db_err(dbenv, fmt, va_alist)
00357         const DB_ENV *dbenv;
00358         const char *fmt;
00359         va_dcl
00360 #endif
00361 {
00362         DB_REAL_ERR(dbenv, 0, 0, 0, fmt);
00363 }
00364 
00365 /*
00366  * __db_errcall --
00367  *      Do the error message work for callback functions.
00368  *
00369  * PUBLIC: void __db_errcall
00370  * PUBLIC:          __P((const DB_ENV *, int, int, const char *, va_list));
00371  */
00372 void
00373 __db_errcall(dbenv, error, error_set, fmt, ap)
00374         const DB_ENV *dbenv;
00375         int error, error_set;
00376         const char *fmt;
00377         va_list ap;
00378 {
00379         char *p;
00380         char buf[2048];         /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
00381 
00382         p = buf;
00383         if (fmt != NULL)
00384                 p += vsnprintf(buf, sizeof(buf), fmt, ap);
00385         if (error_set)
00386                 p += snprintf(p,
00387                     sizeof(buf) - (size_t)(p - buf), ": %s",
00388                     db_strerror(error));
00389 
00390         dbenv->db_errcall(dbenv, dbenv->db_errpfx, buf);
00391 }
00392 
00393 /*
00394  * __db_errfile --
00395  *      Do the error message work for FILE *s.
00396  *
00397  * PUBLIC: void __db_errfile
00398  * PUBLIC:          __P((const DB_ENV *, int, int, const char *, va_list));
00399  */
00400 void
00401 __db_errfile(dbenv, error, error_set, fmt, ap)
00402         const DB_ENV *dbenv;
00403         int error, error_set;
00404         const char *fmt;
00405         va_list ap;
00406 {
00407         FILE *fp;
00408 
00409         fp = dbenv == NULL ||
00410             dbenv->db_errfile == NULL ? stderr : dbenv->db_errfile;
00411 
00412         if (dbenv != NULL && dbenv->db_errpfx != NULL)
00413                 (void)fprintf(fp, "%s: ", dbenv->db_errpfx);
00414         if (fmt != NULL) {
00415                 (void)vfprintf(fp, fmt, ap);
00416                 if (error_set)
00417                         (void)fprintf(fp, ": ");
00418         }
00419         if (error_set)
00420                 (void)fprintf(fp, "%s", db_strerror(error));
00421         (void)fprintf(fp, "\n");
00422         (void)fflush(fp);
00423 }
00424 
00425 /*
00426  * __db_msgadd --
00427  *      Aggregate a set of strings into a buffer for the callback API.
00428  *
00429  * PUBLIC: void __db_msgadd __P((DB_ENV *, DB_MSGBUF *, const char *, ...))
00430  * PUBLIC:    __attribute__ ((__format__ (__printf__, 3, 4)));
00431  */
00432 void
00433 #ifdef STDC_HEADERS
00434 __db_msgadd(DB_ENV *dbenv, DB_MSGBUF *mbp, const char *fmt, ...)
00435 #else
00436 __db_msgadd(dbenv, mbp, fmt, va_alist)
00437         DB_ENV *dbenv;
00438         DB_MSGBUF *mbp;
00439         const char *fmt;
00440         va_dcl
00441 #endif
00442 {
00443         va_list ap;
00444         size_t len, olen;
00445         char buf[2048];         /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
00446 
00447 #ifdef STDC_HEADERS
00448         va_start(ap, fmt);
00449 #else
00450         va_start(ap);
00451 #endif
00452         len = (size_t)vsnprintf(buf, sizeof(buf), fmt, ap);
00453 
00454         va_end(ap);
00455 
00456         /*
00457          * There's a heap buffer in the DB_ENV handle we use to aggregate the
00458          * message chunks.  We maintain a pointer to the buffer, the next slot
00459          * to be filled in in the buffer, and a total buffer length.
00460          */
00461         olen = (size_t)(mbp->cur - mbp->buf);
00462         if (olen + len >= mbp->len) {
00463                 if (__os_realloc(dbenv, mbp->len + len + 256, &mbp->buf))
00464                         return;
00465                 mbp->len += (len + 256);
00466                 mbp->cur = mbp->buf + olen;
00467         }
00468 
00469         memcpy(mbp->cur, buf, len + 1);
00470         mbp->cur += len;
00471 }
00472 
00473 /*
00474  * __db_msg --
00475  *      Standard DB stat message routine.
00476  *
00477  * PUBLIC: void __db_msg __P((const DB_ENV *, const char *, ...))
00478  * PUBLIC:    __attribute__ ((__format__ (__printf__, 2, 3)));
00479  */
00480 void
00481 #ifdef STDC_HEADERS
00482 __db_msg(const DB_ENV *dbenv, const char *fmt, ...)
00483 #else
00484 __db_msg(dbenv, fmt, va_alist)
00485         const DB_ENV *dbenv;
00486         const char *fmt;
00487         va_dcl
00488 #endif
00489 {
00490         DB_REAL_MSG(dbenv, fmt);
00491 }
00492 
00493 /*
00494  * __db_msgcall --
00495  *      Do the message work for callback functions.
00496  */
00497 static void
00498 __db_msgcall(dbenv, fmt, ap)
00499         const DB_ENV *dbenv;
00500         const char *fmt;
00501         va_list ap;
00502 {
00503         char buf[2048];         /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
00504 
00505         (void)vsnprintf(buf, sizeof(buf), fmt, ap);
00506 
00507         dbenv->db_msgcall(dbenv, buf);
00508 }
00509 
00510 /*
00511  * __db_msgfile --
00512  *      Do the message work for FILE *s.
00513  */
00514 static void
00515 __db_msgfile(dbenv, fmt, ap)
00516         const DB_ENV *dbenv;
00517         const char *fmt;
00518         va_list ap;
00519 {
00520         FILE *fp;
00521 
00522         fp = dbenv == NULL ||
00523             dbenv->db_msgfile == NULL ? stdout : dbenv->db_msgfile;
00524         (void)vfprintf(fp, fmt, ap);
00525 
00526         (void)fprintf(fp, "\n");
00527         (void)fflush(fp);
00528 }
00529 
00530 /*
00531  * __db_unknown_flag -- report internal error
00532  *
00533  * PUBLIC: int __db_unknown_flag __P((DB_ENV *, char *, u_int32_t));
00534  */
00535 int
00536 __db_unknown_flag(dbenv, routine, flag)
00537         DB_ENV *dbenv;
00538         char *routine;
00539         u_int32_t flag;
00540 {
00541         __db_err(dbenv, "%s: Unknown flag: %#x", routine, (u_int)flag);
00542         DB_ASSERT(0);
00543         return (EINVAL);
00544 }
00545 
00546 /*
00547  * __db_unknown_type -- report internal error
00548  *
00549  * PUBLIC: int __db_unknown_type __P((DB_ENV *, char *, DBTYPE));
00550  */
00551 int
00552 __db_unknown_type(dbenv, routine, type)
00553         DB_ENV *dbenv;
00554         char *routine;
00555         DBTYPE type;
00556 {
00557         __db_err(dbenv,
00558             "%s: Unexpected DB type: %s", routine, __db_dbtype_to_string(type));
00559 
00560         DB_ASSERT(0);
00561         return (EINVAL);
00562 }
00563 
00564 /*
00565  * __db_check_txn --
00566  *      Check for common transaction errors.
00567  *
00568  * PUBLIC: int __db_check_txn __P((DB *, DB_TXN *, u_int32_t, int));
00569  */
00570 int
00571 __db_check_txn(dbp, txn, assoc_lid, read_op)
00572         DB *dbp;
00573         DB_TXN *txn;
00574         u_int32_t assoc_lid;
00575         int read_op;
00576 {
00577         DB_ENV *dbenv;
00578         int isp, ret;
00579 
00580         dbenv = dbp->dbenv;
00581 
00582         /*
00583          * If we are in recovery or aborting a transaction, then we
00584          * don't need to enforce the rules about dbp's not allowing
00585          * transactional operations in non-transactional dbps and
00586          * vica-versa.  This happens all the time as the dbp during
00587          * an abort may be transactional, but we undo operations
00588          * outside a transaction since we're aborting.
00589          */
00590         if (IS_RECOVERING(dbenv) || F_ISSET(dbp, DB_AM_RECOVER))
00591                 return (0);
00592 
00593         /*
00594          * Check for common transaction errors:
00595          *      an operation on a handle whose open commit hasn't completed.
00596          *      a transaction handle in a non-transactional environment
00597          *      a transaction handle for a non-transactional database
00598          */
00599         if (txn == NULL) {
00600                 if (dbp->cur_lid >= TXN_MINIMUM)
00601                         goto open_err;
00602         } else {
00603                 if (!TXN_ON(dbenv))
00604                          return (__db_not_txn_env(dbenv));
00605 
00606                 if (!F_ISSET(dbp, DB_AM_TXN)) {
00607                         __db_err(dbenv,
00608     "Transaction specified for a DB handle opened outside a transaction");
00609                         return (EINVAL);
00610                 }
00611 
00612                 if (F_ISSET(txn, TXN_DEADLOCK)) {
00613                         __db_err(dbenv,
00614                             "Previous deadlock return not resolved");
00615                         return (EINVAL);
00616                 }
00617                 if (dbp->cur_lid >= TXN_MINIMUM && dbp->cur_lid != txn->txnid) {
00618                         if ((ret = __lock_locker_is_parent(dbenv,
00619                              dbp->cur_lid, txn->txnid, &isp)) != 0)
00620                                 return (ret);
00621                         if (!isp)
00622                                 goto open_err;
00623                 }
00624         }
00625 
00626         /*
00627          * If dbp->associate_lid is not DB_LOCK_INVALIDID, that means we're in
00628          * the middle of a DB->associate with DB_CREATE (i.e., a secondary index
00629          * creation).
00630          *
00631          * In addition to the usual transaction rules, we need to lock out
00632          * non-transactional updates that aren't part of the associate (and
00633          * thus are using some other locker ID).
00634          *
00635          * Transactional updates should simply block;  from the time we
00636          * decide to build the secondary until commit, we'll hold a write
00637          * lock on all of its pages, so it should be safe to attempt to update
00638          * the secondary in another transaction (presumably by updating the
00639          * primary).
00640          */
00641         if (!read_op && dbp->associate_lid != DB_LOCK_INVALIDID &&
00642             txn != NULL && dbp->associate_lid != assoc_lid) {
00643                 __db_err(dbenv,
00644             "Operation forbidden while secondary index is being created");
00645                 return (EINVAL);
00646         }
00647 
00648         /*
00649          * Check the txn and dbp are from the same env.
00650          */
00651         if (txn != NULL && dbenv != txn->mgrp->dbenv) {
00652                 __db_err(dbenv,
00653             "Transaction and database from different environments");
00654                 return (EINVAL);
00655         }
00656 
00657         return (0);
00658 open_err:
00659         __db_err(dbenv,
00660             "Transaction that opened the DB handle is still active");
00661         return (EINVAL);
00662 }
00663 
00664 /*
00665  * __db_not_txn_env --
00666  *      DB handle must be in an environment that supports transactions.
00667  *
00668  * PUBLIC: int __db_not_txn_env __P((DB_ENV *));
00669  */
00670 int
00671 __db_not_txn_env(dbenv)
00672         DB_ENV *dbenv;
00673 {
00674         __db_err(dbenv, "DB environment not configured for transactions");
00675         return (EINVAL);
00676 }
00677 
00678 /*
00679  * __db_rec_toobig --
00680  *      Fixed record length exceeded error message.
00681  *
00682  * PUBLIC: int __db_rec_toobig __P((DB_ENV *, u_int32_t, u_int32_t));
00683  */
00684 int
00685 __db_rec_toobig(dbenv, data_len, fixed_rec_len)
00686         DB_ENV *dbenv;
00687         u_int32_t data_len, fixed_rec_len;
00688 {
00689         __db_err(dbenv, "%s: length of %lu larger than database's value of %lu",
00690             "Record length error", (u_long)data_len, (u_long)fixed_rec_len);
00691         return (EINVAL);
00692 }
00693 
00694 /*
00695  * __db_rec_repl --
00696  *      Fixed record replacement length error message.
00697  *
00698  * PUBLIC: int __db_rec_repl __P((DB_ENV *, u_int32_t, u_int32_t));
00699  */
00700 int
00701 __db_rec_repl(dbenv, data_size, data_dlen)
00702         DB_ENV *dbenv;
00703         u_int32_t data_size, data_dlen;
00704 {
00705         __db_err(dbenv,
00706             "%s: replacement length %lu differs from replaced length %lu",
00707             "Record length error", (u_long)data_size, (u_long)data_dlen);
00708         return (EINVAL);
00709 }
00710 
00711 #if defined(DIAGNOSTIC) || defined(DEBUG_ROP)  || defined(DEBUG_WOP)
00712 /*
00713  * __dbc_logging --
00714  *      In DIAGNOSTIC mode, check for bad replication combinations.
00715  *
00716  * PUBLIC: int __dbc_logging __P((DBC *));
00717  */
00718 int
00719 __dbc_logging(dbc)
00720         DBC *dbc;
00721 {
00722         DB_ENV *dbenv;
00723         DB_REP *db_rep;
00724         int ret;
00725 
00726         dbenv = dbc->dbp->dbenv;
00727         db_rep = dbenv->rep_handle;
00728 
00729         ret = LOGGING_ON(dbenv) &&
00730             !F_ISSET(dbc, DBC_RECOVER) && !IS_REP_CLIENT(dbenv);
00731 
00732         /*
00733          * If we're not using replication or running recovery, return.
00734          */
00735         if (db_rep == NULL || F_ISSET(dbc, DBC_RECOVER))
00736                 return (ret);
00737 
00738 #ifndef DEBUG_ROP
00739         /*
00740          * Only check when DEBUG_ROP is not configured.  People often do
00741          * non-transactional reads, and debug_rop is going to write
00742          * a log record.
00743          */
00744         {
00745         REP *rep;
00746 
00747         rep = db_rep->region;
00748 
00749         /*
00750          * If we're a client and not running recovery or internally, error.
00751          */
00752         if (IS_REP_CLIENT(dbenv) && !F_ISSET(dbc->dbp, DB_AM_CL_WRITER)) {
00753                 __db_err(dbenv, "Dbc_logging: Client update");
00754                 goto err;
00755         }
00756         if (IS_REP_MASTER(dbenv) && dbc->txn == NULL) {
00757                 __db_err(dbenv, "Dbc_logging: Master non-txn update");
00758                 goto err;
00759         }
00760         if (0) {
00761 err:            __db_err(dbenv, "Rep: flags 0x%lx msg_th %lu, start_th %d",
00762                     (u_long)rep->flags, (u_long)rep->msg_th, rep->start_th);
00763                 __db_err(dbenv, "Rep: handle %lu, opcnt %lu, in_rec %d",
00764                     (u_long)rep->handle_cnt, (u_long)rep->op_cnt,
00765                     rep->in_recovery);
00766                 abort();
00767         }
00768         }
00769 #endif
00770         return (ret);
00771 }
00772 #endif
00773 
00774 /*
00775  * __db_check_lsn --
00776  *      Display the log sequence error message.
00777  *
00778  * PUBLIC: int __db_check_lsn __P((DB_ENV *, DB_LSN *, DB_LSN *));
00779  */
00780 int
00781 __db_check_lsn(dbenv, lsn, prev)
00782         DB_ENV *dbenv;
00783         DB_LSN *lsn, *prev;
00784 {
00785         __db_err(dbenv,
00786             "Log sequence error: page LSN %lu %lu; previous LSN %lu %lu",
00787             (u_long)(lsn)->file, (u_long)(lsn)->offset,
00788             (u_long)(prev)->file, (u_long)(prev)->offset);
00789         return (EINVAL);
00790 }
00791 
00792 /*
00793  * __db_rdonly --
00794  *      Common readonly message.
00795  * PUBLIC: int __db_rdonly __P((const DB_ENV *, const char *));
00796  */
00797 int
00798 __db_rdonly(dbenv, name)
00799         const DB_ENV *dbenv;
00800         const char *name;
00801 {
00802         __db_err(dbenv, "%s: attempt to modify a read-only database", name);
00803         return (EACCES);
00804 }
00805 
00806 /*
00807  * __db_space_err --
00808  *      Common out of space message.
00809  * PUBLIC: int __db_space_err __P((const DB *));
00810  */
00811 int
00812 __db_space_err(dbp)
00813         const DB *dbp;
00814 {
00815         __db_err(dbp->dbenv,
00816             "%s: file limited to %lu pages",
00817             dbp->fname, (u_long)dbp->mpf->mfp->maxpgno);
00818         return (ENOSPC);
00819 }
00820 
00821 /*
00822  * __db_failed --
00823  *      Common failed thread  message.
00824  *
00825  * PUBLIC: int __db_failed __P((const DB_ENV *,
00826  * PUBLIC:      const char *, pid_t, db_threadid_t));
00827  */
00828 int
00829 __db_failed(dbenv, msg, pid, tid)
00830         const DB_ENV *dbenv;
00831         const char *msg;
00832         pid_t pid;
00833         db_threadid_t tid;
00834 {
00835         char buf[DB_THREADID_STRLEN];
00836 
00837         __db_err(dbenv, "Thread/process %s failed: %s",
00838             dbenv->thread_id_string((DB_ENV*)dbenv, pid, tid, buf),  msg);
00839         return (DB_RUNRECOVERY);
00840 }

Generated on Sun Dec 25 12:14:17 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2