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

📄 dbreg_util.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1997-2002 *	Sleepycat Software.  All rights reserved. */#include "db_config.h"#ifndef lintstatic const char revid[] = "$Id: dbreg_util.c,v 11.22 2002/09/10 02:43:10 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_am.h"#include "dbinc/log.h"#include "dbinc/txn.h"static int __dbreg_check_master __P((DB_ENV *, u_int8_t *, char *));/* * __dbreg_add_dbentry -- *	Adds a DB entry to the dbreg DB entry table. * * PUBLIC: int __dbreg_add_dbentry __P((DB_ENV *, DB_LOG *, DB *, int32_t)); */int__dbreg_add_dbentry(dbenv, dblp, dbp, ndx)	DB_ENV *dbenv;	DB_LOG *dblp;	DB *dbp;	int32_t ndx;{	int32_t i;	int ret;	ret = 0;	MUTEX_THREAD_LOCK(dbenv, dblp->mutexp);	/*	 * Check if we need to grow the table.  Note, ndx is 0-based (the	 * index into the DB entry table) an dbentry_cnt is 1-based, the	 * number of available slots.	 */	if (dblp->dbentry_cnt <= ndx) {		if ((ret = __os_realloc(dbenv,		    (ndx + DB_GROW_SIZE) * sizeof(DB_ENTRY),		    &dblp->dbentry)) != 0)			goto err;		/* Initialize the new entries. */		for (i = dblp->dbentry_cnt; i < ndx + DB_GROW_SIZE; i++) {			dblp->dbentry[i].dbp = NULL;			dblp->dbentry[i].deleted = 0;		}		dblp->dbentry_cnt = i;	}	DB_ASSERT(dblp->dbentry[ndx].dbp == NULL);	dblp->dbentry[ndx].deleted = dbp == NULL;	dblp->dbentry[ndx].dbp = dbp;err:	MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);	return (ret);}/* * __dbreg_rem_dbentry *	Remove an entry from the DB entry table. * * PUBLIC: void __dbreg_rem_dbentry __P((DB_LOG *, int32_t)); */void__dbreg_rem_dbentry(dblp, ndx)	DB_LOG *dblp;	int32_t ndx;{	MUTEX_THREAD_LOCK(dblp->dbenv, dblp->mutexp);	dblp->dbentry[ndx].dbp = NULL;	dblp->dbentry[ndx].deleted = 0;	MUTEX_THREAD_UNLOCK(dblp->dbenv, dblp->mutexp);}/* * __dbreg_open_files -- *	Put a LOG_CHECKPOINT log record for each open database. * * PUBLIC: int __dbreg_open_files __P((DB_ENV *)); */int__dbreg_open_files(dbenv)	DB_ENV *dbenv;{	DB_LOG *dblp;	DB_LSN r_unused;	DBT *dbtp, fid_dbt, t;	FNAME *fnp;	LOG *lp;	int ret;	dblp = dbenv->lg_handle;	lp = dblp->reginfo.primary;	ret = 0;	MUTEX_LOCK(dbenv, &lp->fq_mutex);	for (fnp = SH_TAILQ_FIRST(&lp->fq, __fname);	    fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {		if (fnp->name_off == INVALID_ROFF)			dbtp = NULL;		else {			memset(&t, 0, sizeof(t));			t.data = R_ADDR(&dblp->reginfo, fnp->name_off);			t.size = (u_int32_t)strlen(t.data) + 1;			dbtp = &t;		}		memset(&fid_dbt, 0, sizeof(fid_dbt));		fid_dbt.data = fnp->ufid;		fid_dbt.size = DB_FILE_ID_LEN;		/*		 * Output LOG_CHECKPOINT records which will be		 * processed during the OPENFILES pass of recovery.		 * At the end of recovery we want to output the		 * files that were open so that a future recovery		 * run will have the correct files open during		 * a backward pass.  For this we output LOG_RCLOSE		 * records so that the files will be closed on		 * the forward pass.		 */		if ((ret = __dbreg_register_log(dbenv,		    NULL, &r_unused, 0,		    F_ISSET(dblp, DBLOG_RECOVER) ? LOG_RCLOSE : LOG_CHECKPOINT,		    dbtp, &fid_dbt, fnp->id, fnp->s_type, fnp->meta_pgno,		    TXN_INVALID)) != 0)			break;	}	MUTEX_UNLOCK(dbenv, &lp->fq_mutex);	return (ret);}/* * __dbreg_close_files -- *	Close files that were opened by the recovery daemon.  We sync the *	file, unless its mpf pointer has been NULLed by a db_remove or *	db_rename.  We may not have flushed the log_register record that *	closes the file. * * PUBLIC: int __dbreg_close_files __P((DB_ENV *)); */int__dbreg_close_files(dbenv)	DB_ENV *dbenv;{	DB_LOG *dblp;	DB *dbp;	int ret, t_ret;	int32_t i;	/* If we haven't initialized logging, we have nothing to do. */	if (!LOGGING_ON(dbenv))		return (0);	dblp = dbenv->lg_handle;	ret = 0;	MUTEX_THREAD_LOCK(dbenv, dblp->mutexp);	for (i = 0; i < dblp->dbentry_cnt; i++) {		/* We only want to close dbps that recovery opened. */		if ((dbp = dblp->dbentry[i].dbp) != NULL &&		    F_ISSET(dbp, DB_AM_RECOVER)) {			/*			 * It's unsafe to call DB->close while holding the			 * thread lock, because we'll call __dbreg_rem_dbentry			 * and grab it again.			 *			 * Just drop it.  Since dbreg ids go monotonically			 * upward, concurrent opens should be safe, and the			 * user should have no business closing files while			 * we're in this loop anyway--we're in the process of			 * making all outstanding dbps invalid.			 */			MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);			if ((t_ret = dbp->close(dbp,			    dbp->mpf == NULL ? DB_NOSYNC : 0)) != 0 && ret == 0)				ret = t_ret;			MUTEX_THREAD_LOCK(dbenv, dblp->mutexp);		}		dblp->dbentry[i].deleted = 0;		dblp->dbentry[i].dbp = NULL;	}	MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);	return (ret);}/* * __dbreg_nofiles -- *	Check that there are no open files in the process local table. *	Returns 0 if there are no files and EINVAL if there are any. * * PUBLIC: int __dbreg_nofiles __P((DB_ENV *)); */int__dbreg_nofiles(dbenv)	DB_ENV *dbenv;{	DB *dbp;	DB_LOG *dblp;	int ret;	int32_t i;	/* If we haven't initialized logging, we have nothing to do. */	if (!LOGGING_ON(dbenv))		return (0);	dblp = dbenv->lg_handle;	ret = 0;	MUTEX_THREAD_LOCK(dbenv, dblp->mutexp);	for (i = 0; i < dblp->dbentry_cnt; i++) {		if ((dbp = dblp->dbentry[i].dbp) != NULL &&		    !F_ISSET(dbp, DB_AM_RECOVER)) {			ret = EINVAL;			break;		}	}	MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);	return (ret);}/* * __dbreg_id_to_db -- *	Return the DB corresponding to the specified dbreg id. * * PUBLIC: int __dbreg_id_to_db __P((DB_ENV *, DB_TXN *, DB **, int32_t, int)); */int__dbreg_id_to_db(dbenv, txn, dbpp, ndx, inc)	DB_ENV *dbenv;	DB_TXN *txn;	DB **dbpp;	int32_t ndx;	int inc;{	return (__dbreg_id_to_db_int(dbenv, txn, dbpp, ndx, inc, 1));}/* * __dbreg_id_to_db_int -- *	Return the DB corresponding to the specified dbreg id.  The internal * version takes a final parameter that indicates whether we should attempt * to open the file if no mapping is found.  During recovery, the recovery * routines all want to try to open the file (and this is called from * __dbreg_id_to_db), however, if we have a multi-process environment where * some processes may not have the files open (e.g., XA), then we also get * called from __dbreg_assign_id and it's OK if there is no mapping. * * PUBLIC: int __dbreg_id_to_db_int __P((DB_ENV *, * PUBLIC:     DB_TXN *, DB **, int32_t, int, int)); */int__dbreg_id_to_db_int(dbenv, txn, dbpp, ndx, inc, tryopen)	DB_ENV *dbenv;	DB_TXN *txn;	DB **dbpp;	int32_t ndx;	int inc, tryopen;{	DB_LOG *dblp;	FNAME *fname;	int ret;	char *name;	ret = 0;	dblp = dbenv->lg_handle;	COMPQUIET(inc, 0);	MUTEX_THREAD_LOCK(dbenv, dblp->mutexp);	/*	 * Under XA, a process different than the one issuing DB operations	 * may abort a transaction.  In this case, the "recovery" routines	 * are run by a process that does not necessarily have the file open,	 * so we we must open the file explicitly.	 */	if (ndx >= dblp->dbentry_cnt ||	    (!dblp->dbentry[ndx].deleted && dblp->dbentry[ndx].dbp == NULL)) {		if (!tryopen || F_ISSET(dblp, DBLOG_RECOVER)) {			ret = ENOENT;			goto err;		}		/*		 * __dbreg_id_to_fname acquires the region's fq_mutex,		 * which we can't safely acquire while we hold the thread lock.		 * We no longer need it anyway--the dbentry table didn't		 * have what we needed.		 */		MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);		if (__dbreg_id_to_fname(dblp, ndx, 0, &fname) != 0)			/*			 * With transactional opens, we may actually have			 * closed this file in the transaction in which			 * case this will fail too.  Then it's up to the			 * caller to reopen the file.			 */			return (ENOENT);		/*		 * Note that we're relying on fname not to change, even		 * though we released the mutex that protects it (fq_mutex)		 * inside __dbreg_id_to_fname.  This should be a safe		 * assumption, because the other process that has the file		 * open shouldn't be closing it while we're trying to abort.		 */		name = R_ADDR(&dblp->reginfo, fname->name_off);		/*		 * At this point, we are not holding the thread lock, so exit		 * directly instead of going through the exit code at the		 * bottom.  If the __dbreg_do_open succeeded, then we don't need		 * to do any of the remaining error checking at the end of this		 * routine.		 * XXX I am sending a NULL txnlist and 0 txnid which may be		 * completely broken ;(		 */		if ((ret = __dbreg_do_open(dbenv, txn, dblp,		    fname->ufid, name, fname->s_type,		    ndx, fname->meta_pgno, NULL, 0)) != 0)			return (ret);		*dbpp = dblp->dbentry[ndx].dbp;		return (0);	}	/*	 * Return DB_DELETED if the file has been deleted (it's not an error).	 */	if (dblp->dbentry[ndx].deleted) {		ret = DB_DELETED;		goto err;	}	/* It's an error if we don't have a corresponding writeable DB. */	if ((*dbpp = dblp->dbentry[ndx].dbp) == NULL)		ret = ENOENT;err:	MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);	return (ret);}/* * __dbreg_id_to_fname -- *	Traverse the shared-memory region looking for the entry that *	matches the passed dbreg id.  Returns 0 on success; -1 on error. * * PUBLIC: int __dbreg_id_to_fname __P((DB_LOG *, int32_t, int, FNAME **)); */int__dbreg_id_to_fname(dblp, lid, have_lock, fnamep)	DB_LOG *dblp;	int32_t lid;	int have_lock;	FNAME **fnamep;{	DB_ENV *dbenv;	FNAME *fnp;	LOG *lp;	int ret;	dbenv = dblp->dbenv;	lp = dblp->reginfo.primary;	ret = -1;	if (!have_lock)		MUTEX_LOCK(dbenv, &lp->fq_mutex);	for (fnp = SH_TAILQ_FIRST(&lp->fq, __fname);	    fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {		if (fnp->id == lid) {			*fnamep = fnp;			ret = 0;			break;		}	}	if (!have_lock)		MUTEX_UNLOCK(dbenv, &lp->fq_mutex);	return (ret);}/*

⌨️ 快捷键说明

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