~vlad-lesin/percona-server/mysql-5.0.33-original

« back to all changes in this revision

Viewing changes to bdb/common/db_err.c

  • Committer: Vlad Lesin
  • Date: 2012-07-31 09:21:34 UTC
  • Revision ID: vladislav.lesin@percona.com-20120731092134-zfodx022b7992wsi
VirginĀ 5.0.33

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-
 
2
 * See the file LICENSE for redistribution information.
 
3
 *
 
4
 * Copyright (c) 1996-2002
 
5
 *      Sleepycat Software.  All rights reserved.
 
6
 */
 
7
 
 
8
#include "db_config.h"
 
9
 
 
10
#ifndef lint
 
11
static const char revid[] = "$Id: db_err.c,v 11.80 2002/07/30 01:21:53 bostic Exp $";
 
12
#endif /* not lint */
 
13
 
 
14
#ifndef NO_SYSTEM_INCLUDES
 
15
#include <sys/types.h>
 
16
 
 
17
#include <stdio.h>
 
18
#include <stdlib.h>
 
19
#include <string.h>
 
20
#endif
 
21
 
 
22
#include "db_int.h"
 
23
#include "dbinc/db_page.h"
 
24
#include "dbinc/db_am.h"
 
25
#include "dbinc/db_shash.h"
 
26
#include "dbinc/lock.h"
 
27
#include "dbinc/log.h"
 
28
#include "dbinc/txn.h"
 
29
 
 
30
/*
 
31
 * __db_fchk --
 
32
 *      General flags checking routine.
 
33
 *
 
34
 * PUBLIC: int __db_fchk __P((DB_ENV *, const char *, u_int32_t, u_int32_t));
 
35
 */
 
36
int
 
37
__db_fchk(dbenv, name, flags, ok_flags)
 
38
        DB_ENV *dbenv;
 
39
        const char *name;
 
40
        u_int32_t flags, ok_flags;
 
41
{
 
42
        return (LF_ISSET(~ok_flags) ? __db_ferr(dbenv, name, 0) : 0);
 
43
}
 
44
 
 
45
/*
 
46
 * __db_fcchk --
 
47
 *      General combination flags checking routine.
 
48
 *
 
49
 * PUBLIC: int __db_fcchk
 
50
 * PUBLIC:    __P((DB_ENV *, const char *, u_int32_t, u_int32_t, u_int32_t));
 
51
 */
 
52
int
 
53
__db_fcchk(dbenv, name, flags, flag1, flag2)
 
54
        DB_ENV *dbenv;
 
55
        const char *name;
 
56
        u_int32_t flags, flag1, flag2;
 
57
{
 
58
        return (LF_ISSET(flag1) &&
 
59
            LF_ISSET(flag2) ? __db_ferr(dbenv, name, 1) : 0);
 
60
}
 
61
 
 
62
/*
 
63
 * __db_ferr --
 
64
 *      Common flag errors.
 
65
 *
 
66
 * PUBLIC: int __db_ferr __P((const DB_ENV *, const char *, int));
 
67
 */
 
68
int
 
69
__db_ferr(dbenv, name, iscombo)
 
70
        const DB_ENV *dbenv;
 
71
        const char *name;
 
72
        int iscombo;
 
73
{
 
74
        __db_err(dbenv, "illegal flag %sspecified to %s",
 
75
            iscombo ? "combination " : "", name);
 
76
        return (EINVAL);
 
77
}
 
78
 
 
79
/*
 
80
 * __db_pgerr --
 
81
 *      Error when unable to retrieve a specified page.
 
82
 *
 
83
 * PUBLIC: void __db_pgerr __P((DB *, db_pgno_t, int));
 
84
 */
 
85
void
 
86
__db_pgerr(dbp, pgno, errval)
 
87
        DB *dbp;
 
88
        db_pgno_t pgno;
 
89
        int errval;
 
90
{
 
91
        /*
 
92
         * Three things are certain:
 
93
         * Death, taxes, and lost data.
 
94
         * Guess which has occurred.
 
95
         */
 
96
        __db_err(dbp->dbenv,
 
97
            "unable to create/retrieve page %lu", (u_long)pgno);
 
98
        (void)__db_panic(dbp->dbenv, errval);
 
99
}
 
