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