1 /*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1999, 2013 Oracle and/or its affiliates. All rights reserved. 5 * 6 * $Id$ 7 */ 8 9 #ifndef _DB_VERIFY_H_ 10 #define _DB_VERIFY_H_ 11 12 #if defined(__cplusplus) 13 extern "C" { 14 #endif 15 16 /* 17 * Structures and macros for the storage and retrieval of all information 18 * needed for inter-page verification of a database. 19 */ 20 21 /* 22 * EPRINT is the macro for error printing. Takes as an arg the arg set 23 * for DB->err. 24 */ 25 #define EPRINT(x) do { \ 26 if (!LF_ISSET(DB_SALVAGE)) \ 27 __db_errx x; \ 28 } while (0) 29 30 /* Complain about a totally zeroed page where we don't expect one. */ 31 #define ZEROPG_ERR_PRINT(dbenv, pgno, str) do { \ 32 EPRINT(((dbenv), DB_STR_A("0501", \ 33 "Page %lu: %s is of inappropriate type %lu", "%lu %s %lu"), \ 34 (u_long)(pgno), str, (u_long)P_INVALID)); \ 35 EPRINT(((dbenv), DB_STR_A("0502", \ 36 "Page %lu: totally zeroed page", \ 37 "%lu"), (u_long)(pgno))); \ 38 } while (0) 39 40 /* 41 * Note that 0 is, in general, a valid pgno, despite equaling PGNO_INVALID; 42 * we have to test it separately where it's not appropriate. 43 */ 44 #define IS_VALID_PGNO(x) ((x) <= vdp->last_pgno) 45 46 /* 47 * VRFY_DBINFO is the fundamental structure; it either represents the database 48 * of subdatabases, or the sole database if there are no subdatabases. 49 */ 50 struct __vrfy_dbinfo { 51 DB_THREAD_INFO *thread_info; 52 /* Info about this database in particular. */ 53 DBTYPE type; 54 55 /* List of subdatabase meta pages, if any. */ 56 LIST_HEAD(__subdbs, __vrfy_childinfo) subdbs; 57 58 /* Transaction handle for CDS group. */ 59 DB_TXN *txn; 60 61 /* File-global info--stores VRFY_PAGEINFOs for each page. */ 62 DB *pgdbp; 63 64 /* Child database--stores VRFY_CHILDINFOs of each page. */ 65 DB *cdbp; 66 67 /* Page info structures currently in use. */ 68 LIST_HEAD(__activepips, __vrfy_pageinfo) activepips; 69 70 /* 71 * DB we use to keep track of which pages are linked somehow 72 * during verification. 0 is the default, "unseen"; 1 is seen. 73 */ 74 DB *pgset; 75 76 /* 77 * This is a database we use during salvaging to keep track of which 78 * overflow and dup pages we need to come back to at the end and print 79 * with key "UNKNOWN". Pages which print with a good key get set 80 * to SALVAGE_IGNORE; others get set, as appropriate, to SALVAGE_LDUP, 81 * SALVAGE_LRECNODUP, SALVAGE_OVERFLOW for normal db overflow pages, 82 * and SALVAGE_BTREE, SALVAGE_LRECNO, and SALVAGE_HASH for subdb 83 * pages. 84 */ 85 #define SALVAGE_INVALID 0 86 #define SALVAGE_IGNORE 1 87 #define SALVAGE_LDUP 2 88 #define SALVAGE_IBTREE 3 89 #define SALVAGE_OVERFLOW 4 90 #define SALVAGE_LBTREE 5 91 #define SALVAGE_HASH 6 92 #define SALVAGE_LRECNO 7 93 #define SALVAGE_LRECNODUP 8 94 DB *salvage_pages; 95 96 db_pgno_t last_pgno; 97 db_pgno_t meta_last_pgno; 98 db_pgno_t pgs_remaining; /* For dbp->db_feedback(). */ 99 100 /* 101 * These are used during __bam_vrfy_subtree to keep track, while 102 * walking up and down the Btree structure, of the prev- and next-page 103 * chain of leaf pages and verify that it's intact. Also, make sure 104 * that this chain contains pages of only one type. 105 */ 106 db_pgno_t prev_pgno; 107 db_pgno_t next_pgno; 108 u_int8_t leaf_type; 109 110 /* Queue needs these to verify data pages in the first pass. */ 111 u_int32_t re_pad; /* Record pad character. */ 112 u_int32_t re_len; /* Record length. */ 113 u_int32_t rec_page; 114 u_int32_t page_ext; 115 u_int32_t first_recno; 116 u_int32_t last_recno; 117 int nextents; 118 db_pgno_t *extents; 119 120 #define SALVAGE_PRINTABLE 0x01 /* Output printable chars literally. */ 121 #define SALVAGE_PRINTHEADER 0x02 /* Print the unknown-key header. */ 122 #define SALVAGE_PRINTFOOTER 0x04 /* Print the unknown-key footer. */ 123 #define SALVAGE_HASSUBDBS 0x08 /* There are subdatabases to salvage. */ 124 #define VRFY_LEAFCHAIN_BROKEN 0x10 /* Lost one or more Btree leaf pgs. */ 125 #define VRFY_QMETA_SET 0x20 /* We've seen a QUEUE meta page and 126 set things up for it. */ 127 u_int32_t flags; 128 }; /* VRFY_DBINFO */ 129 130 /* 131 * The amount of state information we need per-page is small enough that 132 * it's not worth the trouble to define separate structures for each 133 * possible type of page, and since we're doing verification with these we 134 * have to be open to the possibility that page N will be of a completely 135 * unexpected type anyway. So we define one structure here with all the 136 * info we need for inter-page verification. 137 */ 138 struct __vrfy_pageinfo { 139 u_int8_t type; 140 u_int8_t bt_level; 141 u_int8_t unused1; 142 u_int8_t unused2; 143 db_pgno_t pgno; 144 db_pgno_t prev_pgno; 145 db_pgno_t next_pgno; 146 147 /* meta pages */ 148 db_pgno_t root; 149 db_pgno_t free; /* Free list head. */ 150 151 db_indx_t entries; /* Actual number of entries. */ 152 u_int16_t unused; 153 db_recno_t rec_cnt; /* Record count. */ 154 u_int32_t re_pad; /* Record pad character. */ 155 u_int32_t re_len; /* Record length. */ 156 u_int32_t bt_minkey; 157 u_int32_t h_ffactor; 158 u_int32_t h_nelem; 159 160 /* overflow pages */ 161 /* 162 * Note that refcount is the refcount for an overflow page; pi_refcount 163 * is this structure's own refcount! 164 */ 165 u_int32_t refcount; 166 u_int32_t olen; 167 168 #define VRFY_DUPS_UNSORTED 0x0001 /* Have to flag the negative! */ 169 #define VRFY_HAS_CHKSUM 0x0002 170 #define VRFY_HAS_DUPS 0x0004 171 #define VRFY_HAS_DUPSORT 0x0008 /* Has the flag set. */ 172 #define VRFY_HAS_PART_RANGE 0x0010 /* Has the flag set. */ 173 #define VRFY_HAS_PART_CALLBACK 0x0020 /* Has the flag set. */ 174 #define VRFY_HAS_RECNUMS 0x0040 175 #define VRFY_HAS_SUBDBS 0x0080 176 #define VRFY_INCOMPLETE 0x0100 /* Meta or item order checks incomp. */ 177 #define VRFY_IS_ALLZEROES 0x0200 /* Hash page we haven't touched? */ 178 #define VRFY_IS_FIXEDLEN 0x0400 179 #define VRFY_IS_RECNO 0x0800 180 #define VRFY_IS_RRECNO 0x1000 181 #define VRFY_OVFL_LEAFSEEN 0x2000 182 #define VRFY_HAS_COMPRESS 0x4000 183 #define VRFY_NONEXISTENT 0x8000 184 u_int32_t flags; 185 186 LIST_ENTRY(__vrfy_pageinfo) links; 187 u_int32_t pi_refcount; 188 }; /* VRFY_PAGEINFO */ 189 190 struct __vrfy_childinfo { 191 /* The following fields are set by the caller of __db_vrfy_childput. */ 192 db_pgno_t pgno; 193 194 #define V_DUPLICATE 1 /* off-page dup metadata */ 195 #define V_OVERFLOW 2 /* overflow page */ 196 #define V_RECNO 3 /* btree internal or leaf page */ 197 u_int32_t type; 198 db_recno_t nrecs; /* record count on a btree subtree */ 199 u_int32_t tlen; /* ovfl. item total size */ 200 201 /* The following field is maintained by __db_vrfy_childput. */ 202 u_int32_t refcnt; /* # of times parent points to child. */ 203 204 LIST_ENTRY(__vrfy_childinfo) links; 205 }; /* VRFY_CHILDINFO */ 206 207 #if defined(__cplusplus) 208 } 209 #endif 210 #endif /* !_DB_VERIFY_H_ */ 211