100
 
 
101
/*
 
102
 * __db_pgfmt --
 
103
 *      Error when a page has the wrong format.
 
104
 *
 
105
 * PUBLIC: int __db_pgfmt __P((DB_ENV *, db_pgno_t));
 
106
 */
 
107
int
 
108
__db_pgfmt(dbenv, pgno)
 
109
        DB_ENV *dbenv;
 
110
        db_pgno_t pgno;
 
111
{
 
112
        __db_err(dbenv, "page %lu: illegal page type or format", (u_long)pgno);
 
113
        return (__db_panic(dbenv, EINVAL));
 
114
}
 
115
 
 
116
/*
 
117
 * __db_eopnotsup --
 
118
 *      Common operation not supported message.
 
119
 *
 
120
 * PUBLIC: int __db_eopnotsup __P((const DB_ENV *));
 
121
 */
 
122
int
 
123
__db_eopnotsup(dbenv)
 
124
        const DB_ENV *dbenv;
 
125
{
 
126
        __db_err(dbenv, "operation not supported");
 
127
#ifdef EOPNOTSUPP
 
128
        return (EOPNOTSUPP);
 
129
#else
 
130
        return (EINVAL);
 
131
#endif
 
132
}
 
133
 
 
134
#ifdef DIAGNOSTIC
 
135
/*
 
136
 * __db_assert --
 
137
 *      Error when an assertion fails.  Only checked if #DIAGNOSTIC defined.
 
138
 *
 
139
 * PUBLIC: #ifdef DIAGNOSTIC
 
140
 * PUBLIC: void __db_assert __P((const char *, const char *, int));
 
141
 * PUBLIC: #endif
 
142
 */
 
143
void
 
144
__db_assert(failedexpr, file, line)
 
145
        const char *failedexpr, *file;
 
146
        int line;
 
147
{
 
148
        (void)fprintf(stderr,
 
149
            "__db_assert: \"%s\" failed: file \"%s\", line %d\n",
 
150
            failedexpr, file, line);
 
151
        (void)fflush(stderr);
 
152
 
 
153
        /* We want a stack trace of how this could possibly happen. */
 
154
        abort();
 
155
 
 
156
        /* NOTREACHED */
 
157
}
 
158
#endif
 
159
 
 
160
/*
 
161
 * __db_panic_msg --
 
162
 *      Just report that someone else paniced.
 
163
 *
 
164
 * PUBLIC: int __db_panic_msg __P((DB_ENV *));
 
165
 */
 
166
int
 
167
__db_panic_msg(dbenv)
 
168
        DB_ENV *dbenv;
 
169
{
 
170
        __db_err(dbenv, "fatal region error detected; run recovery");
 
171
        return (DB_RUNRECOVERY);
 
172
}
 
173
 
 
174
/*
 
175
 * __db_panic --
 
176
 *      Lock out the tree due to unrecoverable error.
 
177
 *
 
178
 * PUBLIC: int __db_panic __P((DB_ENV *, int));
 
179
 */
 
180
int
 
181
__db_panic(dbenv, errval)
 
182
        DB_ENV *dbenv;
 
183
        int errval;
 
184
{
 
185
        if (dbenv != NULL) {
 
186
                PANIC_SET(dbenv, 1);
 
187
 
 
188
                dbenv->panic_errval = errval;
 
189
 
 
190
                __db_err(dbenv, "PANIC: %s", db_strerror(errval));
 
191
 
 
192
                if (dbenv->db_paniccall != NULL)
 
193
                        dbenv->db_paniccall(dbenv, errval);
 
194
        }
 
195
 
 
196
#if defined(DIAGNOSTIC) && !defined(CONFIG_TEST)
 
197
        /*
 
198
         * We want a stack trace of how this could possibly happen.
 
199
         *
 
200
         * Don't drop core if it's the test suite -- it's reasonable for the
 
201
         * test suite to check to make sure that DB_RUNRECOVERY is returned
 
202
         * under certain conditions.
 
203
         */
 
204
        abort();
 
205
#endif
 
206
 
 
207
        /*
 
208
         * Chaos reigns within.
 
209
         * Reflect, repent, and reboot.
 
210
         * Order shall return.
 
211
         */
 
212
        return (DB_RUNRECOVERY);
 
213
}
 
