diff options
Diffstat (limited to 'src/log/log.c')
| -rw-r--r-- | src/log/log.c | 201 |
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)); } /* |
