summaryrefslogtreecommitdiff
path: root/src/log/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/log/log.c')
-rw-r--r--src/log/log.c201
1 files changed, 108 insertions, 93 deletions
diff --git a/src/log/log.c b/src/log/log.c
index 5808145f..9bef8d69 100644
--- a/src/log/log.c
+++ b/src/log/log.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$
*/
@@ -32,6 +32,7 @@ __log_open(env)
DB_ENV *dbenv;
DB_LOG *dblp;
LOG *lp;
+ u_int32_t log_flags;
u_int8_t *bulk;
int region_locked, ret;
@@ -130,47 +131,59 @@ __log_open(env)
}
} else {
/*
- * A process joining the region may have reset the log file
- * size, too. If so, it only affects the next log file we
- * create. We need to check that the size is reasonable given
- * the buffer size in the region.
+ * The log file size and DB_LOG_AUTO_REMOVE will be ignored
+ * when joining the environment, so print a warning if either
+ * was set.
*/
- LOG_SYSTEM_LOCK(env);
- region_locked = 1;
-
- if (dbenv->lg_size != 0) {
- if ((ret =
- __log_check_sizes(env, dbenv->lg_size, 0)) != 0)
- goto err;
-
- lp->log_nsize = dbenv->lg_size;
- }
-
- LOG_SYSTEM_UNLOCK(env);
- region_locked = 0;
-
- if (dbenv->lg_flags != 0 && (ret =
- __log_set_config_int(dbenv, dbenv->lg_flags, 1, 0)) != 0)
+ if (dbenv->lg_size != 0 && lp->log_nsize != dbenv->lg_size)
+ __db_msg(env, DB_STR("2585",
+"Warning: Ignoring maximum log file size when joining the environment"));
+
+ log_flags = dbenv->lg_flags & ~DB_LOG_AUTO_REMOVE;
+ if ((dbenv->lg_flags & DB_LOG_AUTO_REMOVE) &&
+ lp->db_log_autoremove == 0)
+ __db_msg(env, DB_STR("2586",
+"Warning: Ignoring DB_LOG_AUTO_REMOVE when joining the environment."));
+ if (log_flags != 0 && (ret =
+ __log_set_config_int(dbenv, log_flags, 1, 0)) != 0)
return (ret);
}
dblp->reginfo.mtx_alloc = lp->mtx_region;
return (0);
-err: if (dblp->reginfo.addr != NULL) {
- if (region_locked)
- LOG_SYSTEM_UNLOCK(env);
- (void)__env_region_detach(env, &dblp->reginfo, 0);
- }
- env->lg_handle = NULL;
-
+err: if (region_locked)
+ LOG_SYSTEM_UNLOCK(env);
(void)__mutex_free(env, &dblp->mtx_dbreg);
- __os_free(env, dblp);
+ (void)__log_region_detach(env, dblp);
return (ret);
}
/*
+ * __log_region_detach --
+ *
+ * PUBLIC: int __log_region_detach __P((ENV *, DB_LOG *));
+ */
+int
+__log_region_detach(env, dblp)
+ ENV *env;
+ DB_LOG *dblp;
+{
+ int ret;
+
+ ret = 0;
+ if (dblp != NULL) {
+ if (dblp->reginfo.addr != NULL)
+ ret = __env_region_detach(env, &dblp->reginfo, 0);
+ /* Discard DB_LOG. */
+ __os_free(env, dblp);
+ env->lg_handle = NULL;
+ }
+ return (ret);
+}
+
+/*
* __log_init --
* Initialize a log region in shared memory.
*/
@@ -638,7 +651,6 @@ __log_valid(dblp, number, set_persist, fhpp, flags, statusp, versionp)
recsize = sizeof(LOGP);
if (CRYPTO_ON(env)) {
hdrsize = HDR_CRYPTO_SZ;
- recsize = sizeof(LOGP);
recsize += db_cipher->adj_size(recsize);
is_hmac = 1;
}
@@ -700,7 +712,7 @@ __log_valid(dblp, number, set_persist, fhpp, flags, statusp, versionp)
* we can only detect that by having an unreasonable
* data length for our persistent data.
*/
- if ((hdr->len - hdrsize) != sizeof(LOGP)) {
+ if ((hdr->len - hdrsize) != recsize) {
__db_errx(env, "log record size mismatch");
goto err;
}
@@ -722,10 +734,10 @@ __log_valid(dblp, number, set_persist, fhpp, flags, statusp, versionp)
hdr->len - hdrsize, is_hmac)) != 0)
goto bad_checksum;
/*
- * The checksum verifies without the header. Make note
- * of that, because it is only acceptable when the log
- * version < DB_LOGCHKSUM. Later, when we determine log
- * version, we will confirm this.
+ * The checksum verifies without the header. Make note
+ * of that, because it is only acceptable when the log
+ * version < DB_LOGCHKSUM. Later, when we determine log
+ * version, we will confirm this.
*/
chksum_includes_hdr = 0;
}
@@ -800,7 +812,7 @@ __log_valid(dblp, number, set_persist, fhpp, flags, statusp, versionp)
/*
* We might have to declare a checksum failure here, if:
* - the checksum verified only by ignoring the header, and
- * - the log version indicates that the header should have
+ * - the log version indicates that the header should have
* been included.
*/
if (!chksum_includes_hdr && logversion >= DB_LOGCHKSUM)
@@ -899,66 +911,69 @@ __log_env_refresh(env)
/*
* After we close the files, check for any unlogged closes left in
* the shared memory queue. If we find any, try to log it, otherwise
- * return the error. We cannot say the environment was closed
- * cleanly.
+ * return the error; we cannot say the environment was closed cleanly.
+ * This does not use the typical MUTEX_LOCK(), but MUTEX_LOCK_RET(). The
+ * normal function would immediately return DB_RUNRECOVERY if we are
+ * closing the env down during a panic. By using MUTEX_LOCK_RET(), we
+ * continue with the rest of the cleanup.
*/
- MUTEX_LOCK(env, lp->mtx_filelist);
- SH_TAILQ_FOREACH(fnp, &lp->fq, q, __fname)
- if (F_ISSET(fnp, DB_FNAME_NOTLOGGED) &&
- (t_ret = __dbreg_close_id_int(
- env, fnp, DBREG_CLOSE, 1)) != 0)
- ret = t_ret;
- MUTEX_UNLOCK(env, lp->mtx_filelist);
-
+ if (MUTEX_LOCK_RET(env, lp->mtx_filelist) == 0) {
+ SH_TAILQ_FOREACH(fnp, &lp->fq, q, __fname)
+ if (F_ISSET(fnp, DB_FNAME_NOTLOGGED) &&
+ (t_ret = __dbreg_close_id_int(
+ env, fnp, DBREG_CLOSE, 1)) != 0)
+ ret = t_ret;
+ MUTEX_UNLOCK(env, lp->mtx_filelist);
+ }
/*
- * If a private region, return the memory to the heap. Not needed for
- * filesystem-backed or system shared memory regions, that memory isn't
- * owned by any particular process.
+ * If a private region, return the memory to the heap. Not
+ * needed for filesystem-backed or system shared memory regions,
+ * that memory isn't owned by any particular process.
*/
if (F_ISSET(env, ENV_PRIVATE)) {
- reginfo->mtx_alloc = MUTEX_INVALID;
- /* Discard the flush mutex. */
- if ((t_ret =
- __mutex_free(env, &lp->mtx_flush)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Discard the buffer. */
- __env_alloc_free(reginfo, R_ADDR(reginfo, lp->buffer_off));
-
- /* Discard stack of free file IDs. */
- if (lp->free_fid_stack != INVALID_ROFF)
- __env_alloc_free(reginfo,
- R_ADDR(reginfo, lp->free_fid_stack));
-
- /* Discard the list of in-memory log file markers. */
- while ((filestart = SH_TAILQ_FIRST(&lp->logfiles,
- __db_filestart)) != NULL) {
- SH_TAILQ_REMOVE(&lp->logfiles, filestart, links,
- __db_filestart);
- __env_alloc_free(reginfo, filestart);
- }
-
- while ((filestart = SH_TAILQ_FIRST(&lp->free_logfiles,
- __db_filestart)) != NULL) {
- SH_TAILQ_REMOVE(&lp->free_logfiles, filestart, links,
- __db_filestart);
- __env_alloc_free(reginfo, filestart);
- }
-
- /* Discard commit queue elements. */
- while ((commit = SH_TAILQ_FIRST(&lp->free_commits,
- __db_commit)) != NULL) {
- SH_TAILQ_REMOVE(&lp->free_commits, commit, links,
- __db_commit);
- __env_alloc_free(reginfo, commit);
- }
-
- /* Discard replication bulk buffer. */
- if (lp->bulk_buf != INVALID_ROFF) {
- __env_alloc_free(reginfo,
- R_ADDR(reginfo, lp->bulk_buf));
- lp->bulk_buf = INVALID_ROFF;
- }
+ reginfo->mtx_alloc = MUTEX_INVALID;
+ /* Discard the flush mutex. */
+ if ((t_ret =
+ __mutex_free(env, &lp->mtx_flush)) != 0 && ret == 0)
+ ret = t_ret;
+
+ /* Discard the log buffer. */
+ __env_alloc_free(reginfo, R_ADDR(reginfo, lp->buffer_off));
+
+ /* Discard stack of free file IDs. */
+ if (lp->free_fid_stack != INVALID_ROFF)
+ __env_alloc_free(reginfo,
+ R_ADDR(reginfo, lp->free_fid_stack));
+
+ /* Discard the list of in-memory log file markers. */
+ while ((filestart = SH_TAILQ_FIRST(&lp->logfiles,
+ __db_filestart)) != NULL) {
+ SH_TAILQ_REMOVE(&lp->logfiles, filestart, links,
+ __db_filestart);
+ __env_alloc_free(reginfo, filestart);
+ }
+
+ while ((filestart = SH_TAILQ_FIRST(&lp->free_logfiles,
+ __db_filestart)) != NULL) {
+ SH_TAILQ_REMOVE(&lp->free_logfiles, filestart, links,
+ __db_filestart);
+ __env_alloc_free(reginfo, filestart);
+ }
+
+ /* Discard commit queue elements. */
+ while ((commit = SH_TAILQ_FIRST(&lp->free_commits,
+ __db_commit)) != NULL) {
+ SH_TAILQ_REMOVE(&lp->free_commits, commit, links,
+ __db_commit);
+ __env_alloc_free(reginfo, commit);
+ }
+
+ /* Discard replication bulk buffer. */
+ if (lp->bulk_buf != INVALID_ROFF) {
+ __env_alloc_free(reginfo,
+ R_ADDR(reginfo, lp->bulk_buf));
+ lp->bulk_buf = INVALID_ROFF;
+ }
}
/* Discard the per-thread DBREG mutex. */
@@ -1394,7 +1409,7 @@ __log_inmem_lsnoff(dblp, lsnp, offsetp)
return (0);
}
- return (DB_NOTFOUND);
+ return (USR_ERR(dblp->env, DB_NOTFOUND));
}
/*