db_vrfy.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:59k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  *
  7.  * $Id: db_vrfy.c,v 1.53 2001/01/11 18:19:51 bostic Exp $
  8.  */
  9. #include "db_config.h"
  10. #ifndef lint
  11. static const char revid[] = "$Id: db_vrfy.c,v 1.53 2001/01/11 18:19:51 bostic Exp $";
  12. #endif /* not lint */
  13. #ifndef NO_SYSTEM_INCLUDES
  14. #include <sys/types.h>
  15. #include <string.h>
  16. #endif
  17. #include "db_int.h"
  18. #include "db_page.h"
  19. #include "db_swap.h"
  20. #include "db_verify.h"
  21. #include "db_ext.h"
  22. #include "btree.h"
  23. #include "hash.h"
  24. #include "qam.h"
  25. static int  __db_guesspgsize __P((DB_ENV *, DB_FH *));
  26. static int  __db_is_valid_magicno __P((u_int32_t, DBTYPE *));
  27. static int  __db_is_valid_pagetype __P((u_int32_t));
  28. static int  __db_meta2pgset
  29. __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, DB *));
  30. static int  __db_salvage_subdbs
  31. __P((DB *, VRFY_DBINFO *, void *,
  32. int(*)(void *, const void *), u_int32_t, int *));
  33. static int  __db_salvage_unknowns
  34. __P((DB *, VRFY_DBINFO *, void *,
  35. int (*)(void *, const void *), u_int32_t));
  36. static int  __db_vrfy_common
  37. __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
  38. static int  __db_vrfy_freelist __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t));
  39. static int  __db_vrfy_invalid
  40. __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
  41. static int  __db_vrfy_orderchkonly __P((DB *,
  42. VRFY_DBINFO *, const char *, const char *, u_int32_t));
  43. static int  __db_vrfy_pagezero __P((DB *, VRFY_DBINFO *, DB_FH *, u_int32_t));
  44. static int  __db_vrfy_subdbs
  45. __P((DB *, VRFY_DBINFO *, const char *, u_int32_t));
  46. static int  __db_vrfy_structure
  47. __P((DB *, VRFY_DBINFO *, const char *, db_pgno_t, u_int32_t));
  48. static int  __db_vrfy_walkpages
  49. __P((DB *, VRFY_DBINFO *, void *, int (*)(void *, const void *),
  50. u_int32_t));
  51. /*
  52.  * This is the code for DB->verify, the DB database consistency checker.
  53.  * For now, it checks all subdatabases in a database, and verifies
  54.  * everything it knows how to (i.e. it's all-or-nothing, and one can't
  55.  * check only for a subset of possible problems).
  56.  */
  57. /*
  58.  * __db_verify --
  59.  * Walk the entire file page-by-page, either verifying with or without
  60.  * dumping in db_dump -d format, or DB_SALVAGE-ing whatever key/data
  61.  * pairs can be found and dumping them in standard (db_load-ready)
  62.  * dump format.
  63.  *
  64.  * (Salvaging isn't really a verification operation, but we put it
  65.  * here anyway because it requires essentially identical top-level
  66.  * code.)
  67.  *
  68.  * flags may be 0, DB_NOORDERCHK, DB_ORDERCHKONLY, or DB_SALVAGE
  69.  * (and optionally DB_AGGRESSIVE).
  70.  *
  71.  * __db_verify itself is simply a wrapper to __db_verify_internal,
  72.  * which lets us pass appropriate equivalents to FILE * in from the
  73.  * non-C APIs.
  74.  *
  75.  * PUBLIC: int __db_verify
  76.  * PUBLIC:     __P((DB *, const char *, const char *, FILE *, u_int32_t));
  77.  */
  78. int
  79. __db_verify(dbp, file, database, outfile, flags)
  80. DB *dbp;
  81. const char *file, *database;
  82. FILE *outfile;
  83. u_int32_t flags;
  84. {
  85. return (__db_verify_internal(dbp,
  86.     file, database, outfile, __db_verify_callback, flags));
  87. }
  88. /*
  89.  * __db_verify_callback --
  90.  * Callback function for using pr_* functions from C.
  91.  *
  92.  * PUBLIC: int  __db_verify_callback __P((void *, const void *));
  93.  */
  94. int
  95. __db_verify_callback(handle, str_arg)
  96. void *handle;
  97. const void *str_arg;
  98. {
  99. char *str;
  100. FILE *f;
  101. str = (char *)str_arg;
  102. f = (FILE *)handle;
  103. if (fprintf(f, "%s", str) != (int)strlen(str))
  104. return (EIO);
  105. return (0);
  106. }
  107. /*
  108.  * __db_verify_internal --
  109.  * Inner meat of __db_verify.
  110.  *
  111.  * PUBLIC: int __db_verify_internal __P((DB *, const char *,
  112.  * PUBLIC:     const char *, void *, int (*)(void *, const void *), u_int32_t));
  113.  */
  114. int
  115. __db_verify_internal(dbp_orig, name, subdb, handle, callback, flags)
  116. DB *dbp_orig;
  117. const char *name, *subdb;
  118. void *handle;
  119. int (*callback) __P((void *, const void *));
  120. u_int32_t flags;
  121. {
  122. DB *dbp;
  123. DB_ENV *dbenv;
  124. DB_FH fh, *fhp;
  125. PAGE *h;
  126. VRFY_DBINFO *vdp;
  127. db_pgno_t last;
  128. int has, ret, isbad;
  129. char *real_name;
  130. dbenv = dbp_orig->dbenv;
  131. vdp = NULL;
  132. real_name = NULL;
  133. ret = isbad = 0;
  134. memset(&fh, 0, sizeof(fh));
  135. fhp = &fh;
  136. PANIC_CHECK(dbenv);
  137. DB_ILLEGAL_AFTER_OPEN(dbp_orig, "verify");
  138. #define OKFLAGS (DB_AGGRESSIVE | DB_NOORDERCHK | DB_ORDERCHKONLY | DB_SALVAGE)
  139. if ((ret = __db_fchk(dbenv, "DB->verify", flags, OKFLAGS)) != 0)
  140. return (ret);
  141. /*
  142.  * DB_SALVAGE is mutually exclusive with the other flags except
  143.  * DB_AGGRESSIVE.
  144.  */
  145. if (LF_ISSET(DB_SALVAGE) &&
  146.     (flags & ~DB_AGGRESSIVE) != DB_SALVAGE)
  147. return (__db_ferr(dbenv, "__db_verify", 1));
  148. if (LF_ISSET(DB_ORDERCHKONLY) && flags != DB_ORDERCHKONLY)
  149. return (__db_ferr(dbenv, "__db_verify", 1));
  150. if (LF_ISSET(DB_ORDERCHKONLY) && subdb == NULL) {
  151. __db_err(dbenv, "DB_ORDERCHKONLY requires a database name");
  152. return (EINVAL);
  153. }
  154. /*
  155.  * Forbid working in an environment that uses transactions or
  156.  * locking;  we're going to be looking at the file freely,
  157.  * and while we're not going to modify it, we aren't obeying
  158.  * locking conventions either.
  159.  */
  160. if (TXN_ON(dbenv) || LOCKING_ON(dbenv) || LOGGING_ON(dbenv)) {
  161. dbp_orig->errx(dbp_orig,
  162.     "verify may not be used with transactions, logging, or locking");
  163. return (EINVAL);
  164. /* NOTREACHED */
  165. }
  166. /* Create a dbp to use internally, which we can close at our leisure. */
  167. if ((ret = db_create(&dbp, dbenv, 0)) != 0)
  168. goto err;
  169. F_SET(dbp, DB_AM_VERIFYING);
  170. /* Copy the supplied pagesize, which we use if the file one is bogus. */
  171. if (dbp_orig->pgsize >= DB_MIN_PGSIZE &&
  172.     dbp_orig->pgsize <= DB_MAX_PGSIZE)
  173. dbp->set_pagesize(dbp, dbp_orig->pgsize);
  174. /* Copy the feedback function, if present, and initialize it. */
  175. if (!LF_ISSET(DB_SALVAGE) && dbp_orig->db_feedback != NULL) {
  176. dbp->set_feedback(dbp, dbp_orig->db_feedback);
  177. dbp->db_feedback(dbp, DB_VERIFY, 0);
  178. }
  179. /*
  180.  * Copy the comparison and hashing functions.  Note that
  181.  * even if the database is not a hash or btree, the respective
  182.  * internal structures will have been initialized.
  183.  */
  184. if (dbp_orig->dup_compare != NULL &&
  185.     (ret = dbp->set_dup_compare(dbp, dbp_orig->dup_compare)) != 0)
  186. goto err;
  187. if (((BTREE *)dbp_orig->bt_internal)->bt_compare != NULL &&
  188.     (ret = dbp->set_bt_compare(dbp,
  189.     ((BTREE *)dbp_orig->bt_internal)->bt_compare)) != 0)
  190. goto err;
  191. if (((HASH *)dbp_orig->h_internal)->h_hash != NULL &&
  192.     (ret = dbp->set_h_hash(dbp,
  193.     ((HASH *)dbp_orig->h_internal)->h_hash)) != 0)
  194. goto err;
  195. /*
  196.  * We don't know how large the cache is, and if the database
  197.  * in question uses a small page size--which we don't know
  198.  * yet!--it may be uncomfortably small for the default page
  199.  * size [#2143].  However, the things we need temporary
  200.  * databases for in dbinfo are largely tiny, so using a
  201.  * 1024-byte pagesize is probably not going to be a big hit,
  202.  * and will make us fit better into small spaces.
  203.  */
  204. if ((ret = __db_vrfy_dbinfo_create(dbenv, 1024, &vdp)) != 0)
  205. goto err;
  206. /* Find the real name of the file. */
  207. if ((ret = __db_appname(dbenv,
  208.     DB_APP_DATA, NULL, name, 0, NULL, &real_name)) != 0)
  209. goto err;
  210. /*
  211.  * Our first order of business is to verify page 0, which is
  212.  * the metadata page for the master database of subdatabases
  213.  * or of the only database in the file.  We want to do this by hand
  214.  * rather than just calling __db_open in case it's corrupt--various
  215.  * things in __db_open might act funny.
  216.  *
  217.  * Once we know the metadata page is healthy, I believe that it's
  218.  * safe to open the database normally and then use the page swapping
  219.  * code, which makes life easier.
  220.  */
  221. if ((ret = __os_open(dbenv, real_name, DB_OSO_RDONLY, 0444, fhp)) != 0)
  222. goto err;
  223. /* Verify the metadata page 0; set pagesize and type. */
  224. if ((ret = __db_vrfy_pagezero(dbp, vdp, fhp, flags)) != 0) {
  225. if (ret == DB_VERIFY_BAD)
  226. isbad = 1;
  227. else
  228. goto err;
  229. }
  230. /*
  231.  * We can assume at this point that dbp->pagesize and dbp->type are
  232.  * set correctly, or at least as well as they can be, and that
  233.  * locking, logging, and txns are not in use.  Thus we can trust
  234.  * the memp code not to look at the page, and thus to be safe
  235.  * enough to use.
  236.  *
  237.  * The dbp is not open, but the file is open in the fhp, and we
  238.  * cannot assume that __db_open is safe.  Call __db_dbenv_setup,
  239.  * the [safe] part of __db_open that initializes the environment--
  240.  * and the mpool--manually.
  241.  */
  242. if ((ret = __db_dbenv_setup(dbp,
  243.     name, DB_ODDFILESIZE | DB_RDONLY)) != 0)
  244. return (ret);
  245. /* Mark the dbp as opened, so that we correctly handle its close. */
  246. F_SET(dbp, DB_OPEN_CALLED);
  247. /*
  248.  * Find out the page number of the last page in the database.
  249.  *
  250.  * XXX: This currently fails if the last page is of bad type,
  251.  * because it calls __db_pgin and that pukes.  This is bad.
  252.  */
  253. if ((ret = memp_fget(dbp->mpf, &last, DB_MPOOL_LAST, &h)) != 0)
  254. goto err;
  255. if ((ret = memp_fput(dbp->mpf, h, 0)) != 0)
  256. goto err;
  257. vdp->last_pgno = last;
  258. /*
  259.  * DB_ORDERCHKONLY is a special case;  our file consists of
  260.  * several subdatabases, which use different hash, bt_compare,
  261.  * and/or dup_compare functions.  Consequently, we couldn't verify
  262.  * sorting and hashing simply by calling DB->verify() on the file.
  263.  * DB_ORDERCHKONLY allows us to come back and check those things;  it
  264.  * requires a subdatabase, and assumes that everything but that
  265.  * database's sorting/hashing is correct.
  266.  */
  267. if (LF_ISSET(DB_ORDERCHKONLY)) {
  268. ret = __db_vrfy_orderchkonly(dbp, vdp, name, subdb, flags);
  269. goto done;
  270. }
  271. /*
  272.  * When salvaging, we use a db to keep track of whether we've seen a
  273.  * given overflow or dup page in the course of traversing normal data.
  274.  * If in the end we have not, we assume its key got lost and print it
  275.  * with key "UNKNOWN".
  276.  */
  277. if (LF_ISSET(DB_SALVAGE)) {
  278. if ((ret = __db_salvage_init(vdp)) != 0)
  279. return (ret);
  280. /*
  281.  * If we're not being aggressive, attempt to crack subdbs.
  282.  * "has" will indicate whether the attempt has succeeded
  283.  * (even in part), meaning that we have some semblance of
  284.  * subdbs;  on the walkpages pass, we print out
  285.  * whichever data pages we have not seen.
  286.  */
  287. has = 0;
  288. if (!LF_ISSET(DB_AGGRESSIVE) && (__db_salvage_subdbs(dbp,
  289.     vdp, handle, callback, flags, &has)) != 0)
  290. isbad = 1;
  291. /*
  292.  * If we have subdatabases, we need to signal that if
  293.  * any keys are found that don't belong to a subdatabase,
  294.  * they'll need to have an "__OTHER__" subdatabase header
  295.  * printed first.  Flag this.  Else, print a header for
  296.  * the normal, non-subdb database.
  297.  */
  298. if (has == 1)
  299. F_SET(vdp, SALVAGE_PRINTHEADER);
  300. else if ((ret = __db_prheader(dbp,
  301.     NULL, 0, 0, handle, callback, vdp, PGNO_BASE_MD)) != 0)
  302. goto err;
  303. }
  304. if ((ret =
  305.     __db_vrfy_walkpages(dbp, vdp, handle, callback, flags)) != 0) {
  306. if (ret == DB_VERIFY_BAD)
  307. isbad = 1;
  308. else if (ret != 0)
  309. goto err;
  310. }
  311. /* If we're verifying, verify inter-page structure. */
  312. if (!LF_ISSET(DB_SALVAGE) && isbad == 0)
  313. if ((ret =
  314.     __db_vrfy_structure(dbp, vdp, name, 0, flags)) != 0) {
  315. if (ret == DB_VERIFY_BAD)
  316. isbad = 1;
  317. else if (ret != 0)
  318. goto err;
  319. }
  320. /*
  321.  * If we're salvaging, output with key UNKNOWN any overflow or dup pages
  322.  * we haven't been able to put in context.  Then destroy the salvager's
  323.  * state-saving database.
  324.  */
  325. if (LF_ISSET(DB_SALVAGE)) {
  326. if ((ret = __db_salvage_unknowns(dbp,
  327.     vdp, handle, callback, flags)) != 0)
  328. isbad = 1;
  329. /* No return value, since there's little we can do. */
  330. __db_salvage_destroy(vdp);
  331. }
  332. if (0) {
  333. err: (void)__db_err(dbenv, "%s: %s", name, db_strerror(ret));
  334. }
  335. if (LF_ISSET(DB_SALVAGE) &&
  336.     (has == 0 || F_ISSET(vdp, SALVAGE_PRINTFOOTER)))
  337. (void)__db_prfooter(handle, callback);
  338. /* Send feedback that we're done. */
  339. done: if (!LF_ISSET(DB_SALVAGE) && dbp->db_feedback != NULL)
  340. dbp->db_feedback(dbp, DB_VERIFY, 100);
  341. if (F_ISSET(fhp, DB_FH_VALID))
  342. (void)__os_closehandle(fhp);
  343. if (dbp)
  344. (void)dbp->close(dbp, 0);
  345. if (vdp)
  346. (void)__db_vrfy_dbinfo_destroy(vdp);
  347. if (real_name)
  348. __os_freestr(real_name);
  349. if ((ret == 0 && isbad == 1) || ret == DB_VERIFY_FATAL)
  350. ret = DB_VERIFY_BAD;
  351. return (ret);
  352. }
  353. /*
  354.  * __db_vrfy_pagezero --
  355.  * Verify the master metadata page.  Use seek, read, and a local buffer
  356.  * rather than the DB paging code, for safety.
  357.  *
  358.  * Must correctly (or best-guess) set dbp->type and dbp->pagesize.
  359.  */
  360. static int
  361. __db_vrfy_pagezero(dbp, vdp, fhp, flags)
  362. DB *dbp;
  363. VRFY_DBINFO *vdp;
  364. DB_FH *fhp;
  365. u_int32_t flags;
  366. {
  367. DBMETA *meta;
  368. DB_ENV *dbenv;
  369. VRFY_PAGEINFO *pip;
  370. db_pgno_t freelist;
  371. int t_ret, ret, nr, swapped;
  372. u_int8_t mbuf[DBMETASIZE];
  373. swapped = ret = t_ret = 0;
  374. freelist = 0;
  375. dbenv = dbp->dbenv;
  376. meta = (DBMETA *)mbuf;
  377. dbp->type = DB_UNKNOWN;
  378. /*
  379.  * Seek to the metadata page.
  380.  * Note that if we're just starting a verification, dbp->pgsize
  381.  * may be zero;  this is okay, as we want page zero anyway and
  382.  * 0*0 == 0.
  383.  */
  384. if ((ret = __os_seek(dbenv, fhp, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0)
  385. goto err;
  386. if ((ret = __os_read(dbenv, fhp, mbuf, DBMETASIZE, (size_t *)&nr)) != 0)
  387. goto err;
  388. if (nr != DBMETASIZE) {
  389. EPRINT((dbp->dbenv,
  390.     "Incomplete metadata page %lu", (u_long)PGNO_BASE_MD));
  391. t_ret = DB_VERIFY_FATAL;
  392. goto err;
  393. }
  394. /*
  395.  * Check all of the fields that we can.
  396.  */
  397. /* 08-11: Current page number.  Must == pgno. */
  398. /* Note that endianness doesn't matter--it's zero. */
  399. if (meta->pgno != PGNO_BASE_MD) {
  400. EPRINT((dbp->dbenv, "Bad pgno: was %lu, should be %lu",
  401.     (u_long)meta->pgno, (u_long)PGNO_BASE_MD));
  402. ret = DB_VERIFY_BAD;
  403. }
  404. /* 12-15: Magic number.  Must be one of valid set. */
  405. if (__db_is_valid_magicno(meta->magic, &dbp->type))
  406. swapped = 0;
  407. else {
  408. M_32_SWAP(meta->magic);
  409. if (__db_is_valid_magicno(meta->magic,
  410.     &dbp->type))
  411. swapped = 1;
  412. else {
  413. EPRINT((dbp->dbenv,
  414.     "Bad magic number: %lu", (u_long)meta->magic));
  415. ret = DB_VERIFY_BAD;
  416. }
  417. }
  418. /*
  419.  * 16-19: Version.  Must be current;  for now, we
  420.  * don't support verification of old versions.
  421.  */
  422. if (swapped)
  423. M_32_SWAP(meta->version);
  424. if ((dbp->type == DB_BTREE && meta->version != DB_BTREEVERSION) ||
  425.     (dbp->type == DB_HASH && meta->version != DB_HASHVERSION) ||
  426.     (dbp->type == DB_QUEUE && meta->version != DB_QAMVERSION)) {
  427. ret = DB_VERIFY_BAD;
  428. EPRINT((dbp->dbenv, "%s%s", "Old or incorrect DB ",
  429.     "version; extraneous errors may result"));
  430. }
  431. /*
  432.  * 20-23: Pagesize.  Must be power of two,
  433.  * greater than 512, and less than 64K.
  434.  */
  435. if (swapped)
  436. M_32_SWAP(meta->pagesize);
  437. if (IS_VALID_PAGESIZE(meta->pagesize))
  438. dbp->pgsize = meta->pagesize;
  439. else {
  440. EPRINT((dbp->dbenv,
  441.     "Bad page size: %lu", (u_long)meta->pagesize));
  442. ret = DB_VERIFY_BAD;
  443. /*
  444.  * Now try to settle on a pagesize to use.
  445.  * If the user-supplied one is reasonable,
  446.  * use it;  else, guess.
  447.  */
  448. if (!IS_VALID_PAGESIZE(dbp->pgsize))
  449. dbp->pgsize = __db_guesspgsize(dbenv, fhp);
  450. }
  451. /*
  452.  * 25: Page type.  Must be correct for dbp->type,
  453.  * which is by now set as well as it can be.
  454.  */
  455. /* Needs no swapping--only one byte! */
  456. if ((dbp->type == DB_BTREE && meta->type != P_BTREEMETA) ||
  457.     (dbp->type == DB_HASH && meta->type != P_HASHMETA) ||
  458.     (dbp->type == DB_QUEUE && meta->type != P_QAMMETA)) {
  459. ret = DB_VERIFY_BAD;
  460. EPRINT((dbp->dbenv, "Bad page type: %lu", (u_long)meta->type));
  461. }
  462. /*
  463.  * 28-31: Free list page number.
  464.  * We'll verify its sensibility when we do inter-page
  465.  * verification later;  for now, just store it.
  466.  */
  467. if (swapped)
  468.     M_32_SWAP(meta->free);
  469. freelist = meta->free;
  470. /*
  471.  * Initialize vdp->pages to fit a single pageinfo structure for
  472.  * this one page.  We'll realloc later when we know how many
  473.  * pages there are.
  474.  */
  475. if ((ret = __db_vrfy_getpageinfo(vdp, PGNO_BASE_MD, &pip)) != 0)
  476. return (ret);
  477. pip->pgno = PGNO_BASE_MD;
  478. pip->type = meta->type;
  479. /*
  480.  * Signal that we still have to check the info specific to
  481.  * a given type of meta page.
  482.  */
  483. F_SET(pip, VRFY_INCOMPLETE);
  484. pip->free = freelist;
  485. if ((ret = __db_vrfy_putpageinfo(vdp, pip)) != 0)
  486. return (ret);
  487. /* Set up the dbp's fileid.  We don't use the regular open path. */
  488. memcpy(dbp->fileid, meta->uid, DB_FILE_ID_LEN);
  489. if (0) {
  490. err: __db_err(dbenv, "%s", db_strerror(ret));
  491. }
  492. if (swapped == 1)
  493. F_SET(dbp, DB_AM_SWAP);
  494. if (t_ret != 0)
  495. ret = t_ret;
  496. return (ret);
  497. }
  498. /*
  499.  * __db_vrfy_walkpages --
  500.  * Main loop of the verifier/salvager.  Walks through,
  501.  * page by page, and verifies all pages and/or prints all data pages.
  502.  */
  503. static int
  504. __db_vrfy_walkpages(dbp, vdp, handle, callback, flags)
  505. DB *dbp;
  506. VRFY_DBINFO *vdp;
  507. void *handle;
  508. int (*callback) __P((void *, const void *));
  509. u_int32_t flags;
  510. {
  511. DB_ENV *dbenv;
  512. PAGE *h;
  513. db_pgno_t i;
  514. int ret, t_ret, isbad;
  515. ret = isbad = t_ret = 0;
  516. dbenv = dbp->dbenv;
  517. if ((ret = __db_fchk(dbenv,
  518.     "__db_vrfy_walkpages", flags, OKFLAGS)) != 0)
  519. return (ret);
  520. for (i = 0; i <= vdp->last_pgno; i++) {
  521. /*
  522.  * If DB_SALVAGE is set, we inspect our database of
  523.  * completed pages, and skip any we've already printed in
  524.  * the subdb pass.
  525.  */
  526. if (LF_ISSET(DB_SALVAGE) && (__db_salvage_isdone(vdp, i) != 0))
  527. continue;
  528. /* If an individual page get fails, keep going. */
  529. if ((t_ret = memp_fget(dbp->mpf, &i, 0, &h)) != 0) {
  530. if (ret == 0)
  531. ret = t_ret;
  532. continue;
  533. }
  534. if (LF_ISSET(DB_SALVAGE)) {
  535. /*
  536.  * We pretty much don't want to quit unless a
  537.  * bomb hits.  May as well return that something
  538.  * was screwy, however.
  539.  */
  540. if ((t_ret = __db_salvage(dbp,
  541.     vdp, i, h, handle, callback, flags)) != 0) {
  542. if (ret == 0)
  543. ret = t_ret;
  544. isbad = 1;
  545. }
  546. } else {
  547. /*
  548.  * Verify info common to all page
  549.  * types.
  550.  */
  551. if (i != PGNO_BASE_MD)
  552. if ((t_ret = __db_vrfy_common(dbp,
  553.     vdp, h, i, flags)) == DB_VERIFY_BAD)
  554. isbad = 1;
  555. switch (TYPE(h)) {
  556. case P_INVALID:
  557. t_ret = __db_vrfy_invalid(dbp,
  558.     vdp, h, i, flags);
  559. break;
  560. case __P_DUPLICATE:
  561. isbad = 1;
  562. EPRINT((dbp->dbenv,
  563.     "Old-style duplicate page: %lu",
  564.     (u_long)i));
  565. break;
  566. case P_HASH:
  567. t_ret = __ham_vrfy(dbp,
  568.     vdp, h, i, flags);
  569. break;
  570. case P_IBTREE:
  571. case P_IRECNO:
  572. case P_LBTREE:
  573. case P_LDUP:
  574. t_ret = __bam_vrfy(dbp,
  575.     vdp, h, i, flags);
  576. break;
  577. case P_LRECNO:
  578. t_ret = __ram_vrfy_leaf(dbp,
  579.     vdp, h, i, flags);
  580. break;
  581. case P_OVERFLOW:
  582. t_ret = __db_vrfy_overflow(dbp,
  583.     vdp, h, i, flags);
  584. break;
  585. case P_HASHMETA:
  586. t_ret = __ham_vrfy_meta(dbp,
  587.     vdp, (HMETA *)h, i, flags);
  588. break;
  589. case P_BTREEMETA:
  590. t_ret = __bam_vrfy_meta(dbp,
  591.     vdp, (BTMETA *)h, i, flags);
  592. break;
  593. case P_QAMMETA:
  594. t_ret = __qam_vrfy_meta(dbp,
  595.     vdp, (QMETA *)h, i, flags);
  596. break;
  597. case P_QAMDATA:
  598. t_ret = __qam_vrfy_data(dbp,
  599.     vdp, (QPAGE *)h, i, flags);
  600. break;
  601. default:
  602. EPRINT((dbp->dbenv,
  603.     "Unknown page type: %lu", (u_long)TYPE(h)));
  604. isbad = 1;
  605. break;
  606. }
  607. /*
  608.  * Set up error return.
  609.  */
  610. if (t_ret == DB_VERIFY_BAD)
  611. isbad = 1;
  612. else if (t_ret == DB_VERIFY_FATAL)
  613. goto err;
  614. else
  615. ret = t_ret;
  616. /*
  617.  * Provide feedback to the application about our
  618.  * progress.  The range 0-50% comes from the fact
  619.  * that this is the first of two passes through the
  620.  * database (front-to-back, then top-to-bottom).
  621.  */
  622. if (dbp->db_feedback != NULL)
  623. dbp->db_feedback(dbp, DB_VERIFY,
  624.     (i + 1) * 50 / (vdp->last_pgno + 1));
  625. }
  626. if ((t_ret = memp_fput(dbp->mpf, h, 0)) != 0 && ret == 0)
  627. ret = t_ret;
  628. }
  629. if (0) {
  630. err: if ((t_ret = memp_fput(dbp->mpf, h, 0)) != 0)
  631. return (ret == 0 ? t_ret : ret);
  632. return (DB_VERIFY_BAD);
  633. }
  634. return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);
  635. }
  636. /*
  637.  * __db_vrfy_structure--
  638.  * After a beginning-to-end walk through the database has been
  639.  * completed, put together the information that has been collected
  640.  * to verify the overall database structure.
  641.  *
  642.  * Should only be called if we want to do a database verification,
  643.  * i.e. if DB_SALVAGE is not set.
  644.  */
  645. static int
  646. __db_vrfy_structure(dbp, vdp, dbname, meta_pgno, flags)
  647. DB *dbp;
  648. VRFY_DBINFO *vdp;
  649. const char *dbname;
  650. db_pgno_t meta_pgno;
  651. u_int32_t flags;
  652. {
  653. DB *pgset;
  654. DB_ENV *dbenv;
  655. VRFY_PAGEINFO *pip;
  656. db_pgno_t i;
  657. int ret, isbad, hassubs, p;
  658. isbad = 0;
  659. pip = NULL;
  660. dbenv = dbp->dbenv;
  661. pgset = vdp->pgset;
  662. if ((ret = __db_fchk(dbenv, "DB->verify", flags, OKFLAGS)) != 0)
  663. return (ret);
  664. if (LF_ISSET(DB_SALVAGE)) {
  665. __db_err(dbenv, "__db_vrfy_structure called with DB_SALVAGE");
  666. return (EINVAL);
  667. }
  668. /*
  669.  * Providing feedback here is tricky;  in most situations,
  670.  * we fetch each page one more time, but we do so in a top-down
  671.  * order that depends on the access method.  Worse, we do this
  672.  * recursively in btree, such that on any call where we're traversing
  673.  * a subtree we don't know where that subtree is in the whole database;
  674.  * worse still, any given database may be one of several subdbs.
  675.  *
  676.  * The solution is to decrement a counter vdp->pgs_remaining each time
  677.  * we verify (and call feedback on) a page.  We may over- or
  678.  * under-count, but the structure feedback function will ensure that we
  679.  * never give a percentage under 50 or over 100.  (The first pass
  680.  * covered the range 0-50%.)
  681.  */
  682. if (dbp->db_feedback != NULL)
  683. vdp->pgs_remaining = vdp->last_pgno + 1;
  684. /*
  685.  * Call the appropriate function to downwards-traverse the db type.
  686.  */
  687. switch(dbp->type) {
  688. case DB_BTREE:
  689. case DB_RECNO:
  690. if ((ret = __bam_vrfy_structure(dbp, vdp, 0, flags)) != 0) {
  691. if (ret == DB_VERIFY_BAD)
  692. isbad = 1;
  693. else
  694. goto err;
  695. }
  696. /*
  697.  * If we have subdatabases and we know that the database is,
  698.  * thus far, sound, it's safe to walk the tree of subdatabases.
  699.  * Do so, and verify the structure of the databases within.
  700.  */
  701. if ((ret = __db_vrfy_getpageinfo(vdp, 0, &pip)) != 0)
  702. goto err;
  703. hassubs = F_ISSET(pip, VRFY_HAS_SUBDBS);
  704. if ((ret = __db_vrfy_putpageinfo(vdp, pip)) != 0)
  705. goto err;
  706. if (isbad == 0 && hassubs)
  707. if ((ret =
  708.     __db_vrfy_subdbs(dbp, vdp, dbname, flags)) != 0) {
  709. if (ret == DB_VERIFY_BAD)
  710. isbad = 1;
  711. else
  712. goto err;
  713. }
  714. break;
  715. case DB_HASH:
  716. if ((ret = __ham_vrfy_structure(dbp, vdp, 0, flags)) != 0) {
  717. if (ret == DB_VERIFY_BAD)
  718. isbad = 1;
  719. else
  720. goto err;
  721. }
  722. break;
  723. case DB_QUEUE:
  724. if ((ret = __qam_vrfy_structure(dbp, vdp, flags)) != 0) {
  725. if (ret == DB_VERIFY_BAD)
  726. isbad = 1;
  727. }
  728. /*
  729.  * Queue pages may be unreferenced and totally zeroed, if
  730.  * they're empty;  queue doesn't have much structure, so
  731.  * this is unlikely to be wrong in any troublesome sense.
  732.  * Skip to "err".
  733.  */
  734. goto err;
  735. /* NOTREACHED */
  736. default:
  737. /* This should only happen if the verifier is somehow broken. */
  738. DB_ASSERT(0);
  739. ret = EINVAL;
  740. goto err;
  741. /* NOTREACHED */
  742. }
  743. /* Walk free list. */
  744. if ((ret =
  745.     __db_vrfy_freelist(dbp, vdp, meta_pgno, flags)) == DB_VERIFY_BAD)
  746. isbad = 1;
  747. /*
  748.  * If structure checks up until now have failed, it's likely that
  749.  * checking what pages have been missed will result in oodles of
  750.  * extraneous error messages being EPRINTed.  Skip to the end
  751.  * if this is the case;  we're going to be printing at least one
  752.  * error anyway, and probably all the more salient ones.
  753.  */
  754. if (ret != 0 || isbad == 1)
  755. goto err;
  756. /*
  757.  * Make sure no page has been missed and that no page is still marked
  758.  * "all zeroes" (only certain hash pages can be, and they're unmarked
  759.  * in __ham_vrfy_structure).
  760.  */
  761. for (i = 0; i < vdp->last_pgno + 1; i++) {
  762. if ((ret = __db_vrfy_getpageinfo(vdp, i, &pip)) != 0)
  763. goto err;
  764. if ((ret = __db_vrfy_pgset_get(pgset, i, &p)) != 0)
  765. goto err;
  766. if (p == 0) {
  767. EPRINT((dbp->dbenv,
  768.     "Unreferenced page %lu", (u_long)i));
  769. isbad = 1;
  770. }
  771. if (F_ISSET(pip, VRFY_IS_ALLZEROES)) {
  772. EPRINT((dbp->dbenv,
  773.     "Totally zeroed page %lu", (u_long)i));
  774. isbad = 1;
  775. }
  776. if ((ret = __db_vrfy_putpageinfo(vdp, pip)) != 0)
  777. goto err;
  778. pip = NULL;
  779. }
  780. err: if (pip != NULL)
  781. (void)__db_vrfy_putpageinfo(vdp, pip);
  782. return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);
  783. }
  784. /*
  785.  * __db_is_valid_pagetype
  786.  */
  787. static int
  788. __db_is_valid_pagetype(type)
  789. u_int32_t type;
  790. {
  791. switch (type) {
  792. case P_INVALID: /* Order matches ordinal value. */
  793. case P_HASH:
  794. case P_IBTREE:
  795. case P_IRECNO:
  796. case P_LBTREE:
  797. case P_LRECNO:
  798. case P_OVERFLOW:
  799. case P_HASHMETA:
  800. case P_BTREEMETA:
  801. case P_QAMMETA:
  802. case P_QAMDATA:
  803. case P_LDUP:
  804. return (1);
  805. }
  806. return (0);
  807. }
  808. /*
  809.  * __db_is_valid_magicno
  810.  */
  811. static int
  812. __db_is_valid_magicno(magic, typep)
  813. u_int32_t magic;
  814. DBTYPE *typep;
  815. {
  816. switch (magic) {
  817. case DB_BTREEMAGIC:
  818. *typep = DB_BTREE;
  819. return (1);
  820. case DB_HASHMAGIC:
  821. *typep = DB_HASH;
  822. return (1);
  823. case DB_QAMMAGIC:
  824. *typep = DB_QUEUE;
  825. return (1);
  826. }
  827. *typep = DB_UNKNOWN;
  828. return (0);
  829. }
  830. /*
  831.  * __db_vrfy_common --
  832.  * Verify info common to all page types.
  833.  */
  834. static int
  835. __db_vrfy_common(dbp, vdp, h, pgno, flags)
  836. DB *dbp;
  837. VRFY_DBINFO *vdp;
  838. PAGE *h;
  839. db_pgno_t pgno;
  840. u_int32_t flags;
  841. {
  842. VRFY_PAGEINFO *pip;
  843. int ret, t_ret;
  844. u_int8_t *p;
  845. if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
  846. return (ret);
  847. pip->pgno = pgno;
  848. F_CLR(pip, VRFY_IS_ALLZEROES);
  849. /*
  850.  * Hash expands the table by leaving some pages between the
  851.  * old last and the new last totally zeroed.  Its pgin function
  852.  * should fix things, but we might not be using that (e.g. if
  853.  * we're a subdatabase).
  854.  *
  855.  * Queue will create sparse files if sparse record numbers are used.
  856.  */
  857. if (pgno != 0 && PGNO(h) == 0) {
  858. for (p = (u_int8_t *)h; p < (u_int8_t *)h + dbp->pgsize; p++)
  859. if (*p != 0) {
  860. EPRINT((dbp->dbenv,
  861.     "Page %lu should be zeroed and is not",
  862.     (u_long)pgno));
  863. ret = DB_VERIFY_BAD;
  864. goto err;
  865. }
  866. /*
  867.  * It's totally zeroed;  mark it as a hash, and we'll
  868.  * check that that makes sense structurally later.
  869.  * (The queue verification doesn't care, since queues
  870.  * don't really have much in the way of structure.)
  871.  */
  872. pip->type = P_HASH;
  873. F_SET(pip, VRFY_IS_ALLZEROES);
  874. ret = 0;
  875. goto err; /* well, not really an err. */
  876. }
  877. if (PGNO(h) != pgno) {
  878. EPRINT((dbp->dbenv,
  879.     "Bad page number: %lu should be %lu",
  880.     (u_long)h->pgno, (u_long)pgno));
  881. ret = DB_VERIFY_BAD;
  882. }
  883. if (!__db_is_valid_pagetype(h->type)) {
  884. EPRINT((dbp->dbenv, "Bad page type: %lu", (u_long)h->type));
  885. ret = DB_VERIFY_BAD;
  886. }
  887. pip->type = h->type;
  888. err: if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0)
  889. ret = t_ret;
  890. return (ret);
  891. }
  892. /*
  893.  * __db_vrfy_invalid --
  894.  * Verify P_INVALID page.
  895.  * (Yes, there's not much to do here.)
  896.  */
  897. static int
  898. __db_vrfy_invalid(dbp, vdp, h, pgno, flags)
  899. DB *dbp;
  900. VRFY_DBINFO *vdp;
  901. PAGE *h;
  902. db_pgno_t pgno;
  903. u_int32_t flags;
  904. {
  905. VRFY_PAGEINFO *pip;
  906. int ret, t_ret;
  907. if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
  908. return (ret);
  909. pip->next_pgno = pip->prev_pgno = 0;
  910. if (!IS_VALID_PGNO(NEXT_PGNO(h))) {
  911. EPRINT((dbp->dbenv,
  912.     "Invalid next_pgno %lu on page %lu",
  913.     (u_long)NEXT_PGNO(h), (u_long)pgno));
  914. ret = DB_VERIFY_BAD;
  915. } else
  916. pip->next_pgno = NEXT_PGNO(h);
  917. if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0)
  918. ret = t_ret;
  919. return (ret);
  920. }
  921. /*
  922.  * __db_vrfy_datapage --
  923.  * Verify elements common to data pages (P_HASH, P_LBTREE,
  924.  * P_IBTREE, P_IRECNO, P_LRECNO, P_OVERFLOW, P_DUPLICATE)--i.e.,
  925.  * those defined in the PAGE structure.
  926.  *
  927.  * Called from each of the per-page routines, after the
  928.  * all-page-type-common elements of pip have been verified and filled
  929.  * in.
  930.  *
  931.  * PUBLIC: int __db_vrfy_datapage
  932.  * PUBLIC:     __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
  933.  */
  934. int
  935. __db_vrfy_datapage(dbp, vdp, h, pgno, flags)
  936. DB *dbp;
  937. VRFY_DBINFO *vdp;
  938. PAGE *h;
  939. db_pgno_t pgno;
  940. u_int32_t flags;
  941. {
  942. VRFY_PAGEINFO *pip;
  943. int isbad, ret, t_ret;
  944. if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
  945. return (ret);
  946. isbad = 0;
  947. /*
  948.  * prev_pgno and next_pgno:  store for inter-page checks,
  949.  * verify that they point to actual pages and not to self.
  950.  *
  951.  * !!!
  952.  * Internal btree pages do not maintain these fields (indeed,
  953.  * they overload them).  Skip.
  954.  */
  955. if (TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO) {
  956. if (!IS_VALID_PGNO(PREV_PGNO(h)) || PREV_PGNO(h) == pip->pgno) {
  957. isbad = 1;
  958. EPRINT((dbp->dbenv, "Page %lu: Invalid prev_pgno %lu",
  959.     (u_long)pip->pgno, (u_long)PREV_PGNO(h)));
  960. }
  961. if (!IS_VALID_PGNO(NEXT_PGNO(h)) || NEXT_PGNO(h) == pip->pgno) {
  962. isbad = 1;
  963. EPRINT((dbp->dbenv, "Page %lu: Invalid next_pgno %lu",
  964.     (u_long)pip->pgno, (u_long)NEXT_PGNO(h)));
  965. }
  966. pip->prev_pgno = PREV_PGNO(h);
  967. pip->next_pgno = NEXT_PGNO(h);
  968. }
  969. /*
  970.  * Verify the number of entries on the page.
  971.  * There is no good way to determine if this is accurate;  the
  972.  * best we can do is verify that it's not more than can, in theory,
  973.  * fit on the page.  Then, we make sure there are at least
  974.  * this many valid elements in inp[], and hope that this catches
  975.  * most cases.
  976.  */
  977. if (TYPE(h) != P_OVERFLOW) {
  978. if (BKEYDATA_PSIZE(0) * NUM_ENT(h) > dbp->pgsize) {
  979. isbad = 1;
  980. EPRINT((dbp->dbenv,
  981.     "Page %lu: Too many entries: %lu",
  982.     (u_long)pgno, (u_long)NUM_ENT(h)));
  983. }
  984. pip->entries = NUM_ENT(h);
  985. }
  986. /*
  987.  * btree level.  Should be zero unless we're a btree;
  988.  * if we are a btree, should be between LEAFLEVEL and MAXBTREELEVEL,
  989.  * and we need to save it off.
  990.  */
  991. switch (TYPE(h)) {
  992. case P_IBTREE:
  993. case P_IRECNO:
  994. if (LEVEL(h) < LEAFLEVEL + 1 || LEVEL(h) > MAXBTREELEVEL) {
  995. isbad = 1;
  996. EPRINT((dbp->dbenv, "Bad btree level %lu on page %lu",
  997.     (u_long)LEVEL(h), (u_long)pgno));
  998. }
  999. pip->bt_level = LEVEL(h);
  1000. break;
  1001. case P_LBTREE:
  1002. case P_LDUP:
  1003. case P_LRECNO:
  1004. if (LEVEL(h) != LEAFLEVEL) {
  1005. isbad = 1;
  1006. EPRINT((dbp->dbenv,
  1007.     "Btree leaf page %lu has incorrect level %lu",
  1008.     (u_long)pgno, (u_long)LEVEL(h)));
  1009. }
  1010. break;
  1011. default:
  1012. if (LEVEL(h) != 0) {
  1013. isbad = 1;
  1014. EPRINT((dbp->dbenv,
  1015.     "Nonzero level %lu in non-btree database page %lu",
  1016.     (u_long)LEVEL(h), (u_long)pgno));
  1017. }
  1018. break;
  1019. }
  1020. /*
  1021.  * Even though inp[] occurs in all PAGEs, we look at it in the
  1022.  * access-method-specific code, since btree and hash treat
  1023.  * item lengths very differently, and one of the most important
  1024.  * things we want to verify is that the data--as specified
  1025.  * by offset and length--cover the right part of the page
  1026.  * without overlaps, gaps, or violations of the page boundary.
  1027.  */
  1028. if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0)
  1029. ret = t_ret;
  1030. return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
  1031. }
  1032. /*
  1033.  * __db_vrfy_meta--
  1034.  * Verify the access-method common parts of a meta page, using
  1035.  * normal mpool routines.
  1036.  *
  1037.  * PUBLIC: int __db_vrfy_meta
  1038.  * PUBLIC:     __P((DB *, VRFY_DBINFO *, DBMETA *, db_pgno_t, u_int32_t));
  1039.  */
  1040. int
  1041. __db_vrfy_meta(dbp, vdp, meta, pgno, flags)
  1042. DB *dbp;
  1043. VRFY_DBINFO *vdp;
  1044. DBMETA *meta;
  1045. db_pgno_t pgno;
  1046. u_int32_t flags;
  1047. {
  1048. DBTYPE dbtype, magtype;
  1049. VRFY_PAGEINFO *pip;
  1050. int isbad, ret, t_ret;
  1051. isbad = 0;
  1052. if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
  1053. return (ret);
  1054. /* type plausible for a meta page */
  1055. switch (meta->type) {
  1056. case P_BTREEMETA:
  1057. dbtype = DB_BTREE;
  1058. break;
  1059. case P_HASHMETA:
  1060. dbtype = DB_HASH;
  1061. break;
  1062. case P_QAMMETA:
  1063. dbtype = DB_QUEUE;
  1064. break;
  1065. default:
  1066. /* The verifier should never let us get here. */
  1067. DB_ASSERT(0);
  1068. ret = EINVAL;
  1069. goto err;
  1070. }
  1071. /* magic number valid */
  1072. if (!__db_is_valid_magicno(meta->magic, &magtype)) {
  1073. isbad = 1;
  1074. EPRINT((dbp->dbenv,
  1075.     "Magic number invalid on page %lu", (u_long)pgno));
  1076. }
  1077. if (magtype != dbtype) {
  1078. isbad = 1;
  1079. EPRINT((dbp->dbenv,
  1080.     "Magic number does not match type of page %lu",
  1081.     (u_long)pgno));
  1082. }
  1083. /* version */
  1084. if ((dbtype == DB_BTREE && meta->version != DB_BTREEVERSION) ||
  1085.     (dbtype == DB_HASH && meta->version != DB_HASHVERSION) ||
  1086.     (dbtype == DB_QUEUE && meta->version != DB_QAMVERSION)) {
  1087. isbad = 1;
  1088. EPRINT((dbp->dbenv, "%s%s", "Old of incorrect DB ",
  1089.     "version; extraneous errors may result"));
  1090. }
  1091. /* pagesize */
  1092. if (meta->pagesize != dbp->pgsize) {
  1093. isbad = 1;
  1094. EPRINT((dbp->dbenv,
  1095.     "Invalid pagesize %lu on page %lu",
  1096.     (u_long)meta->pagesize, (u_long)pgno));
  1097. }
  1098. /* free list */
  1099. /*
  1100.  * If this is not the main, master-database meta page, it
  1101.  * should not have a free list.
  1102.  */
  1103. if (pgno != PGNO_BASE_MD && meta->free != PGNO_INVALID) {
  1104. isbad = 1;
  1105. EPRINT((dbp->dbenv,
  1106.     "Nonempty free list on subdatabase metadata page %lu",
  1107.     pgno));
  1108. }
  1109. /* Can correctly be PGNO_INVALID--that's just the end of the list. */
  1110. if (meta->free != PGNO_INVALID && IS_VALID_PGNO(meta->free))
  1111. pip->free = meta->free;
  1112. else if (!IS_VALID_PGNO(meta->free)) {
  1113. isbad = 1;
  1114. EPRINT((dbp->dbenv,
  1115.     "Nonsensical free list pgno %lu on page %lu",
  1116.     (u_long)meta->free, (u_long)pgno));
  1117. }
  1118. /*
  1119.  * We have now verified the common fields of the metadata page.
  1120.  * Clear the flag that told us they had been incompletely checked.
  1121.  */
  1122. F_CLR(pip, VRFY_INCOMPLETE);
  1123. err: if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0)
  1124. ret = t_ret;
  1125. return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
  1126. }
  1127. /*
  1128.  * __db_vrfy_freelist --
  1129.  * Walk free list, checking off pages and verifying absence of
  1130.  * loops.
  1131.  */
  1132. static int
  1133. __db_vrfy_freelist(dbp, vdp, meta, flags)
  1134. DB *dbp;
  1135. VRFY_DBINFO *vdp;
  1136. db_pgno_t meta;
  1137. u_int32_t flags;
  1138. {
  1139. DB *pgset;
  1140. VRFY_PAGEINFO *pip;
  1141. db_pgno_t pgno;
  1142. int p, ret, t_ret;
  1143. pgset = vdp->pgset;
  1144. DB_ASSERT(pgset != NULL);
  1145. if ((ret = __db_vrfy_getpageinfo(vdp, meta, &pip)) != 0)
  1146. return (ret);
  1147. for (pgno = pip->free; pgno != PGNO_INVALID; pgno = pip->next_pgno) {
  1148. if ((ret = __db_vrfy_putpageinfo(vdp, pip)) != 0)
  1149. return (ret);
  1150. /* This shouldn't happen, but just in case. */
  1151. if (!IS_VALID_PGNO(pgno)) {
  1152. EPRINT((dbp->dbenv,
  1153.     "Invalid next_pgno on free list page %lu",
  1154.     (u_long)pgno));
  1155. return (DB_VERIFY_BAD);
  1156. }
  1157. /* Detect cycles. */
  1158. if ((ret = __db_vrfy_pgset_get(pgset, pgno, &p)) != 0)
  1159. return (ret);
  1160. if (p != 0) {
  1161. EPRINT((dbp->dbenv,
  1162.     "Page %lu encountered a second time on free list",
  1163.     (u_long)pgno));
  1164. return (DB_VERIFY_BAD);
  1165. }
  1166. if ((ret = __db_vrfy_pgset_inc(pgset, pgno)) != 0)
  1167. return (ret);
  1168. if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
  1169. return (ret);
  1170. if (pip->type != P_INVALID) {
  1171. EPRINT((dbp->dbenv,
  1172.     "Non-invalid page %lu on free list", (u_long)pgno));
  1173. ret = DB_VERIFY_BAD;   /* unsafe to continue */
  1174. break;
  1175. }
  1176. }
  1177. if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0)
  1178. ret = t_ret;
  1179. return (ret);
  1180. }
  1181. /*
  1182.  * __db_vrfy_subdbs --
  1183.  * Walk the known-safe master database of subdbs with a cursor,
  1184.  * verifying the structure of each subdatabase we encounter.
  1185.  */
  1186. static int
  1187. __db_vrfy_subdbs(dbp, vdp, dbname, flags)
  1188. DB *dbp;
  1189. VRFY_DBINFO *vdp;
  1190. const char *dbname;
  1191. u_int32_t flags;
  1192. {
  1193. DB *mdbp;
  1194. DBC *dbc;
  1195. DBT key, data;
  1196. VRFY_PAGEINFO *pip;
  1197. db_pgno_t meta_pgno;
  1198. int ret, t_ret, isbad;
  1199. u_int8_t type;
  1200. isbad = 0;
  1201. dbc = NULL;
  1202. if ((ret = __db_master_open(dbp, dbname, DB_RDONLY, 0, &mdbp)) != 0)
  1203. return (ret);
  1204. if ((ret =
  1205.     __db_icursor(mdbp, NULL, DB_BTREE, PGNO_INVALID, 0, &dbc)) != 0)
  1206. goto err;
  1207. memset(&key, 0, sizeof(key));
  1208. memset(&data, 0, sizeof(data));
  1209. while ((ret = dbc->c_get(dbc, &key, &data, DB_NEXT)) == 0) {
  1210. if (data.size != sizeof(db_pgno_t)) {
  1211. EPRINT((dbp->dbenv, "Database entry of invalid size"));
  1212. isbad = 1;
  1213. goto err;
  1214. }
  1215. memcpy(&meta_pgno, data.data, data.size);
  1216. /*
  1217.  * Subdatabase meta pgnos are stored in network byte
  1218.  * order for cross-endian compatibility.  Swap if appropriate.
  1219.  */
  1220. DB_NTOHL(&meta_pgno);
  1221. if (meta_pgno == PGNO_INVALID || meta_pgno > vdp->last_pgno) {
  1222. EPRINT((dbp->dbenv,
  1223.     "Database entry references invalid page %lu",
  1224.     (u_long)meta_pgno));
  1225. isbad = 1;
  1226. goto err;
  1227. }
  1228. if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &pip)) != 0)
  1229. goto err;
  1230. type = pip->type;
  1231. if ((ret = __db_vrfy_putpageinfo(vdp, pip)) != 0)
  1232. goto err;
  1233. switch (type) {
  1234. case P_BTREEMETA:
  1235. if ((ret = __bam_vrfy_structure(
  1236.     dbp, vdp, meta_pgno, flags)) != 0) {
  1237. if (ret == DB_VERIFY_BAD)
  1238. isbad = 1;
  1239. else
  1240. goto err;
  1241. }
  1242. break;
  1243. case P_HASHMETA:
  1244. if ((ret = __ham_vrfy_structure(
  1245.     dbp, vdp, meta_pgno, flags)) != 0) {
  1246. if (ret == DB_VERIFY_BAD)
  1247. isbad = 1;
  1248. else
  1249. goto err;
  1250. }
  1251. break;
  1252. case P_QAMMETA:
  1253. default:
  1254. EPRINT((dbp->dbenv,
  1255.     "Database entry references page %lu of invalid type %lu",
  1256.     (u_long)meta_pgno, (u_long)type));
  1257. ret = DB_VERIFY_BAD;
  1258. goto err;
  1259. /* NOTREACHED */
  1260. }
  1261. }
  1262. if (ret == DB_NOTFOUND)
  1263. ret = 0;
  1264. err: if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0)
  1265. ret = t_ret;
  1266. if ((t_ret = mdbp->close(mdbp, 0)) != 0 && ret == 0)
  1267. ret = t_ret;
  1268. return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
  1269. }
  1270. /*
  1271.  * __db_vrfy_struct_feedback --
  1272.  * Provide feedback during top-down database structure traversal.
  1273.  * (See comment at the beginning of __db_vrfy_structure.)
  1274.  *
  1275.  * PUBLIC: int __db_vrfy_struct_feedback __P((DB *, VRFY_DBINFO *));
  1276.  */
  1277. int
  1278. __db_vrfy_struct_feedback(dbp, vdp)
  1279. DB *dbp;
  1280. VRFY_DBINFO *vdp;
  1281. {
  1282. int progress;
  1283. if (dbp->db_feedback == NULL)
  1284. return (0);
  1285. if (vdp->pgs_remaining > 0)
  1286. vdp->pgs_remaining--;
  1287. /* Don't allow a feedback call of 100 until we're really done. */
  1288. progress = 100 - (vdp->pgs_remaining * 50 / (vdp->last_pgno + 1));
  1289. dbp->db_feedback(dbp, DB_VERIFY, progress == 100 ? 99 : progress);
  1290. return (0);
  1291. }
  1292. /*
  1293.  * __db_vrfy_orderchkonly --
  1294.  * Do an sort-order/hashing check on a known-otherwise-good subdb.
  1295.  */
  1296. static int
  1297. __db_vrfy_orderchkonly(dbp, vdp, name, subdb, flags)
  1298. DB *dbp;
  1299. VRFY_DBINFO *vdp;
  1300. const char *name, *subdb;
  1301. u_int32_t flags;
  1302. {
  1303. BTMETA *btmeta;
  1304. DB *mdbp, *pgset;
  1305. DBC *pgsc;
  1306. DBT key, data;
  1307. HASH *h_internal;
  1308. HMETA *hmeta;
  1309. PAGE *h, *currpg;
  1310. db_pgno_t meta_pgno, p, pgno;
  1311. u_int32_t bucket;
  1312. int t_ret, ret;
  1313. currpg = h = NULL;
  1314. pgsc = NULL;
  1315. pgset = NULL;
  1316. LF_CLR(DB_NOORDERCHK);
  1317. /* Open the master database and get the meta_pgno for the subdb. */
  1318. if ((ret = db_create(&mdbp, NULL, 0)) != 0)
  1319. return (ret);
  1320. if ((ret = __db_master_open(dbp, name, DB_RDONLY, 0, &mdbp)) != 0)
  1321. goto err;
  1322. memset(&key, 0, sizeof(key));
  1323. key.data = (void *)subdb;
  1324. memset(&data, 0, sizeof(data));
  1325. if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) != 0)
  1326. goto err;
  1327. if (data.size != sizeof(db_pgno_t)) {
  1328. EPRINT((dbp->dbenv, "Database entry of invalid size"));
  1329. ret = DB_VERIFY_BAD;
  1330. goto err;
  1331. }
  1332. memcpy(&meta_pgno, data.data, data.size);
  1333. if ((ret = memp_fget(dbp->mpf, &meta_pgno, 0, &h)) != 0)
  1334. goto err;
  1335. if ((ret = __db_vrfy_pgset(dbp->dbenv, dbp->pgsize, &pgset)) != 0)
  1336. goto err;
  1337. switch (TYPE(h)) {
  1338. case P_BTREEMETA:
  1339. btmeta = (BTMETA *)h;
  1340. if (F_ISSET(&btmeta->dbmeta, BTM_RECNO)) {
  1341. /* Recnos have no order to check. */
  1342. ret = 0;
  1343. goto err;
  1344. }
  1345. if ((ret =
  1346.     __db_meta2pgset(dbp, vdp, meta_pgno, flags, pgset)) != 0)
  1347. goto err;
  1348. if ((ret = pgset->cursor(pgset, NULL, &pgsc, 0)) != 0)
  1349. goto err;
  1350. while ((ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) {
  1351. if ((ret = memp_fget(dbp->mpf, &p, 0, &currpg)) != 0)
  1352. goto err;
  1353. if ((ret = __bam_vrfy_itemorder(dbp,
  1354.     NULL, currpg, p, NUM_ENT(currpg), 1,
  1355.     F_ISSET(&btmeta->dbmeta, BTM_DUP), flags)) != 0)
  1356. goto err;
  1357. if ((ret = memp_fput(dbp->mpf, currpg, 0)) != 0)
  1358. goto err;
  1359. currpg = NULL;
  1360. }
  1361. if ((ret = pgsc->c_close(pgsc)) != 0)
  1362. goto err;
  1363. break;
  1364. case P_HASHMETA:
  1365. hmeta = (HMETA *)h;
  1366. h_internal = (HASH *)dbp->h_internal;
  1367. /*
  1368.  * Make sure h_charkey is right.
  1369.  */
  1370. if (h_internal == NULL || h_internal->h_hash == NULL) {
  1371. EPRINT((dbp->dbenv,
  1372.     "DB_ORDERCHKONLY requires that a hash function be set"));
  1373. ret = DB_VERIFY_BAD;
  1374. goto err;
  1375. }
  1376. if (hmeta->h_charkey !=
  1377.     h_internal->h_hash(dbp, CHARKEY, sizeof(CHARKEY))) {
  1378. EPRINT((dbp->dbenv,
  1379.     "Incorrect hash function for database"));
  1380. ret = DB_VERIFY_BAD;
  1381. goto err;
  1382. }
  1383. /*
  1384.  * Foreach bucket, verify hashing on each page in the
  1385.  * corresponding chain of pages.
  1386.  */
  1387. for (bucket = 0; bucket <= hmeta->max_bucket; bucket++) {
  1388. pgno = BS_TO_PAGE(bucket, hmeta->spares);
  1389. while (pgno != PGNO_INVALID) {
  1390. if ((ret = memp_fget(dbp->mpf,
  1391.     &pgno, 0, &currpg)) != 0)
  1392. goto err;
  1393. if ((ret = __ham_vrfy_hashing(dbp,
  1394.     NUM_ENT(currpg),hmeta, bucket, pgno,
  1395.     flags, h_internal->h_hash)) != 0)
  1396. goto err;
  1397. pgno = NEXT_PGNO(currpg);
  1398. if ((ret = memp_fput(dbp->mpf, currpg, 0)) != 0)
  1399. goto err;
  1400. currpg = NULL;
  1401. }
  1402. }
  1403. break;
  1404. default:
  1405. EPRINT((dbp->dbenv, "Database meta page %lu of bad type %lu",
  1406.     (u_long)meta_pgno, (u_long)TYPE(h)));
  1407. ret = DB_VERIFY_BAD;
  1408. break;
  1409. }
  1410. err: if (pgsc != NULL)
  1411. (void)pgsc->c_close(pgsc);
  1412. if (pgset != NULL)
  1413. (void)pgset->close(pgset, 0);
  1414. if (h != NULL && (t_ret = memp_fput(dbp->mpf, h, 0)) != 0)
  1415. ret = t_ret;
  1416. if (currpg != NULL && (t_ret = memp_fput(dbp->mpf, currpg, 0)) != 0)
  1417. ret = t_ret;
  1418. if ((t_ret = mdbp->close(mdbp, 0)) != 0)
  1419. ret = t_ret;
  1420. return (ret);
  1421. }
  1422. /*
  1423.  * __db_salvage --
  1424.  * Walk through a page, salvaging all likely or plausible (w/
  1425.  * DB_AGGRESSIVE) key/data pairs.
  1426.  *
  1427.  * PUBLIC: int __db_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *,
  1428.  * PUBLIC:     void *, int (*)(void *, const void *), u_int32_t));
  1429.  */
  1430. int
  1431. __db_salvage(dbp, vdp, pgno, h, handle, callback, flags)
  1432. DB *dbp;
  1433. VRFY_DBINFO *vdp;
  1434. db_pgno_t pgno;
  1435. PAGE *h;
  1436. void *handle;
  1437. int (*callback) __P((void *, const void *));
  1438. u_int32_t flags;
  1439. {
  1440. DB_ASSERT(LF_ISSET(DB_SALVAGE));
  1441. /* If we got this page in the subdb pass, we can safely skip it. */
  1442. if (__db_salvage_isdone(vdp, pgno))
  1443. return (0);
  1444. switch (TYPE(h)) {
  1445. case P_HASH:
  1446. return (__ham_salvage(dbp,
  1447.     vdp, pgno, h, handle, callback, flags));
  1448. /* NOTREACHED */
  1449. case P_LBTREE:
  1450. return (__bam_salvage(dbp,
  1451.     vdp, pgno, P_LBTREE, h, handle, callback, NULL, flags));
  1452. /* NOTREACHED */
  1453. case P_LDUP:
  1454. return (__db_salvage_markneeded(vdp, pgno, SALVAGE_LDUP));
  1455. /* NOTREACHED */
  1456. case P_OVERFLOW:
  1457. return (__db_salvage_markneeded(vdp, pgno, SALVAGE_OVERFLOW));
  1458. /* NOTREACHED */
  1459. case P_LRECNO:
  1460. /*
  1461.  * Recnos are tricky -- they may represent dup pages, or
  1462.  * they may be subdatabase/regular database pages in their
  1463.  * own right.  If the former, they need to be printed with a
  1464.  * key, preferably when we hit the corresponding datum in
  1465.  * a btree/hash page.  If the latter, there is no key.
  1466.  *
  1467.  * If a database is sufficiently frotzed, we're not going
  1468.  * to be able to get this right, so we best-guess:  just
  1469.  * mark it needed now, and if we're really a normal recno
  1470.  * database page, the "unknowns" pass will pick us up.
  1471.  */
  1472. return (__db_salvage_markneeded(vdp, pgno, SALVAGE_LRECNO));
  1473. /* NOTREACHED */
  1474. case P_IBTREE:
  1475. case P_INVALID:
  1476. case P_IRECNO:
  1477. case __P_DUPLICATE:
  1478. default:
  1479. /* XXX: Should we be more aggressive here? */
  1480. break;
  1481. }
  1482. return (0);
  1483. }
  1484. /*
  1485.  * __db_salvage_unknowns --
  1486.  * Walk through the salvager database, printing with key "UNKNOWN"
  1487.  * any pages we haven't dealt with.
  1488.  */
  1489. static int
  1490. __db_salvage_unknowns(dbp, vdp, handle, callback, flags)
  1491. DB *dbp;
  1492. VRFY_DBINFO *vdp;
  1493. void *handle;
  1494. int (*callback) __P((void *, const void *));
  1495. u_int32_t flags;
  1496. {
  1497. DBT unkdbt, key, *dbt;
  1498. PAGE *h;
  1499. db_pgno_t pgno;
  1500. u_int32_t pgtype;
  1501. int ret, err_ret;
  1502. void *ovflbuf;
  1503. memset(&unkdbt, 0, sizeof(DBT));
  1504. unkdbt.size = strlen("UNKNOWN") + 1;
  1505. unkdbt.data = "UNKNOWN";
  1506. if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, 0, &ovflbuf)) != 0)
  1507. return (ret);
  1508. err_ret = 0;
  1509. while ((ret = __db_salvage_getnext(vdp, &pgno, &pgtype)) == 0) {
  1510. dbt = NULL;
  1511. if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0) {
  1512. err_ret = ret;
  1513. continue;
  1514. }
  1515. switch (pgtype) {
  1516. case SALVAGE_LDUP:
  1517. case SALVAGE_LRECNODUP:
  1518. dbt = &unkdbt;
  1519. /* FALLTHROUGH */
  1520. case SALVAGE_LBTREE:
  1521. case SALVAGE_LRECNO:
  1522. if ((ret = __bam_salvage(dbp, vdp, pgno, pgtype,
  1523.     h, handle, callback, dbt, flags)) != 0)
  1524. err_ret = ret;
  1525. break;
  1526. case SALVAGE_OVERFLOW:
  1527. /*
  1528.  * XXX:
  1529.  * This may generate multiple "UNKNOWN" keys in
  1530.  * a database with no dups.  What to do?
  1531.  */
  1532. if ((ret = __db_safe_goff(dbp,
  1533.     vdp, pgno, &key, &ovflbuf, flags)) != 0) {
  1534. err_ret = ret;
  1535. continue;
  1536. }
  1537. if ((ret = __db_prdbt(&key,
  1538.     0, " ", handle, callback, 0, NULL)) != 0) {
  1539. err_ret = ret;
  1540. continue;
  1541. }
  1542. if ((ret = __db_prdbt(&unkdbt,
  1543. 0, " ", handle, callback, 0, NULL)) != 0)
  1544. err_ret = ret;
  1545. break;
  1546. case SALVAGE_HASH:
  1547. if ((ret = __ham_salvage(
  1548.     dbp, vdp, pgno, h, handle, callback, flags)) != 0)
  1549. err_ret = ret;
  1550. break;
  1551. case SALVAGE_INVALID:
  1552. case SALVAGE_IGNORE:
  1553. default:
  1554. /*
  1555.  * Shouldn't happen, but if it does, just do what the
  1556.  * nice man says.
  1557.  */
  1558. DB_ASSERT(0);
  1559. break;
  1560. }
  1561. if ((ret = memp_fput(dbp->mpf, h, 0)) != 0)
  1562. err_ret = ret;
  1563. }
  1564. __os_free(ovflbuf, 0);
  1565. if (err_ret != 0 && ret == 0)
  1566. ret = err_ret;
  1567. return (ret == DB_NOTFOUND ? 0 : ret);
  1568. }
  1569. /*
  1570.  * Offset of the ith inp array entry, which we can compare to the offset
  1571.  * the entry stores.
  1572.  */
  1573. #define INP_OFFSET(h, i)
  1574.     ((db_indx_t)((u_int8_t *)(h)->inp + (i) - (u_int8_t *)(h)))
  1575. /*
  1576.  * __db_vrfy_inpitem --
  1577.  * Verify that a single entry in the inp array is sane, and update
  1578.  * the high water mark and current item offset.  (The former of these is
  1579.  * used for state information between calls, and is required;  it must
  1580.  * be initialized to the pagesize before the first call.)
  1581.  *
  1582.  * Returns DB_VERIFY_FATAL if inp has collided with the data,
  1583.  * since verification can't continue from there;  returns DB_VERIFY_BAD
  1584.  * if anything else is wrong.
  1585.  *
  1586.  * PUBLIC: int __db_vrfy_inpitem __P((DB *, PAGE *,
  1587.  * PUBLIC:     db_pgno_t, u_int32_t, int, u_int32_t, u_int32_t *, u_int32_t *));
  1588.  */
  1589. int
  1590. __db_vrfy_inpitem(dbp, h, pgno, i, is_btree, flags, himarkp, offsetp)
  1591. DB *dbp;
  1592. PAGE *h;
  1593. db_pgno_t pgno;
  1594. u_int32_t i;
  1595. int is_btree;
  1596. u_int32_t flags, *himarkp, *offsetp;
  1597. {
  1598. BKEYDATA *bk;
  1599. db_indx_t offset, len;
  1600. DB_ASSERT(himarkp != NULL);
  1601. /*
  1602.  * Check that the inp array, which grows from the beginning of the
  1603.  * page forward, has not collided with the data, which grow from the
  1604.  * end of the page backward.
  1605.  */
  1606. if (h->inp + i >= (db_indx_t *)((u_int8_t *)h + *himarkp)) {
  1607. /* We've collided with the data.  We need to bail. */
  1608. EPRINT((dbp->dbenv,
  1609.     "Page %lu entries listing %lu overlaps data",
  1610.     (u_long)pgno, (u_long)i));
  1611. return (DB_VERIFY_FATAL);
  1612. }
  1613. offset = h->inp[i];
  1614. /*
  1615.  * Check that the item offset is reasonable:  it points somewhere
  1616.  * after the inp array and before the end of the page.
  1617.  */
  1618. if (offset <= INP_OFFSET(h, i) || offset > dbp->pgsize) {
  1619. EPRINT((dbp->dbenv,
  1620.     "Bad offset %lu at page %lu index %lu",
  1621.     (u_long)offset, (u_long)pgno, (u_long)i));
  1622. return (DB_VERIFY_BAD);
  1623. }
  1624. /* Update the high-water mark (what HOFFSET should be) */
  1625. if (offset < *himarkp)
  1626. *himarkp = offset;
  1627. if (is_btree) {
  1628. /*
  1629.  * Check that the item length remains on-page.
  1630.  */
  1631. bk = GET_BKEYDATA(h, i);
  1632. /*
  1633.  * We need to verify the type of the item here;
  1634.  * we can't simply assume that it will be one of the
  1635.  * expected three.  If it's not a recognizable type,
  1636.  * it can't be considered to have a verifiable
  1637.  * length, so it's not possible to certify it as safe.
  1638.  */
  1639. switch (B_TYPE(bk->type)) {
  1640. case B_KEYDATA:
  1641. len = bk->len;
  1642. break;
  1643. case B_DUPLICATE:
  1644. case B_OVERFLOW:
  1645. len = BOVERFLOW_SIZE;
  1646. break;
  1647. default:
  1648. EPRINT((dbp->dbenv,
  1649.     "Item %lu on page %lu of unrecognizable type",
  1650.     i, pgno));
  1651. return (DB_VERIFY_BAD);
  1652. }
  1653. if ((size_t)(offset + len) > dbp->pgsize) {
  1654. EPRINT((dbp->dbenv,
  1655.     "Item %lu on page %lu extends past page boundary",
  1656.     (u_long)i, (u_long)pgno));
  1657. return (DB_VERIFY_BAD);
  1658. }
  1659. }
  1660. if (offsetp != NULL)
  1661. *offsetp = offset;
  1662. return (0);
  1663. }
  1664. /*
  1665.  * __db_vrfy_duptype--
  1666.  * Given a page number and a set of flags to __bam_vrfy_subtree,
  1667.  * verify that the dup tree type is correct--i.e., it's a recno
  1668.  * if DUPSORT is not set and a btree if it is.
  1669.  *
  1670.  * PUBLIC: int __db_vrfy_duptype
  1671.  * PUBLIC:     __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t));
  1672.  */
  1673. int
  1674. __db_vrfy_duptype(dbp, vdp, pgno, flags)
  1675. DB *dbp;
  1676. VRFY_DBINFO *vdp;
  1677. db_pgno_t pgno;
  1678. u_int32_t flags;
  1679. {
  1680. VRFY_PAGEINFO *pip;
  1681. int ret, isbad;
  1682. isbad = 0;
  1683. if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
  1684. return (ret);
  1685. switch (pip->type) {
  1686. case P_IBTREE:
  1687. case P_LDUP:
  1688. if (!LF_ISSET(ST_DUPSORT)) {
  1689. EPRINT((dbp->dbenv,
  1690.     "Sorted duplicate set at page %lu in unsorted-dup database",
  1691.     (u_long)pgno));
  1692. isbad = 1;
  1693. }
  1694. break;
  1695. case P_IRECNO:
  1696. case P_LRECNO:
  1697. if (LF_ISSET(ST_DUPSORT)) {
  1698. EPRINT((dbp->dbenv,
  1699.     "Unsorted duplicate set at page %lu in sorted-dup database",
  1700.     (u_long)pgno));
  1701. isbad = 1;
  1702. }
  1703. break;
  1704. default:
  1705. EPRINT((dbp->dbenv,
  1706.     "Duplicate page %lu of inappropriate type %lu",
  1707.     (u_long)pgno, (u_long)pip->type));
  1708. isbad = 1;
  1709. break;
  1710. }
  1711. if ((ret = __db_vrfy_putpageinfo(vdp, pip)) != 0)
  1712. return (ret);
  1713. return (isbad == 1 ? DB_VERIFY_BAD : 0);
  1714. }
  1715. /*
  1716.  * __db_salvage_duptree --
  1717.  * Attempt to salvage a given duplicate tree, given its alleged root.
  1718.  *
  1719.  * The key that corresponds to this dup set has been passed to us
  1720.  * in DBT *key.  Because data items follow keys, though, it has been
  1721.  * printed once already.
  1722.  *
  1723.  * The basic idea here is that pgno ought to be a P_LDUP, a P_LRECNO, a
  1724.  * P_IBTREE, or a P_IRECNO.  If it's an internal page, use the verifier
  1725.  * functions to make sure it's safe;  if it's not, we simply bail and the
  1726.  * data will have to be printed with no key later on.  if it is safe,
  1727.  * recurse on each of its children.
  1728.  *
  1729.  * Whether or not it's safe, if it's a leaf page, __bam_salvage it.
  1730.  *
  1731.  * At all times, use the DB hanging off vdp to mark and check what we've
  1732.  * done, so each page gets printed exactly once and we don't get caught
  1733.  * in any cycles.
  1734.  *
  1735.  * PUBLIC: int __db_salvage_duptree __P((DB *, VRFY_DBINFO *, db_pgno_t,
  1736.  * PUBLIC:     DBT *, void *, int (*)(void *, const void *), u_int32_t));
  1737.  */
  1738. int
  1739. __db_salvage_duptree(dbp, vdp, pgno, key, handle, callback, flags)
  1740. DB *dbp;
  1741. VRFY_DBINFO *vdp;
  1742. db_pgno_t pgno;
  1743. DBT *key;
  1744. void *handle;
  1745. int (*callback) __P((void *, const void *));
  1746. u_int32_t flags;
  1747. {
  1748. PAGE *h;
  1749. int ret, t_ret;
  1750. if (pgno == PGNO_INVALID || !IS_VALID_PGNO(pgno))
  1751. return (DB_VERIFY_BAD);
  1752. /* We have a plausible page.  Try it. */
  1753. if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0)
  1754. return (ret);
  1755. switch (TYPE(h)) {
  1756. case P_IBTREE:
  1757. case P_IRECNO:
  1758. if ((ret = __db_vrfy_common(dbp, vdp, h, pgno, flags)) != 0)
  1759. goto err;
  1760. if ((ret = __bam_vrfy(dbp,
  1761.     vdp, h, pgno, flags | DB_NOORDERCHK)) != 0 ||
  1762.     (ret = __db_salvage_markdone(vdp, pgno)) != 0)
  1763. goto err;
  1764. /*
  1765.  * We have a known-healthy internal page.  Walk it.
  1766.  */
  1767. if ((ret = __bam_salvage_walkdupint(dbp, vdp, h, key,
  1768.     handle, callback, flags)) != 0)
  1769. goto err;
  1770. break;
  1771. case P_LRECNO:
  1772. case P_LDUP:
  1773. if ((ret = __bam_salvage(dbp,
  1774.     vdp, pgno, TYPE(h), h, handle, callback, key, flags)) != 0)
  1775. goto err;
  1776. break;
  1777. default:
  1778. ret = DB_VERIFY_BAD;
  1779. goto err;
  1780. /* NOTREACHED */
  1781. }
  1782. err: if ((t_ret = memp_fput(dbp->mpf, h, 0)) != 0 && ret == 0)
  1783. ret = t_ret;
  1784. return (ret);
  1785. }
  1786. /*
  1787.  * __db_salvage_subdbs --
  1788.  * Check and see if this database has subdbs;  if so, try to salvage
  1789.  * them independently.
  1790.  */
  1791. static int
  1792. __db_salvage_subdbs(dbp, vdp, handle, callback, flags, hassubsp)
  1793. DB *dbp;
  1794. VRFY_DBINFO *vdp;
  1795. void *handle;
  1796. int (*callback) __P((void *, const void *));
  1797. u_int32_t flags;
  1798. int *hassubsp;
  1799. {
  1800. BTMETA *btmeta;
  1801. DB *pgset;
  1802. DBC *pgsc;
  1803. PAGE *h;
  1804. db_pgno_t p, meta_pgno;
  1805. int ret, err_ret;
  1806. err_ret = 0;
  1807. pgsc = NULL;
  1808. pgset = NULL;
  1809. meta_pgno = PGNO_BASE_MD;
  1810. if ((ret = memp_fget(dbp->mpf, &meta_pgno, 0, &h)) != 0)
  1811. return (ret);
  1812. if (TYPE(h) == P_BTREEMETA)
  1813. btmeta = (BTMETA *)h;
  1814. else {
  1815. /* Not a btree metadata, ergo no subdbs, so just return. */
  1816. ret = 0;
  1817. goto err;
  1818. }
  1819. /* If it's not a safe page, bail on the attempt. */
  1820. if ((ret = __db_vrfy_common(dbp, vdp, h, PGNO_BASE_MD, flags)) != 0 ||
  1821.    (ret = __bam_vrfy_meta(dbp, vdp, btmeta, PGNO_BASE_MD, flags)) != 0)
  1822. goto err;
  1823. if (!F_ISSET(&btmeta->dbmeta, BTM_SUBDB)) {
  1824. /* No subdbs, just return. */
  1825. ret = 0;
  1826. goto err;
  1827. }
  1828. /* We think we've got subdbs.  Mark it so. */
  1829. *hassubsp = 1;
  1830. if ((ret = memp_fput(dbp->mpf, h, 0)) != 0)
  1831. return (ret);
  1832. /*
  1833.  * We have subdbs.  Try to crack them.
  1834.  *
  1835.  * To do so, get a set of leaf pages in the master
  1836.  * database, and then walk each of the valid ones, salvaging
  1837.  * subdbs as we go.  If any prove invalid, just drop them;  we'll
  1838.  * pick them up on a later pass.
  1839.  */
  1840. if ((ret = __db_vrfy_pgset(dbp->dbenv, dbp->pgsize, &pgset)) != 0)
  1841. return (ret);
  1842. if ((ret =
  1843.     __db_meta2pgset(dbp, vdp, PGNO_BASE_MD, flags, pgset)) != 0)
  1844. goto err;
  1845. if ((ret = pgset->cursor(pgset, NULL, &pgsc, 0)) != 0)
  1846. goto err;
  1847. while ((ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) {
  1848. if ((ret = memp_fget(dbp->mpf, &p, 0, &h)) != 0) {
  1849. err_ret = ret;
  1850. continue;
  1851. }
  1852. if ((ret = __db_vrfy_common(dbp, vdp, h, p, flags)) != 0 ||
  1853.     (ret = __bam_vrfy(dbp,
  1854.     vdp, h, p, flags | DB_NOORDERCHK)) != 0)
  1855. goto nextpg;
  1856. if (TYPE(h) != P_LBTREE)
  1857. goto nextpg;
  1858. else if ((ret = __db_salvage_subdbpg(
  1859.     dbp, vdp, h, handle, callback, flags)) != 0)
  1860. err_ret = ret;
  1861. nextpg: if ((ret = memp_fput(dbp->mpf, h, 0)) != 0)
  1862. err_ret = ret;
  1863. }
  1864. if (ret != DB_NOTFOUND)
  1865. goto err;
  1866. if ((ret = pgsc->c_close(pgsc)) != 0)
  1867. goto err;
  1868. ret = pgset->close(pgset, 0);
  1869. return ((ret == 0 && err_ret != 0) ? err_ret : ret);
  1870. /* NOTREACHED */
  1871. err: if (pgsc != NULL)
  1872. (void)pgsc->c_close(pgsc);
  1873. if (pgset != NULL)
  1874. (void)pgset->close(pgset, 0);
  1875. (void)memp_fput(dbp->mpf, h, 0);
  1876. return (ret);
  1877. }
  1878. /*
  1879.  * __db_salvage_subdbpg --
  1880.  * Given a known-good leaf page in the master database, salvage all
  1881.  * leaf pages corresponding to each subdb.
  1882.  *
  1883.  * PUBLIC: int __db_salvage_subdbpg
  1884.  * PUBLIC:     __P((DB *, VRFY_DBINFO *, PAGE *, void *,
  1885.  * PUBLIC:     int (*)(void *, const void *), u_int32_t));
  1886.  */
  1887. int
  1888. __db_salvage_subdbpg(dbp, vdp, master, handle, callback, flags)
  1889. DB *dbp;
  1890. VRFY_DBINFO *vdp;
  1891. PAGE *master;
  1892. void *handle;
  1893. int (*callback) __P((void *, const void *));
  1894. u_int32_t flags;
  1895. {
  1896. BKEYDATA *bkkey, *bkdata;
  1897. BOVERFLOW *bo;
  1898. DB *pgset;
  1899. DBC *pgsc;
  1900. DBT key;
  1901. PAGE *subpg;
  1902. db_indx_t i;
  1903. db_pgno_t meta_pgno, p;
  1904. int ret, err_ret, t_ret;
  1905. char *subdbname;
  1906. ret = err_ret = 0;
  1907. subdbname = NULL;
  1908. if ((ret = __db_vrfy_pgset(dbp->dbenv, dbp->pgsize, &pgset)) != 0)
  1909. return (ret);
  1910. /*
  1911.  * For each entry, get and salvage the set of pages
  1912.  * corresponding to that entry.
  1913.  */
  1914. for (i = 0; i < NUM_ENT(master); i += P_INDX) {
  1915. bkkey = GET_BKEYDATA(master, i);
  1916. bkdata = GET_BKEYDATA(master, i + O_INDX);
  1917. /* Get the subdatabase name. */
  1918. if (B_TYPE(bkkey->type) == B_OVERFLOW) {
  1919. /*
  1920.  * We can, in principle anyway, have a subdb
  1921.  * name so long it overflows.  Ick.
  1922.  */
  1923. bo = (BOVERFLOW *)bkkey;
  1924. if ((ret = __db_safe_goff(dbp, vdp, bo->pgno, &key,
  1925.     (void **)&subdbname, flags)) != 0) {
  1926. err_ret = DB_VERIFY_BAD;
  1927. continue;
  1928. }
  1929. /* Nul-terminate it. */
  1930. if ((ret = __os_realloc(dbp->dbenv,
  1931.     key.size + 1, NULL, &subdbname)) != 0)
  1932. goto err;
  1933. subdbname[key.size] = '';
  1934. } else if (B_TYPE(bkkey->type == B_KEYDATA)) {
  1935. if ((ret = __os_realloc(dbp->dbenv,
  1936.     bkkey->len + 1, NULL, &subdbname)) != 0)
  1937. goto err;
  1938. memcpy(subdbname, bkkey->data, bkkey->len);
  1939. subdbname[bkkey->len] = '';
  1940. }
  1941. /* Get the corresponding pgno. */
  1942. if (bkdata->len != sizeof(db_pgno_t)) {
  1943. err_ret = DB_VERIFY_BAD;
  1944. continue;
  1945. }
  1946. memcpy(&meta_pgno, bkdata->data, sizeof(db_pgno_t));
  1947. /* If we can't get the subdb meta page, just skip the subdb. */
  1948. if (!IS_VALID_PGNO(meta_pgno) ||
  1949.     (ret = memp_fget(dbp->mpf, &meta_pgno, 0, &subpg)) != 0) {
  1950. err_ret = ret;
  1951. continue;
  1952. }
  1953. /*
  1954.  * Verify the subdatabase meta page.  This has two functions.
  1955.  * First, if it's bad, we have no choice but to skip the subdb
  1956.  * and let the pages just get printed on a later pass.  Second,
  1957.  * the access-method-specific meta verification routines record
  1958.  * the various state info (such as the presence of dups)
  1959.  * that we need for __db_prheader().
  1960.  */
  1961. if ((ret =
  1962.     __db_vrfy_common(dbp, vdp, subpg, meta_pgno, flags)) != 0) {
  1963. err_ret = ret;
  1964. (void)memp_fput(dbp->mpf, subpg, 0);
  1965. continue;
  1966. }
  1967. switch (TYPE(subpg)) {
  1968. case P_BTREEMETA:
  1969. if ((ret = __bam_vrfy_meta(dbp,
  1970.     vdp, (BTMETA *)subpg, meta_pgno, flags)) != 0) {
  1971. err_ret = ret;
  1972. (void)memp_fput(dbp->mpf, subpg, 0);
  1973. continue;
  1974. }
  1975. break;
  1976. case P_HASHMETA:
  1977. if ((ret = __ham_vrfy_meta(dbp,
  1978.     vdp, (HMETA *)subpg, meta_pgno, flags)) != 0) {
  1979. err_ret = ret;
  1980. (void)memp_fput(dbp->mpf, subpg, 0);
  1981. continue;
  1982. }
  1983. break;
  1984. default:
  1985. /* This isn't an appropriate page;  skip this subdb. */
  1986. err_ret = DB_VERIFY_BAD;
  1987. continue;
  1988. /* NOTREACHED */
  1989. }
  1990. if ((ret = memp_fput(dbp->mpf, subpg, 0)) != 0) {
  1991. err_ret = ret;
  1992. continue;
  1993. }
  1994. /* Print a subdatabase header. */
  1995. if ((ret = __db_prheader(dbp,
  1996.     subdbname, 0, 0, handle, callback, vdp, meta_pgno)) != 0)
  1997. goto err;
  1998. if ((ret = __db_meta2pgset(dbp, vdp, meta_pgno,
  1999.     flags, pgset)) != 0) {
  2000. err_ret = ret;
  2001. continue;
  2002. }
  2003. if ((ret = pgset->cursor(pgset, NULL, &pgsc, 0)) != 0)
  2004. goto err;
  2005. while ((ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) {
  2006. if ((ret = memp_fget(dbp->mpf, &p, 0, &subpg)) != 0) {
  2007. err_ret = ret;
  2008. continue;
  2009. }
  2010. if ((ret = __db_salvage(dbp, vdp, p, subpg,
  2011.     handle, callback, flags)) != 0)
  2012. err_ret = ret;
  2013. if ((ret = memp_fput(dbp->mpf, subpg, 0)) != 0)
  2014. err_ret = ret;
  2015. }
  2016. if (ret != DB_NOTFOUND)
  2017. goto err;
  2018. if ((ret = pgsc->c_close(pgsc)) != 0)
  2019. goto err;
  2020. if ((ret = __db_prfooter(handle, callback)) != 0)
  2021. goto err;
  2022. }
  2023. err: if (subdbname)
  2024. __os_free(subdbname, 0);
  2025. if ((t_ret = pgset->close(pgset, 0)) != 0)
  2026. ret = t_ret;
  2027. if ((t_ret = __db_salvage_markdone(vdp, PGNO(master))) != 0)
  2028. return (t_ret);
  2029. return ((err_ret != 0) ? err_ret : ret);
  2030. }
  2031. /*
  2032.  * __db_meta2pgset --
  2033.  * Given a known-safe meta page number, return the set of pages
  2034.  * corresponding to the database it represents.  Return DB_VERIFY_BAD if
  2035.  * it's not a suitable meta page or is invalid.
  2036.  */
  2037. static int
  2038. __db_meta2pgset(dbp, vdp, pgno, flags, pgset)
  2039. DB *dbp;
  2040. VRFY_DBINFO *vdp;
  2041. db_pgno_t pgno;
  2042. u_int32_t flags;
  2043. DB *pgset;
  2044. {
  2045. PAGE *h;
  2046. int ret, t_ret;
  2047. if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0)
  2048. return (ret);
  2049. switch (TYPE(h)) {
  2050. case P_BTREEMETA:
  2051. ret = __bam_meta2pgset(dbp, vdp, (BTMETA *)h, flags, pgset);
  2052. break;
  2053. case P_HASHMETA:
  2054. ret = __ham_meta2pgset(dbp, vdp, (HMETA *)h, flags, pgset);
  2055. break;
  2056. default:
  2057. ret = DB_VERIFY_BAD;
  2058. break;
  2059. }
  2060. if ((t_ret = memp_fput(dbp->mpf, h, 0)) != 0)
  2061. return (t_ret);
  2062. return (ret);
  2063. }
  2064. /*
  2065.  * __db_guesspgsize --
  2066.  * Try to guess what the pagesize is if the one on the meta page
  2067.  * and the one in the db are invalid.
  2068.  */
  2069. static int
  2070. __db_guesspgsize(dbenv, fhp)
  2071. DB_ENV *dbenv;
  2072. DB_FH *fhp;
  2073. {
  2074. db_pgno_t i;
  2075. size_t nr;
  2076. u_int32_t guess;
  2077. u_int8_t type;
  2078. int ret;
  2079. for (guess = DB_MAX_PGSIZE; guess >= DB_MIN_PGSIZE; guess >>= 1) {
  2080. /*
  2081.  * We try to read three pages ahead after the first one
  2082.  * and make sure we have plausible types for all of them.
  2083.  * If the seeks fail, continue with a smaller size;
  2084.  * we're probably just looking past the end of the database.
  2085.  * If they succeed and the types are reasonable, also continue
  2086.  * with a size smaller;  we may be looking at pages N,
  2087.  * 2N, and 3N for some N > 1.
  2088.  *
  2089.  * As soon as we hit an invalid type, we stop and return
  2090.  * our previous guess; that last one was probably the page size.
  2091.  */
  2092. for (i = 1; i <= 3; i++) {
  2093. if ((ret = __os_seek(dbenv, fhp, guess,
  2094.     i, SSZ(DBMETA, type), 0, DB_OS_SEEK_SET)) != 0)
  2095. break;
  2096. if ((ret = __os_read(dbenv,
  2097.     fhp, &type, 1, &nr)) != 0 || nr == 0)
  2098. break;
  2099. if (type == P_INVALID || type >= P_PAGETYPE_MAX)
  2100. return (guess << 1);
  2101. }
  2102. }
  2103. /*
  2104.  * If we're just totally confused--the corruption takes up most of the
  2105.  * beginning pages of the database--go with the default size.
  2106.  */
  2107. return (DB_DEF_IOSIZE);
  2108. }