2
* See the file LICENSE for redistribution information.
4
* Copyright (c) 1996-2002
5
* Sleepycat Software. All rights reserved.
11
static const char copyright[] =
12
"Copyright (c) 1996-2002\nSleepycat Software Inc. All rights reserved.\n";
13
static const char revid[] =
17
#ifndef NO_SYSTEM_INCLUDES
18
#include <sys/types.h>
20
#if TIME_WITH_SYS_TIME
37
#include "dbinc/txn.h"
39
int db_recover_main __P((int, char *[]));
40
int db_recover_read_timestamp __P((const char *, char *, time_t *));
41
int db_recover_usage __P((void));
42
int db_recover_version_check __P((const char *));
51
__db_util_arg("db_recover", args, &argc, &argv);
52
return (db_recover_main(argc, argv) ? EXIT_FAILURE : EXIT_SUCCESS);
56
#define ERROR_RETURN ERROR
59
db_recover_main(argc, argv)
64
extern int optind, __db_getopt_reset;
65
const char *progname = "db_recover";
68
time_t now, timestamp;
70
int ch, exitval, fatal_recover, ret, retain_env, verbose;
73
if ((ret = db_recover_version_check(progname)) != 0)
78
exitval = fatal_recover = retain_env = verbose = 0;
79
__db_getopt_reset = 1;
80
while ((ch = getopt(argc, argv, "ceh:P:t:Vv")) != EOF)
92
passwd = strdup(optarg);
93
memset(optarg, 0, strlen(optarg));
95
fprintf(stderr, "%s: strdup: %s\n",
96
progname, strerror(errno));
97
return (EXIT_FAILURE);
102
db_recover_read_timestamp(progname, optarg, ×tamp)) != 0)
106
printf("%s\n", db_version(NULL, NULL, NULL));
107
return (EXIT_SUCCESS);
113
return (db_recover_usage());
119
return (db_recover_usage());
121
/* Handle possible interruptions. */
125
* Create an environment object and initialize it for error
128
if ((ret = db_env_create(&dbenv, 0)) != 0) {
130
"%s: db_env_create: %s\n", progname, db_strerror(ret));
131
return (EXIT_FAILURE);
133
dbenv->set_errfile(dbenv, stderr);
134
dbenv->set_errpfx(dbenv, progname);
136
(void)dbenv->set_verbose(dbenv, DB_VERB_RECOVERY, 1);
137
(void)dbenv->set_verbose(dbenv, DB_VERB_CHKPOINT, 1);
140
(ret = dbenv->set_tx_timestamp(dbenv, ×tamp)) != 0) {
141
dbenv->err(dbenv, ret, "DB_ENV->set_timestamp");
145
if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv,
146
passwd, DB_ENCRYPT_AES)) != 0) {
147
dbenv->err(dbenv, ret, "set_passwd");
152
* Initialize the environment -- we don't actually do anything
153
* else, that all that's needed to run recovery.
155
* Note that unless the caller specified the -e option, we use a
156
* private environment, as we're about to create a region, and we
157
* don't want to to leave it around. If we leave the region around,
158
* the application that should create it will simply join it instead,
159
* and will then be running with incorrectly sized (and probably
160
* terribly small) caches. Applications that use -e should almost
161
* certainly use DB_CONFIG files in the directory.
164
LF_SET(DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG |
165
DB_INIT_MPOOL | DB_INIT_TXN | DB_USE_ENVIRON);
166
LF_SET(fatal_recover ? DB_RECOVER_FATAL : DB_RECOVER);
167
LF_SET(retain_env ? 0 : DB_PRIVATE);
168
if ((ret = dbenv->open(dbenv, home, flags, 0)) != 0) {
169
dbenv->err(dbenv, ret, "DB_ENV->open");
175
region = ((DB_TXNMGR *)dbenv->tx_handle)->reginfo.primary;
176
dbenv->errx(dbenv, "Recovery complete at %.24s", ctime(&now));
177
dbenv->errx(dbenv, "%s %lx %s [%lu][%lu]",
178
"Maximum transaction id", (u_long)region->last_txnid,
179
"Recovery checkpoint", (u_long)region->last_ckp.file,
180
(u_long)region->last_ckp.offset);
184
shutdown: exitval = 1;
187
/* Clean up the environment. */
188
if ((ret = dbenv->close(dbenv, 0)) != 0) {
191
"%s: dbenv->close: %s\n", progname, db_strerror(ret));
194
/* Resend any caught signal. */
195
__db_util_sigresend();
197
return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
200
#define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2;
204
* Convert a time argument to Epoch seconds.
207
* The Regents of the University of California. All rights reserved.
209
* Redistribution and use in source and binary forms, with or without
210
* modification, are permitted provided that the following conditions
212
* 1. Redistributions of source code must retain the above copyright
213
* notice, this list of conditions and the following disclaimer.
214
* 2. Redistributions in binary form must reproduce the above copyright
215
* notice, this list of conditions and the following disclaimer in the
216
* documentation and/or other materials provided with the distribution.
217
* 3. Neither the name of the University nor the names of its contributors
218
* may be used to endorse or promote products derived from this software
219
* without specific prior written permission.
221
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
222
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
223
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
224
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
225
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
226
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
227
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
228
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
229
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
230
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
234
db_recover_read_timestamp(progname, arg, timep)
235
const char *progname;
243
/* Start with the current time. */
245
if ((t = localtime(&now)) == NULL) {
247
"%s: localtime: %s\n", progname, strerror(errno));
248
return (EXIT_FAILURE);
250
/* [[CC]YY]MMDDhhmm[.SS] */
251
if ((p = strchr(arg, '.')) == NULL)
252
t->tm_sec = 0; /* Seconds defaults to 0. */
254
if (strlen(p + 1) != 2)
257
t->tm_sec = ATOI2(p);
261
switch(strlen(arg)) {
262
case 12: /* CCYYMMDDhhmm */
263
t->tm_year = ATOI2(arg);
267
case 10: /* YYMMDDhhmm */
269
yearset = ATOI2(arg);
270
t->tm_year += yearset;
272
yearset = ATOI2(arg);
274
t->tm_year = yearset + 2000;
276
t->tm_year = yearset + 1900;
278
t->tm_year -= 1900; /* Convert to UNIX time. */
280
case 8: /* MMDDhhmm */
281
t->tm_mon = ATOI2(arg);
282
--t->tm_mon; /* Convert from 01-12 to 00-11 */
283
t->tm_mday = ATOI2(arg);
284
t->tm_hour = ATOI2(arg);
285
t->tm_min = ATOI2(arg);
291
t->tm_isdst = -1; /* Figure out DST. */
295
terr: fprintf(stderr,
296
"%s: out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]",
298
return (EXIT_FAILURE);
306
(void)fprintf(stderr, "%s\n",
307
"usage: db_recover [-ceVv] [-h home] [-P password] [-t [[CC]YY]MMDDhhmm[.SS]]");
308
return (EXIT_FAILURE);
312
db_recover_version_check(progname)
313
const char *progname;
315
int v_major, v_minor, v_patch;
317
/* Make sure we're loaded with the right version of the DB library. */
318
(void)db_version(&v_major, &v_minor, &v_patch);
319
if (v_major != DB_VERSION_MAJOR ||
320
v_minor != DB_VERSION_MINOR || v_patch != DB_VERSION_PATCH) {
322
"%s: version %d.%d.%d doesn't match library version %d.%d.%d\n",
323
progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
324
DB_VERSION_PATCH, v_major, v_minor, v_patch);
325
return (EXIT_FAILURE);