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

📄 db_vrfy.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
		else {			isbad = 1;			EPRINT((dbenv,			    "Page %lu: bad magic number %lu",			    (u_long)PGNO_BASE_MD, (u_long)meta->magic));		}	}	/*	 * 16-19: Version.  Must be current;  for now, we	 * don't support verification of old versions.	 */	if (swapped)		M_32_SWAP(meta->version);	if ((dbp->type == DB_BTREE &&	    (meta->version > DB_BTREEVERSION ||	    meta->version < DB_BTREEOLDVER)) ||	    (dbp->type == DB_HASH &&	    (meta->version > DB_HASHVERSION ||	    meta->version < DB_HASHOLDVER)) ||	    (dbp->type == DB_QUEUE &&	    (meta->version > DB_QAMVERSION ||	    meta->version < DB_QAMOLDVER))) {		isbad = 1;		EPRINT((dbenv,    "Page %lu: unsupported DB version %lu; extraneous errors may result",		    (u_long)PGNO_BASE_MD, (u_long)meta->version));	}	/*	 * 20-23: Pagesize.  Must be power of two,	 * greater than 512, and less than 64K.	 */	if (swapped)		M_32_SWAP(meta->pagesize);	if (IS_VALID_PAGESIZE(meta->pagesize))		dbp->pgsize = meta->pagesize;	else {		isbad = 1;		EPRINT((dbenv, "Page %lu: bad page size %lu",		    (u_long)PGNO_BASE_MD, (u_long)meta->pagesize));		/*		 * Now try to settle on a pagesize to use.		 * If the user-supplied one is reasonable,		 * use it;  else, guess.		 */		if (!IS_VALID_PAGESIZE(dbp->pgsize))			dbp->pgsize = __db_guesspgsize(dbenv, fhp);	}	/*	 * 25: Page type.  Must be correct for dbp->type,	 * which is by now set as well as it can be.	 */	/* Needs no swapping--only one byte! */	if ((dbp->type == DB_BTREE && meta->type != P_BTREEMETA) ||	    (dbp->type == DB_HASH && meta->type != P_HASHMETA) ||	    (dbp->type == DB_QUEUE && meta->type != P_QAMMETA)) {		isbad = 1;		EPRINT((dbenv, "Page %lu: bad page type %lu",		    (u_long)PGNO_BASE_MD, (u_long)meta->type));	}	/*	 * 28-31: Free list page number.	 * We'll verify its sensibility when we do inter-page	 * verification later;  for now, just store it.	 */	if (swapped)	    M_32_SWAP(meta->free);	freelist = meta->free;	/*	 * Initialize vdp->pages to fit a single pageinfo structure for	 * this one page.  We'll realloc later when we know how many	 * pages there are.	 */	if ((ret = __db_vrfy_getpageinfo(vdp, PGNO_BASE_MD, &pip)) != 0)		return (ret);	pip->pgno = PGNO_BASE_MD;	pip->type = meta->type;	/*	 * Signal that we still have to check the info specific to	 * a given type of meta page.	 */	F_SET(pip, VRFY_INCOMPLETE);	pip->free = freelist;	if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0)		return (ret);	/* Set up the dbp's fileid.  We don't use the regular open path. */	memcpy(dbp->fileid, meta->uid, DB_FILE_ID_LEN);	if (swapped == 1)		F_SET(dbp, DB_AM_SWAP);	return (isbad ? DB_VERIFY_BAD : 0);}/* * __db_vrfy_walkpages -- *	Main loop of the verifier/salvager.  Walks through, *	page by page, and verifies all pages and/or prints all data pages. */static int__db_vrfy_walkpages(dbp, vdp, handle, callback, flags)	DB *dbp;	VRFY_DBINFO *vdp;	void *handle;	int (*callback) __P((void *, const void *));	u_int32_t flags;{	DB_ENV *dbenv;	DB_MPOOLFILE *mpf;	PAGE *h;	db_pgno_t i;	int ret, t_ret, isbad;	dbenv = dbp->dbenv;	mpf = dbp->mpf;	ret = isbad = t_ret = 0;	if ((ret = __db_fchk(dbenv,	    "__db_vrfy_walkpages", flags, OKFLAGS)) != 0)		return (ret);	for (i = 0; i <= vdp->last_pgno; i++) {		/*		 * If DB_SALVAGE is set, we inspect our database of		 * completed pages, and skip any we've already printed in		 * the subdb pass.		 */		if (LF_ISSET(DB_SALVAGE) && (__db_salvage_isdone(vdp, i) != 0))			continue;		/*		 * If an individual page get fails, keep going if and only		 * if we're salvaging.		 */		if ((t_ret = mpf->get(mpf, &i, 0, &h)) != 0) {			if (ret == 0)				ret = t_ret;			if (LF_ISSET(DB_SALVAGE))				continue;			else				return (ret);		}		if (LF_ISSET(DB_SALVAGE)) {			/*			 * We pretty much don't want to quit unless a			 * bomb hits.  May as well return that something			 * was screwy, however.			 */			if ((t_ret = __db_salvage(dbp,			    vdp, i, h, handle, callback, flags)) != 0) {				if (ret == 0)					ret = t_ret;				isbad = 1;			}		} else {			/*			 * If we are not salvaging, and we get any error			 * other than DB_VERIFY_BAD, return immediately;			 * it may not be safe to proceed.  If we get			 * DB_VERIFY_BAD, keep going;  listing more errors			 * may make it easier to diagnose problems and			 * determine the magnitude of the corruption.			 */			/*			 * Verify info common to all page			 * types.			 */			if (i != PGNO_BASE_MD) {				ret = __db_vrfy_common(dbp, vdp, h, i, flags);				if (ret == DB_VERIFY_BAD)					isbad = 1;				else if (ret != 0)					goto err;			}			switch (TYPE(h)) {			case P_INVALID:				ret = __db_vrfy_invalid(dbp, vdp, h, i, flags);				break;			case __P_DUPLICATE:				isbad = 1;				EPRINT((dbenv,				    "Page %lu: old-style duplicate page",				    (u_long)i));				break;			case P_HASH:				ret = __ham_vrfy(dbp,				    vdp, h, i, flags);				break;			case P_IBTREE:			case P_IRECNO:			case P_LBTREE:			case P_LDUP:				ret = __bam_vrfy(dbp,				    vdp, h, i, flags);				break;			case P_LRECNO:				ret = __ram_vrfy_leaf(dbp,				    vdp, h, i, flags);				break;			case P_OVERFLOW:				ret = __db_vrfy_overflow(dbp,				    vdp, h, i, flags);				break;			case P_HASHMETA:				ret = __ham_vrfy_meta(dbp,				    vdp, (HMETA *)h, i, flags);				break;			case P_BTREEMETA:				ret = __bam_vrfy_meta(dbp,				    vdp, (BTMETA *)h, i, flags);				break;			case P_QAMMETA:				ret = __qam_vrfy_meta(dbp,				    vdp, (QMETA *)h, i, flags);				break;			case P_QAMDATA:				ret = __qam_vrfy_data(dbp,				    vdp, (QPAGE *)h, i, flags);				break;			default:				EPRINT((dbenv,				    "Page %lu: unknown page type %lu",				    (u_long)i, (u_long)TYPE(h)));				isbad = 1;				break;			}			/*			 * Set up error return.			 */			if (ret == DB_VERIFY_BAD)				isbad = 1;			else if (ret != 0)				goto err;			/*			 * Provide feedback to the application about our			 * progress.  The range 0-50% comes from the fact			 * that this is the first of two passes through the			 * database (front-to-back, then top-to-bottom).			 */			if (dbp->db_feedback != NULL)				dbp->db_feedback(dbp, DB_VERIFY,				    (i + 1) * 50 / (vdp->last_pgno + 1));		}		/*		 * Just as with the page get, bail if and only if we're		 * not salvaging.		 */		if ((t_ret = mpf->put(mpf, h, 0)) != 0) {			if (ret == 0)				ret = t_ret;			if (!LF_ISSET(DB_SALVAGE))				return (ret);		}	}	if (0) {err:		if ((t_ret = mpf->put(mpf, h, 0)) != 0)			return (ret == 0 ? t_ret : ret);	}	return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);}/* * __db_vrfy_structure-- *	After a beginning-to-end walk through the database has been *	completed, put together the information that has been collected *	to verify the overall database structure. * *	Should only be called if we want to do a database verification, *	i.e. if DB_SALVAGE is not set. */static int__db_vrfy_structure(dbp, vdp, dbname, meta_pgno, flags)	DB *dbp;	VRFY_DBINFO *vdp;	const char *dbname;	db_pgno_t meta_pgno;	u_int32_t flags;{	DB *pgset;	DB_ENV *dbenv;	VRFY_PAGEINFO *pip;	db_pgno_t i;	int ret, isbad, hassubs, p;	isbad = 0;	pip = NULL;	dbenv = dbp->dbenv;	pgset = vdp->pgset;	if ((ret = __db_fchk(dbenv, "DB->verify", flags, OKFLAGS)) != 0)		return (ret);	if (LF_ISSET(DB_SALVAGE)) {		__db_err(dbenv, "__db_vrfy_structure called with DB_SALVAGE");		return (EINVAL);	}	/*	 * Providing feedback here is tricky;  in most situations,	 * we fetch each page one more time, but we do so in a top-down	 * order that depends on the access method.  Worse, we do this	 * recursively in btree, such that on any call where we're traversing	 * a subtree we don't know where that subtree is in the whole database;	 * worse still, any given database may be one of several subdbs.	 *	 * The solution is to decrement a counter vdp->pgs_remaining each time	 * we verify (and call feedback on) a page.  We may over- or	 * under-count, but the structure feedback function will ensure that we	 * never give a percentage under 50 or over 100.  (The first pass	 * covered the range 0-50%.)	 */	if (dbp->db_feedback != NULL)		vdp->pgs_remaining = vdp->last_pgno + 1;	/*	 * Call the appropriate function to downwards-traverse the db type.	 */	switch(dbp->type) {	case DB_BTREE:	case DB_RECNO:		if ((ret = __bam_vrfy_structure(dbp, vdp, 0, flags)) != 0) {			if (ret == DB_VERIFY_BAD)				isbad = 1;			else				goto err;		}		/*		 * If we have subdatabases and we know that the database is,		 * thus far, sound, it's safe to walk the tree of subdatabases.		 * Do so, and verify the structure of the databases within.		 */		if ((ret = __db_vrfy_getpageinfo(vdp, 0, &pip)) != 0)			goto err;		hassubs = F_ISSET(pip, VRFY_HAS_SUBDBS) ? 1 : 0;		if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0)			goto err;		if (isbad == 0 && hassubs)			if ((ret =			    __db_vrfy_subdbs(dbp, vdp, dbname, flags)) != 0) {				if (ret == DB_VERIFY_BAD)					isbad = 1;				else					goto err;			}		break;	case DB_HASH:		if ((ret = __ham_vrfy_structure(dbp, vdp, 0, flags)) != 0) {			if (ret == DB_VERIFY_BAD)				isbad = 1;			else				goto err;		}		break;	case DB_QUEUE:		if ((ret = __qam_vrfy_structure(dbp, vdp, flags)) != 0) {			if (ret == DB_VERIFY_BAD)				isbad = 1;		}		/*		 * Queue pages may be unreferenced and totally zeroed, if		 * they're empty;  queue doesn't have much structure, so		 * this is unlikely to be wrong in any troublesome sense.		 * Skip to "err".		 */		goto err;		/* NOTREACHED */	default:		/* This should only happen if the verifier is somehow broken. */		DB_ASSERT(0);		ret = EINVAL;		goto err;		/* NOTREACHED */	}	/* Walk free list. */	if ((ret =	    __db_vrfy_freelist(dbp, vdp, meta_pgno, flags)) == DB_VERIFY_BAD)		isbad = 1;	/*	 * If structure checks up until now have failed, it's likely that	 * checking what pages have been missed will result in oodles of	 * extraneous error messages being EPRINTed.  Skip to the end	 * if this is the case;  we're going to be printing at least one	 * error anyway, and probably all the more salient ones.	 */	if (ret != 0 || isbad == 1)		goto err;	/*	 * Make sure no page has been missed and that no page is still marked	 * "all zeroes" (only certain hash pages can be, and they're unmarked	 * in __ham_vrfy_structure).	 */	for (i = 0; i < vdp->last_pgno + 1; i++) {		if ((ret = __db_vrfy_getpageinfo(vdp, i, &pip)) != 0)			goto err;		if ((ret = __db_vrfy_pgset_get(pgset, i, &p)) != 0)			goto err;		if (p == 0) {			EPRINT((dbenv,			    "Page %lu: unreferenced page", (u_long)i));			isbad = 1;		}		if (F_ISSET(pip, VRFY_IS_ALLZEROES)) {			EPRINT((dbenv,			    "Page %lu: totally zeroed page", (u_long)i));			isbad = 1;		}		if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0)			goto err;		pip = NULL;	}err:	if (pip != NULL)		(void)__db_vrfy_putpageinfo(dbenv, vdp, pip);	return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);}/* * __db_is_valid_pagetype */static int__db_is_valid_pagetype(type)	u_int32_t type;{	switch (type) {	case P_INVALID:			/* Order matches ordinal value. */	case P_HASH:	case P_IBTREE:	case P_IRECNO:	case P_LBTREE:	case P_LRECNO:	case P_OVERFLOW:	case P_HASHMETA:	case P_BTREEMETA:	case P_QAMMETA:	case P_QAMDATA:	case P_LDUP:		return (1);	}	return (0);}/* * __db_is_valid_magicno */static int__db_is_valid_magicno(magic, typep)	u_int32_t magic;	DBTYPE *typep;{	switch (magic) {	case DB_BTREEMAGIC:		*typep = DB_BTREE;		return (1);	case DB_HASHMAGIC:		*typep = DB_HASH;		return (1);	case DB_QAMMAGIC:		*typep = DB_QUEUE;		return (1);	}	*typep = DB_UNKNOWN;	return (0);}/* * __db_vrfy_common -- *	Verify info common to all page types. */static int

⌨️ 快捷键说明

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