214
 
 
215
/*
 
216
 * db_strerror --
 
217
 *      ANSI C strerror(3) for DB.
 
218
 *
 
219
 * EXTERN: char *db_strerror __P((int));
 
220
 */
 
221
char *
 
222
db_strerror(error)
 
223
        int error;
 
224
{
 
225
        if (error == 0)
 
226
                return ("Successful return: 0");
 
227
        if (error > 0)
 
228
                return (strerror(error));
 
229
 
 
230
        /*
 
231
         * !!!
 
232
         * The Tcl API requires that some of these return strings be compared
 
233
         * against strings stored in application scripts.  So, any of these
 
234
         * errors that do not invariably result in a Tcl exception may not be
 
235
         * altered.
 
236
         */
 
237
        switch (error) {
 
238
        case DB_DONOTINDEX:
 
239
                return ("DB_DONOTINDEX: Secondary index callback returns null");
 
240
        case DB_KEYEMPTY:
 
241
                return ("DB_KEYEMPTY: Non-existent key/data pair");
 
242
        case DB_KEYEXIST:
 
243
                return ("DB_KEYEXIST: Key/data pair already exists");
 
244
        case DB_LOCK_DEADLOCK:
 
245
                return
 
246
                    ("DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock");
 
247
        case DB_LOCK_NOTGRANTED:
 
248
                return ("DB_LOCK_NOTGRANTED: Lock not granted");
 
249
        case DB_NOSERVER:
 
250
                return ("DB_NOSERVER: Fatal error, no server");
 
251
        case DB_NOSERVER_HOME:
 
252
                return ("DB_NOSERVER_HOME: Home unrecognized at server");
 
253
        case DB_NOSERVER_ID:
 
254
                return ("DB_NOSERVER_ID: Identifier unrecognized at server");
 
255
        case DB_NOTFOUND:
 
256
                return ("DB_NOTFOUND: No matching key/data pair found");
 
257
        case DB_OLD_VERSION:
 
258
                return ("DB_OLDVERSION: Database requires a version upgrade");
 
259
        case DB_PAGE_NOTFOUND:
 
260
                return ("DB_PAGE_NOTFOUND: Requested page not found");
 
261
        case DB_REP_DUPMASTER:
 
262
                return ("DB_REP_DUPMASTER: A second master site appeared");
 
263
        case DB_REP_HOLDELECTION:
 
264
                return ("DB_REP_HOLDELECTION: Need to hold an election");
 
265
        case DB_REP_NEWMASTER:
 
266
                return ("DB_REP_NEWMASTER: A new master has declared itself");
 
267
        case DB_REP_NEWSITE:
 
268
                return ("DB_REP_NEWSITE: A new site has entered the system");
 
269
        case DB_REP_OUTDATED:
 
270
                return
 
271
                    ("DB_REP_OUTDATED: Insufficient logs on master to recover");
 
272
        case DB_REP_UNAVAIL:
 
273
                return ("DB_REP_UNAVAIL: Unable to elect a master");
 
274
        case DB_RUNRECOVERY:
 
275
                return ("DB_RUNRECOVERY: Fatal error, run database recovery");
 
276
        case DB_SECONDARY_BAD:
 
277
                return
 
278
            ("DB_SECONDARY_BAD: Secondary index item missing from primary");
 
279
        case DB_VERIFY_BAD:
 
280
                return ("DB_VERIFY_BAD: Database verification failed");
 
281
        default: {
 
282
                /*
 
283
                 * !!!
 
284
                 * Room for a 64-bit number + slop.  This buffer is only used
 
285
                 * if we're given an unknown error, which should never happen.
 
286
                 * Note, however, we're no longer thread-safe if it does.
 
287
                 */
 
288
                static char ebuf[40];
 
289
 
 
290
                (void)snprintf(ebuf, sizeof(ebuf), "Unknown error: %d", error);
 
291
                return (ebuf);
 
292
        }
 
293
        }
 
294
}
 
