diff options
Diffstat (limited to 'db2/progs')
-rw-r--r-- | db2/progs/db_archive/db_archive.c | 165 | ||||
-rw-r--r-- | db2/progs/db_checkpoint/db_checkpoint.c | 246 | ||||
-rw-r--r-- | db2/progs/db_deadlock/db_deadlock.c | 236 | ||||
-rw-r--r-- | db2/progs/db_dump/db_dump.c | 280 | ||||
-rw-r--r-- | db2/progs/db_dump185/db_dump185.c | 322 | ||||
-rw-r--r-- | db2/progs/db_load/db_load.c | 457 | ||||
-rw-r--r-- | db2/progs/db_printlog/db_printlog.c | 160 | ||||
-rw-r--r-- | db2/progs/db_recover/db_recover.c | 122 | ||||
-rw-r--r-- | db2/progs/db_stat/db_stat.c | 434 |
9 files changed, 2422 insertions, 0 deletions
diff --git a/db2/progs/db_archive/db_archive.c b/db2/progs/db_archive/db_archive.c new file mode 100644 index 0000000000..136cf2c360 --- /dev/null +++ b/db2/progs/db_archive/db_archive.c @@ -0,0 +1,165 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 1997 + * Sleepycat Software. All rights reserved. + */ + +#include "config.h" + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1997\n\ + Sleepycat Software Inc. All rights reserved.\n"; +static const char sccsid[] = "@(#)db_archive.c 10.12 (Sleepycat) 7/25/97"; +#endif + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <errno.h> +#include <signal.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#endif + +#include "db_int.h" +#include "shqueue.h" +#include "log.h" +#include "db_dispatch.h" +#include "clib_ext.h" +#include "common_ext.h" + +DB_ENV *db_init __P((char *, int)); +void onint __P((int)); +void siginit __P((void)); +void usage __P((void)); +int main __P((int, char *[])); + +int interrupted; +const char *progname = "db_archive"; /* Program name. */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB_ENV *dbenv; + int ch, flags, verbose; + char *home, **list; + + flags = verbose = 0; + home = NULL; + while ((ch = getopt(argc, argv, "ah:lsv")) != EOF) + switch (ch) { + case 'a': + flags |= DB_ARCH_ABS; + break; + case 'h': + home = optarg; + break; + case 'l': + flags |= DB_ARCH_LOG; + break; + case 's': + flags |= DB_ARCH_DATA; + break; + case 'v': + verbose = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 0) + usage(); + + /* Initialize the environment. */ + dbenv = db_init(home, verbose); + + /* Get the list of names. */ + if ((errno = log_archive(dbenv->lg_info, &list, flags, NULL)) != 0) { + (void)db_appexit(dbenv); + err(1, "log_archive"); + } + + /* Print the names. */ + if (list != NULL) + for (; *list != NULL; ++list) + printf("%s\n", *list); + + return (db_appexit(dbenv) ? 1 : 0); +} + +/* + * db_init -- + * Initialize the environment. + */ +DB_ENV * +db_init(home, verbose) + char *home; + int verbose; +{ + DB_ENV *dbenv; + + if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) { + errno = ENOMEM; + err(1, NULL); + } + dbenv->db_errfile = stderr; + dbenv->db_errpfx = progname; + dbenv->db_verbose = verbose; + + if ((errno = db_appinit(home, NULL, dbenv, + DB_CREATE | DB_INIT_LOG | DB_INIT_TXN | DB_USE_ENVIRON)) != 0) + err(1, "db_appinit"); + + siginit(); + + return (dbenv); +} + +/* + * siginit -- + * Initialize the set of signals for which we want to clean up. + * Generally, we try not to leave the shared regions locked if + * we can. + */ +void +siginit() +{ +#ifdef SIGHUP + (void)signal(SIGHUP, onint); +#endif + (void)signal(SIGINT, onint); +#ifdef SIGKILL + (void)signal(SIGKILL, onint); +#endif + (void)signal(SIGTERM, onint); +} + +/* + * oninit -- + * Interrupt signal handler. + */ +void +onint(signo) + int signo; +{ + if ((interrupted = signo) == 0) + interrupted = SIGINT; +} + +void +usage() +{ + (void)fprintf(stderr, "usage: db_archive [-alsv] [-h home]\n"); + exit(1); +} diff --git a/db2/progs/db_checkpoint/db_checkpoint.c b/db2/progs/db_checkpoint/db_checkpoint.c new file mode 100644 index 0000000000..586b4b9686 --- /dev/null +++ b/db2/progs/db_checkpoint/db_checkpoint.c @@ -0,0 +1,246 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 1997 + * Sleepycat Software. All rights reserved. + */ + +#include "config.h" + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1997\n\ + Sleepycat Software Inc. All rights reserved.\n"; +static const char sccsid[] = "@(#)db_checkpoint.c 10.9 (Sleepycat) 7/4/97"; +#endif + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <errno.h> +#include <limits.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> +#endif + +#include "db_int.h" +#include "shqueue.h" +#include "db_page.h" +#include "log.h" +#include "btree.h" +#include "hash.h" +#include "clib_ext.h" +#include "common_ext.h" + +char *check __P((DB_ENV *, long, long)); +int checkpoint __P((DB_ENV *, char *, int)); +DB_ENV *db_init __P((char *)); +int logpid __P((char *, int)); +void onint __P((int)); +void siginit __P((void)); +void usage __P((void)); +int main __P((int, char *[])); + +int interrupted; +time_t now; /* Checkpoint time. */ +const char *progname = "db_checkpoint"; /* Program name. */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB_ENV *dbenv; + time_t now; + long kbytes, minutes, seconds; + int ch, rval, verbose; + char *home, *logfile; + + home = logfile = NULL; + kbytes = minutes = 0; + verbose = 0; + while ((ch = getopt(argc, argv, "h:k:L:p:v")) != EOF) + switch (ch) { + case 'h': + home = optarg; + break; + case 'k': + get_long(optarg, 1, LONG_MAX, &kbytes); + break; + case 'L': + logfile = optarg; + break; + case 'p': + get_long(optarg, 1, LONG_MAX, &minutes); + break; + case 'v': + verbose = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 0) + usage(); + + if (kbytes == 0 && minutes == 0) { + warnx("at least one of -k and -p must be specified"); + usage(); + } + + /* Initialize the environment. */ + dbenv = db_init(home); + + if (logfile != NULL && logpid(logfile, 1)) { + (void)db_appexit(dbenv); + return (1); + } + + /* + * If we have only a time delay, then we'll sleep the right amount + * to wake up when a checkpoint is necessary. If we have a "kbytes" + * field set, then we'll check every 30 seconds. + */ + rval = 0; + seconds = kbytes != 0 ? 30 : minutes * 60; + while (!interrupted) { + (void)__db_sleep(seconds, 0); + + if (verbose) { + (void)time(&now); + printf("checkpoint: %s", ctime(&now)); + } + rval = txn_checkpoint(dbenv->tx_info, kbytes, minutes); + if (rval < 0) + break; + + while (rval > 0) { + if (verbose) + __db_err(dbenv, + "checkpoint did not finish, retrying"); + (void)__db_sleep(2, 0); + rval = txn_checkpoint(dbenv->tx_info, 0, 0); + } + if (rval < 0) + break; + } + + if (logfile != NULL && logpid(logfile, 0)) + rval = 1; + + if (interrupted) { + (void)signal(interrupted, SIG_DFL); + (void)raise(interrupted); + /* NOTREACHED */ + } + + return (db_appexit(dbenv) || rval ? 1 : 0); +} + +/* + * db_init -- + * Initialize the environment. + */ +DB_ENV * +db_init(home) + char *home; +{ + DB_ENV *dbenv; + + if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) { + errno = ENOMEM; + err(1, NULL); + } + dbenv->db_errfile = stderr; + dbenv->db_errpfx = progname; + + if ((errno = db_appinit(home, NULL, dbenv, + DB_INIT_LOG | DB_INIT_TXN | DB_INIT_MPOOL | DB_USE_ENVIRON)) != 0) + err(1, "db_appinit"); + + if (memp_register(dbenv->mp_info, + DB_FTYPE_BTREE, __bam_pgin, __bam_pgout) || + memp_register(dbenv->mp_info, + DB_FTYPE_HASH, __ham_pgin, __ham_pgout)) { + (void)db_appexit(dbenv); + errx(1, + "db_appinit: failed to register access method functions"); + } + + siginit(); + + return (dbenv); +} + +/* + * logpid -- + * Log that we're running. + */ +int +logpid(fname, is_open) + char *fname; + int is_open; +{ + FILE *fp; + time_t now; + + if (is_open) { + if ((fp = fopen(fname, "w")) == NULL) { + warn("%s", fname); + return (1); + } + (void)time(&now); + fprintf(fp, + "%s: %lu %s", progname, (u_long)getpid(), ctime(&now)); + fclose(fp); + } else + (void)remove(fname); + return (0); +} + +/* + * siginit -- + * Initialize the set of signals for which we want to clean up. + * Generally, we try not to leave the shared regions locked if + * we can. + */ +void +siginit() +{ +#ifdef SIGHUP + (void)signal(SIGHUP, onint); +#endif + (void)signal(SIGINT, onint); +#ifdef SIGKILL + (void)signal(SIGKILL, onint); +#endif + (void)signal(SIGTERM, onint); +} + +/* + * oninit -- + * Interrupt signal handler. + */ +void +onint(signo) + int signo; +{ + if ((interrupted = signo) == 0) + interrupted = SIGINT; +} + +void +usage() +{ + (void)fprintf(stderr, + "usage: db_checkpoint [-v] [-h home] [-k kbytes] [-L file] [-p min]\n"); + exit(1); +} diff --git a/db2/progs/db_deadlock/db_deadlock.c b/db2/progs/db_deadlock/db_deadlock.c new file mode 100644 index 0000000000..9437e3552d --- /dev/null +++ b/db2/progs/db_deadlock/db_deadlock.c @@ -0,0 +1,236 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 1997 + * Sleepycat Software. All rights reserved. + */ + +#include "config.h" + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1997\n\ + Sleepycat Software Inc. All rights reserved.\n"; +static const char sccsid[] = "@(#)db_deadlock.c 10.13 (Sleepycat) 7/20/97"; +#endif + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <errno.h> +#include <limits.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> +#endif + +#include "db_int.h" +#include "clib_ext.h" +#include "common_ext.h" + +#define BAD_KILLID 0xffffffff + +DB_ENV *db_init __P((char *, int)); +void onint __P((int)); +void siginit __P((void)); +void usage __P((void)); +int logpid __P((char *, int)); +int main __P((int, char *[])); + +int interrupted; +const char *progname = "db_deadlock"; /* Program name. */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB_ENV *dbenv; + u_int32_t atype; + time_t now; + long seconds; + int ch, flags, verbose; + char *home, *logfile; + + atype = DB_LOCK_DEFAULT; + home = logfile = NULL; + seconds = 0; + flags = verbose = 0; + while ((ch = getopt(argc, argv, "a:h:L:t:vw")) != EOF) + switch (ch) { + case 'a': + switch (optarg[0]) { + case 'o': + atype = DB_LOCK_OLDEST; + break; + case 'y': + atype = DB_LOCK_YOUNGEST; + break; + default: + usage(); + /* NOTREACHED */ + } + if (optarg[1] != '\0') + usage(); + break; + case 'h': + home = optarg; + break; + case 'L': + logfile = optarg; + break; + case 't': + get_long(optarg, 1, LONG_MAX, &seconds); + break; + case 'v': + verbose = 1; + break; + case 'w': + LF_SET(DB_LOCK_CONFLICT); + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 0) + usage(); + + if (seconds == 0 && !LF_ISSET(DB_LOCK_CONFLICT)) { + warnx("at least one of -t and -w must be specified"); + usage(); + } + + /* + * We detect every second when we're running in DB_LOCK_CONFLICT mode. + */ + if (seconds == 0) + seconds = 1; + + /* Initialize the deadlock detector by opening the lock manager. */ + dbenv = db_init(home, verbose); + + if (logfile != NULL && logpid(logfile, 1)) { + (void)db_appexit(dbenv); + return (1); + } + + while (!interrupted) { + if (dbenv->db_verbose != 0) { + time(&now); + __db_err(dbenv, "Running at %s", ctime(&now)); + } + + if ((errno = lock_detect(dbenv->lk_info, flags, atype)) != 0) + break; + + /* Make a pass every "seconds" seconds. */ + (void)__db_sleep(seconds, 0); + } + + if (logfile != NULL) + (void)logpid(logfile, 0); + + if (interrupted) { + (void)signal(interrupted, SIG_DFL); + (void)raise(interrupted); + /* NOTREACHED */ + } + + return (db_appexit(dbenv)); +} + +DB_ENV * +db_init(home, verbose) + char *home; + int verbose; +{ + DB_ENV *dbenv; + + if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) { + errno = ENOMEM; + err(1, NULL); + } + dbenv->db_errfile = stderr; + dbenv->db_errpfx = progname; + dbenv->db_verbose = verbose; + + if ((errno = db_appinit(home, + NULL, dbenv, DB_INIT_LOCK | DB_USE_ENVIRON)) != 0) + err(1, "db_appinit"); + + siginit(); + + return (dbenv); +} + +/* + * logpid -- + * Log that we're running. + */ +int +logpid(fname, is_open) + char *fname; + int is_open; +{ + FILE *fp; + time_t now; + + if (is_open) { + if ((fp = fopen(fname, "w")) == NULL) { + warn("%s", fname); + return (1); + } + (void)time(&now); + fprintf(fp, + "%s: %lu %s", progname, (u_long)getpid(), ctime(&now)); + fclose(fp); + } else + (void)remove(fname); + return (0); +} + +/* + * siginit -- + * Initialize the set of signals for which we want to clean up. + * Generally, we try not to leave the shared regions locked if + * we can. + */ +void +siginit() +{ +#ifdef SIGHUP + (void)signal(SIGHUP, onint); +#endif + (void)signal(SIGINT, onint); +#ifdef SIGKILL + (void)signal(SIGKILL, onint); +#endif + (void)signal(SIGTERM, onint); +} + +/* + * oninit -- + * Interrupt signal handler. + */ +void +onint(signo) + int signo; +{ + if ((interrupted = signo) == 0) + interrupted = SIGINT; +} + +void +usage() +{ + (void)fprintf(stderr, + "usage: db_deadlock [-vw] [-a m | o | y] [-h home] [-L file] [-t sec]\n"); + exit(1); +} diff --git a/db2/progs/db_dump/db_dump.c b/db2/progs/db_dump/db_dump.c new file mode 100644 index 0000000000..d60aa9b5c9 --- /dev/null +++ b/db2/progs/db_dump/db_dump.c @@ -0,0 +1,280 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 1997 + * Sleepycat Software. All rights reserved. + */ + +#include "config.h" + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1997\n\ + Sleepycat Software Inc. All rights reserved.\n"; +static const char sccsid[] = "@(#)db_dump.c 10.13 (Sleepycat) 8/19/97"; +#endif + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <ctype.h> +#include <errno.h> +#include <getopt.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#endif + +#include "db_int.h" +#include "db_page.h" +#include "btree.h" +#include "hash.h" +#include "clib_ext.h" + +void configure __P((char *)); +DB_ENV *db_init __P((char *)); +void dbt_dump __P((DBT *)); +void dbt_print __P((DBT *)); +void pheader __P((DB *, int)); +void usage __P((void)); +int main __P((int, char *[])); + +const char *progname = "db_dump"; /* Program name. */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB *dbp; + DBC *dbcp; + DBT key, data; + DB_ENV *dbenv; + int ch, dflag, pflag; + char *home; + + home = NULL; + dflag = pflag = 0; + while ((ch = getopt(argc, argv, "df:h:p")) != EOF) + switch (ch) { + case 'd': + dflag = 1; + break; + case 'f': + if (freopen(optarg, "w", stdout) == NULL) + err(1, "%s", optarg); + break; + case 'h': + home = optarg; + break; + case 'p': + pflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + if (dflag) { + if (home != NULL) + errx(1, + "the -d and -h options may not both be specified"); + if (pflag) + errx(1, + "the -d and -p options may not both be specified"); + } + /* Initialize the environment. */ + dbenv = dflag ? NULL : db_init(home); + + /* Open the DB file. */ + if ((errno = + db_open(argv[0], DB_UNKNOWN, DB_RDONLY, 0, dbenv, NULL, &dbp)) != 0) + err(1, "%s", argv[0]); + + /* DB dump. */ + if (dflag) { + (void)__db_dump(dbp, NULL, 1); + if ((errno = dbp->close(dbp, 0)) != 0) + err(1, "close"); + exit (0); + } + + /* Get a cursor and step through the database. */ + if ((errno = dbp->cursor(dbp, NULL, &dbcp)) != 0) { + (void)dbp->close(dbp, 0); + err(1, "cursor"); + } + + /* Print out the header. */ + pheader(dbp, pflag); + + /* Print out the key/data pairs. */ + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + if (pflag) + while ((errno = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) { + if (dbp->type != DB_RECNO) + dbt_print(&key); + dbt_print(&data); + } + else + while ((errno = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) { + if (dbp->type != DB_RECNO) + dbt_dump(&key); + dbt_dump(&data); + } + if (errno != DB_NOTFOUND) + err(1, "cursor get"); + + if ((errno = dbp->close(dbp, 0)) != 0) + err(1, "close"); + return (0); +} + +/* + * db_init -- + * Initialize the environment. + */ +DB_ENV * +db_init(home) + char *home; +{ + DB_ENV *dbenv; + + if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) { + errno = ENOMEM; + err(1, NULL); + } + dbenv->db_errfile = stderr; + dbenv->db_errpfx = progname; + + if ((errno = + db_appinit(home, NULL, dbenv, DB_CREATE | DB_USE_ENVIRON)) != 0) + err(1, "db_appinit"); + return (dbenv); +} + +/* + * pheader -- + * Write out the header information. + */ +void +pheader(dbp, pflag) + DB *dbp; + int pflag; +{ + DB_BTREE_STAT *btsp; + HTAB *hashp; + HASHHDR *hdr; + db_pgno_t pgno; + + printf("format=%s\n", pflag ? "print" : "bytevalue"); + switch (dbp->type) { + case DB_BTREE: + printf("type=btree\n"); + if ((errno = dbp->stat(dbp, &btsp, NULL, 0)) != 0) + err(1, "dbp->stat"); + if (F_ISSET(dbp, DB_BT_RECNUM)) + printf("recnum=1\n"); + if (btsp->bt_maxkey != 0) + printf("bt_maxkey=%lu\n", (u_long)btsp->bt_maxkey); + if (btsp->bt_minkey != 0) + printf("bt_minkey=%lu\n", (u_long)btsp->bt_minkey); + break; + case DB_HASH: + printf("type=hash\n"); + hashp = dbp->internal; + pgno = PGNO_METADATA; + if (memp_fget(dbp->mpf, &pgno, 0, &hdr) == 0) { + if (hdr->ffactor != 0) + printf("h_ffactor=%lu\n", (u_long)hdr->ffactor); + if (hdr->nelem != 0) + printf("h_nelem=%lu\n", (u_long)hdr->nelem); + (void)memp_fput(dbp->mpf, hdr, 0); + } + break; + case DB_RECNO: + printf("type=recno\n"); + if (F_ISSET(dbp, DB_RE_RENUMBER)) + printf("renumber=1\n"); + if (F_ISSET(dbp, DB_RE_FIXEDLEN)) + printf("re_len=%lu\n", (u_long)btsp->bt_re_len); + if (F_ISSET(dbp, DB_RE_PAD)) + printf("re_pad=%#x\n", btsp->bt_re_pad); + break; + case DB_UNKNOWN: + abort(); + /* NOTREACHED */ + } + + if (F_ISSET(dbp, DB_AM_DUP)) + printf("duplicates=1\n"); + + if (dbp->dbenv->db_lorder != 0) + printf("db_lorder=%lu\n", (u_long)dbp->dbenv->db_lorder); + + if (!F_ISSET(dbp, DB_AM_PGDEF)) + printf("db_pagesize=%lu\n", (u_long)dbp->pgsize); + + printf("HEADER=END\n"); +} + +static char hex[] = "0123456789abcdef"; + +/* + * dbt_dump -- + * Write out a key or data item using byte values. + */ +void +dbt_dump(dbtp) + DBT *dbtp; +{ + u_int32_t len; + u_int8_t *p; + + for (len = dbtp->size, p = dbtp->data; len--; ++p) + (void)printf("%c%c", + hex[(u_int8_t)(*p & 0xf0) >> 4], hex[*p & 0x0f]); + printf("\n"); +} + +/* + * dbt_print -- + * Write out a key or data item using printable characters. + */ +void +dbt_print(dbtp) + DBT *dbtp; +{ + u_int32_t len; + u_int8_t *p; + + for (len = dbtp->size, p = dbtp->data; len--; ++p) + if (isprint(*p)) { + if (*p == '\\') + (void)printf("\\"); + (void)printf("%c", *p); + } else + (void)printf("\\%c%c", + hex[(u_int8_t)(*p & 0xf0) >> 4], hex[*p & 0x0f]); + printf("\n"); +} + +/* + * usage -- + * Display the usage message. + */ +void +usage() +{ + (void)fprintf(stderr, + "usage: db_dump [-dp] [-f file] [-h home] db_file\n"); + exit(1); +} diff --git a/db2/progs/db_dump185/db_dump185.c b/db2/progs/db_dump185/db_dump185.c new file mode 100644 index 0000000000..f3c1187e45 --- /dev/null +++ b/db2/progs/db_dump185/db_dump185.c @@ -0,0 +1,322 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 1997 + * Sleepycat Software. All rights reserved. + */ + +#include "config.h" + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1997\n\ + Sleepycat Software Inc. All rights reserved.\n"; +static const char sccsid[] = "@(#)db_dump185.c 10.5 (Sleepycat) 7/2/97"; +#endif + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#endif + +#include "db_185.h" +#include "clib_ext.h" + +/* Hash Table Information */ +typedef struct hashhdr { /* Disk resident portion */ + int magic; /* Magic NO for hash tables */ + int version; /* Version ID */ + u_int32_t lorder; /* Byte Order */ + int bsize; /* Bucket/Page Size */ + int bshift; /* Bucket shift */ + int dsize; /* Directory Size */ + int ssize; /* Segment Size */ + int sshift; /* Segment shift */ + int ovfl_point; /* Where overflow pages are being + * allocated */ + int last_freed; /* Last overflow page freed */ + int max_bucket; /* ID of Maximum bucket in use */ + int high_mask; /* Mask to modulo into entire table */ + int low_mask; /* Mask to modulo into lower half of + * table */ + int ffactor; /* Fill factor */ + int nkeys; /* Number of keys in hash table */ +} HASHHDR; + +typedef struct htab { /* Memory resident data structure */ + HASHHDR hdr; /* Header */ +} HTAB; + +typedef struct _epgno { + u_int32_t pgno; /* the page number */ + u_int16_t index; /* the index on the page */ +} EPGNO; + +typedef struct _epg { + void *page; /* the (pinned) page */ + u_int16_t index; /* the index on the page */ +} EPG; + +typedef struct _cursor { + EPGNO pg; /* B: Saved tree reference. */ + DBT key; /* B: Saved key, or key.data == NULL. */ + u_int32_t rcursor; /* R: recno cursor (1-based) */ + +#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */ +#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */ +#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */ +#define CURS_INIT 0x08 /* RB: Cursor initialized. */ + u_int8_t flags; +} CURSOR; + +/* The in-memory btree/recno data structure. */ +typedef struct _btree { + void *bt_mp; /* memory pool cookie */ + + void *bt_dbp; /* pointer to enclosing DB */ + + EPG bt_cur; /* current (pinned) page */ + void *bt_pinned; /* page pinned across calls */ + + CURSOR bt_cursor; /* cursor */ + + EPGNO bt_stack[50]; /* stack of parent pages */ + EPGNO *bt_sp; /* current stack pointer */ + + DBT bt_rkey; /* returned key */ + DBT bt_rdata; /* returned data */ + + int bt_fd; /* tree file descriptor */ + + u_int32_t bt_free; /* next free page */ + u_int32_t bt_psize; /* page size */ + u_int16_t bt_ovflsize; /* cut-off for key/data overflow */ + int bt_lorder; /* byte order */ + /* sorted order */ + enum { NOT, BACK, FORWARD } bt_order; + EPGNO bt_last; /* last insert */ + + /* B: key comparison function */ + int (*bt_cmp) __P((const DBT *, const DBT *)); + /* B: prefix comparison function */ + size_t (*bt_pfx) __P((const DBT *, const DBT *)); + /* R: recno input function */ + int (*bt_irec) __P((struct _btree *, u_int32_t)); + + FILE *bt_rfp; /* R: record FILE pointer */ + int bt_rfd; /* R: record file descriptor */ + + void *bt_cmap; /* R: current point in mapped space */ + void *bt_smap; /* R: start of mapped space */ + void *bt_emap; /* R: end of mapped space */ + size_t bt_msize; /* R: size of mapped region. */ + + u_int32_t bt_nrecs; /* R: number of records */ + size_t bt_reclen; /* R: fixed record length */ + u_char bt_bval; /* R: delimiting byte/pad character */ + +/* + * NB: + * B_NODUPS and R_RECNO are stored on disk, and may not be changed. + */ +#define B_INMEM 0x00001 /* in-memory tree */ +#define B_METADIRTY 0x00002 /* need to write metadata */ +#define B_MODIFIED 0x00004 /* tree modified */ +#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */ +#define B_RDONLY 0x00010 /* read-only tree */ + +#define B_NODUPS 0x00020 /* no duplicate keys permitted */ +#define R_RECNO 0x00080 /* record oriented tree */ + +#define R_CLOSEFP 0x00040 /* opened a file pointer */ +#define R_EOF 0x00100 /* end of input file reached. */ +#define R_FIXLEN 0x00200 /* fixed length records */ +#define R_MEMMAPPED 0x00400 /* memory mapped file. */ +#define R_INMEM 0x00800 /* in-memory file */ +#define R_MODIFIED 0x01000 /* modified file */ +#define R_RDONLY 0x02000 /* read-only file */ + +#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */ +#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */ +#define B_DB_TXN 0x10000 /* DB_TXN specified. */ + u_int32_t flags; +} BTREE; + +void db_185_btree __P((DB *, int)); +void db_185_hash __P((DB *, int)); +void dbt_dump __P((DBT *)); +void dbt_print __P((DBT *)); +void usage __P((void)); +int main __P((int, char *[])); + +const char *progname = "db_dump185"; /* Program name. */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB *dbp; + DBT key, data; + int ch, pflag, rval; + + pflag = 0; + while ((ch = getopt(argc, argv, "f:p")) != EOF) + switch (ch) { + case 'f': + if (freopen(optarg, "w", stdout) == NULL) + err(1, "%s", optarg); + break; + case 'p': + pflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_BTREE, NULL)) == NULL) { + if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_HASH, NULL)) == NULL) + return (1); + db_185_hash(dbp, pflag); + } else + db_185_btree(dbp, pflag); + + /* + * !!! + * DB 1.85 DBTs are a subset of DB 2.0 DBTs, so we just use the + * new dump/print routines. + */ + if (pflag) + while (!(rval = dbp->seq(dbp, &key, &data, R_NEXT))) { + dbt_print(&key); + dbt_print(&data); + } + else + while (!(rval = dbp->seq(dbp, &key, &data, R_NEXT))) { + dbt_dump(&key); + dbt_dump(&data); + } + + if (rval == -1) + err(1, "seq"); + return (0); +} + +/* + * db_185_hash -- + * Dump out hash header information. + */ +void +db_185_hash(dbp, pflag) + DB *dbp; + int pflag; +{ + HTAB *hashp; + + hashp = dbp->internal; + + printf("format=%s\n", pflag ? "print" : "bytevalue"); + printf("type=hash\n"); + printf("h_ffactor=%lu\n", (u_long)hashp->hdr.ffactor); +#ifdef NOT_AVAILABLE_IN_DB_185 + printf("h_nelem=%lu\n", (u_long)hashp->hdr.nelem); +#endif + if (hashp->hdr.lorder != 0) + printf("db_lorder=%lu\n", (u_long)hashp->hdr.lorder); + printf("db_pagesize=%lu\n", (u_long)hashp->hdr.bsize); + printf("HEADER=END\n"); +} + +/* + * db_185_btree -- + * Dump out btree header information. + */ +void +db_185_btree(dbp, pflag) + DB *dbp; + int pflag; +{ + BTREE *btp; + + btp = dbp->internal; + + printf("format=%s\n", pflag ? "print" : "bytevalue"); + printf("type=btree\n"); +#ifdef NOT_AVAILABLE_IN_185 + printf("bt_minkey=%lu\n", (u_long)XXX); + printf("bt_maxkey=%lu\n", (u_long)XXX); +#endif + if (btp->bt_lorder != 0) + printf("db_lorder=%lu\n", (u_long)btp->bt_lorder); + printf("db_pagesize=%lu\n", (u_long)btp->bt_psize); + if (!(btp->flags & B_NODUPS)) + printf("duplicates=1\n"); + printf("HEADER=END\n"); +} + +static char hex[] = "0123456789abcdef"; + +/* + * dbt_dump -- + * Write out a key or data item using byte values. + */ +void +dbt_dump(dbtp) + DBT *dbtp; +{ + size_t len; + u_int8_t *p; + + for (len = dbtp->size, p = dbtp->data; len--; ++p) + (void)printf("%c%c", + hex[(*p & 0xf0) >> 4], hex[*p & 0x0f]); + printf("\n"); +} + +/* + * dbt_print -- + * Write out a key or data item using printable characters. + */ +void +dbt_print(dbtp) + DBT *dbtp; +{ + size_t len; + u_int8_t *p; + + for (len = dbtp->size, p = dbtp->data; len--; ++p) + if (isprint(*p)) { + if (*p == '\\') + (void)printf("\\"); + (void)printf("%c", *p); + } else + (void)printf("\\%c%c", + hex[(*p & 0xf0) >> 4], hex[*p & 0x0f]); + printf("\n"); +} + +/* + * usage -- + * Display the usage message. + */ +void +usage() +{ + (void)fprintf(stderr, "usage: db_dump [-p] [-f file] db_file\n"); + exit(1); +} diff --git a/db2/progs/db_load/db_load.c b/db2/progs/db_load/db_load.c new file mode 100644 index 0000000000..cc90e7bd27 --- /dev/null +++ b/db2/progs/db_load/db_load.c @@ -0,0 +1,457 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 1997 + * Sleepycat Software. All rights reserved. + */ + +#include "config.h" + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1997\n\ + Sleepycat Software Inc. All rights reserved.\n"; +static const char sccsid[] = "@(#)db_load.c 10.9 (Sleepycat) 8/19/97"; +#endif + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> +#include <sys/stat.h> + +#include <errno.h> +#include <getopt.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#endif + +#include "db_int.h" +#include "clib_ext.h" + +void badnum __P((void)); +void configure __P((DB_INFO *, char **)); +DB_ENV *db_init __P((char *)); +int dbt_rdump __P((DBT *)); +int dbt_rprint __P((DBT *)); +int digitize __P((int)); +void rheader __P((DBTYPE *, int *, DB_INFO *)); +void usage __P((void)); +int main __P((int, char *[])); + +const char *progname = "db_load"; /* Program name. */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB *dbp; + DBT key, data; + DBTYPE argtype, headertype; + DB_ENV *dbenv; + DB_INFO dbinfo; + db_recno_t recno; + int ch, pflag; + char **clist, **clp, *home; + + /* Allocate enough room for configuration arguments. */ + if ((clp = clist = calloc(argc + 1, sizeof(char *))) == NULL) + err(1, NULL); + + home = NULL; + argtype = DB_UNKNOWN; + while ((ch = getopt(argc, argv, "c:f:h:t:")) != EOF) + switch (ch) { + case 'c': + *clp++ = optarg; + break; + case 'f': + if (freopen(optarg, "r", stdin) == NULL) + err(1, "%s", optarg); + break; + case 'h': + home = optarg; + break; + case 't': + if (strcmp(optarg, "btree") == 0) { + argtype = DB_BTREE; + break; + } + if (strcmp(optarg, "hash") == 0) { + argtype = DB_HASH; + break; + } + usage(); + /* NOTREACHED */ + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + /* Initialize the environment. */ + dbenv = db_init(home); + memset(&dbinfo, 0, sizeof(DB_INFO)); + + /* Read the header. */ + rheader(&headertype, &pflag, &dbinfo); + + /* Apply command-line configuration changes. */ + configure(&dbinfo, clist); + + /* Conversion to/from recno is prohibited. */ + if (argtype != DB_UNKNOWN) { + if (headertype == DB_RECNO) + errx(1, "databases of type recno may not be converted"); + headertype = argtype; + } + + /* Open the DB file. */ + if ((errno = db_open(argv[0], headertype, DB_CREATE | DB_TRUNCATE, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, + dbenv, &dbinfo, &dbp)) != 0) + err(1, "%s", argv[0]); + + /* Initialize the key/data pair. */ + memset(&key, 0, sizeof(DBT)); + if ((key.data = (void *)malloc(key.ulen = 1024)) == NULL) { + errno = ENOMEM; + err(1, NULL); + } + memset(&data, 0, sizeof(DBT)); + if ((data.data = (void *)malloc(data.ulen = 1024)) == NULL) { + errno = ENOMEM; + err(1, NULL); + } + + /* Get each key/data pair and add them to the database. */ + if (headertype == DB_RECNO) { + key.data = &recno; + key.size = sizeof(recno); + for (recno = 1;; ++recno) { + if (pflag) { + if (dbt_rprint(&data)) + break; + } else + if (dbt_rdump(&data)) + break; + if ((errno = dbp->put(dbp, NULL, &key, &data, 0)) != 0) + err(1, "%s", argv[0]); + } + } else + for (;;) { + if (pflag) { + if (dbt_rprint(&key)) + break; + if (dbt_rprint(&data)) + goto fmt; + } else { + if (dbt_rdump(&key)) + break; + if (dbt_rdump(&data)) +fmt: err(1, "odd number of key/data pairs"); + } + if ((errno = dbp->put(dbp, NULL, &key, &data, 0)) != 0) + err(1, "%s", argv[0]); + } + + if ((errno = dbp->close(dbp, 0)) != 0) + err(1, "%s", argv[0]); + return (0); +} + +/* + * db_init -- + * Initialize the environment. + */ +DB_ENV * +db_init(home) + char *home; +{ + DB_ENV *dbenv; + + if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) { + errno = ENOMEM; + err(1, NULL); + } + dbenv->db_errfile = stderr; + dbenv->db_errpfx = progname; + + if ((errno = + db_appinit(home, NULL, dbenv, DB_CREATE | DB_USE_ENVIRON)) != 0) + err(1, "db_appinit"); + return (dbenv); +} + +#define FLAG(name, value, keyword, flag) \ + if (strcmp(name, keyword) == 0) { \ + switch (*value) { \ + case '1': \ + dbinfop->flags |= (flag); \ + break; \ + case '0': \ + dbinfop->flags &= ~(flag); \ + break; \ + default: \ + badnum(); \ + /* NOTREACHED */ \ + } \ + continue; \ + } +#define NUMBER(name, value, keyword, field, flag) \ + if (strcmp(name, keyword) == 0) { \ + get_long(value, 1, LONG_MAX, &val); \ + dbinfop->field = val; \ + if (flag != 0) \ + dbinfop->flags |= (flag); \ + continue; \ + } +#define STRING(name, value, keyword, field, flag) \ + if (strcmp(name, keyword) == 0) { \ + dbinfop->field = value[0]; \ + if (flag != 0) \ + dbinfop->flags |= (flag); \ + continue; \ + } + +/* + * configure -- + * Handle command-line configuration options. + */ +void +configure(dbinfop, clp) + DB_INFO *dbinfop; + char **clp; +{ + long val; + char *name, *value; + + for (; (name = *clp) != NULL; ++clp) { + if ((value = strchr(name, '=')) == NULL) + errx(1, + "command-line configuration uses name=value format"); + *value++ = '\0'; + + NUMBER(name, value, "bt_maxkey", bt_maxkey, 0); + NUMBER(name, value, "bt_minkey", bt_minkey, 0); + NUMBER(name, value, "db_lorder", db_lorder, 0); + NUMBER(name, value, "db_pagesize", db_pagesize, 0); + FLAG(name, value, "duplicates", DB_DUP); + NUMBER(name, value, "h_ffactor", h_ffactor, 0); + NUMBER(name, value, "h_nelem", h_nelem, 0); + NUMBER(name, value, "re_len", re_len, DB_FIXEDLEN); + STRING(name, value, "re_pad", re_pad, DB_PAD); + FLAG(name, value, "recnum", DB_RECNUM); + FLAG(name, value, "renumber", DB_RENUMBER); + + errx(1, "unknown command-line configuration keyword"); + } +} + +/* + * rheader -- + * Read the header message. + */ +void +rheader(dbtypep, pflagp, dbinfop) + DBTYPE *dbtypep; + int *pflagp; + DB_INFO *dbinfop; +{ + long lineno, val; + char name[256], value[256]; + + *dbtypep = DB_UNKNOWN; + *pflagp = 0; + + for (lineno = 1;; ++lineno) { + if (fscanf(stdin, "%[^=]=%s\n", name, value) != 2) + errx(1, "line %lu: unexpected line", lineno); + if (strcmp(name, "HEADER") == 0) + break; + + if (strcmp(name, "format") == 0) { + if (strcmp(value, "bytevalue") == 0) { + *pflagp = 0; + continue; + } + if (strcmp(value, "print") == 0) { + *pflagp = 1; + continue; + } + errx(1, "line %d: unknown format", lineno); + } + if (strcmp(name, "type") == 0) { + if (strcmp(value, "btree") == 0) { + *dbtypep = DB_BTREE; + continue; + } + if (strcmp(value, "hash") == 0) { + *dbtypep = DB_HASH; + continue; + } + if (strcmp(value, "recno") == 0) { + *dbtypep = DB_RECNO; + continue; + } + errx(1, "line %d: unknown type", lineno); + } + NUMBER(name, value, "bt_maxkey", bt_maxkey, 0); + NUMBER(name, value, "bt_minkey", bt_minkey, 0); + NUMBER(name, value, "db_lorder", db_lorder, 0); + NUMBER(name, value, "db_pagesize", db_pagesize, 0); + FLAG(name, value, "duplicates", DB_DUP); + NUMBER(name, value, "h_ffactor", h_ffactor, 0); + NUMBER(name, value, "h_nelem", h_nelem, 0); + NUMBER(name, value, "re_len", re_len, DB_FIXEDLEN); + STRING(name, value, "re_pad", re_pad, DB_PAD); + FLAG(name, value, "recnum", DB_RECNUM); + FLAG(name, value, "renumber", DB_RENUMBER); + + errx(1, "unknown input-file header configuration keyword"); + } +} + +/* + * dbt_rprint -- + * Read a printable line into a DBT structure. + */ +int +dbt_rprint(dbtp) + DBT *dbtp; +{ + u_int32_t len; + u_int8_t *p; + int c1, c2, escape; + + escape = 0; + for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) { + if (c1 == EOF) { + if (len == 0) + return (1); + err(1, "unexpected end of key/data pair"); + } + if (escape) { + if (c1 != '\\') { + if ((c2 = getchar()) == EOF) + err(1, + "unexpected end of key/data pair"); + c1 = digitize(c1) << 4 | digitize(c2); + } + escape = 0; + } else + if (c1 == '\\') { + escape = 1; + continue; + } + if (++len >= dbtp->ulen - 10) { + dbtp->ulen *= 2; + if ((dbtp->data = + (void *)realloc(dbtp->data, dbtp->ulen)) == NULL) { + errno = ENOMEM; + err(1, NULL); + } + p = (u_int8_t *)dbtp->data + len; + } + *p++ = c1; + } + dbtp->size = len; + return (0); +} + +/* + * digitize -- + * Convert a character to an integer. + */ +int +digitize(c) + int c; +{ + switch (c) { /* Don't depend on ASCII ordering. */ + case '0': return (0); + case '1': return (1); + case '2': return (2); + case '3': return (3); + case '4': return (4); + case '5': return (5); + case '6': return (6); + case '7': return (7); + case '8': return (8); + case '9': return (9); + case 'a': return (10); + case 'b': return (11); + case 'c': return (12); + case 'd': return (13); + case 'e': return (14); + case 'f': return (15); + } + + err(1, "unexpected hexadecimal value"); + /* NOTREACHED */ + + return (0); +} + +/* + * dbt_rdump -- + * Read a byte dump line into a DBT structure. + */ +int +dbt_rdump(dbtp) + DBT *dbtp; +{ + u_int32_t len; + u_int8_t *p; + int c1, c2; + + for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) { + if (c1 == EOF) { + if (len == 0) + return (1); + err(1, "unexpected end of key/data pair"); + } + if ((c2 = getchar()) == EOF) + err(1, "unexpected end of key/data pair"); + if (++len >= dbtp->ulen - 10) { + dbtp->ulen *= 2; + if ((dbtp->data = + (void *)realloc(dbtp->data, dbtp->ulen)) == NULL) { + errno = ENOMEM; + err(1, NULL); + } + p = (u_int8_t *)dbtp->data + len; + } + *p++ = digitize(c1) << 4 | digitize(c2); + } + dbtp->size = len; + return (0); +} + +/* + * badnum -- + * Display the bad number message. + */ +void +badnum() +{ + err(1, "boolean name=value pairs require a value of 0 or 1"); +} + +/* + * usage -- + * Display the usage message. + */ +void +usage() +{ + (void)fprintf(stderr, +"usage: db_load [-c name=value] [-f file] [-h home] [-t btree | hash] db_file\n"); + exit(1); +} diff --git a/db2/progs/db_printlog/db_printlog.c b/db2/progs/db_printlog/db_printlog.c new file mode 100644 index 0000000000..12c365524f --- /dev/null +++ b/db2/progs/db_printlog/db_printlog.c @@ -0,0 +1,160 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 1997 + * Sleepycat Software. All rights reserved. + */ + +#include "config.h" + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1997\n\ + Sleepycat Software Inc. All rights reserved.\n"; +static const char sccsid[] = "@(#)db_printlog.c 10.8 (Sleepycat) 7/15/97"; +#endif + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <errno.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#endif + +#include "db_int.h" +#include "shqueue.h" +#include "db_page.h" +#include "btree.h" +#include "hash.h" +#include "log.h" +#include "txn.h" +#include "db_am.h" +#include "clib_ext.h" + +DB_ENV *db_init __P((char *)); +void onint __P((int)); +void usage __P((void)); + +int interrupted; +char *progname = "db_printlog"; /* Program name. */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB_ENV *dbenv; + DBT data; + DB_LSN key; + int ch, eval; + char *home; + + home = NULL; + while ((ch = getopt(argc, argv, "h:")) != EOF) + switch (ch) { + case 'h': + home = optarg; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if ((home != NULL && argc > 0) || argc > 1) + usage(); + + /* XXX: backward compatibility, first argument is home. */ + if (argc == 1) + home = argv[0]; + + dbenv = db_init(home); + + eval = 0; + if ((errno = __bam_init_print(dbenv)) != 0 || + (errno = __db_init_print(dbenv)) != 0 || + (errno = __ham_init_print(dbenv)) != 0 || + (errno = __log_init_print(dbenv)) != 0 || + (errno = __txn_init_print(dbenv)) != 0) { + warn("initialization"); + eval = 1; + (void)db_appexit(dbenv); + } + + (void)signal(SIGINT, onint); + + memset(&data, 0, sizeof(data)); + while (!interrupted) { + if ((errno = + log_get(dbenv->lg_info, &key, &data, DB_NEXT)) != 0) { + if (errno == DB_NOTFOUND) + break; + eval = 1; + warn("log_get"); + break; + } + if ((errno = + __db_dispatch(dbenv->lg_info, &data, &key, 0, NULL)) != 0) { + eval = 1; + warn("dispatch"); + break; + } + } + + (void)db_appexit(dbenv); + + if (interrupted) { + (void)signal(SIGINT, SIG_DFL); + (void)raise(SIGINT); + /* NOTREACHED */ + } + exit (eval); +} + +/* + * db_init -- + * Initialize the environment. + */ +DB_ENV * +db_init(home) + char *home; +{ + DB_ENV *dbenv; + + if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) { + errno = ENOMEM; + err(1, NULL); + } + dbenv->db_errfile = stderr; + dbenv->db_errpfx = progname; + + if ((errno = + db_appinit(home, NULL, dbenv, DB_CREATE | DB_INIT_LOG)) != 0) + err(1, "db_appinit"); + return (dbenv); +} + +/* + * oninit -- + * Interrupt signal handler. + */ +void +onint(signo) + int signo; +{ + signo = 1; /* XXX: Shut the compiler up. */ + interrupted = 1; +} + +void +usage() +{ + fprintf(stderr, "usage: db_printlog [-h home]\n"); + exit (1); +} diff --git a/db2/progs/db_recover/db_recover.c b/db2/progs/db_recover/db_recover.c new file mode 100644 index 0000000000..4ac5925f79 --- /dev/null +++ b/db2/progs/db_recover/db_recover.c @@ -0,0 +1,122 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 1997 + * Sleepycat Software. All rights reserved. + */ + +#include "config.h" + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1997\n\ + Sleepycat Software Inc. All rights reserved.\n"; +static const char sccsid[] = "@(#)db_recover.c 10.12 (Sleepycat) 7/27/97"; +#endif + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <errno.h> +#include <getopt.h> +#include <stdlib.h> +#include <time.h> +#endif + +#include "db_int.h" +#include "txn.h" +#include "common_ext.h" +#include "clib_ext.h" + +DB_ENV *db_init __P((char *, int, int)); +void usage __P((void)); +int main __P((int, char *[])); + +const char *progname = "db_recover"; /* Program name. */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB_ENV *dbenv; + time_t now; + int ch, flags, verbose; + char *home; + + home = NULL; + flags = verbose = 0; + while ((ch = getopt(argc, argv, "ch:v")) != EOF) + switch (ch) { + case 'c': + LF_SET(DB_RECOVER_FATAL); + break; + case 'h': + home = optarg; + break; + case 'v': + verbose = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 0) + usage(); + + dbenv = db_init(home, flags, verbose); + if (verbose) { + __db_err(dbenv, "Recovery complete at %s", ctime(&now)); + __db_err(dbenv, "%s %lu %s [%lu][%lu]", + "Maximum transaction id", + (u_long)dbenv->tx_info->region->last_txnid, + "Recovery checkpoint", + (u_long)dbenv->tx_info->region->last_ckp.file, + (u_long)dbenv->tx_info->region->last_ckp.offset); + } + + exit (db_appexit(dbenv)); +} + +DB_ENV * +db_init(home, flags, verbose) + char *home; + int flags, verbose; +{ + DB_ENV *dbenv; + int local_flags; + + if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) { + errno = ENOMEM; + err(1, NULL); + } + dbenv->db_errfile = stderr; + dbenv->db_errpfx = "db_recover"; + dbenv->db_verbose = verbose; + + /* Initialize environment for pathnames only. */ + local_flags = DB_CREATE | DB_INIT_LOG | + DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN | DB_USE_ENVIRON; + + if (LF_ISSET(DB_RECOVER_FATAL)) + local_flags |= DB_RECOVER_FATAL; + else + local_flags |= DB_RECOVER; + + if ((errno = db_appinit(home, NULL, dbenv, local_flags)) != 0) + err(1, "appinit failed"); + + return (dbenv); +} + +void +usage() +{ + (void)fprintf(stderr, "usage: db_recover [-cv] [-h home]\n"); + exit(1); +} diff --git a/db2/progs/db_stat/db_stat.c b/db2/progs/db_stat/db_stat.c new file mode 100644 index 0000000000..5c7044dbce --- /dev/null +++ b/db2/progs/db_stat/db_stat.c @@ -0,0 +1,434 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 1997 + * Sleepycat Software. All rights reserved. + */ + +#include "config.h" + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1997\n\ + Sleepycat Software Inc. All rights reserved.\n"; +static const char sccsid[] = "@(#)db_stat.c 8.17 (Sleepycat) 8/24/97"; +#endif + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <ctype.h> +#include <errno.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#endif + +#include "db_int.h" +#include "clib_ext.h" + +#define DIVIDER "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" + +typedef enum { T_NOTSET, T_DB, T_MPOOL, T_TXN } test_t; + +void bstat __P((DB *)); +DB_ENV *db_init __P((char *, test_t)); +void hstat __P((DB *)); +void mstat __P((DB_ENV *)); +void prflags __P((u_int32_t, const FN *)); +void onint __P((int)); +void tstat __P((DB_ENV *)); +int txn_compare __P((const void *, const void *)); +void usage __P((void)); +int main __P((int, char *[])); + +int interrupted; +const char *progname = "db_stat"; /* Program name. */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB *dbp; + DB_ENV *dbenv; + test_t ttype; + int ch; + char *db, *home; + + ttype = T_NOTSET; + db = home = NULL; + while ((ch = getopt(argc, argv, "d:h:mt")) != EOF) + switch (ch) { + case 'd': + db = optarg; + ttype = T_DB; + break; + case 'h': + home = optarg; + break; + case 'm': + ttype = T_MPOOL; + break; + case 't': + ttype = T_TXN; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 0 || ttype == T_NOTSET) + usage(); + + dbenv = db_init(home, ttype); + + (void)signal(SIGINT, onint); + + switch (ttype) { + case T_DB: + if ((errno = db_open(db, DB_UNKNOWN, + DB_RDONLY, 0, dbenv, NULL, &dbp)) != 0) + return (1); + switch (dbp->type) { + case DB_BTREE: + case DB_RECNO: + bstat(dbp); + break; + case DB_HASH: + hstat(dbp); + break; + case DB_UNKNOWN: + abort(); /* Impossible. */ + /* NOTREACHED */ + } + (void)dbp->close(dbp, 0); + break; + case T_MPOOL: + mstat(dbenv); + break; + case T_TXN: + tstat(dbenv); + break; + case T_NOTSET: + abort(); /* Impossible. */ + /* NOTREACHED */ + } + + (void)db_appexit(dbenv); + + if (interrupted) { + (void)signal(SIGINT, SIG_DFL); + (void)raise(SIGINT); + /* NOTREACHED */ + } + return (0); +} + +/* + * bstat -- + * Display btree/recno statistics. + */ +void +bstat(dbp) + DB *dbp; +{ + static const FN fn[] = { + { DB_DUP, "DB_DUP" }, + { DB_FIXEDLEN, "DB_FIXEDLEN" }, + { DB_RECNUM, "DB_RECNUM" }, + { DB_RENUMBER, "DB_RENUMBER" }, + { 0 } + }; + DB_BTREE_STAT *sp; + + if (dbp->stat(dbp, &sp, NULL, 0)) + err(1, "dbp->stat"); + +#define PCT(f, t) \ + (t == 0 ? 0 : \ + (((double)((t * sp->bt_pagesize) - f) / (t * sp->bt_pagesize)) * 100)) + + prflags(sp->bt_flags, fn); + if (dbp->type == DB_BTREE) { +#ifdef NOT_IMPLEMENTED + printf("%lu\tMaximum keys per-page.\n", (u_long)sp->bt_maxkey); +#endif + printf("%lu\tMinimum keys per-page.\n", (u_long)sp->bt_minkey); + } + if (dbp->type == DB_RECNO) { + printf("%lu\tFixed-length record size.\n", + (u_long)sp->bt_re_len); + if (isprint(sp->bt_re_pad)) + printf("%c\tFixed-length record pad.\n", + (int)sp->bt_re_pad); + else + printf("0x%x\tFixed-length record pad.\n", + (int)sp->bt_re_pad); + } + printf("%lu\tUnderlying tree page size.\n", (u_long)sp->bt_pagesize); + printf("%lu\tNumber of levels in the tree.\n", (u_long)sp->bt_levels); + printf("%lu\tNumber of keys in the tree.\n", (u_long)sp->bt_nrecs); + printf("%lu\tNumber of tree internal pages.\n", (u_long)sp->bt_int_pg); + printf("%lu\tNumber of tree leaf pages.\n", (u_long)sp->bt_leaf_pg); + printf("%lu\tNumber of tree duplicate pages.\n", + (u_long)sp->bt_dup_pg); + printf("%lu\tNumber of tree overflow pages.\n", + (u_long)sp->bt_over_pg); + printf("%lu\tNumber of pages on the free list.\n", + (u_long)sp->bt_free); + printf("%lu\tNumber of pages freed for reuse.\n", + (u_long)sp->bt_freed); + printf("%lu\tNumber of bytes free in tree internal pages (%.0f%% ff)\n", + (u_long)sp->bt_int_pgfree, + PCT(sp->bt_int_pgfree, sp->bt_int_pg)); + printf("%lu\tNumber of bytes free in tree leaf pages (%.0f%% ff).\n", + (u_long)sp->bt_leaf_pgfree, + PCT(sp->bt_leaf_pgfree, sp->bt_leaf_pg)); +printf("%lu\tNumber of bytes free in tree duplicate pages (%.0f%% ff).\n", + (u_long)sp->bt_dup_pgfree, + PCT(sp->bt_dup_pgfree, sp->bt_dup_pg)); +printf("%lu\tNumber of bytes free in tree overflow pages (%.0f%% ff).\n", + (u_long)sp->bt_over_pgfree, + PCT(sp->bt_over_pgfree, sp->bt_over_pg)); + printf("%lu\tNumber of bytes saved by prefix compression.\n", + (u_long)sp->bt_pfxsaved); + printf("%lu\tTotal number of tree page splits.\n", + (u_long)sp->bt_split); + printf("%lu\tNumber of root page splits.\n", (u_long)sp->bt_rootsplit); + printf("%lu\tNumber of fast splits.\n", (u_long)sp->bt_fastsplit); + printf("%lu\tNumber of hits in tree fast-insert code.\n", + (u_long)sp->bt_cache_hit); + printf("%lu\tNumber of misses in tree fast-insert code.\n", + (u_long)sp->bt_cache_miss); + printf("%lu\tNumber of keys added.\n", (u_long)sp->bt_added); + printf("%lu\tNumber of keys deleted.\n", (u_long)sp->bt_deleted); +} + +/* + * hstat -- + * Display hash statistics. + */ +void +hstat(dbp) + DB *dbp; +{ + return; +} + +/* + * mstat -- + * Display mpool statistics. + */ +void +mstat(dbenv) + DB_ENV *dbenv; +{ + DB_MPOOL_FSTAT **fsp; + DB_MPOOL_STAT *gsp; + + if (memp_stat(dbenv->mp_info, &gsp, &fsp, NULL)) + err(1, NULL); + + printf("%lu\tCache size (%luK).\n", + (u_long)gsp->st_cachesize, (u_long)gsp->st_cachesize / 1024); + printf("%lu\tRequested pages found in the cache", gsp->st_cache_hit); + if (gsp->st_cache_hit + gsp->st_cache_miss != 0) + printf(" (%.0f%%)", ((double)gsp->st_cache_hit / + (gsp->st_cache_hit + gsp->st_cache_miss)) * 100); + printf(".\n"); + printf("%lu\tRequested pages mapped into the process' address space.\n", + gsp->st_map); + printf("%lu\tRequested pages not found in the cache.\n", + gsp->st_cache_miss); + printf("%lu\tPages created in the cache.\n", gsp->st_page_create); + printf("%lu\tPages read into the cache.\n", gsp->st_page_in); + printf("%lu\tPages written from the cache to the backing file.\n", + gsp->st_page_out); + printf("%lu\tRead-only pages forced from the cache.\n", + gsp->st_ro_evict); + printf("%lu\tRead-write pages forced from the cache.\n", + gsp->st_rw_evict); + printf("%lu\tNumber of hash buckets used for page location.\n", + gsp->st_hash_buckets); + printf("%lu\tTotal number of times hash chains searched for a page.\n", + gsp->st_hash_searches); + printf("%lu\tThe longest hash chain searched for a page.\n", + gsp->st_hash_longest); + printf( + "%lu\tTotal number of hash buckets examined for page location.\n", + gsp->st_hash_examined); + + for (; fsp != NULL && *fsp != NULL; ++fsp) { + printf("%s\n", DIVIDER); + printf("%s\n", (*fsp)->file_name); + printf("%lu\tPage size.\n", (u_long)(*fsp)->st_pagesize); + printf("%lu\tRequested pages found in the cache", + (*fsp)->st_cache_hit); + if ((*fsp)->st_cache_hit + (*fsp)->st_cache_miss != 0) + printf(" (%.0f%%)", ((double)(*fsp)->st_cache_hit / + ((*fsp)->st_cache_hit + (*fsp)->st_cache_miss)) * + 100); + printf(".\n"); + printf("%lu\tRequested pages mapped into the process' address space.\n", + (*fsp)->st_map); + printf("%lu\tRequested pages not found in the cache.\n", + (*fsp)->st_cache_miss); + printf("%lu\tPages created in the cache.\n", + (*fsp)->st_page_create); + printf("%lu\tPages read into the cache.\n", (*fsp)->st_page_in); + printf("%lu\tPages written from the cache to the backing file.\n", + (*fsp)->st_page_out); + } +} + +/* + * tstat -- + * Display transaction statistics. + */ +void +tstat(dbenv) + DB_ENV *dbenv; +{ + DB_TXN_STAT *tstat; + unsigned int i; + const char *p; + + if (txn_stat(dbenv->tx_info, &tstat, NULL)) + err(1, NULL); + + p = tstat->st_last_ckp.file == 0 ? + "No checkpoint LSN." : "File/offset for last checkpoint LSN."; + printf("%lu/%lu\t%s\n", (u_long)tstat->st_last_ckp.file, + (u_long)tstat->st_last_ckp.offset, p); + p = tstat->st_pending_ckp.file == 0 ? + "No pending checkpoint LSN." : + "File/offset for last pending checkpoint LSN."; + printf("%lu/%lu\t%s.\n", + (u_long)tstat->st_pending_ckp.file, + (u_long)tstat->st_pending_ckp.offset, p); + if (tstat->st_time_ckp == 0) + printf("0\tNo checkpoint timestamp.\n"); + else + printf("%.24s\tCheckpoint timestamp.\n", + ctime(&tstat->st_time_ckp)); + printf("%lx\tLast transaction ID allocated.\n", + (u_long)tstat->st_last_txnid); + printf("%lu\tMaximum number of active transactions.\n", + (u_long)tstat->st_maxtxns); + printf("%lu\tNumber of transactions begun.\n", + (u_long)tstat->st_nbegins); + printf("%lu\tNumber of transactions aborted.\n", + (u_long)tstat->st_naborts); + printf("%lu\tNumber of transactions committed.\n", + (u_long)tstat->st_ncommits); + printf("%lu\tActive transactions.\n", (u_long)tstat->st_nactive); + qsort(tstat->st_txnarray, + tstat->st_nactive, sizeof(tstat->st_txnarray[0]), txn_compare); + for (i = 0; i < tstat->st_nactive; ++i) + printf("\tid: %lx; initial LSN file/offest %lu/%lu\n", + (u_long)tstat->st_txnarray[i].txnid, + (u_long)tstat->st_txnarray[i].lsn.file, + (u_long)tstat->st_txnarray[i].lsn.offset); +} + +int +txn_compare(a1, b1) + const void *a1, *b1; +{ + const DB_TXN_ACTIVE *a, *b; + + a = a1; + b = b1; + + if (a->txnid > b->txnid) + return (1); + if (a->txnid < b->txnid) + return (-1); + return (0); +} + +/* + * prflags -- + * Print out flag values. + */ +void +prflags(flags, fn) + u_int32_t flags; + FN const *fn; +{ + const FN *fnp; + int found; + const char *sep; + + sep = " "; + printf("Flags:"); + for (found = 0, fnp = fn; fnp->mask != 0; ++fnp) + if (fnp->mask & flags) { + printf("%s%s", sep, fnp->name); + sep = ", "; + found = 1; + } + printf("\n"); +} + +/* + * db_init -- + * Initialize the environment. + */ +DB_ENV * +db_init(home, ttype) + char *home; + test_t ttype; +{ + DB_ENV *dbenv; + int flags; + + flags = DB_USE_ENVIRON; + switch (ttype) { + case T_MPOOL: + flags |= DB_INIT_MPOOL; + break; + case T_TXN: + flags |= DB_INIT_TXN; + break; + default: + break; + } + + if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) { + errno = ENOMEM; + err(1, NULL); + } + dbenv->db_errfile = stderr; + dbenv->db_errpfx = progname; + + if ((errno = db_appinit(home, NULL, dbenv, flags)) != 0) + err(1, "db_appinit"); + return (dbenv); +} + +/* + * oninit -- + * Interrupt signal handler. + */ +void +onint(signo) + int signo; +{ + signo = 1; /* XXX: Shut the compiler up. */ + interrupted = 1; +} + +void +usage() +{ + fprintf(stderr, "usage: db_stat [-mt] [-d file] [-h home]\n"); + exit (1); +} |