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

📄 env_open.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1996-2004 *	Sleepycat Software.  All rights reserved. * * $Id: env_open.c,v 11.177 2004/07/17 18:55:08 ubell Exp $ */#include "db_config.h"#ifndef NO_SYSTEM_INCLUDES#include <sys/types.h>#include <ctype.h>#include <limits.h>#include <stdlib.h>#include <string.h>#endif#include "db_int.h"#include "dbinc/crypto.h"#include "dbinc/db_page.h"#include "dbinc/db_shash.h"#include "dbinc/btree.h"#include "dbinc/hash.h"#include "dbinc/fop.h"#include "dbinc/lock.h"#include "dbinc/log.h"#include "dbinc/mp.h"#include "dbinc/qam.h"#include "dbinc/txn.h"static int __db_parse __P((DB_ENV *, char *));static int __db_tmp_open __P((DB_ENV *, u_int32_t, char *, DB_FH **));static int __dbenv_config __P((DB_ENV *, const char *, u_int32_t));static int __dbenv_refresh __P((DB_ENV *, u_int32_t, int));static int __dbenv_remove_int __P((DB_ENV *, const char *, u_int32_t));/* * db_version -- *	Return version information. * * EXTERN: char *db_version __P((int *, int *, int *)); */char *db_version(majverp, minverp, patchp)	int *majverp, *minverp, *patchp;{	if (majverp != NULL)		*majverp = DB_VERSION_MAJOR;	if (minverp != NULL)		*minverp = DB_VERSION_MINOR;	if (patchp != NULL)		*patchp = DB_VERSION_PATCH;	return ((char *)DB_VERSION_STRING);}/* * __dbenv_open -- *	DB_ENV->open. * * PUBLIC: int __dbenv_open __P((DB_ENV *, const char *, u_int32_t, int)); */int__dbenv_open(dbenv, db_home, flags, mode)	DB_ENV *dbenv;	const char *db_home;	u_int32_t flags;	int mode;{	DB_MPOOL *dbmp;	u_int32_t init_flags, orig_flags;	int rep_check, ret;	orig_flags = dbenv->flags;	rep_check = 0;#undef	OKFLAGS#define	OKFLAGS								\	(DB_CREATE | DB_INIT_CDB | DB_INIT_LOCK | DB_INIT_LOG |		\	DB_INIT_MPOOL | DB_INIT_REP | DB_INIT_TXN | DB_JOINENV |	\	DB_LOCKDOWN | DB_PRIVATE | DB_RECOVER | DB_RECOVER_FATAL |	\	DB_SYSTEM_MEM |	DB_THREAD | DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)#undef	OKFLAGS_CDB#define	OKFLAGS_CDB							\	(DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL | DB_LOCKDOWN |	\	DB_PRIVATE | DB_SYSTEM_MEM | DB_THREAD |			\	DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)	/*	 * Flags saved in the init_flags field of the environment, representing	 * flags to DB_ENV->set_flags and DB_ENV->open that need to be set.	 */#define	DB_INITENV_CDB		0x0001	/* DB_INIT_CDB */#define	DB_INITENV_CDB_ALLDB	0x0002	/* DB_INIT_CDB_ALLDB */#define	DB_INITENV_LOCK		0x0004	/* DB_INIT_LOCK */#define	DB_INITENV_LOG		0x0008	/* DB_INIT_LOG */#define	DB_INITENV_MPOOL	0x0010	/* DB_INIT_MPOOL */#define	DB_INITENV_REP		0x0020	/* DB_INIT_REP */#define	DB_INITENV_TXN		0x0040	/* DB_INIT_TXN */	if ((ret = __db_fchk(dbenv, "DB_ENV->open", flags, OKFLAGS)) != 0)		return (ret);	if (LF_ISSET(DB_INIT_CDB) &&	    (ret = __db_fchk(dbenv, "DB_ENV->open", flags, OKFLAGS_CDB)) != 0)		return (ret);	if ((ret = __db_fcchk(dbenv,	    "DB_ENV->open", flags, DB_PRIVATE, DB_SYSTEM_MEM)) != 0)		return (ret);	if ((ret = __db_fcchk(dbenv,	    "DB_ENV->open", flags, DB_RECOVER, DB_RECOVER_FATAL)) != 0)		return (ret);	if ((ret = __db_fcchk(dbenv, "DB_ENV->open", flags, DB_JOINENV,	    DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL |	    DB_INIT_REP | DB_INIT_TXN |	    DB_PRIVATE | DB_RECOVER | DB_RECOVER_FATAL)) != 0)		return (ret);	if (LF_ISSET(DB_INIT_REP) && !LF_ISSET(DB_INIT_TXN)) {		__db_err(dbenv, "Replication requires transaction support");		return (EINVAL);	}	if (LF_ISSET(DB_INIT_REP) && !LF_ISSET(DB_INIT_LOCK)) {		__db_err(dbenv, "Replication requires locking support");		return (EINVAL);	}	if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) && !LF_ISSET(DB_INIT_TXN)) {		__db_err(dbenv, "Recovery requires transaction support");		return (EINVAL);	}	/*	 * Currently we support one kind of mutex that is intra-process only,	 * POSIX 1003.1 pthreads, because a variety of systems don't support	 * the full pthreads API, and our only alternative is test-and-set.	 */#ifdef HAVE_MUTEX_THREAD_ONLY	if (!LF_ISSET(DB_PRIVATE)) {		__db_err(dbenv,    "Berkeley DB library configured to support only private environments");		return (EINVAL);	}#endif	/*	 * If we're doing recovery, destroy the environment so that we create	 * all the regions from scratch.  I'd like to reuse already created	 * regions, but that's hard.  We would have to create the environment	 * region from scratch, at least, as we have no way of knowing if its	 * linked lists are corrupted.	 *	 * I suppose we could set flags while modifying those links, but that	 * is going to be difficult to get right.  The major concern I have	 * is if the application stomps the environment with a rogue pointer.	 * We have no way of detecting that, and we could be forced into a	 * situation where we start up and then crash, repeatedly.	 *	 * Note that we do not check any flags like DB_PRIVATE before calling	 * remove.  We don't care if the current environment was private or	 * not, we just want to nail any files that are left-over for whatever	 * reason, from whatever session.	 */	if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL))		if ((ret = __dbenv_remove_int(dbenv, db_home, DB_FORCE)) != 0 ||		    (ret = __dbenv_refresh(dbenv, orig_flags, 0)) != 0)			return (ret);	/* Initialize the DB_ENV structure. */	if ((ret = __dbenv_config(dbenv, db_home, flags)) != 0)		goto err;	/* Convert the DB_ENV->open flags to internal flags. */	if (LF_ISSET(DB_CREATE))		F_SET(dbenv, DB_ENV_CREATE);	if (LF_ISSET(DB_LOCKDOWN))		F_SET(dbenv, DB_ENV_LOCKDOWN);	if (LF_ISSET(DB_PRIVATE))		F_SET(dbenv, DB_ENV_PRIVATE);	if (LF_ISSET(DB_RECOVER_FATAL))		F_SET(dbenv, DB_ENV_FATAL);	if (LF_ISSET(DB_SYSTEM_MEM))		F_SET(dbenv, DB_ENV_SYSTEM_MEM);	if (LF_ISSET(DB_THREAD))		F_SET(dbenv, DB_ENV_THREAD);	/* Default permissions are read-write for both owner and group. */	dbenv->db_mode = mode == 0 ? __db_omode("rwrw--") : mode;	/*	 * Create/join the environment.  We pass in the flags that will be of	 * interest to an environment joining later; if we're not the ones to	 * do the create, we pull out whatever has been stored.	 */	init_flags = 0;	if (LF_ISSET(DB_INIT_CDB))		FLD_SET(init_flags, DB_INITENV_CDB);	if (LF_ISSET(DB_INIT_LOCK))		FLD_SET(init_flags, DB_INITENV_LOCK);	if (LF_ISSET(DB_INIT_LOG))		FLD_SET(init_flags, DB_INITENV_LOG);	if (LF_ISSET(DB_INIT_MPOOL))		FLD_SET(init_flags, DB_INITENV_MPOOL);	if (LF_ISSET(DB_INIT_REP))		FLD_SET(init_flags, DB_INITENV_REP);	if (LF_ISSET(DB_INIT_TXN))		FLD_SET(init_flags, DB_INITENV_TXN);	if (F_ISSET(dbenv, DB_ENV_CDB_ALLDB))		FLD_SET(init_flags, DB_INITENV_CDB_ALLDB);	if ((ret = __db_e_attach(dbenv, &init_flags)) != 0)		goto err;	/*	 * __db_e_attach will return the saved init_flags field, which contains	 * the DB_INIT_* flags used when the environment was created.	 *	 * Check if existing environment flags conflict with our flags.	 */	if (LF_ISSET(DB_INIT_CDB) && FLD_ISSET(init_flags, DB_INITENV_TXN)) {		__db_err(dbenv,		    "Concurrent Data Store incompatible with environment");		ret = EINVAL;		goto err;	}	if (LF_ISSET(DB_INIT_TXN) && FLD_ISSET(init_flags, DB_INITENV_CDB)) {		__db_err(dbenv,		    "Transactional Data Store incompatible with environment");		ret = EINVAL;		goto err;	}	/* If we're joining the environment, find out what we're joining. */	if (LF_ISSET(DB_JOINENV)) {		LF_CLR(DB_JOINENV);		if (FLD_ISSET(init_flags, DB_INITENV_CDB))			LF_SET(DB_INIT_CDB);		if (FLD_ISSET(init_flags, DB_INITENV_LOCK))			LF_SET(DB_INIT_LOCK);		if (FLD_ISSET(init_flags, DB_INITENV_LOG))			LF_SET(DB_INIT_LOG);		if (FLD_ISSET(init_flags, DB_INITENV_MPOOL))			LF_SET(DB_INIT_MPOOL);		if (FLD_ISSET(init_flags, DB_INITENV_REP))			LF_SET(DB_INIT_REP);		if (FLD_ISSET(init_flags, DB_INITENV_TXN))			LF_SET(DB_INIT_TXN);		if (FLD_ISSET(init_flags, DB_INITENV_CDB_ALLDB) &&		    (ret = __dbenv_set_flags(dbenv, DB_CDB_ALLDB, 1)) != 0)			goto err;	}	/*	 * Save the flags passed to create the DB_ENV->open, that is, we've	 * now replaced flags like DB_JOINENV with the flags responsible for	 * the underlying set of subsystems.	 */	dbenv->open_flags = flags;	/* Initialize for CDB product. */	if (LF_ISSET(DB_INIT_CDB)) {		LF_SET(DB_INIT_LOCK);		F_SET(dbenv, DB_ENV_CDB);	}	/*	 * Initialize the subsystems.	 *	 * Initialize the replication area first, so that we can lock out this	 * call if we're currently running recovery for replication.	 */	if (LF_ISSET(DB_INIT_REP) && (ret = __rep_open(dbenv)) != 0)		goto err;	rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0;	if (rep_check)		__env_rep_enter(dbenv);	if (LF_ISSET(DB_INIT_MPOOL))		if ((ret = __memp_open(dbenv)) != 0)			goto err;	/*	 * Initialize the ciphering area prior to any running of recovery so	 * that we can initialize the keys, etc. before recovery.	 *	 * !!!	 * This must be after the mpool init, but before the log initialization	 * because log_open may attempt to run log_recover during its open.	 */	if (LF_ISSET(DB_INIT_MPOOL | DB_INIT_LOG | DB_INIT_TXN) &&	    (ret = __crypto_region_init(dbenv)) != 0)		goto err;	/*	 * Transactions imply logging but do not imply locking.  While almost	 * all applications want both locking and logging, it would not be	 * unreasonable for a single threaded process to want transactions for	 * atomicity guarantees, but not necessarily need concurrency.	 */	if (LF_ISSET(DB_INIT_LOG | DB_INIT_TXN))		if ((ret = __log_open(dbenv)) != 0)			goto err;	if (LF_ISSET(DB_INIT_LOCK))		if ((ret = __lock_open(dbenv)) != 0)			goto err;	if (LF_ISSET(DB_INIT_TXN)) {		if ((ret = __txn_open(dbenv)) != 0)			goto err;		/*		 * If the application is running with transactions, initialize		 * the function tables.		 */		if ((ret = __bam_init_recover(dbenv, &dbenv->recover_dtab,		    &dbenv->recover_dtab_size)) != 0)			goto err;		if ((ret = __crdel_init_recover(dbenv, &dbenv->recover_dtab,		    &dbenv->recover_dtab_size)) != 0)			goto err;		if ((ret = __db_init_recover(dbenv, &dbenv->recover_dtab,		    &dbenv->recover_dtab_size)) != 0)			goto err;		if ((ret = __dbreg_init_recover(dbenv, &dbenv->recover_dtab,		    &dbenv->recover_dtab_size)) != 0)			goto err;		if ((ret = __fop_init_recover(dbenv, &dbenv->recover_dtab,		    &dbenv->recover_dtab_size)) != 0)			goto err;		if ((ret = __ham_init_recover(dbenv, &dbenv->recover_dtab,		    &dbenv->recover_dtab_size)) != 0)			goto err;		if ((ret = __qam_init_recover(dbenv, &dbenv->recover_dtab,		    &dbenv->recover_dtab_size)) != 0)			goto err;		if ((ret = __txn_init_recover(dbenv, &dbenv->recover_dtab,		    &dbenv->recover_dtab_size)) != 0)			goto err;	}	/*	 * Initialize the DB list, and its mutex as necessary.  If the env	 * handle isn't free-threaded we don't need a mutex because there	 * will never be more than a single DB handle on the list.  If the	 * mpool wasn't initialized, then we can't ever open a DB handle.	 *	 * We also need to initialize the MT mutex as necessary, so do them	 * both.  If we error, __dbenv_refresh() will clean up.	 *	 * !!!	 * This must come after the __memp_open call above because if we are	 * recording mutexes for system resources, we will do it in the mpool	 * region for environments and db handles.  So, the mpool region must	 * already be initialized.	 */	LIST_INIT(&dbenv->dblist);	if (LF_ISSET(DB_INIT_MPOOL)) {		dbmp = dbenv->mp_handle;		if (F_ISSET(dbenv, DB_ENV_THREAD)) {			if ((ret = __db_mutex_setup(			    dbenv, dbmp->reginfo, &dbenv->dblist_mutexp,			    MUTEX_ALLOC | MUTEX_THREAD)) != 0)				goto err;			if ((ret = __db_mutex_setup(			    dbenv, dbmp->reginfo, &dbenv->mt_mutexp,			    MUTEX_ALLOC | MUTEX_THREAD)) != 0)				goto err;		}		/* Register DB's pgin/pgout functions.  */		if ((ret = __memp_register(		    dbenv, DB_FTYPE_SET, __db_pgin, __db_pgout)) != 0)			return (ret);	}	/* Perform recovery for any previous run. */	if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) &&	    (ret = __db_apprec(dbenv, NULL, NULL, 1,	    LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL))) != 0)		goto err;	/*	 * If we've created the regions, are running with transactions, and did	 * not just run recovery, we need to log the fact that the transaction	 * IDs got reset.	 *	 * If we ran recovery, there may be prepared-but-not-yet-committed	 * transactions that need to be resolved.  Recovery resets the minimum	 * transaction ID and logs the reset if that's appropriate, so we	 * don't need to do anything here in the recover case.	 */	if (TXN_ON(dbenv) &&	    !F_ISSET(dbenv, DB_ENV_LOG_INMEMORY) &&	    F_ISSET((REGINFO *)dbenv->reginfo, REGION_CREATE) &&	    !LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) &&	    (ret = __txn_reset(dbenv)) != 0)		goto err;	if (rep_check)		__env_db_rep_exit(dbenv);	return (0);err:	/*	 * If we fail after creating the regions, remove them.	 *	 * !!!	 * No need to call __env_db_rep_exit, that work is done by the calls to	 * __dbenv_refresh.	 */	if (dbenv->reginfo != NULL &&	    F_ISSET((REGINFO *)dbenv->reginfo, REGION_CREATE)) {		ret = __db_panic(dbenv, ret);		/* Refresh the DB_ENV so we can use it to call remove. */		(void)__dbenv_refresh(dbenv, orig_flags, rep_check);		(void)__dbenv_remove_int(dbenv, db_home, DB_FORCE);		(void)__dbenv_refresh(dbenv, orig_flags, 0);	} else		(void)__dbenv_refresh(dbenv, orig_flags, rep_check);	return (ret);}/* * __dbenv_remove -- *	DB_ENV->remove. * * PUBLIC: int __dbenv_remove __P((DB_ENV *, const char *, u_int32_t)); */int__dbenv_remove(dbenv, db_home, flags)	DB_ENV *dbenv;	const char *db_home;	u_int32_t flags;{	int ret, t_ret;#undef	OKFLAGS#define	OKFLAGS								\	(DB_FORCE | DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)	/* Validate arguments. */	if ((ret = __db_fchk(dbenv, "DB_ENV->remove", flags, OKFLAGS)) != 0)		return (ret);	ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->remove");	ret = __dbenv_remove_int(dbenv, db_home, flags);	if ((t_ret = __dbenv_close(dbenv, 0)) != 0 && ret == 0)		ret = t_ret;	return (ret);}/* * __dbenv_remove_int --

⌨️ 快捷键说明

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