⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bt_verify.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1999-2002 *	Sleepycat Software.  All rights reserved. * * $Id: bt_verify.c,v 1.76 2002/07/03 19:03:51 bostic Exp $ */#include "db_config.h"#ifndef lintstatic const char revid[] = "$Id: bt_verify.c,v 1.76 2002/07/03 19:03:51 bostic Exp $";#endif /* not lint */#ifndef NO_SYSTEM_INCLUDES#include <sys/types.h>#include <string.h>#endif#include "db_int.h"#include "dbinc/db_page.h"#include "dbinc/db_verify.h"#include "dbinc/btree.h"static int __bam_safe_getdata __P((DB *, PAGE *, u_int32_t, int, DBT *, int *));static int __bam_vrfy_inp __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,    db_indx_t *, u_int32_t));static int __bam_vrfy_treeorder __P((DB *, db_pgno_t, PAGE *, BINTERNAL *,    BINTERNAL *, int (*)(DB *, const DBT *, const DBT *), u_int32_t));static int __ram_vrfy_inp __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,    db_indx_t *, u_int32_t));#define	OKFLAGS	(DB_AGGRESSIVE | DB_NOORDERCHK | DB_SALVAGE)/* * __bam_vrfy_meta -- *	Verify the btree-specific part of a metadata page. * * PUBLIC: int __bam_vrfy_meta __P((DB *, VRFY_DBINFO *, BTMETA *, * PUBLIC:     db_pgno_t, u_int32_t)); */int__bam_vrfy_meta(dbp, vdp, meta, pgno, flags)	DB *dbp;	VRFY_DBINFO *vdp;	BTMETA *meta;	db_pgno_t pgno;	u_int32_t flags;{	VRFY_PAGEINFO *pip;	int isbad, t_ret, ret;	db_indx_t ovflsize;	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)		return (ret);	isbad = 0;	/*	 * If VRFY_INCOMPLETE is not set, then we didn't come through	 * __db_vrfy_pagezero and didn't incompletely	 * check this page--we haven't checked it at all.	 * Thus we need to call __db_vrfy_meta and check the common fields.	 *	 * If VRFY_INCOMPLETE is set, we've already done all the same work	 * in __db_vrfy_pagezero, so skip the check.	 */	if (!F_ISSET(pip, VRFY_INCOMPLETE) &&	    (ret = __db_vrfy_meta(dbp, vdp, &meta->dbmeta, pgno, flags)) != 0) {		if (ret == DB_VERIFY_BAD)			isbad = 1;		else			goto err;	}	/* bt_minkey:  must be >= 2; must produce sensible ovflsize */	/* avoid division by zero */	ovflsize = meta->minkey > 0 ?	    B_MINKEY_TO_OVFLSIZE(dbp, meta->minkey, dbp->pgsize) : 0;	if (meta->minkey < 2 ||	    ovflsize > B_MINKEY_TO_OVFLSIZE(dbp, DEFMINKEYPAGE, dbp->pgsize)) {		pip->bt_minkey = 0;		isbad = 1;		EPRINT((dbp->dbenv,	    "Page %lu: nonsensical bt_minkey value %lu on metadata page",		    (u_long)pgno, (u_long)meta->minkey));	} else		pip->bt_minkey = meta->minkey;	/* bt_maxkey: no constraints (XXX: right?) */	pip->bt_maxkey = meta->maxkey;	/* re_len: no constraints on this (may be zero or huge--we make rope) */	pip->re_len = meta->re_len;	/*	 * The root must not be current page or 0 and it must be within	 * database.  If this metadata page is the master meta data page	 * of the file, then the root page had better be page 1.	 */	pip->root = 0;	if (meta->root == PGNO_INVALID ||	    meta->root == pgno || !IS_VALID_PGNO(meta->root) ||	    (pgno == PGNO_BASE_MD && meta->root != 1)) {		isbad = 1;		EPRINT((dbp->dbenv,		    "Page %lu: nonsensical root page %lu on metadata page",		    (u_long)pgno, (u_long)meta->root));	} else		pip->root = meta->root;	/* Flags. */	if (F_ISSET(&meta->dbmeta, BTM_RENUMBER))		F_SET(pip, VRFY_IS_RRECNO);	if (F_ISSET(&meta->dbmeta, BTM_SUBDB)) {		/*		 * If this is a master db meta page, it had better not have		 * duplicates.		 */		if (F_ISSET(&meta->dbmeta, BTM_DUP) && pgno == PGNO_BASE_MD) {			isbad = 1;			EPRINT((dbp->dbenv,"Page %lu: Btree metadata page has both duplicates and multiple databases",			    (u_long)pgno));		}		F_SET(pip, VRFY_HAS_SUBDBS);	}	if (F_ISSET(&meta->dbmeta, BTM_DUP))		F_SET(pip, VRFY_HAS_DUPS);	if (F_ISSET(&meta->dbmeta, BTM_DUPSORT))		F_SET(pip, VRFY_HAS_DUPSORT);	if (F_ISSET(&meta->dbmeta, BTM_RECNUM))		F_SET(pip, VRFY_HAS_RECNUMS);	if (F_ISSET(pip, VRFY_HAS_RECNUMS) && F_ISSET(pip, VRFY_HAS_DUPS)) {		EPRINT((dbp->dbenv,    "Page %lu: Btree metadata page illegally has both recnums and dups",		    (u_long)pgno));		isbad = 1;	}	if (F_ISSET(&meta->dbmeta, BTM_RECNO)) {		F_SET(pip, VRFY_IS_RECNO);		dbp->type = DB_RECNO;	} else if (F_ISSET(pip, VRFY_IS_RRECNO)) {		isbad = 1;		EPRINT((dbp->dbenv,    "Page %lu: metadata page has renumber flag set but is not recno",		    (u_long)pgno));	}	if (F_ISSET(pip, VRFY_IS_RECNO) && F_ISSET(pip, VRFY_HAS_DUPS)) {		EPRINT((dbp->dbenv,		    "Page %lu: recno metadata page specifies duplicates",		    (u_long)pgno));		isbad = 1;	}	if (F_ISSET(&meta->dbmeta, BTM_FIXEDLEN))		F_SET(pip, VRFY_IS_FIXEDLEN);	else if (pip->re_len > 0) {		/*		 * It's wrong to have an re_len if it's not a fixed-length		 * database		 */		isbad = 1;		EPRINT((dbp->dbenv,		    "Page %lu: re_len of %lu in non-fixed-length database",		    (u_long)pgno, (u_long)pip->re_len));	}	/*	 * We do not check that the rest of the page is 0, because it may	 * not be and may still be correct.	 */err:	if ((t_ret =	    __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0)		ret = t_ret;	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);}/* * __ram_vrfy_leaf -- *	Verify a recno leaf page. * * PUBLIC: int __ram_vrfy_leaf __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, * PUBLIC:     u_int32_t)); */int__ram_vrfy_leaf(dbp, vdp, h, pgno, flags)	DB *dbp;	VRFY_DBINFO *vdp;	PAGE *h;	db_pgno_t pgno;	u_int32_t flags;{	BKEYDATA *bk;	VRFY_PAGEINFO *pip;	db_indx_t i;	int ret, t_ret, isbad;	u_int32_t re_len_guess, len;	isbad = 0;	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)		return (ret);	if ((ret = __db_fchk(dbp->dbenv,	    "__ram_vrfy_leaf", flags, OKFLAGS)) != 0)		goto err;	if (TYPE(h) != P_LRECNO) {		/* We should not have been called. */		TYPE_ERR_PRINT(dbp->dbenv, "__ram_vrfy_leaf", pgno, TYPE(h));		DB_ASSERT(0);		ret = EINVAL;		goto err;	}	/*	 * Verify (and, if relevant, save off) page fields common to	 * all PAGEs.	 */	if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) {		if (ret == DB_VERIFY_BAD)			isbad = 1;		else			goto err;	}	/*	 * Verify inp[].  Return immediately if it returns DB_VERIFY_BAD;	 * further checks are dangerous.	 */	if ((ret = __bam_vrfy_inp(dbp,	    vdp, h, pgno, &pip->entries, flags)) != 0)		goto err;	if (F_ISSET(pip, VRFY_HAS_DUPS)) {		EPRINT((dbp->dbenv,		    "Page %lu: Recno database has dups", (u_long)pgno));		ret = DB_VERIFY_BAD;		goto err;	}	/*	 * Walk through inp and see if the lengths of all the records are the	 * same--if so, this may be a fixed-length database, and we want to	 * save off this value.  We know inp to be safe if we've gotten this	 * far.	 */	re_len_guess = 0;	for (i = 0; i < NUM_ENT(h); i++) {		bk = GET_BKEYDATA(dbp, h, i);		/* KEYEMPTY.  Go on. */		if (B_DISSET(bk->type))			continue;		if (bk->type == B_OVERFLOW)			len = ((BOVERFLOW *)bk)->tlen;		else if (bk->type == B_KEYDATA)			len = bk->len;		else {			isbad = 1;			EPRINT((dbp->dbenv,			    "Page %lu: nonsensical type for item %lu",			    (u_long)pgno, (u_long)i));			continue;		}		if (re_len_guess == 0)			re_len_guess = len;		/*		 * Is this item's len the same as the last one's?  If not,		 * reset to 0 and break--we don't have a single re_len.		 * Otherwise, go on to the next item.		 */		if (re_len_guess != len) {			re_len_guess = 0;			break;		}	}	pip->re_len = re_len_guess;	/* Save off record count. */	pip->rec_cnt = NUM_ENT(h);err:	if ((t_ret =	    __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0)		ret = t_ret;	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);}/* * __bam_vrfy -- *	Verify a btree leaf or internal page. * * PUBLIC: int __bam_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, * PUBLIC:     u_int32_t)); */int__bam_vrfy(dbp, vdp, h, pgno, flags)	DB *dbp;	VRFY_DBINFO *vdp;	PAGE *h;	db_pgno_t pgno;	u_int32_t flags;{	VRFY_PAGEINFO *pip;	int ret, t_ret, isbad;	isbad = 0;	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)		return (ret);	switch (TYPE(h)) {	case P_IBTREE:	case P_IRECNO:	case P_LBTREE:	case P_LDUP:		break;	default:		TYPE_ERR_PRINT(dbp->dbenv, "__bam_vrfy", pgno, TYPE(h));		DB_ASSERT(0);		ret = EINVAL;		goto err;	}	/*	 * Verify (and, if relevant, save off) page fields common to	 * all PAGEs.	 */	if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) {		if (ret == DB_VERIFY_BAD)			isbad = 1;		else			goto err;	}	/*	 * The record count is, on internal pages, stored in an overloaded	 * next_pgno field.  Save it off;  we'll verify it when we check	 * overall database structure.  We could overload the field	 * in VRFY_PAGEINFO, too, but this seems gross, and space	 * is not at such a premium.	 */	pip->rec_cnt = RE_NREC(h);	/*	 * Verify inp[].	 */	if (TYPE(h) == P_IRECNO) {		if ((ret = __ram_vrfy_inp(dbp,		    vdp, h, pgno, &pip->entries, flags)) != 0)			goto err;	} else if ((ret = __bam_vrfy_inp(dbp,	    vdp, h, pgno, &pip->entries, flags)) != 0) {		if (ret == DB_VERIFY_BAD)			isbad = 1;		else			goto err;		EPRINT((dbp->dbenv,		    "Page %lu: item order check unsafe: skipping",		    (u_long)pgno));	} else if (!LF_ISSET(DB_NOORDERCHK) && (ret =	    __bam_vrfy_itemorder(dbp, vdp, h, pgno, 0, 0, 0, flags)) != 0) {		/*		 * We know that the elements of inp are reasonable.		 *		 * Check that elements fall in the proper order.		 */		if (ret == DB_VERIFY_BAD)			isbad = 1;		else			goto err;	}err:	if ((t_ret =	    __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0)		ret = t_ret;	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);}/* * __ram_vrfy_inp -- *	Verify that all entries in a P_IRECNO inp[] array are reasonable, *	and count them.  Note that P_LRECNO uses __bam_vrfy_inp; *	P_IRECNOs are a special, and simpler, case, since they have *	RINTERNALs rather than BKEYDATA/BINTERNALs. */static int__ram_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags)	DB *dbp;	VRFY_DBINFO *vdp;	PAGE *h;	db_pgno_t pgno;	db_indx_t *nentriesp;	u_int32_t flags;{	RINTERNAL *ri;	VRFY_CHILDINFO child;	VRFY_PAGEINFO *pip;	int ret, t_ret, isbad;	u_int32_t himark, i, offset, nentries;	db_indx_t *inp;	u_int8_t *pagelayout, *p;	isbad = 0;	memset(&child, 0, sizeof(VRFY_CHILDINFO));	nentries = 0;	pagelayout = NULL;	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)		return (ret);	if (TYPE(h) != P_IRECNO) {		TYPE_ERR_PRINT(dbp->dbenv, "__ram_vrfy_inp", pgno, TYPE(h));		DB_ASSERT(0);		ret = EINVAL;		goto err;	}	himark = dbp->pgsize;	if ((ret =	    __os_malloc(dbp->dbenv, dbp->pgsize, &pagelayout)) != 0)		goto err;	memset(pagelayout, 0, dbp->pgsize);	inp = P_INP(dbp, h);	for (i = 0; i < NUM_ENT(h); i++) {		if ((u_int8_t *)inp + i >= (u_int8_t *)h + himark) {			EPRINT((dbp->dbenv,			    "Page %lu: entries listing %lu overlaps data",			    (u_long)pgno, (u_long)i));			ret = DB_VERIFY_BAD;			goto err;		}		offset = inp[i];		/*		 * Check that the item offset is reasonable:  it points		 * somewhere after the inp array and before the end of the		 * page.		 */		if (offset <= (u_int32_t)((u_int8_t *)inp + i -		    (u_int8_t *)h) ||		    offset > (u_int32_t)(dbp->pgsize - RINTERNAL_SIZE)) {			isbad = 1;			EPRINT((dbp->dbenv,			    "Page %lu: bad offset %lu at index %lu",			    (u_long)pgno, (u_long)offset, (u_long)i));			continue;		}		/* Update the high-water mark (what HOFFSET should be) */		if (offset < himark)			himark = offset;		nentries++;		/* Make sure this RINTERNAL is not multiply referenced. */		ri = GET_RINTERNAL(dbp, h, i);		if (pagelayout[offset] == 0) {			pagelayout[offset] = 1;			child.pgno = ri->pgno;			child.type = V_RECNO;			child.nrecs = ri->nrecs;			if ((ret = __db_vrfy_childput(vdp, pgno, &child)) != 0)				goto err;		} else {			EPRINT((dbp->dbenv,		"Page %lu: RINTERNAL structure at offset %lu referenced twice",			    (u_long)pgno, (u_long)offset));			isbad = 1;		}	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -