1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1996-2009 Oracle. All rights reserved. 5 * 6 * $Id$ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12#include "dbinc/db_page.h" 13#include "dbinc/db_am.h" 14#include "dbinc/lock.h" 15#include "dbinc/log.h" 16#include "dbinc/mp.h" 17#include "dbinc/txn.h" 18 19static void __db_msgcall __P((const DB_ENV *, const char *, va_list)); 20static void __db_msgfile __P((const DB_ENV *, const char *, va_list)); 21 22/* 23 * __db_fchk -- 24 * General flags checking routine. 25 * 26 * PUBLIC: int __db_fchk __P((ENV *, const char *, u_int32_t, u_int32_t)); 27 */ 28int 29__db_fchk(env, name, flags, ok_flags) 30 ENV *env; 31 const char *name; 32 u_int32_t flags, ok_flags; 33{ 34 return (LF_ISSET(~ok_flags) ? __db_ferr(env, name, 0) : 0); 35} 36 37/* 38 * __db_fcchk -- 39 * General combination flags checking routine. 40 * 41 * PUBLIC: int __db_fcchk 42 * PUBLIC: __P((ENV *, const char *, u_int32_t, u_int32_t, u_int32_t)); 43 */ 44int 45__db_fcchk(env, name, flags, flag1, flag2) 46 ENV *env; 47 const char *name; 48 u_int32_t flags, flag1, flag2; 49{ 50 return (LF_ISSET(flag1) && 51 LF_ISSET(flag2) ? __db_ferr(env, name, 1) : 0); 52} 53 54/* 55 * __db_ferr -- 56 * Common flag errors. 57 * 58 * PUBLIC: int __db_ferr __P((const ENV *, const char *, int)); 59 */ 60int 61__db_ferr(env, name, iscombo) 62 const ENV *env; 63 const char *name; 64 int iscombo; 65{ 66 __db_errx(env, "illegal flag %sspecified to %s", 67 iscombo ? "combination " : "", name); 68 return (EINVAL); 69} 70 71/* 72 * __db_fnl -- 73 * Common flag-needs-locking message. 74 * 75 * PUBLIC: int __db_fnl __P((const ENV *, const char *)); 76 */ 77int 78__db_fnl(env, name) 79 const ENV *env; 80 const char *name; 81{ 82 __db_errx(env, 83 "%s: DB_READ_COMMITTED, DB_READ_UNCOMMITTED and DB_RMW require locking", 84 name); 85 return (EINVAL); 86} 87 88/* 89 * __db_pgerr -- 90 * Error when unable to retrieve a specified page. 91 * 92 * PUBLIC: int __db_pgerr __P((DB *, db_pgno_t, int)); 93 */ 94int 95__db_pgerr(dbp, pgno, errval) 96 DB *dbp; 97 db_pgno_t pgno; 98 int errval; 99{ 100 /* 101 * Three things are certain: 102 * Death, taxes, and lost data. 103 * Guess which has occurred. 104 */ 105 __db_errx(dbp->env, 106 "unable to create/retrieve page %lu", (u_long)pgno); 107 return (__env_panic(dbp->env, errval)); 108} 109 110/* 111 * __db_pgfmt -- 112 * Error when a page has the wrong format. 113 * 114 * PUBLIC: int __db_pgfmt __P((ENV *, db_pgno_t)); 115 */ 116int 117__db_pgfmt(env, pgno) 118 ENV *env; 119 db_pgno_t pgno; 120{ 121 __db_errx(env, "page %lu: illegal page type or format", (u_long)pgno); 122 return (__env_panic(env, EINVAL)); 123} 124 125#ifdef DIAGNOSTIC 126/* 127 * __db_assert -- 128 * Error when an assertion fails. Only checked if #DIAGNOSTIC defined. 129 * 130 * PUBLIC: #ifdef DIAGNOSTIC 131 * PUBLIC: void __db_assert __P((ENV *, const char *, const char *, int)); 132 * PUBLIC: #endif 133 */ 134void 135__db_assert(env, e, file, line) 136 ENV *env; 137 const char *e, *file; 138 int line; 139{ 140 __db_errx(env, "assert failure: %s/%d: \"%s\"", file, line, e); 141 142 __os_abort(env); 143 /* NOTREACHED */ 144} 145#endif 146 147/* 148 * __env_panic_msg -- 149 * Just report that someone else paniced. 150 * 151 * PUBLIC: int __env_panic_msg __P((ENV *)); 152 */ 153int 154__env_panic_msg(env) 155 ENV *env; 156{ 157 DB_ENV *dbenv; 158 int ret; 159 160 dbenv = env->dbenv; 161 162 ret = DB_RUNRECOVERY; 163 164 __db_errx(env, "PANIC: fatal region error detected; run recovery"); 165 166 if (dbenv->db_paniccall != NULL) /* Deprecated */ 167 dbenv->db_paniccall(dbenv, ret); 168 169 /* Must check for DB_EVENT_REG_PANIC panic first because it is never 170 * set by itself. If set, it means panic came from DB_REGISTER code 171 * only, otherwise it could be from many possible places in the code. 172 */ 173 if ((env->reginfo != NULL) && 174 (((REGENV *)env->reginfo->primary)->reg_panic)) 175 DB_EVENT(env, DB_EVENT_REG_PANIC, &ret); 176 else 177 DB_EVENT(env, DB_EVENT_PANIC, &ret); 178 179 return (ret); 180} 181 182/* 183 * __env_panic -- 184 * Lock out the database environment due to unrecoverable error. 185 * 186 * PUBLIC: int __env_panic __P((ENV *, int)); 187 */ 188int 189__env_panic(env, errval) 190 ENV *env; 191 int errval; 192{ 193 DB_ENV *dbenv; 194 195 dbenv = env->dbenv; 196 197 if (env != NULL) { 198 __env_panic_set(env, 1); 199 200 __db_err(env, errval, "PANIC"); 201 202 if (dbenv->db_paniccall != NULL) /* Deprecated */ 203 dbenv->db_paniccall(dbenv, errval); 204 205 /* Must check for DB_EVENT_REG_PANIC first because it is never 206 * set by itself. If set, it means panic came from DB_REGISTER 207 * code only, otherwise it could be from many possible places 208 * in the code. 209 */ 210 if ((env->reginfo != NULL) && 211 (((REGENV *)env->reginfo->primary)->reg_panic)) 212 DB_EVENT(env, DB_EVENT_REG_PANIC, &errval); 213 else 214 DB_EVENT(env, DB_EVENT_PANIC, &errval); 215 } 216 217#if defined(DIAGNOSTIC) && !defined(CONFIG_TEST) 218 /* 219 * We want a stack trace of how this could possibly happen. 220 * 221 * Don't drop core if it's the test suite -- it's reasonable for the 222 * test suite to check to make sure that DB_RUNRECOVERY is returned 223 * under certain conditions. 224 */ 225 __os_abort(env); 226 /* NOTREACHED */ 227#endif 228 229 /* 230 * Chaos reigns within. 231 * Reflect, repent, and reboot. 232 * Order shall return. 233 */ 234 return (DB_RUNRECOVERY); 235} 236 237/* 238 * db_strerror -- 239 * ANSI C strerror(3) for DB. 240 * 241 * EXTERN: char *db_strerror __P((int)); 242 */ 243char * 244db_strerror(error) 245 int error; 246{ 247 char *p; 248 249 if (error == 0) 250 return ("Successful return: 0"); 251 if (error > 0) { 252 if ((p = strerror(error)) != NULL) 253 return (p); 254 return (__db_unknown_error(error)); 255 } 256 257 /* 258 * !!! 259 * The Tcl API requires that some of these return strings be compared 260 * against strings stored in application scripts. So, any of these 261 * errors that do not invariably result in a Tcl exception may not be 262 * altered. 263 */ 264 switch (error) { 265 case DB_BUFFER_SMALL: 266 return 267 ("DB_BUFFER_SMALL: User memory too small for return value"); 268 case DB_DONOTINDEX: 269 return ("DB_DONOTINDEX: Secondary index callback returns null"); 270 case DB_FOREIGN_CONFLICT: 271 return 272 ("DB_FOREIGN_CONFLICT: A foreign database constraint has been violated"); 273 case DB_KEYEMPTY: 274 return ("DB_KEYEMPTY: Non-existent key/data pair"); 275 case DB_KEYEXIST: 276 return ("DB_KEYEXIST: Key/data pair already exists"); 277 case DB_LOCK_DEADLOCK: 278 return 279 ("DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock"); 280 case DB_LOCK_NOTGRANTED: 281 return ("DB_LOCK_NOTGRANTED: Lock not granted"); 282 case DB_LOG_BUFFER_FULL: 283 return ("DB_LOG_BUFFER_FULL: In-memory log buffer is full"); 284 case DB_NOSERVER: 285 return ("DB_NOSERVER: Fatal error, no RPC server"); 286 case DB_NOSERVER_HOME: 287 return ("DB_NOSERVER_HOME: Home unrecognized at server"); 288 case DB_NOSERVER_ID: 289 return ("DB_NOSERVER_ID: Identifier unrecognized at server"); 290 case DB_NOTFOUND: 291 return ("DB_NOTFOUND: No matching key/data pair found"); 292 case DB_OLD_VERSION: 293 return ("DB_OLDVERSION: Database requires a version upgrade"); 294 case DB_PAGE_NOTFOUND: 295 return ("DB_PAGE_NOTFOUND: Requested page not found"); 296 case DB_REP_DUPMASTER: 297 return ("DB_REP_DUPMASTER: A second master site appeared"); 298 case DB_REP_HANDLE_DEAD: 299 return ("DB_REP_HANDLE_DEAD: Handle is no longer valid"); 300 case DB_REP_HOLDELECTION: 301 return ("DB_REP_HOLDELECTION: Need to hold an election"); 302 case DB_REP_IGNORE: 303 return ("DB_REP_IGNORE: Replication record/operation ignored"); 304 case DB_REP_ISPERM: 305 return ("DB_REP_ISPERM: Permanent record written"); 306 case DB_REP_JOIN_FAILURE: 307 return 308 ("DB_REP_JOIN_FAILURE: Unable to join replication group"); 309 case DB_REP_LEASE_EXPIRED: 310 return 311 ("DB_REP_LEASE_EXPIRED: Replication leases have expired"); 312 case DB_REP_LOCKOUT: 313 return 314 ("DB_REP_LOCKOUT: Waiting for replication recovery to complete"); 315 case DB_REP_NEWSITE: 316 return ("DB_REP_NEWSITE: A new site has entered the system"); 317 case DB_REP_NOTPERM: 318 return ("DB_REP_NOTPERM: Permanent log record not written"); 319 case DB_REP_UNAVAIL: 320 return ("DB_REP_UNAVAIL: Unable to elect a master"); 321 case DB_RUNRECOVERY: 322 return ("DB_RUNRECOVERY: Fatal error, run database recovery"); 323 case DB_SECONDARY_BAD: 324 return 325 ("DB_SECONDARY_BAD: Secondary index inconsistent with primary"); 326 case DB_VERIFY_BAD: 327 return ("DB_VERIFY_BAD: Database verification failed"); 328 case DB_VERSION_MISMATCH: 329 return 330 ("DB_VERSION_MISMATCH: Database environment version mismatch"); 331 default: 332 break; 333 } 334 335 return (__db_unknown_error(error)); 336} 337 338/* 339 * __db_unknown_error -- 340 * Format an unknown error value into a static buffer. 341 * 342 * PUBLIC: char *__db_unknown_error __P((int)); 343 */ 344char * 345__db_unknown_error(error) 346 int error; 347{ 348 /* 349 * !!! 350 * Room for a 64-bit number + slop. This buffer is only used 351 * if we're given an unknown error number, which should never 352 * happen. 353 * 354 * We're no longer thread-safe if it does happen, but the worst 355 * result is a corrupted error string because there will always 356 * be a trailing nul byte since the error buffer is nul filled 357 * and longer than any error message. 358 */ 359 (void)snprintf(DB_GLOBAL(error_buf), 360 sizeof(DB_GLOBAL(error_buf)), "Unknown error: %d", error); 361 return (DB_GLOBAL(error_buf)); 362} 363 364/* 365 * __db_syserr -- 366 * Standard error routine. 367 * 368 * PUBLIC: void __db_syserr __P((const ENV *, int, const char *, ...)) 369 * PUBLIC: __attribute__ ((__format__ (__printf__, 3, 4))); 370 */ 371void 372#ifdef STDC_HEADERS 373__db_syserr(const ENV *env, int error, const char *fmt, ...) 374#else 375__db_syserr(env, error, fmt, va_alist) 376 const ENV *env; 377 int error; 378 const char *fmt; 379 va_dcl 380#endif 381{ 382 DB_ENV *dbenv; 383 384 dbenv = env == NULL ? NULL : env->dbenv; 385 386 /* 387 * The same as DB->err, except we don't default to writing to stderr 388 * after any output channel has been configured, and we use a system- 389 * specific function to translate errors to strings. 390 */ 391 DB_REAL_ERR(dbenv, error, DB_ERROR_SYSTEM, 0, fmt); 392} 393 394/* 395 * __db_err -- 396 * Standard error routine. 397 * 398 * PUBLIC: void __db_err __P((const ENV *, int, const char *, ...)) 399 * PUBLIC: __attribute__ ((__format__ (__printf__, 3, 4))); 400 */ 401void 402#ifdef STDC_HEADERS 403__db_err(const ENV *env, int error, const char *fmt, ...) 404#else 405__db_err(env, error, fmt, va_alist) 406 const ENV *env; 407 int error; 408 const char *fmt; 409 va_dcl 410#endif 411{ 412 DB_ENV *dbenv; 413 414 dbenv = env == NULL ? NULL : env->dbenv; 415 416 /* 417 * The same as DB->err, except we don't default to writing to stderr 418 * once an output channel has been configured. 419 */ 420 DB_REAL_ERR(dbenv, error, DB_ERROR_SET, 0, fmt); 421} 422 423/* 424 * __db_errx -- 425 * Standard error routine. 426 * 427 * PUBLIC: void __db_errx __P((const ENV *, const char *, ...)) 428 * PUBLIC: __attribute__ ((__format__ (__printf__, 2, 3))); 429 */ 430void 431#ifdef STDC_HEADERS 432__db_errx(const ENV *env, const char *fmt, ...) 433#else 434__db_errx(env, fmt, va_alist) 435 const ENV *env; 436 const char *fmt; 437 va_dcl 438#endif 439{ 440 DB_ENV *dbenv; 441 442 dbenv = env == NULL ? NULL : env->dbenv; 443 444 /* 445 * The same as DB->errx, except we don't default to writing to stderr 446 * once an output channel has been configured. 447 */ 448 DB_REAL_ERR(dbenv, 0, DB_ERROR_NOT_SET, 0, fmt); 449} 450 451/* 452 * __db_errcall -- 453 * Do the error message work for callback functions. 454 * 455 * PUBLIC: void __db_errcall 456 * PUBLIC: __P((const DB_ENV *, int, db_error_set_t, const char *, va_list)); 457 */ 458void 459__db_errcall(dbenv, error, error_set, fmt, ap) 460 const DB_ENV *dbenv; 461 int error; 462 db_error_set_t error_set; 463 const char *fmt; 464 va_list ap; 465{ 466 char *p; 467 char buf[2048]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ 468 char sysbuf[1024]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ 469 470 p = buf; 471 if (fmt != NULL) 472 p += vsnprintf(buf, sizeof(buf), fmt, ap); 473 if (error_set != DB_ERROR_NOT_SET) 474 p += snprintf(p, 475 sizeof(buf) - (size_t)(p - buf), ": %s", 476 error_set == DB_ERROR_SET ? db_strerror(error) : 477 __os_strerror(error, sysbuf, sizeof(sysbuf))); 478 479 dbenv->db_errcall(dbenv, dbenv->db_errpfx, buf); 480} 481 482/* 483 * __db_errfile -- 484 * Do the error message work for FILE *s. 485 * 486 * PUBLIC: void __db_errfile 487 * PUBLIC: __P((const DB_ENV *, int, db_error_set_t, const char *, va_list)); 488 */ 489void 490__db_errfile(dbenv, error, error_set, fmt, ap) 491 const DB_ENV *dbenv; 492 int error; 493 db_error_set_t error_set; 494 const char *fmt; 495 va_list ap; 496{ 497 FILE *fp; 498 int need_sep; 499 char sysbuf[1024]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ 500 501 fp = dbenv == NULL || 502 dbenv->db_errfile == NULL ? stderr : dbenv->db_errfile; 503 need_sep = 0; 504 505 if (dbenv != NULL && dbenv->db_errpfx != NULL) { 506 (void)fprintf(fp, "%s", dbenv->db_errpfx); 507 need_sep = 1; 508 } 509 if (fmt != NULL && fmt[0] != '\0') { 510 if (need_sep) 511 (void)fprintf(fp, ": "); 512 need_sep = 1; 513 (void)vfprintf(fp, fmt, ap); 514 } 515 if (error_set != DB_ERROR_NOT_SET) 516 (void)fprintf(fp, "%s%s", 517 need_sep ? ": " : "", 518 error_set == DB_ERROR_SET ? db_strerror(error) : 519 __os_strerror(error, sysbuf, sizeof(sysbuf))); 520 (void)fprintf(fp, "\n"); 521 (void)fflush(fp); 522} 523 524/* 525 * __db_msgadd -- 526 * Aggregate a set of strings into a buffer for the callback API. 527 * 528 * PUBLIC: void __db_msgadd __P((ENV *, DB_MSGBUF *, const char *, ...)) 529 * PUBLIC: __attribute__ ((__format__ (__printf__, 3, 4))); 530 */ 531void 532#ifdef STDC_HEADERS 533__db_msgadd(ENV *env, DB_MSGBUF *mbp, const char *fmt, ...) 534#else 535__db_msgadd(env, mbp, fmt, va_alist) 536 ENV *env; 537 DB_MSGBUF *mbp; 538 const char *fmt; 539 va_dcl 540#endif 541{ 542 va_list ap; 543 544#ifdef STDC_HEADERS 545 va_start(ap, fmt); 546#else 547 va_start(ap); 548#endif 549 __db_msgadd_ap(env, mbp, fmt, ap); 550 va_end(ap); 551} 552 553/* 554 * __db_msgadd_ap -- 555 * Aggregate a set of strings into a buffer for the callback API. 556 * 557 * PUBLIC: void __db_msgadd_ap 558 * PUBLIC: __P((ENV *, DB_MSGBUF *, const char *, va_list)); 559 */ 560void 561__db_msgadd_ap(env, mbp, fmt, ap) 562 ENV *env; 563 DB_MSGBUF *mbp; 564 const char *fmt; 565 va_list ap; 566{ 567 size_t len, olen; 568 char buf[2048]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ 569 570 len = (size_t)vsnprintf(buf, sizeof(buf), fmt, ap); 571 572 /* 573 * There's a heap buffer in the ENV handle we use to aggregate the 574 * message chunks. We maintain a pointer to the buffer, the next slot 575 * to be filled in in the buffer, and a total buffer length. 576 */ 577 olen = (size_t)(mbp->cur - mbp->buf); 578 if (olen + len >= mbp->len) { 579 if (__os_realloc(env, mbp->len + len + 256, &mbp->buf)) 580 return; 581 mbp->len += (len + 256); 582 mbp->cur = mbp->buf + olen; 583 } 584 585 memcpy(mbp->cur, buf, len + 1); 586 mbp->cur += len; 587} 588 589/* 590 * __db_msg -- 591 * Standard DB stat message routine. 592 * 593 * PUBLIC: void __db_msg __P((const ENV *, const char *, ...)) 594 * PUBLIC: __attribute__ ((__format__ (__printf__, 2, 3))); 595 */ 596void 597#ifdef STDC_HEADERS 598__db_msg(const ENV *env, const char *fmt, ...) 599#else 600__db_msg(env, fmt, va_alist) 601 const ENV *env; 602 const char *fmt; 603 va_dcl 604#endif 605{ 606 DB_ENV *dbenv; 607 608 dbenv = env == NULL ? NULL : env->dbenv; 609 610 DB_REAL_MSG(dbenv, fmt); 611} 612 613/* 614 * __db_msgcall -- 615 * Do the message work for callback functions. 616 */ 617static void 618__db_msgcall(dbenv, fmt, ap) 619 const DB_ENV *dbenv; 620 const char *fmt; 621 va_list ap; 622{ 623 char buf[2048]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ 624 625 (void)vsnprintf(buf, sizeof(buf), fmt, ap); 626 627 dbenv->db_msgcall(dbenv, buf); 628} 629 630/* 631 * __db_msgfile -- 632 * Do the message work for FILE *s. 633 */ 634static void 635__db_msgfile(dbenv, fmt, ap) 636 const DB_ENV *dbenv; 637 const char *fmt; 638 va_list ap; 639{ 640 FILE *fp; 641 642 fp = dbenv == NULL || 643 dbenv->db_msgfile == NULL ? stdout : dbenv->db_msgfile; 644 (void)vfprintf(fp, fmt, ap); 645 646 (void)fprintf(fp, "\n"); 647 (void)fflush(fp); 648} 649 650/* 651 * __db_unknown_flag -- report internal error 652 * 653 * PUBLIC: int __db_unknown_flag __P((ENV *, char *, u_int32_t)); 654 */ 655int 656__db_unknown_flag(env, routine, flag) 657 ENV *env; 658 char *routine; 659 u_int32_t flag; 660{ 661 __db_errx(env, "%s: Unknown flag: %#x", routine, (u_int)flag); 662 663#ifdef DIAGNOSTIC 664 __os_abort(env); 665 /* NOTREACHED */ 666#endif 667 return (EINVAL); 668} 669 670/* 671 * __db_unknown_type -- report internal database type error 672 * 673 * PUBLIC: int __db_unknown_type __P((ENV *, char *, DBTYPE)); 674 */ 675int 676__db_unknown_type(env, routine, type) 677 ENV *env; 678 char *routine; 679 DBTYPE type; 680{ 681 __db_errx(env, 682 "%s: Unexpected database type: %s", 683 routine, __db_dbtype_to_string(type)); 684 685#ifdef DIAGNOSTIC 686 __os_abort(env); 687 /* NOTREACHED */ 688#endif 689 return (EINVAL); 690} 691 692/* 693 * __db_unknown_path -- report unexpected database code path error. 694 * 695 * PUBLIC: int __db_unknown_path __P((ENV *, char *)); 696 */ 697int 698__db_unknown_path(env, routine) 699 ENV *env; 700 char *routine; 701{ 702 __db_errx(env, "%s: Unexpected code path error", routine); 703 704#ifdef DIAGNOSTIC 705 __os_abort(env); 706 /* NOTREACHED */ 707#endif 708 return (EINVAL); 709} 710 711/* 712 * __db_check_txn -- 713 * Check for common transaction errors. 714 * 715 * PUBLIC: int __db_check_txn __P((DB *, DB_TXN *, DB_LOCKER *, int)); 716 */ 717int 718__db_check_txn(dbp, txn, assoc_locker, read_op) 719 DB *dbp; 720 DB_TXN *txn; 721 DB_LOCKER *assoc_locker; 722 int read_op; 723{ 724 ENV *env; 725 int isp, ret; 726 727 env = dbp->env; 728 729 /* 730 * If we are in recovery or aborting a transaction, then we 731 * don't need to enforce the rules about dbp's not allowing 732 * transactional operations in non-transactional dbps and 733 * vica-versa. This happens all the time as the dbp during 734 * an abort may be transactional, but we undo operations 735 * outside a transaction since we're aborting. 736 */ 737 if (IS_RECOVERING(env) || F_ISSET(dbp, DB_AM_RECOVER)) 738 return (0); 739 740 /* 741 * Check for common transaction errors: 742 * an operation on a handle whose open commit hasn't completed. 743 * a transaction handle in a non-transactional environment 744 * a transaction handle for a non-transactional database 745 */ 746 if (txn == NULL || F_ISSET(txn, TXN_PRIVATE)) { 747 if (dbp->cur_locker != NULL && 748 dbp->cur_locker->id >= TXN_MINIMUM) 749 goto open_err; 750 751 if (!read_op && F_ISSET(dbp, DB_AM_TXN)) { 752 __db_errx(env, 753 "Transaction not specified for a transactional database"); 754 return (EINVAL); 755 } 756 } else if (F_ISSET(txn, TXN_CDSGROUP)) { 757 if (!CDB_LOCKING(env)) { 758 __db_errx(env, 759 "CDS groups can only be used in a CDS environment"); 760 return (EINVAL); 761 } 762 /* 763 * CDS group handles can be passed to any method, since they 764 * only determine locker IDs. 765 */ 766 return (0); 767 } else { 768 if (!TXN_ON(env)) 769 return (__db_not_txn_env(env)); 770 771 if (!F_ISSET(dbp, DB_AM_TXN)) { 772 __db_errx(env, 773 "Transaction specified for a non-transactional database"); 774 return (EINVAL); 775 } 776 777 if (F_ISSET(txn, TXN_DEADLOCK)) 778 return (__db_txn_deadlock_err(env, txn)); 779 if (dbp->cur_locker != NULL && 780 dbp->cur_locker->id >= TXN_MINIMUM && 781 dbp->cur_locker->id != txn->txnid) { 782 if ((ret = __lock_locker_is_parent(env, 783 dbp->cur_locker, txn->locker, &isp)) != 0) 784 return (ret); 785 if (!isp) 786 goto open_err; 787 } 788 } 789 790 /* 791 * If dbp->associate_locker is not NULL, that means we're in 792 * the middle of a DB->associate with DB_CREATE (i.e., a secondary index 793 * creation). 794 * 795 * In addition to the usual transaction rules, we need to lock out 796 * non-transactional updates that aren't part of the associate (and 797 * thus are using some other locker ID). 798 * 799 * Transactional updates should simply block; from the time we 800 * decide to build the secondary until commit, we'll hold a write 801 * lock on all of its pages, so it should be safe to attempt to update 802 * the secondary in another transaction (presumably by updating the 803 * primary). 804 */ 805 if (!read_op && dbp->associate_locker != NULL && 806 txn != NULL && dbp->associate_locker != assoc_locker) { 807 __db_errx(env, 808 "Operation forbidden while secondary index is being created"); 809 return (EINVAL); 810 } 811 812 /* 813 * Check the txn and dbp are from the same env. 814 */ 815 if (txn != NULL && env != txn->mgrp->env) { 816 __db_errx(env, 817 "Transaction and database from different environments"); 818 return (EINVAL); 819 } 820 821 return (0); 822open_err: 823 __db_errx(env, 824 "Transaction that opened the DB handle is still active"); 825 return (EINVAL); 826} 827 828/* 829 * __db_txn_deadlock_err -- 830 * Transaction has allready been deadlocked. 831 * 832 * PUBLIC: int __db_txn_deadlock_err __P((ENV *, DB_TXN *)); 833 */ 834int 835__db_txn_deadlock_err(env, txn) 836 ENV *env; 837 DB_TXN *txn; 838{ 839 const char *name; 840 841 name = NULL; 842 (void)__txn_get_name(txn, &name); 843 844 __db_errx(env, 845 "%s%sprevious transaction deadlock return not resolved", 846 name == NULL ? "" : name, name == NULL ? "" : ": "); 847 848 return (EINVAL); 849} 850 851/* 852 * __db_not_txn_env -- 853 * DB handle must be in an environment that supports transactions. 854 * 855 * PUBLIC: int __db_not_txn_env __P((ENV *)); 856 */ 857int 858__db_not_txn_env(env) 859 ENV *env; 860{ 861 __db_errx(env, "DB environment not configured for transactions"); 862 return (EINVAL); 863} 864 865/* 866 * __db_rec_toobig -- 867 * Fixed record length exceeded error message. 868 * 869 * PUBLIC: int __db_rec_toobig __P((ENV *, u_int32_t, u_int32_t)); 870 */ 871int 872__db_rec_toobig(env, data_len, fixed_rec_len) 873 ENV *env; 874 u_int32_t data_len, fixed_rec_len; 875{ 876 __db_errx(env, 877 "%lu larger than database's maximum record length %lu", 878 (u_long)data_len, (u_long)fixed_rec_len); 879 return (EINVAL); 880} 881 882/* 883 * __db_rec_repl -- 884 * Fixed record replacement length error message. 885 * 886 * PUBLIC: int __db_rec_repl __P((ENV *, u_int32_t, u_int32_t)); 887 */ 888int 889__db_rec_repl(env, data_size, data_dlen) 890 ENV *env; 891 u_int32_t data_size, data_dlen; 892{ 893 __db_errx(env, 894 "%s: replacement length %lu differs from replaced length %lu", 895 "Record length error", (u_long)data_size, (u_long)data_dlen); 896 return (EINVAL); 897} 898 899#if defined(DIAGNOSTIC) || defined(DEBUG_ROP) || defined(DEBUG_WOP) 900/* 901 * __dbc_logging -- 902 * In DIAGNOSTIC mode, check for bad replication combinations. 903 * 904 * PUBLIC: int __dbc_logging __P((DBC *)); 905 */ 906int 907__dbc_logging(dbc) 908 DBC *dbc; 909{ 910 DB_REP *db_rep; 911 ENV *env; 912 int ret; 913 914 env = dbc->env; 915 db_rep = env->rep_handle; 916 917 ret = LOGGING_ON(env) && 918 !F_ISSET(dbc, DBC_RECOVER) && !IS_REP_CLIENT(env); 919 920 /* 921 * If we're not using replication or running recovery, return. 922 */ 923 if (db_rep == NULL || F_ISSET(dbc, DBC_RECOVER)) 924 return (ret); 925 926#ifndef DEBUG_ROP 927 /* 928 * Only check when DEBUG_ROP is not configured. People often do 929 * non-transactional reads, and debug_rop is going to write 930 * a log record. 931 */ 932 { 933 REP *rep; 934 935 rep = db_rep->region; 936 937 /* 938 * If we're a client and not running recovery or non durably, error. 939 */ 940 if (IS_REP_CLIENT(env) && !F_ISSET(dbc->dbp, DB_AM_NOT_DURABLE)) { 941 __db_errx(env, "dbc_logging: Client update"); 942 goto err; 943 } 944 945#ifndef DEBUG_WOP 946 /* 947 * If DEBUG_WOP is enabled, then we'll generate debugging log records 948 * that are non-transactional. This is OK. 949 */ 950 if (IS_REP_MASTER(env) && 951 dbc->txn == NULL && !F_ISSET(dbc->dbp, DB_AM_NOT_DURABLE)) { 952 __db_errx(env, "Dbc_logging: Master non-txn update"); 953 goto err; 954 } 955#endif 956 957 if (0) { 958err: __db_errx(env, "Rep: flags 0x%lx msg_th %lu", 959 (u_long)rep->flags, (u_long)rep->msg_th); 960 __db_errx(env, "Rep: handle %lu, opcnt %lu", 961 (u_long)rep->handle_cnt, (u_long)rep->op_cnt); 962 __os_abort(env); 963 /* NOTREACHED */ 964 } 965 } 966#endif 967 return (ret); 968} 969#endif 970 971/* 972 * __db_check_lsn -- 973 * Display the log sequence error message. 974 * 975 * PUBLIC: int __db_check_lsn __P((ENV *, DB_LSN *, DB_LSN *)); 976 */ 977int 978__db_check_lsn(env, lsn, prev) 979 ENV *env; 980 DB_LSN *lsn, *prev; 981{ 982 __db_errx(env, 983 "Log sequence error: page LSN %lu %lu; previous LSN %lu %lu", 984 (u_long)(lsn)->file, (u_long)(lsn)->offset, 985 (u_long)(prev)->file, (u_long)(prev)->offset); 986 return (EINVAL); 987} 988 989/* 990 * __db_rdonly -- 991 * Common readonly message. 992 * PUBLIC: int __db_rdonly __P((const ENV *, const char *)); 993 */ 994int 995__db_rdonly(env, name) 996 const ENV *env; 997 const char *name; 998{ 999 __db_errx(env, "%s: attempt to modify a read-only database", name); 1000 return (EACCES); 1001} 1002 1003/* 1004 * __db_space_err -- 1005 * Common out of space message. 1006 * PUBLIC: int __db_space_err __P((const DB *)); 1007 */ 1008int 1009__db_space_err(dbp) 1010 const DB *dbp; 1011{ 1012 __db_errx(dbp->env, 1013 "%s: file limited to %lu pages", 1014 dbp->fname, (u_long)dbp->mpf->mfp->maxpgno); 1015 return (ENOSPC); 1016} 1017 1018/* 1019 * __db_failed -- 1020 * Common failed thread message. 1021 * 1022 * PUBLIC: int __db_failed __P((const ENV *, 1023 * PUBLIC: const char *, pid_t, db_threadid_t)); 1024 */ 1025int 1026__db_failed(env, msg, pid, tid) 1027 const ENV *env; 1028 const char *msg; 1029 pid_t pid; 1030 db_threadid_t tid; 1031{ 1032 DB_ENV *dbenv; 1033 char buf[DB_THREADID_STRLEN]; 1034 1035 dbenv = env->dbenv; 1036 1037 __db_errx(env, "Thread/process %s failed: %s", 1038 dbenv->thread_id_string(dbenv, pid, tid, buf), msg); 1039 return (DB_RUNRECOVERY); 1040} 1041