00001 /*- 00002 * See the file LICENSE for redistribution information. 00003 * 00004 * Copyright (c) 1999-2005 00005 * Sleepycat Software. All rights reserved. 00006 * 00007 * $Id: db_verify.h,v 12.4 2005/06/16 20:21:47 bostic Exp $ 00008 */ 00009 00010 #ifndef _DB_VERIFY_H_ 00011 #define _DB_VERIFY_H_ 00012 00013 /* 00014 * Structures and macros for the storage and retrieval of all information 00015 * needed for inter-page verification of a database. 00016 */ 00017 00018 /* 00019 * EPRINT is the macro for error printing. Takes as an arg the arg set 00020 * for DB->err. 00021 */ 00022 #define EPRINT(x) do { \ 00023 if (!LF_ISSET(DB_SALVAGE)) \ 00024 __db_err x; \ 00025 } while (0) 00026 00027 /* For fatal type errors--i.e., verifier bugs. */ 00028 #define TYPE_ERR_PRINT(dbenv, func, pgno, ptype) \ 00029 EPRINT(((dbenv), \ 00030 "Page %lu: %s called on nonsensical page of type %lu", \ 00031 (u_long)(pgno), (func), (u_long)(ptype))); 00032 00033 /* Complain about a totally zeroed page where we don't expect one. */ 00034 #define ZEROPG_ERR_PRINT(dbenv, pgno, str) do { \ 00035 EPRINT(((dbenv), "Page %lu: %s is of inappropriate type %lu", \ 00036 (u_long)(pgno), str, (u_long)P_INVALID)); \ 00037 EPRINT(((dbenv), "Page %lu: totally zeroed page", \ 00038 (u_long)(pgno))); \ 00039 } while (0) 00040 00041 /* 00042 * Note that 0 is, in general, a valid pgno, despite equalling PGNO_INVALID; 00043 * we have to test it separately where it's not appropriate. 00044 */ 00045 #define IS_VALID_PGNO(x) ((x) <= vdp->last_pgno) 00046 00047 /* 00048 * Flags understood by the btree structure checks (esp. __bam_vrfy_subtree). 00049 * These share the same space as the global flags to __db_verify, and must not 00050 * dip below 0x00010000. 00051 */ 00052 #define ST_DUPOK 0x00010000 /* Duplicates are acceptable. */ 00053 #define ST_DUPSET 0x00020000 /* Subtree is in a duplicate tree. */ 00054 #define ST_DUPSORT 0x00040000 /* Duplicates are sorted. */ 00055 #define ST_IS_RECNO 0x00080000 /* Subtree is a recno. */ 00056 #define ST_OVFL_LEAF 0x00100000 /* Overflow reffed from leaf page. */ 00057 #define ST_RECNUM 0x00200000 /* Subtree has record numbering on. */ 00058 #define ST_RELEN 0x00400000 /* Subtree has fixed-length records. */ 00059 #define ST_TOPLEVEL 0x00800000 /* Subtree == entire tree */ 00060 00061 /* 00062 * Flags understood by __bam_salvage and __db_salvage. These need not share 00063 * the same space with the __bam_vrfy_subtree flags, but must share with 00064 * __db_verify. 00065 */ 00066 #define SA_SKIPFIRSTKEY 0x00080000 00067 00068 /* 00069 * VRFY_DBINFO is the fundamental structure; it either represents the database 00070 * of subdatabases, or the sole database if there are no subdatabases. 00071 */ 00072 struct __vrfy_dbinfo { 00073 /* Info about this database in particular. */ 00074 DBTYPE type; 00075 00076 /* List of subdatabase meta pages, if any. */ 00077 LIST_HEAD(__subdbs, __vrfy_childinfo) subdbs; 00078 00079 /* File-global info--stores VRFY_PAGEINFOs for each page. */ 00080 DB *pgdbp; 00081 00082 /* Child database--stores VRFY_CHILDINFOs of each page. */ 00083 DB *cdbp; 00084 00085 /* Page info structures currently in use. */ 00086 LIST_HEAD(__activepips, __vrfy_pageinfo) activepips; 00087 00088 /* 00089 * DB we use to keep track of which pages are linked somehow 00090 * during verification. 0 is the default, "unseen"; 1 is seen. 00091 */ 00092 DB *pgset; 00093 00094 /* 00095 * This is a database we use during salvaging to keep track of which 00096 * overflow and dup pages we need to come back to at the end and print 00097 * with key "UNKNOWN". Pages which print with a good key get set 00098 * to SALVAGE_IGNORE; others get set, as appropriate, to SALVAGE_LDUP, 00099 * SALVAGE_LRECNODUP, SALVAGE_OVERFLOW for normal db overflow pages, 00100 * and SALVAGE_BTREE, SALVAGE_LRECNO, and SALVAGE_HASH for subdb 00101 * pages. 00102 */ 00103 #define SALVAGE_INVALID 0 00104 #define SALVAGE_IGNORE 1 00105 #define SALVAGE_LDUP 2 00106 #define SALVAGE_LRECNODUP 3 00107 #define SALVAGE_OVERFLOW 4 00108 #define SALVAGE_LBTREE 5 00109 #define SALVAGE_HASH 6 00110 #define SALVAGE_LRECNO 7 00111 DB *salvage_pages; 00112 00113 db_pgno_t last_pgno; 00114 db_pgno_t pgs_remaining; /* For dbp->db_feedback(). */ 00115 00116 /* 00117 * These are used during __bam_vrfy_subtree to keep track, while 00118 * walking up and down the Btree structure, of the prev- and next-page 00119 * chain of leaf pages and verify that it's intact. Also, make sure 00120 * that this chain contains pages of only one type. 00121 */ 00122 db_pgno_t prev_pgno; 00123 db_pgno_t next_pgno; 00124 u_int8_t leaf_type; 00125 00126 /* Queue needs these to verify data pages in the first pass. */ 00127 u_int32_t re_pad; /* Record pad character. */ 00128 u_int32_t re_len; /* Record length. */ 00129 u_int32_t rec_page; 00130 u_int32_t page_ext; 00131 u_int32_t first_recno; 00132 u_int32_t last_recno; 00133 int nextents; 00134 db_pgno_t *extents; 00135 00136 #define SALVAGE_PRINTABLE 0x01 /* Output printable chars literally. */ 00137 #define SALVAGE_PRINTHEADER 0x02 /* Print the unknown-key header. */ 00138 #define SALVAGE_PRINTFOOTER 0x04 /* Print the unknown-key footer. */ 00139 #define VRFY_LEAFCHAIN_BROKEN 0x08 /* Lost one or more Btree leaf pgs. */ 00140 #define VRFY_QMETA_SET 0x10 /* We've seen a QUEUE meta page and 00141 set things up for it. */ 00142 u_int32_t flags; 00143 }; /* VRFY_DBINFO */ 00144 00145 /* 00146 * The amount of state information we need per-page is small enough that 00147 * it's not worth the trouble to define separate structures for each 00148 * possible type of page, and since we're doing verification with these we 00149 * have to be open to the possibility that page N will be of a completely 00150 * unexpected type anyway. So we define one structure here with all the 00151 * info we need for inter-page verification. 00152 */ 00153 struct __vrfy_pageinfo { 00154 u_int8_t type; 00155 u_int8_t bt_level; 00156 u_int8_t unused1; 00157 u_int8_t unused2; 00158 db_pgno_t pgno; 00159 db_pgno_t prev_pgno; 00160 db_pgno_t next_pgno; 00161 00162 /* meta pages */ 00163 db_pgno_t root; 00164 db_pgno_t free; /* Free list head. */ 00165 00166 db_indx_t entries; /* Actual number of entries. */ 00167 u_int16_t unused; 00168 db_recno_t rec_cnt; /* Record count. */ 00169 u_int32_t re_pad; /* Record pad character. */ 00170 u_int32_t re_len; /* Record length. */ 00171 u_int32_t bt_minkey; 00172 u_int32_t h_ffactor; 00173 u_int32_t h_nelem; 00174 00175 /* overflow pages */ 00176 /* 00177 * Note that refcount is the refcount for an overflow page; pi_refcount 00178 * is this structure's own refcount! 00179 */ 00180 u_int32_t refcount; 00181 u_int32_t olen; 00182 00183 #define VRFY_DUPS_UNSORTED 0x0001 /* Have to flag the negative! */ 00184 #define VRFY_HAS_CHKSUM 0x0002 00185 #define VRFY_HAS_DUPS 0x0004 00186 #define VRFY_HAS_DUPSORT 0x0008 /* Has the flag set. */ 00187 #define VRFY_HAS_RECNUMS 0x0010 00188 #define VRFY_HAS_SUBDBS 0x0020 00189 #define VRFY_INCOMPLETE 0x0040 /* Meta or item order checks incomp. */ 00190 #define VRFY_IS_ALLZEROES 0x0080 /* Hash page we haven't touched? */ 00191 #define VRFY_IS_FIXEDLEN 0x0100 00192 #define VRFY_IS_RECNO 0x0200 00193 #define VRFY_IS_RRECNO 0x0400 00194 #define VRFY_OVFL_LEAFSEEN 0x0800 00195 u_int32_t flags; 00196 00197 LIST_ENTRY(__vrfy_pageinfo) links; 00198 u_int32_t pi_refcount; 00199 }; /* VRFY_PAGEINFO */ 00200 00201 struct __vrfy_childinfo { 00202 /* The following fields are set by the caller of __db_vrfy_childput. */ 00203 db_pgno_t pgno; 00204 00205 #define V_DUPLICATE 1 /* off-page dup metadata */ 00206 #define V_OVERFLOW 2 /* overflow page */ 00207 #define V_RECNO 3 /* btree internal or leaf page */ 00208 u_int32_t type; 00209 db_recno_t nrecs; /* record count on a btree subtree */ 00210 u_int32_t tlen; /* ovfl. item total size */ 00211 00212 /* The following field is maintained by __db_vrfy_childput. */ 00213 u_int32_t refcnt; /* # of times parent points to child. */ 00214 00215 LIST_ENTRY(__vrfy_childinfo) links; 00216 }; /* VRFY_CHILDINFO */ 00217 00218 #endif /* !_DB_VERIFY_H_ */