295
 
 
296
/*
 
297
 * __db_err --
 
298
 *      Standard DB error routine.  The same as errx, except we don't write
 
299
 *      to stderr if no output mechanism was specified.
 
300
 *
 
301
 * PUBLIC: void __db_err __P((const DB_ENV *, const char *, ...));
 
302
 */
 
303
void
 
304
#ifdef __STDC__
 
305
__db_err(const DB_ENV *dbenv, const char *fmt, ...)
 
306
#else
 
307
__db_err(dbenv, fmt, va_alist)
 
308
        const DB_ENV *dbenv;
 
309
        const char *fmt;
 
310
        va_dcl
 
311
#endif
 
312
{
 
313
        DB_REAL_ERR(dbenv, 0, 0, 0, fmt);
 
314
}
 
315
 
 
316
/*
 
317
 * __db_errcall --
 
318
 *      Do the error message work for callback functions.
 
319
 *
 
320
 * PUBLIC: void __db_errcall
 
321
 * PUBLIC:          __P((const DB_ENV *, int, int, const char *, va_list));
 
322
 */
 
323
void
 
324
__db_errcall(dbenv, error, error_set, fmt, ap)
 
325
        const DB_ENV *dbenv;
 
326
        int error, error_set;
 
327
        const char *fmt;
 
328
        va_list ap;
 
329
{
 
330
        char *p;
 
331
        char errbuf[2048];      /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
 
332
 
 
333
        p = errbuf;
 
334
        if (fmt != NULL)
 
335
                p += vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
 
336
        if (error_set)
 
337
                p += snprintf(p,
 
338
                    sizeof(errbuf) - (p - errbuf), ": %s", db_strerror(error));
 
339
        /*
 
340
         * !!!
 
341
         * We're potentially manipulating strings handed us by the application,
 
342
         * and on systems without a real snprintf() the sprintf() calls could
 
343
         * have overflowed the buffer.  We can't do anything about it now, but
 
344
         * we don't want to return control to the application, we might have
 
345
         * overwritten the stack with a Trojan horse.  We're not trying to do
 
346
         * anything recoverable here because systems without snprintf support
 
347
         * are pretty rare anymore.
 
348
         */
 
349
        if ((size_t)(p - errbuf) > sizeof(errbuf)) {
 
350
                (void)fprintf(stderr,
 
351
                    "Berkeley DB: error callback interface buffer overflow\n");
 
352
                (void)fflush(stderr);
 
353
 
 
354
                abort();
 
355
                /* NOTREACHED */
 
356
        }
 
357
 
 
358
        dbenv->db_errcall(dbenv->db_errpfx, errbuf);
 
359
}
 
360
 
 
361
/*
 
362
 * __db_errfile --
 
363
 *      Do the error message work for FILE *s.
 
364
 *
 
365
 * PUBLIC: void __db_errfile
 
366
 * PUBLIC:          __P((const DB_ENV *, int, int, const char *, va_list));
 
367
 */
 
368
void
 
369
__db_errfile(dbenv, error, error_set, fmt, ap)
 
370
        const DB_ENV *dbenv;
 
371
        int error, error_set;
 
372
        const char *fmt;
 
373
        va_list ap;
 
374
{
 
375
        FILE *fp;
 
376
 
 
377
        fp = dbenv == NULL ||
 
378
            dbenv->db_errfile == NULL ? stderr : dbenv->db_errfile;
 
379
 
 
380
        if (dbenv != NULL && dbenv->db_errpfx != NULL)
 
381
                (void)fprintf(fp, "%s: ", dbenv->db_errpfx);
 
382
        if (fmt != NULL) {
 
383
                (void)vfprintf(fp, fmt, ap);
 
384
                if (error_set)
 
385
                        (void)fprintf(fp, ": ");
 
386
        }
 
387
        if (error_set)
 
388
                (void)fprintf(fp, "%s", db_strerror(error));
 
389
        (void)fprintf(fp, "\n");
 
390
        (void)fflush(fp);
 
391
}
 
