summaryrefslogtreecommitdiff
path: root/src/env/env_region.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2015-02-17 17:25:57 +0000
committer <>2015-03-17 16:26:24 +0000
commit780b92ada9afcf1d58085a83a0b9e6bc982203d1 (patch)
tree598f8b9fa431b228d29897e798de4ac0c1d3d970 /src/env/env_region.c
parent7a2660ba9cc2dc03a69ddfcfd95369395cc87444 (diff)
downloadberkeleydb-master.tar.gz
Imported from /home/lorry/working-area/delta_berkeleydb/db-6.1.23.tar.gz.HEADdb-6.1.23master
Diffstat (limited to 'src/env/env_region.c')
-rw-r--r--src/env/env_region.c117
1 files changed, 84 insertions, 33 deletions
diff --git a/src/env/env_region.c b/src/env/env_region.c
index 113bea21..cf7085b7 100644
--- a/src/env/env_region.c
+++ b/src/env/env_region.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -90,8 +90,11 @@ loop: renv = NULL;
* it's actually a creation or not, and we'll have to fall-back to a
* join if it's not a create.
*/
- if (F_ISSET(env, ENV_PRIVATE) || DB_GLOBAL(j_region_map) != NULL)
+ if (F_ISSET(env, ENV_PRIVATE) || DB_GLOBAL(j_region_map) != NULL) {
+ DB_DEBUG_MSG(env, "env_attach: creating %s",
+ F_ISSET(env, ENV_PRIVATE) ? "private" : "user map func");
goto creation;
+ }
/*
* Try to create the file, if we have the authority. We have to ensure
@@ -179,14 +182,15 @@ loop: renv = NULL;
* something in the region file other than meta-data and that
* shouldn't happen.
*/
- if (size < sizeof(ref))
+ if (size < sizeof(ref)) {
+ DB_DEBUG_MSG(env, "region size %d is too small", (int)size);
goto retry;
- else {
+ } else {
if (size == sizeof(ref))
F_SET(env, ENV_SYSTEM_MEM);
else if (F_ISSET(env, ENV_SYSTEM_MEM)) {
- ret = EINVAL;
+ ret = USR_ERR(env, EINVAL);
__db_err(env, ret, DB_STR_A("1535",
"%s: existing environment not created in system memory",
"%s"), infop->name);
@@ -197,6 +201,7 @@ loop: renv = NULL;
nrw < (size_t)sizeof(rbuf) ||
(ret = __os_seek(env,
env->lockfhp, 0, 0, rbuf.region_off)) != 0) {
+ ret = USR_ERR(env, ret);
__db_err(env, ret, DB_STR_A("1536",
"%s: unable to read region info", "%s"),
infop->name);
@@ -207,7 +212,8 @@ loop: renv = NULL;
if ((ret = __os_read(env, env->lockfhp, &ref,
sizeof(ref), &nrw)) != 0 || nrw < (size_t)sizeof(ref)) {
if (ret == 0)
- ret = EIO;
+ ret = USR_ERR(env, EIO);
+ (void)USR_ERR(env, ret);
__db_err(env, ret, DB_STR_A("1537",
"%s: unable to read system-memory information",
"%s"), infop->name);
@@ -218,18 +224,16 @@ loop: renv = NULL;
segid = ref.segid;
}
-#ifndef HAVE_MUTEX_FCNTL
/*
- * If we're not doing fcntl locking, we can close the file handle. We
- * no longer need it and the less contact between the buffer cache and
- * the VM, the better.
+ * We no longer need the file handle; the less contact between the
+ * buffer cache and the VM, the better.
*/
(void)__os_closehandle(env, env->lockfhp);
env->lockfhp = NULL;
-#endif
/* Call the region join routine to acquire the region. */
memset(&tregion, 0, sizeof(tregion));
+ tregion.type = REGION_TYPE_ENV;
tregion.size = (roff_t)size;
tregion.max = (roff_t)max;
tregion.segid = segid;
@@ -257,15 +261,15 @@ user_map_functions:
"Program version %d.%d doesn't match environment version %d.%d",
"%d %d %d %d"), DB_VERSION_MAJOR, DB_VERSION_MINOR,
renv->majver, renv->minver);
- ret = DB_VERSION_MISMATCH;
+ ret = USR_ERR(env, DB_VERSION_MISMATCH);
} else
- ret = EINVAL;
+ ret = USR_ERR(env, EINVAL);
goto err;
}
if (renv->signature != signature) {
__db_errx(env, DB_STR("1539",
"Build signature doesn't match environment"));
- ret = DB_VERSION_MISMATCH;
+ ret = USR_ERR(env, DB_VERSION_MISMATCH);
goto err;
}
@@ -287,8 +291,16 @@ user_map_functions:
ret = __env_panic_msg(env);
goto err;
}
- if (renv->magic != DB_REGION_MAGIC)
+ if (renv->magic != DB_REGION_MAGIC) {
+ DB_DEBUG_MSG(env,
+ "attach sees bad region magic 0x%lx", (u_long)renv->magic);
goto retry;
+ }
+
+ if (dbenv->blob_threshold != 0 &&
+ renv->blob_threshold != dbenv->blob_threshold)
+ __db_msg(env, DB_STR("1591",
+"Warning: Ignoring blob_threshold size when joining environment"));
/*
* Get a reference to the underlying REGION information for this
@@ -329,7 +341,7 @@ user_map_functions:
if (*init_flagsp != 0) {
__db_errx(env, DB_STR("1540",
"configured environment flags incompatible with existing environment"));
- ret = EINVAL;
+ ret = USR_ERR(env, EINVAL);
goto err;
}
*init_flagsp = renv->init_flags;
@@ -437,6 +449,8 @@ creation:
renv->minver = (u_int32_t)minver;
renv->patchver = (u_int32_t)patchver;
renv->signature = signature;
+ renv->failure_panic = 0;
+ renv->failure_symptom[0] = '\0';
(void)time(&renv->timestamp);
__os_unique_id(env, &renv->envid);
@@ -447,6 +461,8 @@ creation:
*/
renv->init_flags = (init_flagsp == NULL) ? 0 : *init_flagsp;
+ renv->blob_threshold = dbenv->blob_threshold;
+
/*
* Set up the region array. We use an array rather than a linked list
* as we have to traverse this list after failure in some cases, and
@@ -513,17 +529,14 @@ find_err: __db_errx(env, DB_STR_A("1544",
}
}
-#ifndef HAVE_MUTEX_FCNTL
/*
- * If we're not doing fcntl locking, we can close the file handle. We
- * no longer need it and the less contact between the buffer cache and
- * the VM, the better.
+ * We no longer need the file handle and the less contact between the
+ * buffer cache and the VM, the better.
*/
if (env->lockfhp != NULL) {
(void)__os_closehandle(env, env->lockfhp);
env->lockfhp = NULL;
}
-#endif
/* Everything looks good, we're done. */
env->reginfo = infop;
@@ -550,7 +563,7 @@ retry: /* Close any open file handle. */
(void)__env_sys_detach(env,
infop, F_ISSET(infop, REGION_CREATE));
- if (rp != NULL && F_ISSET(env, DB_PRIVATE))
+ if (rp != NULL && F_ISSET(env, ENV_PRIVATE))
__env_alloc_free(infop, rp);
}
@@ -674,8 +687,23 @@ __env_panic_set(env, on)
ENV *env;
int on;
{
- if (env != NULL && env->reginfo != NULL)
- ((REGENV *)env->reginfo->primary)->panic = on ? 1 : 0;
+ REGENV *renv;
+
+ if (env != NULL && env->reginfo != NULL) {
+ /*
+ * Remember it in the process' env as well, so that the
+ * panic-ness is still known on exit from the final close.
+ */
+ renv = env->reginfo->primary;
+ if (on) {
+ F_SET(env, ENV_REMEMBER_PANIC);
+ if (F_ISSET(env->dbenv, DB_ENV_FAILCHK))
+ renv->failure_panic = 1;
+ }
+ else
+ F_CLR(env, ENV_REMEMBER_PANIC);
+ renv->panic = on ? 1 : 0;
+ }
}
/*
@@ -775,6 +803,31 @@ __env_ref_get(dbenv, countp)
}
/*
+ * __env_region_cleanup --
+ * Detach from any regions, e.g., when closing after a panic.
+ *
+ * PUBLIC: int __env_region_cleanup __P((ENV *));
+ */
+int
+__env_region_cleanup(env)
+ ENV *env;
+{
+ if (env->reginfo != NULL) {
+#ifdef HAVE_MUTEX_SUPPORT
+ (void)__lock_region_detach(env, env->lk_handle);
+ (void)__mutex_region_detach(env, env->mutex_handle);
+#endif
+ (void)__log_region_detach(env, env->lg_handle);
+ (void)__memp_region_detach(env, env->mp_handle);
+ (void)__txn_region_detach(env, env->tx_handle);
+ (void)__env_detach(env, 0);
+ /* Remember the panic state after detaching. */
+ F_SET(env, ENV_REMEMBER_PANIC);
+ }
+ return (0);
+}
+
+/*
* __env_detach --
* Detach from the environment.
*
@@ -796,9 +849,7 @@ __env_detach(env, destroy)
/* Close the locking file handle. */
if (env->lockfhp != NULL) {
- if ((t_ret =
- __os_closehandle(env, env->lockfhp)) != 0 && ret == 0)
- ret = t_ret;
+ ret = __os_closehandle(env, env->lockfhp);
env->lockfhp = NULL;
}
@@ -1249,13 +1300,13 @@ __env_sys_attach(env, infop, rp)
__db_errx(env, DB_STR_A("1548",
"region size %lu is too large; maximum is %lu", "%lu %lu"),
(u_long)rp->size, (u_long)DB_REGIONSIZE_MAX);
- return (EINVAL);
+ return (USR_ERR(env, EINVAL));
}
if (rp->max > DB_REGIONSIZE_MAX) {
__db_errx(env, DB_STR_A("1549",
"region max %lu is too large; maximum is %lu", "%lu %lu"),
(u_long)rp->max, (u_long)DB_REGIONSIZE_MAX);
- return (EINVAL);
+ return (USR_ERR(env, EINVAL));
}
#endif
@@ -1281,7 +1332,7 @@ __env_sys_attach(env, infop, rp)
"architecture does not support locks inside process-local (malloc) memory"));
__db_errx(env, DB_STR("1551",
"application may not specify both DB_PRIVATE and DB_THREAD"));
- return (EINVAL);
+ return (USR_ERR(env, EINVAL));
}
#endif
if ((ret = __os_malloc(
@@ -1310,7 +1361,7 @@ __env_sys_attach(env, infop, rp)
"region memory was not correctly aligned"));
(void)__env_sys_detach(env, infop,
F_ISSET(infop, REGION_CREATE));
- return (EINVAL);
+ return (USR_ERR(env, EINVAL));
}
return (0);
@@ -1402,7 +1453,7 @@ __env_des_get(env, env_infop, infop, rpp)
* the region, fail. The caller generates any error message.
*/
if (!F_ISSET(infop, REGION_CREATE_OK))
- return (ENOENT);
+ return (USR_ERR(env, ENOENT));
/*
* If we didn't find a region and don't have room to create the region
@@ -1411,7 +1462,7 @@ __env_des_get(env, env_infop, infop, rpp)
if (empty_slot == NULL) {
__db_errx(env, DB_STR("1553",
"no room remaining for additional REGIONs"));
- return (ENOENT);
+ return (USR_ERR(env, ENOENT));
}
/*