aboutsummaryrefslogtreecommitdiff
path: root/db2/log
diff options
context:
space:
mode:
Diffstat (limited to 'db2/log')
-rw-r--r--db2/log/log.c540
-rw-r--r--db2/log/log.src19
-rw-r--r--db2/log/log_archive.c417
-rw-r--r--db2/log/log_auto.c231
-rw-r--r--db2/log/log_compare.c34
-rw-r--r--db2/log/log_findckp.c141
-rw-r--r--db2/log/log_get.c330
-rw-r--r--db2/log/log_put.c603
-rw-r--r--db2/log/log_rec.c398
-rw-r--r--db2/log/log_register.c208
10 files changed, 0 insertions, 2921 deletions
diff --git a/db2/log/log.c b/db2/log/log.c
deleted file mode 100644
index ad15f16..0000000
--- a/db2/log/log.c
+++ /dev/null
@@ -1,540 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log.c 10.63 (Sleepycat) 10/10/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <shqueue.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "log.h"
-#include "db_dispatch.h"
-#include "txn.h"
-#include "txn_auto.h"
-#include "common_ext.h"
-
-static int __log_recover __P((DB_LOG *));
-
-/*
- * log_open --
- * Initialize and/or join a log.
- */
-int
-log_open(path, flags, mode, dbenv, lpp)
- const char *path;
- u_int32_t flags;
- int mode;
- DB_ENV *dbenv;
- DB_LOG **lpp;
-{
- DB_LOG *dblp;
- LOG *lp;
- int ret;
-
- /* Validate arguments. */
-#ifdef HAVE_SPINLOCKS
-#define OKFLAGS (DB_CREATE | DB_THREAD)
-#else
-#define OKFLAGS (DB_CREATE)
-#endif
- if ((ret = __db_fchk(dbenv, "log_open", flags, OKFLAGS)) != 0)
- return (ret);
-
- /* Create and initialize the DB_LOG structure. */
- if ((ret = __os_calloc(1, sizeof(DB_LOG), &dblp)) != 0)
- return (ret);
-
- if (path != NULL && (ret = __os_strdup(path, &dblp->dir)) != 0)
- goto err;
-
- dblp->dbenv = dbenv;
- dblp->lfd = -1;
- ZERO_LSN(dblp->c_lsn);
- dblp->c_fd = -1;
-
- /*
- * The log region isn't fixed size because we store the registered
- * file names there. Make it fairly large so that we don't have to
- * grow it.
- */
-#define DEF_LOG_SIZE (30 * 1024)
-
- /* Map in the region. */
- dblp->reginfo.dbenv = dbenv;
- dblp->reginfo.appname = DB_APP_LOG;
- if (path == NULL)
- dblp->reginfo.path = NULL;
- else
- if ((ret = __os_strdup(path, &dblp->reginfo.path)) != 0)
- goto err;
- dblp->reginfo.file = DB_DEFAULT_LOG_FILE;
- dblp->reginfo.mode = mode;
- dblp->reginfo.size = DEF_LOG_SIZE;
- dblp->reginfo.dbflags = flags;
- dblp->reginfo.flags = REGION_SIZEDEF;
- if ((ret = __db_rattach(&dblp->reginfo)) != 0)
- goto err;
-
- /*
- * The LOG structure is first in the region, the rest of the region
- * is free space.
- */
- dblp->lp = dblp->reginfo.addr;
- dblp->addr = (u_int8_t *)dblp->lp + sizeof(LOG);
-
- /* Initialize a created region. */
- if (F_ISSET(&dblp->reginfo, REGION_CREATED)) {
- __db_shalloc_init(dblp->addr, DEF_LOG_SIZE - sizeof(LOG));
-
- /* Initialize the LOG structure. */
- lp = dblp->lp;
- lp->persist.lg_max = dbenv == NULL ? 0 : dbenv->lg_max;
- if (lp->persist.lg_max == 0)
- lp->persist.lg_max = DEFAULT_MAX;
- lp->persist.magic = DB_LOGMAGIC;
- lp->persist.version = DB_LOGVERSION;
- lp->persist.mode = mode;
- SH_TAILQ_INIT(&lp->fq);
-
- /* Initialize LOG LSNs. */
- lp->lsn.file = 1;
- lp->lsn.offset = 0;
- }
-
- /* Initialize thread information, mutex. */
- if (LF_ISSET(DB_THREAD)) {
- F_SET(dblp, DB_AM_THREAD);
- if ((ret = __db_shalloc(dblp->addr,
- sizeof(db_mutex_t), MUTEX_ALIGNMENT, &dblp->mutexp)) != 0)
- goto err;
- (void)__db_mutex_init(dblp->mutexp, 0);
- }
-
- /*
- * If doing recovery, try and recover any previous log files before
- * releasing the lock.
- */
- if (F_ISSET(&dblp->reginfo, REGION_CREATED) &&
- (ret = __log_recover(dblp)) != 0)
- goto err;
-
- UNLOCK_LOGREGION(dblp);
- *lpp = dblp;
- return (0);
-
-err: if (dblp->reginfo.addr != NULL) {
- if (dblp->mutexp != NULL)
- __db_shalloc_free(dblp->addr, dblp->mutexp);
-
- UNLOCK_LOGREGION(dblp);
- (void)__db_rdetach(&dblp->reginfo);
- if (F_ISSET(&dblp->reginfo, REGION_CREATED))
- (void)log_unlink(path, 1, dbenv);
- }
-
- if (dblp->reginfo.path != NULL)
- __os_freestr(dblp->reginfo.path);
- if (dblp->dir != NULL)
- __os_freestr(dblp->dir);
- __os_free(dblp, sizeof(*dblp));
- return (ret);
-}
-
-/*
- * __log_panic --
- * Panic a log.
- *
- * PUBLIC: void __log_panic __P((DB_ENV *));
- */
-void
-__log_panic(dbenv)
- DB_ENV *dbenv;
-{
- if (dbenv->lg_info != NULL)
- dbenv->lg_info->lp->rlayout.panic = 1;
-}
-
-/*
- * __log_recover --
- * Recover a log.
- */
-static int
-__log_recover(dblp)
- DB_LOG *dblp;
-{
- DBT dbt;
- DB_LSN lsn;
- LOG *lp;
- u_int32_t chk;
- int cnt, found_checkpoint, ret;
-
- lp = dblp->lp;
-
- /*
- * Find a log file. If none exist, we simply return, leaving
- * everything initialized to a new log.
- */
- if ((ret = __log_find(dblp, 0, &cnt)) != 0)
- return (ret);
- if (cnt == 0)
- return (0);
-
- /*
- * We have the last useful log file and we've loaded any persistent
- * information. Pretend that the log is larger than it can possibly
- * be, and read the last file, looking for the last checkpoint and
- * the log's end.
- */
- lp->lsn.file = cnt + 1;
- lp->lsn.offset = 0;
- lsn.file = cnt;
- lsn.offset = 0;
-
- /* Set the cursor. Shouldn't fail, leave error messages on. */
- memset(&dbt, 0, sizeof(dbt));
- if ((ret = __log_get(dblp, &lsn, &dbt, DB_SET, 0)) != 0)
- return (ret);
-
- /*
- * Read to the end of the file, saving checkpoints. This will fail
- * at some point, so turn off error messages.
- */
- found_checkpoint = 0;
- while (__log_get(dblp, &lsn, &dbt, DB_NEXT, 1) == 0) {
- if (dbt.size < sizeof(u_int32_t))
- continue;
- memcpy(&chk, dbt.data, sizeof(u_int32_t));
- if (chk == DB_txn_ckp) {
- lp->chkpt_lsn = lsn;
- found_checkpoint = 1;
- }
- }
-
- /*
- * We now know where the end of the log is. Set the first LSN that
- * we want to return to an application and the LSN of the last known
- * record on disk.
- */
- lp->lsn = lp->s_lsn = lsn;
- lp->lsn.offset += dblp->c_len;
-
- /* Set up the current buffer information, too. */
- lp->len = dblp->c_len;
- lp->b_off = 0;
- lp->w_off = lp->lsn.offset;
-
- /*
- * It's possible that we didn't find a checkpoint because there wasn't
- * one in the last log file. Start searching.
- */
- while (!found_checkpoint && cnt > 1) {
- lsn.file = --cnt;
- lsn.offset = 0;
-
- /* Set the cursor. Shouldn't fail, leave error messages on. */
- if ((ret = __log_get(dblp, &lsn, &dbt, DB_SET, 0)) != 0)
- return (ret);
-
- /*
- * Read to the end of the file, saving checkpoints. Shouldn't
- * fail, leave error messages on.
- */
- while (__log_get(dblp, &lsn, &dbt, DB_NEXT, 0) == 0) {
- if (dbt.size < sizeof(u_int32_t))
- continue;
- memcpy(&chk, dbt.data, sizeof(u_int32_t));
- if (chk == DB_txn_ckp) {
- lp->chkpt_lsn = lsn;
- found_checkpoint = 1;
- }
- }
- }
- /*
- * Reset the cursor lsn to the beginning of the log, so that an
- * initial call to DB_NEXT does the right thing.
- */
- ZERO_LSN(dblp->c_lsn);
-
- /* If we never find a checkpoint, that's okay, just 0 it out. */
- if (!found_checkpoint)
- ZERO_LSN(lp->chkpt_lsn);
-
- /*
- * !!!
- * The test suite explicitly looks for this string -- don't change
- * it here unless you also change it there.
- */
- __db_err(dblp->dbenv,
- "Finding last valid log LSN: file: %lu offset %lu",
- (u_long)lp->lsn.file, (u_long)lp->lsn.offset);
-
- return (0);
-}
-
-/*
- * __log_find --
- * Try to find a log file. If find_first is set, valp will contain
- * the number of the first log file, else it will contain the number of
- * the last log file.
- *
- * PUBLIC: int __log_find __P((DB_LOG *, int, int *));
- */
-int
-__log_find(dblp, find_first, valp)
- DB_LOG *dblp;
- int find_first, *valp;
-{
- u_int32_t clv, logval;
- int cnt, fcnt, ret;
- const char *dir;
- char **names, *p, *q;
-
- *valp = 0;
-
- /* Find the directory name. */
- if ((ret = __log_name(dblp, 1, &p, NULL, 0)) != 0)
- return (ret);
- if ((q = __db_rpath(p)) == NULL)
- dir = PATH_DOT;
- else {
- *q = '\0';
- dir = p;
- }
-
- /* Get the list of file names. */
- ret = __os_dirlist(dir, &names, &fcnt);
- __os_freestr(p);
- if (ret != 0) {
- __db_err(dblp->dbenv, "%s: %s", dir, strerror(ret));
- return (ret);
- }
-
- /*
- * Search for a valid log file name, return a value of 0 on
- * failure.
- *
- * XXX
- * Assumes that atoi(3) returns a 32-bit number.
- */
- for (cnt = fcnt, clv = logval = 0; --cnt >= 0;) {
- if (strncmp(names[cnt], LFPREFIX, sizeof(LFPREFIX) - 1) != 0)
- continue;
-
- clv = atoi(names[cnt] + (sizeof(LFPREFIX) - 1));
- if (find_first) {
- if (logval != 0 && clv > logval)
- continue;
- } else
- if (logval != 0 && clv < logval)
- continue;
-
- if (__log_valid(dblp, clv, 1) == 0)
- logval = clv;
- }
-
- *valp = logval;
-
- /* Discard the list. */
- __os_dirfree(names, fcnt);
-
- return (0);
-}
-
-/*
- * log_valid --
- * Validate a log file.
- *
- * PUBLIC: int __log_valid __P((DB_LOG *, u_int32_t, int));
- */
-int
-__log_valid(dblp, number, set_persist)
- DB_LOG *dblp;
- u_int32_t number;
- int set_persist;
-{
- LOGP persist;
- ssize_t nw;
- char *fname;
- int fd, ret;
-
- /* Try to open the log file. */
- if ((ret = __log_name(dblp,
- number, &fname, &fd, DB_RDONLY | DB_SEQUENTIAL)) != 0) {
- __os_freestr(fname);
- return (ret);
- }
-
- /* Try to read the header. */
- if ((ret = __os_seek(fd, 0, 0, sizeof(HDR), 0, SEEK_SET)) != 0 ||
- (ret = __os_read(fd, &persist, sizeof(LOGP), &nw)) != 0 ||
- nw != sizeof(LOGP)) {
- if (ret == 0)
- ret = EIO;
-
- (void)__os_close(fd);
-
- __db_err(dblp->dbenv,
- "Ignoring log file: %s: %s", fname, strerror(ret));
- goto err;
- }
- (void)__os_close(fd);
-
- /* Validate the header. */
- if (persist.magic != DB_LOGMAGIC) {
- __db_err(dblp->dbenv,
- "Ignoring log file: %s: magic number %lx, not %lx",
- fname, (u_long)persist.magic, (u_long)DB_LOGMAGIC);
- ret = EINVAL;
- goto err;
- }
- if (persist.version < DB_LOGOLDVER || persist.version > DB_LOGVERSION) {
- __db_err(dblp->dbenv,
- "Ignoring log file: %s: unsupported log version %lu",
- fname, (u_long)persist.version);
- ret = EINVAL;
- goto err;
- }
-
- /*
- * If we're going to use this log file, set the region's persistent
- * information based on the headers.
- */
- if (set_persist) {
- dblp->lp->persist.lg_max = persist.lg_max;
- dblp->lp->persist.mode = persist.mode;
- }
- ret = 0;
-
-err: __os_freestr(fname);
- return (ret);
-}
-
-/*
- * log_close --
- * Close a log.
- */
-int
-log_close(dblp)
- DB_LOG *dblp;
-{
- int ret, t_ret;
-
- LOG_PANIC_CHECK(dblp);
-
- /* We may have opened files as part of XA; if so, close them. */
- __log_close_files(dblp);
-
- /* Discard the per-thread pointer. */
- if (dblp->mutexp != NULL) {
- LOCK_LOGREGION(dblp);
- __db_shalloc_free(dblp->addr, dblp->mutexp);
- UNLOCK_LOGREGION(dblp);
- }
-
- /* Close the region. */
- ret = __db_rdetach(&dblp->reginfo);
-
- /* Close open files, release allocated memory. */
- if (dblp->lfd != -1 && (t_ret = __os_close(dblp->lfd)) != 0 && ret == 0)
- ret = t_ret;
- if (dblp->c_dbt.data != NULL)
- __os_free(dblp->c_dbt.data, dblp->c_dbt.ulen);
- if (dblp->c_fd != -1 &&
- (t_ret = __os_close(dblp->c_fd)) != 0 && ret == 0)
- ret = t_ret;
- if (dblp->dbentry != NULL)
- __os_free(dblp->dbentry,
- (dblp->dbentry_cnt * sizeof(DB_ENTRY)));
- if (dblp->dir != NULL)
- __os_freestr(dblp->dir);
-
- if (dblp->reginfo.path != NULL)
- __os_freestr(dblp->reginfo.path);
- __os_free(dblp, sizeof(*dblp));
-
- return (ret);
-}
-
-/*
- * log_unlink --
- * Exit a log.
- */
-int
-log_unlink(path, force, dbenv)
- const char *path;
- int force;
- DB_ENV *dbenv;
-{
- REGINFO reginfo;
- int ret;
-
- memset(&reginfo, 0, sizeof(reginfo));
- reginfo.dbenv = dbenv;
- reginfo.appname = DB_APP_LOG;
- if (path != NULL && (ret = __os_strdup(path, &reginfo.path)) != 0)
- return (ret);
- reginfo.file = DB_DEFAULT_LOG_FILE;
- ret = __db_runlink(&reginfo, force);
- if (reginfo.path != NULL)
- __os_freestr(reginfo.path);
- return (ret);
-}
-
-/*
- * log_stat --
- * Return LOG statistics.
- */
-int
-log_stat(dblp, gspp, db_malloc)
- DB_LOG *dblp;
- DB_LOG_STAT **gspp;
- void *(*db_malloc) __P((size_t));
-{
- LOG *lp;
- int ret;
-
- *gspp = NULL;
- lp = dblp->lp;
-
- LOG_PANIC_CHECK(dblp);
-
- if ((ret = __os_malloc(sizeof(**gspp), db_malloc, gspp)) != 0)
- return (ret);
-
- /* Copy out the global statistics. */
- LOCK_LOGREGION(dblp);
- **gspp = lp->stat;
-
- (*gspp)->st_magic = lp->persist.magic;
- (*gspp)->st_version = lp->persist.version;
- (*gspp)->st_mode = lp->persist.mode;
- (*gspp)->st_lg_max = lp->persist.lg_max;
-
- (*gspp)->st_region_nowait = lp->rlayout.lock.mutex_set_nowait;
- (*gspp)->st_region_wait = lp->rlayout.lock.mutex_set_wait;
-
- (*gspp)->st_cur_file = lp->lsn.file;
- (*gspp)->st_cur_offset = lp->lsn.offset;
-
- (*gspp)->st_refcnt = lp->rlayout.refcnt;
- (*gspp)->st_regsize = lp->rlayout.size;
-
- UNLOCK_LOGREGION(dblp);
-
- return (0);
-}
diff --git a/db2/log/log.src b/db2/log/log.src
deleted file mode 100644
index 12883bd..0000000
--- a/db2/log/log.src
+++ /dev/null
@@ -1,19 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- *
- * @(#)log.src 10.5 (Sleepycat) 4/10/98
- */
-
-PREFIX log
-
-/* Used for registering name/id translations at open or close. */
-BEGIN register
-ARG opcode u_int32_t lu
-DBT name DBT s
-DBT uid DBT s
-ARG id u_int32_t lu
-ARG ftype DBTYPE lx
-END
diff --git a/db2/log/log_archive.c b/db2/log/log_archive.c
deleted file mode 100644
index 9f3b24d..0000000
--- a/db2/log/log_archive.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_archive.c 10.44 (Sleepycat) 10/9/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "db_dispatch.h"
-#include "shqueue.h"
-#include "log.h"
-#include "common_ext.h"
-#include "clib_ext.h" /* XXX: needed for getcwd. */
-
-static int __absname __P((char *, char *, char **));
-static int __build_data __P((DB_LOG *, char *, char ***, void *(*)(size_t)));
-static int __cmpfunc __P((const void *, const void *));
-static int __usermem __P((char ***, void *(*)(size_t)));
-
-/*
- * log_archive --
- * Supporting function for db_archive(1).
- */
-int
-log_archive(dblp, listp, flags, db_malloc)
- DB_LOG *dblp;
- char ***listp;
- u_int32_t flags;
- void *(*db_malloc) __P((size_t));
-{
- DBT rec;
- DB_LSN stable_lsn;
- u_int32_t fnum;
- int array_size, n, ret;
- char **array, **arrayp, *name, *p, *pref, buf[MAXPATHLEN];
-
- name = NULL;
- COMPQUIET(fnum, 0);
-
- LOG_PANIC_CHECK(dblp);
-
-#define OKFLAGS (DB_ARCH_ABS | DB_ARCH_DATA | DB_ARCH_LOG)
- if (flags != 0) {
- if ((ret =
- __db_fchk(dblp->dbenv, "log_archive", flags, OKFLAGS)) != 0)
- return (ret);
- if ((ret =
- __db_fcchk(dblp->dbenv,
- "log_archive", flags, DB_ARCH_DATA, DB_ARCH_LOG)) != 0)
- return (ret);
- }
-
- /*
- * Get the absolute pathname of the current directory. It would
- * be nice to get the shortest pathname of the database directory,
- * but that's just not possible.
- */
- if (LF_ISSET(DB_ARCH_ABS)) {
- errno = 0;
- if ((pref = getcwd(buf, sizeof(buf))) == NULL)
- return (errno == 0 ? ENOMEM : errno);
- } else
- pref = NULL;
-
- switch (LF_ISSET(~DB_ARCH_ABS)) {
- case DB_ARCH_DATA:
- return (__build_data(dblp, pref, listp, db_malloc));
- case DB_ARCH_LOG:
- memset(&rec, 0, sizeof(rec));
- if (F_ISSET(dblp, DB_AM_THREAD))
- F_SET(&rec, DB_DBT_MALLOC);
- if ((ret = log_get(dblp, &stable_lsn, &rec, DB_LAST)) != 0)
- return (ret);
- if (F_ISSET(dblp, DB_AM_THREAD))
- __os_free(rec.data, rec.size);
- fnum = stable_lsn.file;
- break;
- case 0:
- if ((ret = __log_findckp(dblp, &stable_lsn)) != 0) {
- /*
- * A return of DB_NOTFOUND means that we didn't find
- * any records in the log (so we are not going to be
- * deleting any log files).
- */
- if (ret != DB_NOTFOUND)
- return (ret);
- *listp = NULL;
- return (0);
- }
- /* Remove any log files before the last stable LSN. */
- fnum = stable_lsn.file - 1;
- break;
- }
-
-#define LIST_INCREMENT 64
- /* Get some initial space. */
- array_size = 10;
- if ((ret = __os_malloc(sizeof(char *) * array_size, NULL, &array)) != 0)
- return (ret);
- array[0] = NULL;
-
- /* Build an array of the file names. */
- for (n = 0; fnum > 0; --fnum) {
- if ((ret = __log_name(dblp, fnum, &name, NULL, 0)) != 0)
- goto err;
- if (__os_exists(name, NULL) != 0) {
- __os_freestr(name);
- name = NULL;
- break;
- }
-
- if (n >= array_size - 1) {
- array_size += LIST_INCREMENT;
- if ((ret = __os_realloc(&array,
- sizeof(char *) * array_size)) != 0)
- goto err;
- }
-
- if (LF_ISSET(DB_ARCH_ABS)) {
- if ((ret = __absname(pref, name, &array[n])) != 0)
- goto err;
- __os_freestr(name);
- } else if ((p = __db_rpath(name)) != NULL) {
- if ((ret = __os_strdup(p + 1, &array[n])) != 0)
- goto err;
- __os_freestr(name);
- } else
- array[n] = name;
-
- name = NULL;
- array[++n] = NULL;
- }
-
- /* If there's nothing to return, we're done. */
- if (n == 0) {
- *listp = NULL;
- ret = 0;
- goto err;
- }
-
- /* Sort the list. */
- qsort(array, (size_t)n, sizeof(char *), __cmpfunc);
-
- /* Rework the memory. */
- if ((ret = __usermem(&array, db_malloc)) != 0)
- goto err;
-
- *listp = array;
- return (0);
-
-err: if (array != NULL) {
- for (arrayp = array; *arrayp != NULL; ++arrayp)
- __os_freestr(*arrayp);
- __os_free(array, sizeof(char *) * array_size);
- }
- if (name != NULL)
- __os_freestr(name);
- return (ret);
-}
-
-/*
- * __build_data --
- * Build a list of datafiles for return.
- */
-static int
-__build_data(dblp, pref, listp, db_malloc)
- DB_LOG *dblp;
- char *pref, ***listp;
- void *(*db_malloc) __P((size_t));
-{
- DBT rec;
- DB_LSN lsn;
- __log_register_args *argp;
- u_int32_t rectype;
- int array_size, last, n, nxt, ret;
- char **array, **arrayp, *p, *real_name;
-
- /* Get some initial space. */
- array_size = 10;
- if ((ret = __os_malloc(sizeof(char *) * array_size, NULL, &array)) != 0)
- return (ret);
- array[0] = NULL;
-
- memset(&rec, 0, sizeof(rec));
- if (F_ISSET(dblp, DB_AM_THREAD))
- F_SET(&rec, DB_DBT_MALLOC);
- for (n = 0, ret = log_get(dblp, &lsn, &rec, DB_FIRST);
- ret == 0; ret = log_get(dblp, &lsn, &rec, DB_NEXT)) {
- if (rec.size < sizeof(rectype)) {
- ret = EINVAL;
- __db_err(dblp->dbenv, "log_archive: bad log record");
- goto lg_free;
- }
-
- memcpy(&rectype, rec.data, sizeof(rectype));
- if (rectype != DB_log_register) {
- if (F_ISSET(dblp, DB_AM_THREAD)) {
- __os_free(rec.data, rec.size);
- rec.data = NULL;
- }
- continue;
- }
- if ((ret = __log_register_read(rec.data, &argp)) != 0) {
- ret = EINVAL;
- __db_err(dblp->dbenv,
- "log_archive: unable to read log record");
- goto lg_free;
- }
-
- if (n >= array_size - 1) {
- array_size += LIST_INCREMENT;
- if ((ret = __os_realloc(&array,
- sizeof(char *) * array_size)) != 0)
- goto lg_free;
- }
-
- if ((ret = __os_strdup(argp->name.data, &array[n])) != 0) {
-lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
- __os_free(rec.data, rec.size);
- goto err1;
- }
-
- array[++n] = NULL;
- __os_free(argp, 0);
-
- if (F_ISSET(dblp, DB_AM_THREAD)) {
- __os_free(rec.data, rec.size);
- rec.data = NULL;
- }
- }
-
- /* If there's nothing to return, we're done. */
- if (n == 0) {
- ret = 0;
- *listp = NULL;
- goto err1;
- }
-
- /* Sort the list. */
- qsort(array, (size_t)n, sizeof(char *), __cmpfunc);
-
- /*
- * Build the real pathnames, discarding nonexistent files and
- * duplicates.
- */
- for (last = nxt = 0; nxt < n;) {
- /*
- * Discard duplicates. Last is the next slot we're going
- * to return to the user, nxt is the next slot that we're
- * going to consider.
- */
- if (last != nxt) {
- array[last] = array[nxt];
- array[nxt] = NULL;
- }
- for (++nxt; nxt < n &&
- strcmp(array[last], array[nxt]) == 0; ++nxt) {
- __os_freestr(array[nxt]);
- array[nxt] = NULL;
- }
-
- /* Get the real name. */
- if ((ret = __db_appname(dblp->dbenv,
- DB_APP_DATA, NULL, array[last], 0, NULL, &real_name)) != 0)
- goto err2;
-
- /* If the file doesn't exist, ignore it. */
- if (__os_exists(real_name, NULL) != 0) {
- __os_freestr(real_name);
- __os_freestr(array[last]);
- array[last] = NULL;
- continue;
- }
-
- /* Rework the name as requested by the user. */
- __os_freestr(array[last]);
- array[last] = NULL;
- if (pref != NULL) {
- ret = __absname(pref, real_name, &array[last]);
- __os_freestr(real_name);
- if (ret != 0)
- goto err2;
- } else if ((p = __db_rpath(real_name)) != NULL) {
- ret = __os_strdup(p + 1, &array[last]);
- __os_freestr(real_name);
- if (ret != 0)
- goto err2;
- } else
- array[last] = real_name;
- ++last;
- }
-
- /* NULL-terminate the list. */
- array[last] = NULL;
-
- /* Rework the memory. */
- if ((ret = __usermem(&array, db_malloc)) != 0)
- goto err1;
-
- *listp = array;
- return (0);
-
-err2: /*
- * XXX
- * We've possibly inserted NULLs into the array list, so clean up a
- * bit so that the other error processing works.
- */
- if (array != NULL)
- for (; nxt < n; ++nxt)
- __os_freestr(array[nxt]);
- /* FALLTHROUGH */
-
-err1: if (array != NULL) {
- for (arrayp = array; *arrayp != NULL; ++arrayp)
- __os_freestr(*arrayp);
- __os_free(array, array_size * sizeof(char *));
- }
- return (ret);
-}
-
-/*
- * __absname --
- * Return an absolute path name for the file.
- */
-static int
-__absname(pref, name, newnamep)
- char *pref, *name, **newnamep;
-{
- size_t l_pref, l_name;
- int isabspath, ret;
- char *newname;
-
- l_name = strlen(name);
- isabspath = __os_abspath(name);
- l_pref = isabspath ? 0 : strlen(pref);
-
- /* Malloc space for concatenating the two. */
- if ((ret = __os_malloc(l_pref + l_name + 2, NULL, &newname)) != 0)
- return (ret);
- *newnamep = newname;
-
- /* Build the name. If `name' is an absolute path, ignore any prefix. */
- if (!isabspath) {
- memcpy(newname, pref, l_pref);
- if (strchr(PATH_SEPARATOR, newname[l_pref - 1]) == NULL)
- newname[l_pref++] = PATH_SEPARATOR[0];
- }
- memcpy(newname + l_pref, name, l_name + 1);
-
- return (0);
-}
-
-/*
- * __usermem --
- * Create a single chunk of memory that holds the returned information.
- * If the user has their own malloc routine, use it.
- */
-static int
-__usermem(listp, db_malloc)
- char ***listp;
- void *(*db_malloc) __P((size_t));
-{
- size_t len;
- int ret;
- char **array, **arrayp, **orig, *strp;
-
- /* Find out how much space we need. */
- for (len = 0, orig = *listp; *orig != NULL; ++orig)
- len += sizeof(char *) + strlen(*orig) + 1;
- len += sizeof(char *);
-
- /* Allocate it and set up the pointers. */
- if ((ret = __os_malloc(len, db_malloc, &array)) != 0)
- return (ret);
-
- strp = (char *)(array + (orig - *listp) + 1);
-
- /* Copy the original information into the new memory. */
- for (orig = *listp, arrayp = array; *orig != NULL; ++orig, ++arrayp) {
- len = strlen(*orig);
- memcpy(strp, *orig, len + 1);
- *arrayp = strp;
- strp += len + 1;
-
- __os_freestr(*orig);
- }
-
- /* NULL-terminate the list. */
- *arrayp = NULL;
-
- __os_free(*listp, 0);
- *listp = array;
-
- return (0);
-}
-
-static int
-__cmpfunc(p1, p2)
- const void *p1, *p2;
-{
- return (strcmp(*((char * const *)p1), *((char * const *)p2)));
-}
diff --git a/db2/log/log_auto.c b/db2/log/log_auto.c
deleted file mode 100644
index 92e6826..0000000
--- a/db2/log/log_auto.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* Do not edit: automatically built by dist/db_gen.sh. */
-#include "config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <ctype.h>
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "db_page.h"
-#include "db_dispatch.h"
-#include "log.h"
-#include "db_am.h"
-/*
- * PUBLIC: int __log_register_log
- * PUBLIC: __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
- * PUBLIC: u_int32_t, const DBT *, const DBT *, u_int32_t,
- * PUBLIC: DBTYPE));
- */
-int __log_register_log(logp, txnid, ret_lsnp, flags,
- opcode, name, uid, id, ftype)
- DB_LOG *logp;
- DB_TXN *txnid;
- DB_LSN *ret_lsnp;
- u_int32_t flags;
- u_int32_t opcode;
- const DBT *name;
- const DBT *uid;
- u_int32_t id;
- DBTYPE ftype;
-{
- DBT logrec;
- DB_LSN *lsnp, null_lsn;
- u_int32_t zero;
- u_int32_t rectype, txn_num;
- int ret;
- u_int8_t *bp;
-
- rectype = DB_log_register;
- txn_num = txnid == NULL ? 0 : txnid->txnid;
- if (txnid == NULL) {
- ZERO_LSN(null_lsn);
- lsnp = &null_lsn;
- } else
- lsnp = &txnid->last_lsn;
- logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
- + sizeof(opcode)
- + sizeof(u_int32_t) + (name == NULL ? 0 : name->size)
- + sizeof(u_int32_t) + (uid == NULL ? 0 : uid->size)
- + sizeof(id)
- + sizeof(ftype);
- if ((ret = __os_malloc(logrec.size, NULL, &logrec.data)) != 0)
- return (ret);
-
- bp = logrec.data;
- memcpy(bp, &rectype, sizeof(rectype));
- bp += sizeof(rectype);
- memcpy(bp, &txn_num, sizeof(txn_num));
- bp += sizeof(txn_num);
- memcpy(bp, lsnp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(bp, &opcode, sizeof(opcode));
- bp += sizeof(opcode);
- if (name == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &name->size, sizeof(name->size));
- bp += sizeof(name->size);
- memcpy(bp, name->data, name->size);
- bp += name->size;
- }
- if (uid == NULL) {
- zero = 0;
- memcpy(bp, &zero, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- } else {
- memcpy(bp, &uid->size, sizeof(uid->size));
- bp += sizeof(uid->size);
- memcpy(bp, uid->data, uid->size);
- bp += uid->size;
- }
- memcpy(bp, &id, sizeof(id));
- bp += sizeof(id);
- memcpy(bp, &ftype, sizeof(ftype));
- bp += sizeof(ftype);
-#ifdef DIAGNOSTIC
- if ((u_int32_t)(bp - (u_int8_t *)logrec.data) != logrec.size)
- fprintf(stderr, "Error in log record length");
-#endif
- ret = __log_put(logp, ret_lsnp, (DBT *)&logrec, flags);
- if (txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
- __os_free(logrec.data, 0);
- return (ret);
-}
-
-/*
- * PUBLIC: int __log_register_print
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__log_register_print(notused1, dbtp, lsnp, notused2, notused3)
- DB_LOG *notused1;
- DBT *dbtp;
- DB_LSN *lsnp;
- int notused2;
- void *notused3;
-{
- __log_register_args *argp;
- u_int32_t i;
- u_int ch;
- int ret;
-
- i = 0;
- ch = 0;
- notused1 = NULL;
- notused2 = 0;
- notused3 = NULL;
-
- if ((ret = __log_register_read(dbtp->data, &argp)) != 0)
- return (ret);
- printf("[%lu][%lu]log_register: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- printf("\topcode: %lu\n", (u_long)argp->opcode);
- printf("\tname: ");
- for (i = 0; i < argp->name.size; i++) {
- ch = ((u_int8_t *)argp->name.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tuid: ");
- for (i = 0; i < argp->uid.size; i++) {
- ch = ((u_int8_t *)argp->uid.data)[i];
- if (isprint(ch) || ch == 0xa)
- putchar(ch);
- else
- printf("%#x ", ch);
- }
- printf("\n");
- printf("\tid: %lu\n", (u_long)argp->id);
- printf("\tftype: 0x%lx\n", (u_long)argp->ftype);
- printf("\n");
- __os_free(argp, 0);
- return (0);
-}
-
-/*
- * PUBLIC: int __log_register_read __P((void *, __log_register_args **));
- */
-int
-__log_register_read(recbuf, argpp)
- void *recbuf;
- __log_register_args **argpp;
-{
- __log_register_args *argp;
- u_int8_t *bp;
- int ret;
-
- ret = __os_malloc(sizeof(__log_register_args) +
- sizeof(DB_TXN), NULL, &argp);
- if (ret != 0)
- return (ret);
- argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
- memcpy(&argp->type, bp, sizeof(argp->type));
- bp += sizeof(argp->type);
- memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
- bp += sizeof(argp->txnid->txnid);
- memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
- bp += sizeof(DB_LSN);
- memcpy(&argp->opcode, bp, sizeof(argp->opcode));
- bp += sizeof(argp->opcode);
- memcpy(&argp->name.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->name.data = bp;
- bp += argp->name.size;
- memcpy(&argp->uid.size, bp, sizeof(u_int32_t));
- bp += sizeof(u_int32_t);
- argp->uid.data = bp;
- bp += argp->uid.size;
- memcpy(&argp->id, bp, sizeof(argp->id));
- bp += sizeof(argp->id);
- memcpy(&argp->ftype, bp, sizeof(argp->ftype));
- bp += sizeof(argp->ftype);
- *argpp = argp;
- return (0);
-}
-
-/*
- * PUBLIC: int __log_init_print __P((DB_ENV *));
- */
-int
-__log_init_print(dbenv)
- DB_ENV *dbenv;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv,
- __log_register_print, DB_log_register)) != 0)
- return (ret);
- return (0);
-}
-
-/*
- * PUBLIC: int __log_init_recover __P((DB_ENV *));
- */
-int
-__log_init_recover(dbenv)
- DB_ENV *dbenv;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv,
- __log_register_recover, DB_log_register)) != 0)
- return (ret);
- return (0);
-}
-
diff --git a/db2/log/log_compare.c b/db2/log/log_compare.c
deleted file mode 100644
index 320b34a..0000000
--- a/db2/log/log_compare.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_compare.c 10.3 (Sleepycat) 4/10/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-#endif
-
-#include "db_int.h"
-
-/*
- * log_compare --
- * Compare two LSN's.
- */
-int
-log_compare(lsn0, lsn1)
- const DB_LSN *lsn0, *lsn1;
-{
- if (lsn0->file != lsn1->file)
- return (lsn0->file < lsn1->file ? -1 : 1);
-
- if (lsn0->offset != lsn1->offset)
- return (lsn0->offset < lsn1->offset ? -1 : 1);
-
- return (0);
-}
diff --git a/db2/log/log_findckp.c b/db2/log/log_findckp.c
deleted file mode 100644
index ab13c83..0000000
--- a/db2/log/log_findckp.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_findckp.c 10.17 (Sleepycat) 9/17/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "log.h"
-#include "txn.h"
-#include "common_ext.h"
-
-/*
- * __log_findckp --
- *
- * Looks for the most recent checkpoint that occurs before the most recent
- * checkpoint LSN, subject to the constraint that there must be at least two
- * checkpoints. The reason you need two checkpoints is that you might have
- * crashed during the most recent one and may not have a copy of all the
- * open files. This is the point from which recovery can start and the
- * point up to which archival/truncation can take place. Checkpoints in
- * the log look like:
- *
- * -------------------------------------------------------------------
- * | ckp A, ckplsn 100 | .... record .... | ckp B, ckplsn 600 | ...
- * -------------------------------------------------------------------
- * LSN 500 LSN 1000
- *
- * If we read what log returns from using the DB_CKP parameter to logput,
- * we'll get the record at LSN 1000. The checkpoint LSN there is 600.
- * Now we have to scan backwards looking for a checkpoint before LSN 600.
- * We find one at 500. This means that we can truncate the log before
- * 500 or run recovery beginning at 500.
- *
- * Returns 0 if we find a suitable checkpoint or we retrieved the
- * first record in the log from which to start.
- * Returns DB_NOTFOUND if there are no log records.
- * Returns errno on error.
- *
- * PUBLIC: int __log_findckp __P((DB_LOG *, DB_LSN *));
- */
-int
-__log_findckp(lp, lsnp)
- DB_LOG *lp;
- DB_LSN *lsnp;
-{
- DBT data;
- DB_LSN ckp_lsn, final_ckp, last_ckp, next_lsn;
- __txn_ckp_args *ckp_args;
- int ret, verbose;
-
- verbose = lp->dbenv != NULL && lp->dbenv->db_verbose != 0;
-
- /*
- * Need to find the appropriate point from which to begin
- * recovery.
- */
- memset(&data, 0, sizeof(data));
- if (F_ISSET(lp, DB_AM_THREAD))
- F_SET(&data, DB_DBT_MALLOC);
- ZERO_LSN(ckp_lsn);
- if ((ret = log_get(lp, &last_ckp, &data, DB_CHECKPOINT)) != 0) {
- if (ret == ENOENT)
- goto get_first;
- else
- return (ret);
- }
-
- final_ckp = last_ckp;
- next_lsn = last_ckp;
- do {
- if (F_ISSET(lp, DB_AM_THREAD))
- __os_free(data.data, data.size);
-
- if ((ret = log_get(lp, &next_lsn, &data, DB_SET)) != 0)
- return (ret);
- if ((ret = __txn_ckp_read(data.data, &ckp_args)) != 0) {
- if (F_ISSET(lp, DB_AM_THREAD))
- __os_free(data.data, data.size);
- return (ret);
- }
- if (IS_ZERO_LSN(ckp_lsn))
- ckp_lsn = ckp_args->ckp_lsn;
- if (verbose) {
- __db_err(lp->dbenv, "Checkpoint at: [%lu][%lu]",
- (u_long)last_ckp.file, (u_long)last_ckp.offset);
- __db_err(lp->dbenv, "Checkpoint LSN: [%lu][%lu]",
- (u_long)ckp_args->ckp_lsn.file,
- (u_long)ckp_args->ckp_lsn.offset);
- __db_err(lp->dbenv, "Previous checkpoint: [%lu][%lu]",
- (u_long)ckp_args->last_ckp.file,
- (u_long)ckp_args->last_ckp.offset);
- }
- last_ckp = next_lsn;
- next_lsn = ckp_args->last_ckp;
- __os_free(ckp_args, sizeof(*ckp_args));
-
- /*
- * Keep looping until either you 1) run out of checkpoints,
- * 2) you've found a checkpoint before the most recent
- * checkpoint's LSN and you have at least 2 checkpoints.
- */
- } while (!IS_ZERO_LSN(next_lsn) &&
- (log_compare(&last_ckp, &ckp_lsn) > 0 ||
- log_compare(&final_ckp, &last_ckp) == 0));
-
- if (F_ISSET(lp, DB_AM_THREAD))
- __os_free(data.data, data.size);
-
- /*
- * At this point, either, next_lsn is ZERO or ckp_lsn is the
- * checkpoint lsn and last_ckp is the LSN of the last checkpoint
- * before ckp_lsn. If the compare in the loop is still true, then
- * next_lsn must be 0 and we need to roll forward from the
- * beginning of the log.
- */
- if (log_compare(&last_ckp, &ckp_lsn) > 0 ||
- log_compare(&final_ckp, &last_ckp) == 0) {
-get_first: if ((ret = log_get(lp, &last_ckp, &data, DB_FIRST)) != 0)
- return (ret);
- if (F_ISSET(lp, DB_AM_THREAD))
- __os_free(data.data, data.size);
- }
- *lsnp = last_ckp;
-
- return (IS_ZERO_LSN(last_ckp) ? DB_NOTFOUND : 0);
-}
diff --git a/db2/log/log_get.c b/db2/log/log_get.c
deleted file mode 100644
index de81519..0000000
--- a/db2/log/log_get.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_get.c 10.38 (Sleepycat) 10/3/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "log.h"
-#include "hash.h"
-#include "common_ext.h"
-
-/*
- * log_get --
- * Get a log record.
- */
-int
-log_get(dblp, alsn, dbt, flags)
- DB_LOG *dblp;
- DB_LSN *alsn;
- DBT *dbt;
- u_int32_t flags;
-{
- int ret;
-
- LOG_PANIC_CHECK(dblp);
-
- /* Validate arguments. */
- if (flags != DB_CHECKPOINT && flags != DB_CURRENT &&
- flags != DB_FIRST && flags != DB_LAST &&
- flags != DB_NEXT && flags != DB_PREV && flags != DB_SET)
- return (__db_ferr(dblp->dbenv, "log_get", 1));
-
- if (F_ISSET(dblp, DB_AM_THREAD)) {
- if (flags == DB_NEXT || flags == DB_PREV || flags == DB_CURRENT)
- return (__db_ferr(dblp->dbenv, "log_get", 1));
- if (!F_ISSET(dbt, DB_DBT_USERMEM | DB_DBT_MALLOC))
- return (__db_ferr(dblp->dbenv, "threaded data", 1));
- }
-
- LOCK_LOGREGION(dblp);
-
- /*
- * If we get one of the log's header records, repeat the operation.
- * This assumes that applications don't ever request the log header
- * records by LSN, but that seems reasonable to me.
- */
- ret = __log_get(dblp, alsn, dbt, flags, 0);
- if (ret == 0 && alsn->offset == 0) {
- switch (flags) {
- case DB_FIRST:
- flags = DB_NEXT;
- break;
- case DB_LAST:
- flags = DB_PREV;
- break;
- }
- ret = __log_get(dblp, alsn, dbt, flags, 0);
- }
-
- UNLOCK_LOGREGION(dblp);
-
- return (ret);
-}
-
-/*
- * __log_get --
- * Get a log record; internal version.
- *
- * PUBLIC: int __log_get __P((DB_LOG *, DB_LSN *, DBT *, u_int32_t, int));
- */
-int
-__log_get(dblp, alsn, dbt, flags, silent)
- DB_LOG *dblp;
- DB_LSN *alsn;
- DBT *dbt;
- u_int32_t flags;
- int silent;
-{
- DB_LSN nlsn;
- HDR hdr;
- LOG *lp;
- size_t len;
- ssize_t nr;
- int cnt, ret;
- char *np, *tbuf;
- const char *fail;
- void *p, *shortp;
-
- lp = dblp->lp;
- fail = np = tbuf = NULL;
-
- nlsn = dblp->c_lsn;
- switch (flags) {
- case DB_CHECKPOINT:
- nlsn = lp->chkpt_lsn;
- if (IS_ZERO_LSN(nlsn)) {
- __db_err(dblp->dbenv,
- "log_get: unable to find checkpoint record: no checkpoint set.");
- ret = ENOENT;
- goto err2;
- }
- break;
- case DB_NEXT: /* Next log record. */
- if (!IS_ZERO_LSN(nlsn)) {
- /* Increment the cursor by the cursor record size. */
- nlsn.offset += dblp->c_len;
- break;
- }
- /* FALLTHROUGH */
- case DB_FIRST: /* Find the first log record. */
- /* Find the first log file. */
- if ((ret = __log_find(dblp, 1, &cnt)) != 0)
- goto err2;
-
- /*
- * We may have only entered records in the buffer, and not
- * yet written a log file. If no log files were found and
- * there's anything in the buffer, it belongs to file 1.
- */
- if (cnt == 0)
- cnt = 1;
-
- nlsn.file = cnt;
- nlsn.offset = 0;
- break;
- case DB_CURRENT: /* Current log record. */
- break;
- case DB_PREV: /* Previous log record. */
- if (!IS_ZERO_LSN(nlsn)) {
- /* If at start-of-file, move to the previous file. */
- if (nlsn.offset == 0) {
- if (nlsn.file == 1 ||
- __log_valid(dblp, nlsn.file - 1, 0) != 0)
- return (DB_NOTFOUND);
-
- --nlsn.file;
- nlsn.offset = dblp->c_off;
- } else
- nlsn.offset = dblp->c_off;
- break;
- }
- /* FALLTHROUGH */
- case DB_LAST: /* Last log record. */
- nlsn.file = lp->lsn.file;
- nlsn.offset = lp->lsn.offset - lp->len;
- break;
- case DB_SET: /* Set log record. */
- nlsn = *alsn;
- break;
- }
-
-retry:
- /* Return 1 if the request is past end-of-file. */
- if (nlsn.file > lp->lsn.file ||
- (nlsn.file == lp->lsn.file && nlsn.offset >= lp->lsn.offset))
- return (DB_NOTFOUND);
-
- /* If we've switched files, discard the current fd. */
- if (dblp->c_lsn.file != nlsn.file && dblp->c_fd != -1) {
- (void)__os_close(dblp->c_fd);
- dblp->c_fd = -1;
- }
-
- /* If the entire record is in the in-memory buffer, copy it out. */
- if (nlsn.file == lp->lsn.file && nlsn.offset >= lp->w_off) {
- /* Copy the header. */
- p = lp->buf + (nlsn.offset - lp->w_off);
- memcpy(&hdr, p, sizeof(HDR));
-
- /* Copy the record. */
- len = hdr.len - sizeof(HDR);
- if ((ret = __db_retcopy(dbt, (u_int8_t *)p + sizeof(HDR),
- len, &dblp->c_dbt.data, &dblp->c_dbt.ulen, NULL)) != 0)
- goto err1;
- goto cksum;
- }
-
- /* Acquire a file descriptor. */
- if (dblp->c_fd == -1) {
- if ((ret = __log_name(dblp, nlsn.file,
- &np, &dblp->c_fd, DB_RDONLY | DB_SEQUENTIAL)) != 0) {
- fail = np;
- goto err1;
- }
- __os_freestr(np);
- np = NULL;
- }
-
- /* Seek to the header offset and read the header. */
- if ((ret =
- __os_seek(dblp->c_fd, 0, 0, nlsn.offset, 0, SEEK_SET)) != 0) {
- fail = "seek";
- goto err1;
- }
- if ((ret = __os_read(dblp->c_fd, &hdr, sizeof(HDR), &nr)) != 0) {
- fail = "read";
- goto err1;
- }
- if (nr == sizeof(HDR))
- shortp = NULL;
- else {
- /* If read returns EOF, try the next file. */
- if (nr == 0) {
- if (flags != DB_NEXT || nlsn.file == lp->lsn.file)
- goto corrupt;
-
- /* Move to the next file. */
- ++nlsn.file;
- nlsn.offset = 0;
- goto retry;
- }
-
- /*
- * If read returns a short count the rest of the record has
- * to be in the in-memory buffer.
- */
- if (lp->b_off < sizeof(HDR) - nr)
- goto corrupt;
-
- /* Get the rest of the header from the in-memory buffer. */
- memcpy((u_int8_t *)&hdr + nr, lp->buf, sizeof(HDR) - nr);
- shortp = lp->buf + (sizeof(HDR) - nr);
- }
-
- /*
- * Check for buffers of 0's, that's what we usually see during
- * recovery, although it's certainly not something on which we
- * can depend.
- */
- if (hdr.len <= sizeof(HDR))
- goto corrupt;
- len = hdr.len - sizeof(HDR);
-
- /* If we've already moved to the in-memory buffer, fill from there. */
- if (shortp != NULL) {
- if (lp->b_off < ((u_int8_t *)shortp - lp->buf) + len)
- goto corrupt;
- if ((ret = __db_retcopy(dbt, shortp, len,
- &dblp->c_dbt.data, &dblp->c_dbt.ulen, NULL)) != 0)
- goto err1;
- goto cksum;
- }
-
- /*
- * Allocate temporary memory to hold the record.
- *
- * XXX
- * We're calling malloc(3) with a region locked. This isn't
- * a good idea.
- */
- if ((ret = __os_malloc(len, NULL, &tbuf)) != 0)
- goto err1;
-
- /*
- * Read the record into the buffer. If read returns a short count,
- * there was an error or the rest of the record is in the in-memory
- * buffer. Note, the information may be garbage if we're in recovery,
- * so don't read past the end of the buffer's memory.
- */
- if ((ret = __os_read(dblp->c_fd, tbuf, len, &nr)) != 0) {
- fail = "read";
- goto err1;
- }
- if (len - nr > sizeof(lp->buf))
- goto corrupt;
- if (nr != (ssize_t)len) {
- if (lp->b_off < len - nr)
- goto corrupt;
-
- /* Get the rest of the record from the in-memory buffer. */
- memcpy((u_int8_t *)tbuf + nr, lp->buf, len - nr);
- }
-
- /* Copy the record into the user's DBT. */
- if ((ret = __db_retcopy(dbt, tbuf, len,
- &dblp->c_dbt.data, &dblp->c_dbt.ulen, NULL)) != 0)
- goto err1;
- __os_free(tbuf, 0);
- tbuf = NULL;
-
-cksum: if (hdr.cksum != __ham_func4(dbt->data, dbt->size)) {
- if (!silent)
- __db_err(dblp->dbenv, "log_get: checksum mismatch");
- goto corrupt;
- }
-
- /* Update the cursor and the return lsn. */
- dblp->c_off = hdr.prev;
- dblp->c_len = hdr.len;
- dblp->c_lsn = *alsn = nlsn;
-
- return (0);
-
-corrupt:/*
- * This is the catchall -- for some reason we didn't find enough
- * information or it wasn't reasonable information, and it wasn't
- * because a system call failed.
- */
- ret = EIO;
- fail = "read";
-
-err1: if (!silent) {
- if (fail == NULL)
- __db_err(dblp->dbenv, "log_get: %s", strerror(ret));
- else
- __db_err(dblp->dbenv,
- "log_get: %s: %s", fail, strerror(ret));
- }
-err2: if (np != NULL)
- __os_freestr(np);
- if (tbuf != NULL)
- __os_free(tbuf, 0);
- return (ret);
-}
diff --git a/db2/log/log_put.c b/db2/log/log_put.c
deleted file mode 100644
index 86de6b0..0000000
--- a/db2/log/log_put.c
+++ /dev/null
@@ -1,603 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_put.c 10.44 (Sleepycat) 11/3/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "log.h"
-#include "hash.h"
-#include "clib_ext.h"
-#include "common_ext.h"
-
-static int __log_fill __P((DB_LOG *, DB_LSN *, void *, u_int32_t));
-static int __log_flush __P((DB_LOG *, const DB_LSN *));
-static int __log_newfd __P((DB_LOG *));
-static int __log_putr __P((DB_LOG *, DB_LSN *, const DBT *, u_int32_t));
-static int __log_write __P((DB_LOG *, void *, u_int32_t));
-
-/*
- * log_put --
- * Write a log record.
- */
-int
-log_put(dblp, lsn, dbt, flags)
- DB_LOG *dblp;
- DB_LSN *lsn;
- const DBT *dbt;
- u_int32_t flags;
-{
- int ret;
-
- LOG_PANIC_CHECK(dblp);
-
- /* Validate arguments. */
- if (flags != 0 && flags != DB_CHECKPOINT &&
- flags != DB_CURLSN && flags != DB_FLUSH)
- return (__db_ferr(dblp->dbenv, "log_put", 0));
-
- LOCK_LOGREGION(dblp);
- ret = __log_put(dblp, lsn, dbt, flags);
- UNLOCK_LOGREGION(dblp);
- return (ret);
-}
-
-/*
- * __log_put --
- * Write a log record; internal version.
- *
- * PUBLIC: int __log_put __P((DB_LOG *, DB_LSN *, const DBT *, u_int32_t));
- */
-int
-__log_put(dblp, lsn, dbt, flags)
- DB_LOG *dblp;
- DB_LSN *lsn;
- const DBT *dbt;
- u_int32_t flags;
-{
- DBT fid_dbt, t;
- DB_LSN r_unused;
- FNAME *fnp;
- LOG *lp;
- u_int32_t lastoff;
- int ret;
-
- lp = dblp->lp;
-
- /*
- * If the application just wants to know where we are, fill in
- * the information. Currently used by the transaction manager
- * to avoid writing TXN_begin records.
- */
- if (flags == DB_CURLSN) {
- lsn->file = lp->lsn.file;
- lsn->offset = lp->lsn.offset;
- return (0);
- }
-
- /* If this information won't fit in the file, swap files. */
- if (lp->lsn.offset + sizeof(HDR) + dbt->size > lp->persist.lg_max) {
- if (sizeof(HDR) +
- sizeof(LOGP) + dbt->size > lp->persist.lg_max) {
- __db_err(dblp->dbenv,
- "log_put: record larger than maximum file size");
- return (EINVAL);
- }
-
- /* Flush the log. */
- if ((ret = __log_flush(dblp, NULL)) != 0)
- return (ret);
-
- /*
- * Save the last known offset from the previous file, we'll
- * need it to initialize the persistent header information.
- */
- lastoff = lp->lsn.offset;
-
- /* Point the current LSN to the new file. */
- ++lp->lsn.file;
- lp->lsn.offset = 0;
-
- /* Reset the file write offset. */
- lp->w_off = 0;
- } else
- lastoff = 0;
-
- /* Initialize the LSN information returned to the user. */
- lsn->file = lp->lsn.file;
- lsn->offset = lp->lsn.offset;
-
- /*
- * Insert persistent information as the first record in every file.
- * Note that the previous length is wrong for the very first record
- * of the log, but that's okay, we check for it during retrieval.
- */
- if (lp->lsn.offset == 0) {
- t.data = &lp->persist;
- t.size = sizeof(LOGP);
- if ((ret = __log_putr(dblp, lsn,
- &t, lastoff == 0 ? 0 : lastoff - lp->len)) != 0)
- return (ret);
-
- /* Update the LSN information returned to the user. */
- lsn->file = lp->lsn.file;
- lsn->offset = lp->lsn.offset;
- }
-
- /* Write the application's log record. */
- if ((ret = __log_putr(dblp, lsn, dbt, lp->lsn.offset - lp->len)) != 0)
- return (ret);
-
- /*
- * On a checkpoint, we:
- * Put out the checkpoint record (above).
- * Save the LSN of the checkpoint in the shared region.
- * Append the set of file name information into the log.
- */
- if (flags == DB_CHECKPOINT) {
- lp->chkpt_lsn = *lsn;
-
- for (fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
- fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
- if (fnp->ref == 0) /* Entry not in use. */
- continue;
- memset(&t, 0, sizeof(t));
- t.data = R_ADDR(dblp, fnp->name_off);
- t.size = strlen(t.data) + 1;
- memset(&fid_dbt, 0, sizeof(fid_dbt));
- fid_dbt.data = fnp->ufid;
- fid_dbt.size = DB_FILE_ID_LEN;
- if ((ret = __log_register_log(dblp, NULL, &r_unused, 0,
- LOG_CHECKPOINT, &t, &fid_dbt, fnp->id, fnp->s_type))
- != 0)
- return (ret);
- }
- }
-
- /*
- * On a checkpoint or when flush is requested, we:
- * Flush the current buffer contents to disk.
- * Sync the log to disk.
- */
- if (flags == DB_FLUSH || flags == DB_CHECKPOINT)
- if ((ret = __log_flush(dblp, NULL)) != 0)
- return (ret);
-
- /*
- * On a checkpoint, we:
- * Save the time the checkpoint was written.
- * Reset the bytes written since the last checkpoint.
- */
- if (flags == DB_CHECKPOINT) {
- (void)time(&lp->chkpt);
- lp->stat.st_wc_bytes = lp->stat.st_wc_mbytes = 0;
- }
- return (0);
-}
-
-/*
- * __log_putr --
- * Actually put a record into the log.
- */
-static int
-__log_putr(dblp, lsn, dbt, prev)
- DB_LOG *dblp;
- DB_LSN *lsn;
- const DBT *dbt;
- u_int32_t prev;
-{
- HDR hdr;
- LOG *lp;
- int ret;
-
- lp = dblp->lp;
-
- /*
- * Initialize the header. If we just switched files, lsn.offset will
- * be 0, and what we really want is the offset of the previous record
- * in the previous file. Fortunately, prev holds the value we want.
- */
- hdr.prev = prev;
- hdr.len = sizeof(HDR) + dbt->size;
- hdr.cksum = __ham_func4(dbt->data, dbt->size);
-
- if ((ret = __log_fill(dblp, lsn, &hdr, sizeof(HDR))) != 0)
- return (ret);
- lp->len = sizeof(HDR);
- lp->lsn.offset += sizeof(HDR);
-
- if ((ret = __log_fill(dblp, lsn, dbt->data, dbt->size)) != 0)
- return (ret);
- lp->len += dbt->size;
- lp->lsn.offset += dbt->size;
- return (0);
-}
-
-/*
- * log_flush --
- * Write all records less than or equal to the specified LSN.
- */
-int
-log_flush(dblp, lsn)
- DB_LOG *dblp;
- const DB_LSN *lsn;
-{
- int ret;
-
- LOG_PANIC_CHECK(dblp);
-
- LOCK_LOGREGION(dblp);
- ret = __log_flush(dblp, lsn);
- UNLOCK_LOGREGION(dblp);
- return (ret);
-}
-
-/*
- * __log_flush --
- * Write all records less than or equal to the specified LSN; internal
- * version.
- */
-static int
-__log_flush(dblp, lsn)
- DB_LOG *dblp;
- const DB_LSN *lsn;
-{
- DB_LSN t_lsn;
- LOG *lp;
- int current, ret;
-
- ret = 0;
- lp = dblp->lp;
-
- /*
- * If no LSN specified, flush the entire log by setting the flush LSN
- * to the last LSN written in the log. Otherwise, check that the LSN
- * isn't a non-existent record for the log.
- */
- if (lsn == NULL) {
- t_lsn.file = lp->lsn.file;
- t_lsn.offset = lp->lsn.offset - lp->len;
- lsn = &t_lsn;
- } else
- if (lsn->file > lp->lsn.file ||
- (lsn->file == lp->lsn.file &&
- lsn->offset > lp->lsn.offset - lp->len)) {
- __db_err(dblp->dbenv,
- "log_flush: LSN past current end-of-log");
- return (EINVAL);
- }
-
- /*
- * If the LSN is less than the last-sync'd LSN, we're done. Note,
- * the last-sync LSN saved in s_lsn is the LSN of the first byte
- * we absolutely know has been written to disk, so the test is <=.
- */
- if (lsn->file < lp->s_lsn.file ||
- (lsn->file == lp->s_lsn.file && lsn->offset <= lp->s_lsn.offset))
- return (0);
-
- /*
- * We may need to write the current buffer. We have to write the
- * current buffer if the flush LSN is greater than or equal to the
- * buffer's starting LSN.
- */
- current = 0;
- if (lp->b_off != 0 && log_compare(lsn, &lp->f_lsn) >= 0) {
- if ((ret = __log_write(dblp, lp->buf, lp->b_off)) != 0)
- return (ret);
-
- lp->b_off = 0;
- current = 1;
- }
-
- /*
- * It's possible that this thread may never have written to this log
- * file. Acquire a file descriptor if we don't already have one.
- */
- if (dblp->lfname != dblp->lp->lsn.file)
- if ((ret = __log_newfd(dblp)) != 0)
- return (ret);
-
- /* Sync all writes to disk. */
- if ((ret = __os_fsync(dblp->lfd)) != 0) {
- __db_panic(dblp->dbenv, ret);
- return (ret);
- }
- ++lp->stat.st_scount;
-
- /*
- * Set the last-synced LSN, using the LSN of the current buffer. If
- * the current buffer was flushed, we know the LSN of the first byte
- * of the buffer is on disk, otherwise, we only know that the LSN of
- * the record before the one beginning the current buffer is on disk.
- *
- * XXX
- * Check to make sure that the saved lsn isn't 0 before we go making
- * this change. If DB_CHECKPOINT was called before we actually wrote
- * something, you can end up here without ever having written anything
- * to a log file, and decrementing either s_lsn.file or s_lsn.offset
- * will cause much sadness later on.
- */
- lp->s_lsn = lp->f_lsn;
- if (!current && lp->s_lsn.file != 0) {
- if (lp->s_lsn.offset == 0) {
- --lp->s_lsn.file;
- lp->s_lsn.offset = lp->persist.lg_max;
- } else
- --lp->s_lsn.offset;
- }
-
- return (0);
-}
-
-/*
- * __log_fill --
- * Write information into the log.
- */
-static int
-__log_fill(dblp, lsn, addr, len)
- DB_LOG *dblp;
- DB_LSN *lsn;
- void *addr;
- u_int32_t len;
-{
- LOG *lp;
- u_int32_t nrec;
- size_t nw, remain;
- int ret;
-
- /* Copy out the data. */
- for (lp = dblp->lp; len > 0;) {
- /*
- * If we're beginning a new buffer, note the user LSN to which
- * the first byte of the buffer belongs. We have to know this
- * when flushing the buffer so that we know if the in-memory
- * buffer needs to be flushed.
- */
- if (lp->b_off == 0)
- lp->f_lsn = *lsn;
-
- /*
- * If we're on a buffer boundary and the data is big enough,
- * copy as many records as we can directly from the data.
- */
- if (lp->b_off == 0 && len >= sizeof(lp->buf)) {
- nrec = len / sizeof(lp->buf);
- if ((ret = __log_write(dblp,
- addr, nrec * sizeof(lp->buf))) != 0)
- return (ret);
- addr = (u_int8_t *)addr + nrec * sizeof(lp->buf);
- len -= nrec * sizeof(lp->buf);
- continue;
- }
-
- /* Figure out how many bytes we can copy this time. */
- remain = sizeof(lp->buf) - lp->b_off;
- nw = remain > len ? len : remain;
- memcpy(lp->buf + lp->b_off, addr, nw);
- addr = (u_int8_t *)addr + nw;
- len -= nw;
- lp->b_off += nw;
-
- /* If we fill the buffer, flush it. */
- if (lp->b_off == sizeof(lp->buf)) {
- if ((ret =
- __log_write(dblp, lp->buf, sizeof(lp->buf))) != 0)
- return (ret);
- lp->b_off = 0;
- }
- }
- return (0);
-}
-
-/*
- * __log_write --
- * Write the log buffer to disk.
- */
-static int
-__log_write(dblp, addr, len)
- DB_LOG *dblp;
- void *addr;
- u_int32_t len;
-{
- LOG *lp;
- ssize_t nw;
- int ret;
-
- /*
- * If we haven't opened the log file yet or the current one
- * has changed, acquire a new log file.
- */
- lp = dblp->lp;
- if (dblp->lfd == -1 || dblp->lfname != lp->lsn.file)
- if ((ret = __log_newfd(dblp)) != 0)
- return (ret);
-
- /*
- * Seek to the offset in the file (someone may have written it
- * since we last did).
- */
- if ((ret = __os_seek(dblp->lfd, 0, 0, lp->w_off, 0, SEEK_SET)) != 0 ||
- (ret = __os_write(dblp->lfd, addr, len, &nw)) != 0) {
- __db_panic(dblp->dbenv, ret);
- return (ret);
- }
- if (nw != (int32_t)len)
- return (EIO);
-
- /* Reset the buffer offset and update the seek offset. */
- lp->w_off += len;
-
- /* Update written statistics. */
- if ((lp->stat.st_w_bytes += len) >= MEGABYTE) {
- lp->stat.st_w_bytes -= MEGABYTE;
- ++lp->stat.st_w_mbytes;
- }
- if ((lp->stat.st_wc_bytes += len) >= MEGABYTE) {
- lp->stat.st_wc_bytes -= MEGABYTE;
- ++lp->stat.st_wc_mbytes;
- }
- ++lp->stat.st_wcount;
-
- return (0);
-}
-
-/*
- * log_file --
- * Map a DB_LSN to a file name.
- */
-int
-log_file(dblp, lsn, namep, len)
- DB_LOG *dblp;
- const DB_LSN *lsn;
- char *namep;
- size_t len;
-{
- int ret;
- char *name;
-
- LOG_PANIC_CHECK(dblp);
-
- LOCK_LOGREGION(dblp);
- ret = __log_name(dblp, lsn->file, &name, NULL, 0);
- UNLOCK_LOGREGION(dblp);
- if (ret != 0)
- return (ret);
-
- /* Check to make sure there's enough room and copy the name. */
- if (len < strlen(name) + 1) {
- *namep = '\0';
- return (ENOMEM);
- }
- (void)strcpy(namep, name);
- __os_freestr(name);
-
- return (0);
-}
-
-/*
- * __log_newfd --
- * Acquire a file descriptor for the current log file.
- */
-static int
-__log_newfd(dblp)
- DB_LOG *dblp;
-{
- int ret;
- char *name;
-
- /* Close any previous file descriptor. */
- if (dblp->lfd != -1) {
- (void)__os_close(dblp->lfd);
- dblp->lfd = -1;
- }
-
- /* Get the path of the new file and open it. */
- dblp->lfname = dblp->lp->lsn.file;
- if ((ret = __log_name(dblp,
- dblp->lfname, &name, &dblp->lfd, DB_CREATE | DB_SEQUENTIAL)) != 0)
- __db_err(dblp->dbenv, "log_put: %s: %s", name, strerror(ret));
-
- __os_freestr(name);
- return (ret);
-}
-
-/*
- * __log_name --
- * Return the log name for a particular file, and optionally open it.
- *
- * PUBLIC: int __log_name __P((DB_LOG *, u_int32_t, char **, int *, u_int32_t));
- */
-int
-__log_name(dblp, filenumber, namep, fdp, flags)
- DB_LOG *dblp;
- u_int32_t filenumber, flags;
- char **namep;
- int *fdp;
-{
- int ret;
- char *oname;
- char old[sizeof(LFPREFIX) + 5 + 20], new[sizeof(LFPREFIX) + 10 + 20];
-
- /*
- * !!!
- * The semantics of this routine are bizarre.
- *
- * The reason for all of this is that we need a place where we can
- * intercept requests for log files, and, if appropriate, check for
- * both the old-style and new-style log file names. The trick is
- * that all callers of this routine that are opening the log file
- * read-only want to use an old-style file name if they can't find
- * a match using a new-style name. The only down-side is that some
- * callers may check for the old-style when they really don't need
- * to, but that shouldn't mess up anything, and we only check for
- * the old-style name when we've already failed to find a new-style
- * one.
- *
- * Create a new-style file name, and if we're not going to open the
- * file, return regardless.
- */
- (void)snprintf(new, sizeof(new), LFNAME, filenumber);
- if ((ret = __db_appname(dblp->dbenv,
- DB_APP_LOG, dblp->dir, new, 0, NULL, namep)) != 0 || fdp == NULL)
- return (ret);
-
- /* Open the new-style file -- if we succeed, we're done. */
- if ((ret = __db_open(*namep,
- flags, flags, dblp->lp->persist.mode, fdp)) == 0)
- return (0);
-
- /*
- * The open failed... if the DB_RDONLY flag isn't set, we're done,
- * the caller isn't interested in old-style files.
- */
- if (!LF_ISSET(DB_RDONLY))
- return (ret);
-
- /* Create an old-style file name. */
- (void)snprintf(old, sizeof(old), LFNAME_V1, filenumber);
- if ((ret = __db_appname(dblp->dbenv,
- DB_APP_LOG, dblp->dir, old, 0, NULL, &oname)) != 0)
- goto err;
-
- /*
- * Open the old-style file -- if we succeed, we're done. Free the
- * space allocated for the new-style name and return the old-style
- * name to the caller.
- */
- if ((ret = __db_open(oname,
- flags, flags, dblp->lp->persist.mode, fdp)) == 0) {
- __os_freestr(*namep);
- *namep = oname;
- return (0);
- }
-
- /*
- * Couldn't find either style of name -- return the new-style name
- * for the caller's error message. If it's an old-style name that's
- * actually missing we're going to confuse the user with the error
- * message, but that implies that not only were we looking for an
- * old-style name, but we expected it to exist and we weren't just
- * looking for any log file. That's not a likely error.
- */
-err: __os_freestr(oname);
- return (ret);
-}
diff --git a/db2/log/log_rec.c b/db2/log/log_rec.c
deleted file mode 100644
index 8895150..0000000
--- a/db2/log/log_rec.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1995, 1996
- * The President and Fellows of Harvard University. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_rec.c 10.26 (Sleepycat) 10/21/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "log.h"
-#include "db_dispatch.h"
-#include "common_ext.h"
-
-static int __log_do_open __P((DB_LOG *,
- u_int8_t *, char *, DBTYPE, u_int32_t));
-static int __log_lid_to_fname __P((DB_LOG *, u_int32_t, FNAME **));
-static int __log_open_file __P((DB_LOG *, __log_register_args *));
-
-/*
- * PUBLIC: int __log_register_recover
- * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
- */
-int
-__log_register_recover(logp, dbtp, lsnp, redo, info)
- DB_LOG *logp;
- DBT *dbtp;
- DB_LSN *lsnp;
- int redo;
- void *info;
-{
- __log_register_args *argp;
- int ret;
-
-#ifdef DEBUG_RECOVER
- __log_register_print(logp, dbtp, lsnp, redo, info);
-#endif
- COMPQUIET(info, NULL);
- COMPQUIET(lsnp, NULL);
-
- F_SET(logp, DBC_RECOVER);
-
- if ((ret = __log_register_read(dbtp->data, &argp)) != 0)
- goto out;
-
- if ((argp->opcode == LOG_CHECKPOINT && redo == TXN_OPENFILES) ||
- (argp->opcode == LOG_OPEN &&
- (redo == TXN_REDO || redo == TXN_OPENFILES ||
- redo == TXN_FORWARD_ROLL)) ||
- (argp->opcode == LOG_CLOSE &&
- (redo == TXN_UNDO || redo == TXN_BACKWARD_ROLL))) {
- /*
- * If we are redoing an open or undoing a close, then we need
- * to open a file.
- */
- ret = __log_open_file(logp, argp);
- if (ret == ENOENT) {
- if (redo == TXN_OPENFILES)
- __db_err(logp->dbenv, "warning: %s: %s",
- argp->name.data, strerror(ENOENT));
- ret = 0;
- }
- } else if (argp->opcode != LOG_CHECKPOINT) {
- /*
- * If we are redoing a close or undoing an open, then we need
- * to close the file.
- *
- * If the file is deleted, then we can just ignore this close.
- * Otherwise, we should usually have a valid dbp we should
- * close or whose reference count should be decremented.
- * However, if we shut down without closing a file, we
- * may, in fact, not have the file open, and that's OK.
- */
- LOCK_LOGTHREAD(logp);
- if (logp->dbentry[argp->id].dbp != NULL &&
- --logp->dbentry[argp->id].refcount == 0) {
- ret = logp->dbentry[argp->id].dbp->close(
- logp->dbentry[argp->id].dbp, 0);
- logp->dbentry[argp->id].dbp = NULL;
- }
- UNLOCK_LOGTHREAD(logp);
- } else if (redo == TXN_UNDO &&
- (argp->id >= logp->dbentry_cnt ||
- (!logp->dbentry[argp->id].deleted &&
- logp->dbentry[argp->id].dbp == NULL))) {
- /*
- * It's a checkpoint and we are rolling backward. It
- * is possible that the system was shut down and thus
- * ended with a stable checkpoint; this file was never
- * closed and has therefore not been reopened yet. If
- * so, we need to try to open it.
- */
- ret = __log_open_file(logp, argp);
- if (ret == ENOENT) {
- __db_err(logp->dbenv, "warning: %s: %s",
- argp->name.data, strerror(ENOENT));
- ret = 0;
- }
- }
-
-out: F_CLR(logp, DBC_RECOVER);
- if (argp != NULL)
- __os_free(argp, 0);
- return (ret);
-}
-
-/* Hand coded routines. */
-
-/*
- * Called during log_register recovery. Make sure that we have an
- * entry in the dbentry table for this ndx.
- * Returns 0 on success, non-zero on error.
- */
-static int
-__log_open_file(lp, argp)
- DB_LOG *lp;
- __log_register_args *argp;
-{
- LOCK_LOGTHREAD(lp);
- if (argp->id < lp->dbentry_cnt &&
- (lp->dbentry[argp->id].deleted == 1 ||
- lp->dbentry[argp->id].dbp != NULL)) {
- if (argp->opcode != LOG_CHECKPOINT)
- lp->dbentry[argp->id].refcount++;
-
- UNLOCK_LOGTHREAD(lp);
- return (0);
- }
- UNLOCK_LOGTHREAD(lp);
- return (__log_do_open(lp,
- argp->uid.data, argp->name.data, argp->ftype, argp->id));
-}
-
-/*
- * __log_do_open --
- * Open files referenced in the log. This is the part of the open that
- * is not protected by the thread mutex.
- */
-
-static int
-__log_do_open(lp, uid, name, ftype, ndx)
- DB_LOG *lp;
- u_int8_t *uid;
- char *name;
- DBTYPE ftype;
- u_int32_t ndx;
-{
- DB *dbp;
- int ret;
-
- dbp = NULL;
- if ((ret = db_open(name, ftype, 0, 0, lp->dbenv, NULL, &dbp)) == 0) {
- /*
- * Verify that we are opening the same file that we were
- * referring to when we wrote this log record.
- */
- if (memcmp(uid, dbp->fileid, DB_FILE_ID_LEN) != 0) {
- (void)dbp->close(dbp, 0);
- dbp = NULL;
- ret = ENOENT;
- }
- }
-
- if (ret == 0 || ret == ENOENT)
- (void)__log_add_logid(lp, dbp, ndx);
-
- return (ret);
-}
-
-/*
- * __log_add_logid --
- * Adds a DB entry to the log's DB entry table.
- *
- * PUBLIC: int __log_add_logid __P((DB_LOG *, DB *, u_int32_t));
- */
-int
-__log_add_logid(logp, dbp, ndx)
- DB_LOG *logp;
- DB *dbp;
- u_int32_t ndx;
-{
- u_int32_t i;
- int ret;
-
- ret = 0;
-
- LOCK_LOGTHREAD(logp);
-
- /*
- * 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 (logp->dbentry_cnt <= ndx) {
- if ((ret = __os_realloc(&logp->dbentry,
- (ndx + DB_GROW_SIZE) * sizeof(DB_ENTRY))) != 0)
- goto err;
-
- /* Initialize the new entries. */
- for (i = logp->dbentry_cnt; i < ndx + DB_GROW_SIZE; i++) {
- logp->dbentry[i].dbp = NULL;
- logp->dbentry[i].deleted = 0;
- }
-
- logp->dbentry_cnt = i;
- }
-
- if (logp->dbentry[ndx].deleted == 0 && logp->dbentry[ndx].dbp == NULL) {
- logp->dbentry[ndx].dbp = dbp;
- logp->dbentry[ndx].refcount = 1;
- logp->dbentry[ndx].deleted = dbp == NULL;
- } else
- logp->dbentry[ndx].refcount++;
-
-err: UNLOCK_LOGTHREAD(logp);
- return (ret);
-}
-
-
-/*
- * __db_fileid_to_db --
- * Return the DB corresponding to the specified fileid.
- *
- * PUBLIC: int __db_fileid_to_db __P((DB_LOG *, DB **, u_int32_t));
- */
-int
-__db_fileid_to_db(logp, dbpp, ndx)
- DB_LOG *logp;
- DB **dbpp;
- u_int32_t ndx;
-{
- int ret;
- char *name;
- FNAME *fname;
-
- ret = 0;
- LOCK_LOGTHREAD(logp);
-
- /*
- * Under XA, a process different than the one issuing DB
- * operations may abort a transaction. In this case,
- * recovery routines are run by a process that does not
- * necessarily have the file open. In this case, we must
- * open the file explicitly.
- */
- if (ndx >= logp->dbentry_cnt ||
- (!logp->dbentry[ndx].deleted && logp->dbentry[ndx].dbp == NULL)) {
- if (__log_lid_to_fname(logp, ndx, &fname) != 0) {
- /* Couldn't find entry; this is a fatal error. */
- ret = EINVAL;
- goto err;
- }
- name = R_ADDR(logp, fname->name_off);
- /*
- * __log_do_open is called without protection of the
- * log thread lock.
- */
- UNLOCK_LOGTHREAD(logp);
- /*
- * 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 __log_do_open succeeded, then
- * we don't need to do any of the remaining error checking
- * at the end of this routine.
- */
- if ((ret = __log_do_open(logp,
- fname->ufid, name, fname->s_type, ndx)) != 0)
- return (ret);
- *dbpp = logp->dbentry[ndx].dbp;
- return (0);
- }
-
- /*
- * Return DB_DELETED if the file has been deleted
- * (it's not an error).
- */
- if (logp->dbentry[ndx].deleted) {
- ret = DB_DELETED;
- goto err;
- }
-
- /*
- * Otherwise return 0, but if we don't have a corresponding DB,
- * it's an error.
- */
- if ((*dbpp = logp->dbentry[ndx].dbp) == NULL)
- ret = ENOENT;
-
-err: UNLOCK_LOGTHREAD(logp);
- return (ret);
-}
-
-/*
- * Close files that were opened by the recovery daemon.
- *
- * PUBLIC: void __log_close_files __P((DB_LOG *));
- */
-void
-__log_close_files(logp)
- DB_LOG *logp;
-{
- u_int32_t i;
-
- LOCK_LOGTHREAD(logp);
- for (i = 0; i < logp->dbentry_cnt; i++)
- if (logp->dbentry[i].dbp) {
- logp->dbentry[i].dbp->close(logp->dbentry[i].dbp, 0);
- logp->dbentry[i].dbp = NULL;
- logp->dbentry[i].deleted = 0;
- }
- F_CLR(logp, DBC_RECOVER);
- UNLOCK_LOGTHREAD(logp);
-}
-
-/*
- * PUBLIC: void __log_rem_logid __P((DB_LOG *, u_int32_t));
- */
-void
-__log_rem_logid(logp, ndx)
- DB_LOG *logp;
- u_int32_t ndx;
-{
- LOCK_LOGTHREAD(logp);
- if (--logp->dbentry[ndx].refcount == 0) {
- logp->dbentry[ndx].dbp = NULL;
- logp->dbentry[ndx].deleted = 0;
- }
- UNLOCK_LOGTHREAD(logp);
-}
-
-/*
- * __log_lid_to_fname --
- * Traverse the shared-memory region looking for the entry that
- * matches the passed log fileid. Returns 0 on success; -1 on error.
- */
-static int
-__log_lid_to_fname(dblp, lid, fnamep)
- DB_LOG *dblp;
- u_int32_t lid;
- FNAME **fnamep;
-{
- FNAME *fnp;
-
- for (fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
- fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
- if (fnp->ref == 0) /* Entry not in use. */
- continue;
- if (fnp->id == lid) {
- *fnamep = fnp;
- return (0);
- }
- }
- return (-1);
-}
diff --git a/db2/log/log_register.c b/db2/log/log_register.c
deleted file mode 100644
index 22264e3..0000000
--- a/db2/log/log_register.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)log_register.c 10.22 (Sleepycat) 9/27/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "log.h"
-#include "common_ext.h"
-
-/*
- * log_register --
- * Register a file name.
- */
-int
-log_register(dblp, dbp, name, type, idp)
- DB_LOG *dblp;
- DB *dbp;
- const char *name;
- DBTYPE type;
- u_int32_t *idp;
-{
- DBT fid_dbt, r_name;
- DB_LSN r_unused;
- FNAME *fnp, *reuse_fnp;
- size_t len;
- u_int32_t maxid;
- int inserted, ret;
- char *fullname;
- void *namep;
-
- inserted = 0;
- fullname = NULL;
- fnp = namep = reuse_fnp = NULL;
-
- LOG_PANIC_CHECK(dblp);
-
- /* Check the arguments. */
- if (type != DB_BTREE && type != DB_HASH && type != DB_RECNO) {
- __db_err(dblp->dbenv, "log_register: unknown DB file type");
- return (EINVAL);
- }
-
- /* Get the log file id. */
- if ((ret = __db_appname(dblp->dbenv,
- DB_APP_DATA, NULL, name, 0, NULL, &fullname)) != 0)
- return (ret);
-
- LOCK_LOGREGION(dblp);
-
- /*
- * See if we've already got this file in the log, finding the
- * (maximum+1) in-use file id and some available file id (if we
- * find an available fid, we'll use it, else we'll have to allocate
- * one after the maximum that we found).
- */
- for (maxid = 0, fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
- fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
- if (fnp->ref == 0) { /* Entry is not in use. */
- if (reuse_fnp == NULL)
- reuse_fnp = fnp;
- continue;
- }
- if (!memcmp(dbp->fileid, fnp->ufid, DB_FILE_ID_LEN)) {
- ++fnp->ref;
- goto found;
- }
- if (maxid <= fnp->id)
- maxid = fnp->id + 1;
- }
-
- /* Fill in fnp structure. */
-
- if (reuse_fnp != NULL) /* Reuse existing one. */
- fnp = reuse_fnp;
- else if ((ret = __db_shalloc(dblp->addr, sizeof(FNAME), 0, &fnp)) != 0)
- goto err;
- else /* Allocate a new one. */
- fnp->id = maxid;
-
- fnp->ref = 1;
- fnp->s_type = type;
- memcpy(fnp->ufid, dbp->fileid, DB_FILE_ID_LEN);
-
- len = strlen(name) + 1;
- if ((ret = __db_shalloc(dblp->addr, len, 0, &namep)) != 0)
- goto err;
- fnp->name_off = R_OFFSET(dblp, namep);
- memcpy(namep, name, len);
-
- /* Only do the insert if we allocated a new fnp. */
- if (reuse_fnp == NULL)
- SH_TAILQ_INSERT_HEAD(&dblp->lp->fq, fnp, q, __fname);
- inserted = 1;
-
-found: /* Log the registry. */
- if (!F_ISSET(dblp, DBC_RECOVER)) {
- r_name.data = (void *)name; /* XXX: Yuck! */
- r_name.size = strlen(name) + 1;
- memset(&fid_dbt, 0, sizeof(fid_dbt));
- fid_dbt.data = dbp->fileid;
- fid_dbt.size = DB_FILE_ID_LEN;
- if ((ret = __log_register_log(dblp, NULL, &r_unused,
- 0, LOG_OPEN, &r_name, &fid_dbt, fnp->id, type)) != 0)
- goto err;
- if ((ret = __log_add_logid(dblp, dbp, fnp->id)) != 0)
- goto err;
- }
-
- if (0) {
-err: /*
- * XXX
- * We should grow the region.
- */
- if (inserted)
- SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname);
- if (namep != NULL)
- __db_shalloc_free(dblp->addr, namep);
- if (fnp != NULL)
- __db_shalloc_free(dblp->addr, fnp);
- }
-
- if (idp != NULL)
- *idp = fnp->id;
- UNLOCK_LOGREGION(dblp);
-
- if (fullname != NULL)
- __os_freestr(fullname);
-
- return (ret);
-}
-
-/*
- * log_unregister --
- * Discard a registered file name.
- */
-int
-log_unregister(dblp, fid)
- DB_LOG *dblp;
- u_int32_t fid;
-{
- DBT fid_dbt, r_name;
- DB_LSN r_unused;
- FNAME *fnp;
- int ret;
-
- LOG_PANIC_CHECK(dblp);
-
- ret = 0;
- LOCK_LOGREGION(dblp);
-
- /* Find the entry in the log. */
- for (fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
- fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname))
- if (fid == fnp->id)
- break;
- if (fnp == NULL) {
- __db_err(dblp->dbenv, "log_unregister: non-existent file id");
- ret = EINVAL;
- goto ret1;
- }
-
- /* Unlog the registry. */
- if (!F_ISSET(dblp, DBC_RECOVER)) {
- memset(&r_name, 0, sizeof(r_name));
- r_name.data = R_ADDR(dblp, fnp->name_off);
- r_name.size = strlen(r_name.data) + 1;
- memset(&fid_dbt, 0, sizeof(fid_dbt));
- fid_dbt.data = fnp->ufid;
- fid_dbt.size = DB_FILE_ID_LEN;
- if ((ret = __log_register_log(dblp, NULL, &r_unused,
- 0, LOG_CLOSE, &r_name, &fid_dbt, fid, fnp->s_type)) != 0)
- goto ret1;
- }
-
- /*
- * If more than 1 reference, just decrement the reference and return.
- * Otherwise, free the name.
- */
- --fnp->ref;
- if (fnp->ref == 0)
- __db_shalloc_free(dblp->addr, R_ADDR(dblp, fnp->name_off));
-
- /*
- * Remove from the process local table. If this operation is taking
- * place during recovery, then the logid was never added to the table,
- * so do not remove it.
- */
- if (!F_ISSET(dblp, DBC_RECOVER))
- __log_rem_logid(dblp, fid);
-
-ret1: UNLOCK_LOGREGION(dblp);
- return (ret);
-}