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