392
 
 
393
/*
 
394
 * __db_logmsg --
 
395
 *      Write information into the DB log.
 
396
 *
 
397
 * PUBLIC: void __db_logmsg __P((const DB_ENV *,
 
398
 * PUBLIC:     DB_TXN *, const char *, u_int32_t, const char *, ...));
 
399
 */
 
400
void
 
401
#ifdef __STDC__
 
402
__db_logmsg(const DB_ENV *dbenv,
 
403
    DB_TXN *txnid, const char *opname, u_int32_t flags, const char *fmt, ...)
 
404
#else
 
405
__db_logmsg(dbenv, txnid, opname, flags, fmt, va_alist)
 
406
        const DB_ENV *dbenv;
 
407
        DB_TXN *txnid;
 
408
        const char *opname, *fmt;
 
409
        u_int32_t flags;
 
410
        va_dcl
 
411
#endif
 
412
{
 
413
        DBT opdbt, msgdbt;
 
414
        DB_LSN lsn;
 
415
        va_list ap;
 
416
        char __logbuf[2048];    /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
 
417
 
 
418
        if (!LOGGING_ON(dbenv))
 
419
                return;
 
420
 
 
421
#ifdef __STDC__
 
422
        va_start(ap, fmt);
 
423
#else
 
424
        va_start(ap);
 
425
#endif
 
426
        memset(&opdbt, 0, sizeof(opdbt));
 
427
        opdbt.data = (void *)opname;
 
428
        opdbt.size = (u_int32_t)(strlen(opname) + 1);
 
429
 
 
430
        memset(&msgdbt, 0, sizeof(msgdbt));
 
431
        msgdbt.data = __logbuf;
 
432
        msgdbt.size = vsnprintf(__logbuf, sizeof(__logbuf), fmt, ap);
 
433
 
 
434
        /*
 
435
         * XXX
 
436
         * Explicitly discard the const.  Otherwise, we have to const DB_ENV
 
437
         * references throughout the logging subsystem.
 
438
         */
 
439
        __db_debug_log(
 
440
            (DB_ENV *)dbenv, txnid, &lsn, flags, &opdbt, -1, &msgdbt, NULL, 0);
 
441
 
 
442
        va_end(ap);
 
443
}
 
444
 
 
445
/*
 
446
 * __db_unknown_flag -- report internal error
 
447
 *
 
448
 * PUBLIC: int __db_unknown_flag __P((DB_ENV *, char *, u_int32_t));
 
449
 */
 
450
int
 
451
__db_unknown_flag(dbenv, routine, flag)
 
452
        DB_ENV *dbenv;
 
453
        char *routine;
 
454
        u_int32_t flag;
 
455
{
 
456
        __db_err(dbenv, "%s: Unknown flag: 0x%x", routine, flag);
 
457
        DB_ASSERT(0);
 
458
        return (EINVAL);
 
459
}
 
460
 
 
461
/*
 
462
 * __db_unknown_type -- report internal error
 
463
 *
 
464
 * PUBLIC: int __db_unknown_type __P((DB_ENV *, char *, DBTYPE));
 
465
 */
 
466
int
 
467
__db_unknown_type(dbenv, routine, type)
 
468
        DB_ENV *dbenv;
 
469
        char *routine;
 
470
        DBTYPE type;
 
471
{
 
472
        __db_err(dbenv, "%s: Unknown db type: 0x%x", routine, type);
 
473
        DB_ASSERT(0);
 
474
        return (EINVAL);
 
475
}
 
476
 
 
477
/*
 
478
 * __db_check_txn --
 
479
 *      Check for common transaction errors.
 
480
 *
 
481
 * PUBLIC: int __db_check_txn __P((DB *, DB_TXN *, u_int32_t, int));
 
482
 */
 
483
int
 
484
__db_check_txn(dbp, txn, assoc_lid, read_op)
 
485
        DB *dbp;
 
