1N/A/*-
1N/A * See the file LICENSE for redistribution information.
1N/A *
1N/A * Copyright (c) 1996, 1997, 1998
1N/A * Sleepycat Software. All rights reserved.
1N/A */
1N/A
1N/A#include "config.h"
1N/A
1N/A#ifndef lint
1N/Astatic const char sccsid[] = "@(#)db_err.c 10.42 (Sleepycat) 11/24/98";
1N/A#endif /* not lint */
1N/A
1N/A#ifndef NO_SYSTEM_INCLUDES
1N/A#include <sys/types.h>
1N/A
1N/A#include <errno.h>
1N/A#include <stdio.h>
1N/A#include <string.h>
1N/A
1N/A#ifdef __STDC__
1N/A#include <stdarg.h>
1N/A#else
1N/A#include <varargs.h>
1N/A#endif
1N/A#endif
1N/A
1N/A#include "db_int.h"
1N/A#include "shqueue.h"
1N/A#include "db_shash.h"
1N/A#include "lock.h"
1N/A#include "lock_ext.h"
1N/A#include "log.h"
1N/A#include "log_ext.h"
1N/A#include "mp.h"
1N/A#include "mp_ext.h"
1N/A#include "txn.h"
1N/A#include "txn_ext.h"
1N/A#include "common_ext.h"
1N/A#include "clib_ext.h"
1N/A
1N/A/*
1N/A * __db_fchk --
1N/A * General flags checking routine.
1N/A *
1N/A * PUBLIC: int __db_fchk __P((DB_ENV *, const char *, u_int32_t, u_int32_t));
1N/A */
1N/Aint
1N/A__db_fchk(dbenv, name, flags, ok_flags)
1N/A DB_ENV *dbenv;
1N/A const char *name;
1N/A u_int32_t flags, ok_flags;
1N/A{
1N/A return (flags & ~ok_flags ? __db_ferr(dbenv, name, 0) : 0);
1N/A}
1N/A
1N/A/*
1N/A * __db_fcchk --
1N/A * General combination flags checking routine.
1N/A *
1N/A * PUBLIC: int __db_fcchk
1N/A * PUBLIC: __P((DB_ENV *, const char *, u_int32_t, u_int32_t, u_int32_t));
1N/A */
1N/Aint
1N/A__db_fcchk(dbenv, name, flags, flag1, flag2)
1N/A DB_ENV *dbenv;
1N/A const char *name;
1N/A u_int32_t flags, flag1, flag2;
1N/A{
1N/A return ((flags & flag1) &&
1N/A (flags & flag2) ? __db_ferr(dbenv, name, 1) : 0);
1N/A}
1N/A
1N/A/*
1N/A * __db_ferr --
1N/A * Common flag errors.
1N/A *
1N/A * PUBLIC: int __db_ferr __P((const DB_ENV *, const char *, int));
1N/A */
1N/Aint
1N/A__db_ferr(dbenv, name, iscombo)
1N/A const DB_ENV *dbenv;
1N/A const char *name;
1N/A int iscombo;
1N/A{
1N/A __db_err(dbenv, "illegal flag %sspecified to %s",
1N/A iscombo ? "combination " : "", name);
1N/A return (EINVAL);
1N/A}
1N/A
1N/A/*
1N/A * __db_err --
1N/A * Standard DB error routine.
1N/A *
1N/A * PUBLIC: #ifdef __STDC__
1N/A * PUBLIC: void __db_err __P((const DB_ENV *dbenv, const char *fmt, ...));
1N/A * PUBLIC: #else
1N/A * PUBLIC: void __db_err();
1N/A * PUBLIC: #endif
1N/A */
1N/Avoid
1N/A#ifdef __STDC__
1N/A__db_err(const DB_ENV *dbenv, const char *fmt, ...)
1N/A#else
1N/A__db_err(dbenv, fmt, va_alist)
1N/A const DB_ENV *dbenv;
1N/A const char *fmt;
1N/A va_dcl
1N/A#endif
1N/A{
1N/A va_list ap;
1N/A char errbuf[2048]; /* XXX: END OF THE STACK DON'T TRUST SPRINTF. */
1N/A
1N/A if (dbenv == NULL)
1N/A return;
1N/A
1N/A if (dbenv->db_errcall != NULL) {
1N/A#ifdef __STDC__
1N/A va_start(ap, fmt);
1N/A#else
1N/A va_start(ap);
1N/A#endif
1N/A (void)vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
1N/A dbenv->db_errcall(dbenv->db_errpfx, errbuf);
1N/A va_end(ap);
1N/A }
1N/A if (dbenv->db_errfile != NULL) {
1N/A if (dbenv->db_errpfx != NULL)
1N/A (void)fprintf(dbenv->db_errfile, "%s: ",
1N/A dbenv->db_errpfx);
1N/A#ifdef __STDC__
1N/A va_start(ap, fmt);
1N/A#else
1N/A va_start(ap);
1N/A#endif
1N/A (void)vfprintf(dbenv->db_errfile, fmt, ap);
1N/A (void)fprintf(dbenv->db_errfile, "\n");
1N/A (void)fflush(dbenv->db_errfile);
1N/A va_end(ap);
1N/A }
1N/A}
1N/A
1N/A/*
1N/A * __db_pgerr --
1N/A * Error when unable to retrieve a specified page.
1N/A *
1N/A * PUBLIC: int __db_pgerr __P((DB *, db_pgno_t));
1N/A */
1N/Aint
1N/A__db_pgerr(dbp, pgno)
1N/A DB *dbp;
1N/A db_pgno_t pgno;
1N/A{
1N/A /*
1N/A * Three things are certain:
1N/A * Death, taxes, and lost data.
1N/A * Guess which has occurred.
1N/A */
1N/A __db_err(dbp->dbenv,
1N/A "unable to create/retrieve page %lu", (u_long)pgno);
1N/A return (__db_panic(dbp->dbenv, EIO));
1N/A}
1N/A
1N/A/*
1N/A * __db_pgfmt --
1N/A * Error when a page has the wrong format.
1N/A *
1N/A * PUBLIC: int __db_pgfmt __P((DB *, db_pgno_t));
1N/A */
1N/Aint
1N/A__db_pgfmt(dbp, pgno)
1N/A DB *dbp;
1N/A db_pgno_t pgno;
1N/A{
1N/A __db_err(dbp->dbenv,
1N/A "page %lu: illegal page type or format", (u_long)pgno);
1N/A return (__db_panic(dbp->dbenv, EINVAL));
1N/A}
1N/A
1N/A/*
1N/A * __db_panic --
1N/A * Lock out the tree due to unrecoverable error.
1N/A *
1N/A * PUBLIC: int __db_panic __P((DB_ENV *, int));
1N/A */
1N/Aint
1N/A__db_panic(dbenv, errval)
1N/A DB_ENV *dbenv;
1N/A int errval;
1N/A{
1N/A if (dbenv != NULL) {
1N/A dbenv->db_panic = errval;
1N/A
1N/A (void)__log_panic(dbenv);
1N/A (void)__memp_panic(dbenv);
1N/A (void)__lock_panic(dbenv);
1N/A (void)__txn_panic(dbenv);
1N/A
1N/A __db_err(dbenv, "PANIC: %s", strerror(errval));
1N/A
1N/A if (dbenv->db_paniccall != NULL)
1N/A dbenv->db_paniccall(dbenv, errval);
1N/A }
1N/A
1N/A /*
1N/A * Chaos reigns within.
1N/A * Reflect, repent, and reboot.
1N/A * Order shall return.
1N/A */
1N/A return (DB_RUNRECOVERY);
1N/A}