486
        DB_TXN *txn;
 
487
        u_int32_t assoc_lid;
 
488
        int read_op;
 
489
{
 
490
        DB_ENV *dbenv;
 
491
 
 
492
        dbenv = dbp->dbenv;
 
493
 
 
494
        /*
 
495
         * If we are in recovery or aborting a transaction, then we
 
496
         * don't need to enforce the rules about dbp's not allowing
 
497
         * transactional operations in non-transactional dbps and
 
498
         * vica-versa.  This happens all the time as the dbp during
 
499
         * an abort may be transactional, but we undo operations
 
500
         * outside a transaction since we're aborting.
 
501
         */
 
502
        if (IS_RECOVERING(dbenv) || F_ISSET(dbp, DB_AM_RECOVER))
 
503
                return (0);
 
504
 
 
505
        /*
 
506
         * Check for common transaction errors:
 
507
         *      Failure to pass a transaction handle to a DB operation
 
508
         *      Failure to configure the DB handle in a proper environment
 
509
         *      Operation on a handle whose open commit hasn't completed.
 
510
         *
 
511
         * Read operations don't require a txn even if we've used one before
 
512
         * with this handle, although if they do have a txn, we'd better be
 
513
         * prepared for it.
 
514
         */
 
515
        if (txn == NULL) {
 
516
                if (!read_op && F_ISSET(dbp, DB_AM_TXN)) {
 
517
                        __db_err(dbenv,
 
518
    "DB handle previously used in transaction, missing transaction handle");
 
519
                        return (EINVAL);
 
520
                }
 
521
 
 
522
                if (dbp->cur_lid >= TXN_MINIMUM)
 
523
                        goto open_err;
 
524
        } else {
 
525
                if (dbp->cur_lid >= TXN_MINIMUM && dbp->cur_lid != txn->txnid)
 
526
                        goto open_err;
 
527
 
 
528
                if (!TXN_ON(dbenv))
 
529
                         return (__db_not_txn_env(dbenv));
 
530
 
 
531
                if (!F_ISSET(dbp, DB_AM_TXN)) {
 
532
                        __db_err(dbenv,
 
533
    "Transaction specified for a DB handle opened outside a transaction");
 
534
                        return (EINVAL);
 
535
                }
 
536
        }
 
537
 
 
538
        /*
 
539
         * If dbp->associate_lid is not DB_LOCK_INVALIDID, that means we're in
 
540
         * the middle of a DB->associate with DB_CREATE (i.e., a secondary index
 
541
         * creation).
 
542
         *
 
543
         * In addition to the usual transaction rules, we need to lock out
 
544
         * non-transactional updates that aren't part of the associate (and
 
545
         * thus are using some other locker ID).
 
546
         *
 
547
         * Transactional updates should simply block;  from the time we
 
548
         * decide to build the secondary until commit, we'll hold a write
 
549
         * lock on all of its pages, so it should be safe to attempt to update
 
550
         * the secondary in another transaction (presumably by updating the
 
551
         * primary).
 
552
         */
 
553
        if (!read_op && dbp->associate_lid != DB_LOCK_INVALIDID &&
 
554
            txn != NULL && dbp->associate_lid != assoc_lid) {
 
555
                __db_err(dbenv,
 
556
            "Operation forbidden while secondary index is being created");
 
557
                return (EINVAL);
 
558
        }
 
559
 
 
560
        return (0);
 
561
open_err:
 
562
        __db_err(dbenv,
 
563
            "Transaction that opened the DB handle is still active");
 
564
        return (EINVAL);
 
565
}
 
566
 
 
567
/*
 
568
 * __db_not_txn_env --
 
569
 *      DB handle must be in an environment that supports transactions.
 
570
 *
 
571
 * PUBLIC: int __db_not_txn_env __P((DB_ENV *));
 
572
 */
 
573
int
 
574
__db_not_txn_env(dbenv)
 
575
        DB_ENV *dbenv;
 
576
{
 
577
        __db_err(dbenv, "DB environment not configured for transactions");
 
578
        return (EINVAL);
 
579
}