2
* See the file LICENSE for redistribution information.
4
* Copyright (c) 1996-2002
5
* Sleepycat Software. All rights reserved.
10
#include <sys/types.h>
22
#include "ex_apprec.h"
24
int apprec_dispatch __P((DB_ENV *, DBT *, DB_LSN *, db_recops));
25
int open_env __P((const char *, FILE *, const char *, DB_ENV **));
26
int verify_absence __P((DB_ENV *, const char *));
27
int verify_presence __P((DB_ENV *, const char *));
42
char ch, dirname[256];
43
const char *progname = "ex_apprec"; /* Program name. */
48
while ((ch = getopt(argc, argv, "h:")) != EOF)
54
fprintf(stderr, "usage: %s [-h home]", progname);
58
printf("Set up environment.\n");
59
if ((ret = open_env(home, stderr, progname, &dbenv)) != 0)
60
return (EXIT_FAILURE);
62
printf("Create a directory in a transaction.\n");
64
* This application's convention is to log the full directory name,
65
* including trailing nul.
67
memset(&dirnamedbt, 0, sizeof(dirnamedbt));
68
sprintf(dirname, "%s/MYDIRECTORY", home);
69
dirnamedbt.data = dirname;
70
dirnamedbt.size = strlen(dirname) + 1;
72
if ((ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0) {
73
dbenv->err(dbenv, ret, "txn_begin");
74
return (EXIT_FAILURE);
77
/* Remember, always log actions before you execute them! */
78
memset(&lsn, 0, sizeof(lsn));
80
ex_apprec_mkdir_log(dbenv, txn, &lsn, 0, &dirnamedbt)) != 0) {
81
dbenv->err(dbenv, ret, "mkdir_log");
82
return (EXIT_FAILURE);
84
if (mkdir(dirname, 0755) != 0) {
85
dbenv->err(dbenv, errno, "mkdir");
86
return (EXIT_FAILURE);
89
printf("Verify the directory's presence: ");
90
verify_presence(dbenv, dirname);
93
/* Now abort the transaction and verify that the directory goes away. */
94
printf("Abort the transaction.\n");
95
if ((ret = txn->abort(txn)) != 0) {
96
dbenv->err(dbenv, ret, "txn_abort");
97
return (EXIT_FAILURE);
100
printf("Verify the directory's absence: ");
101
verify_absence(dbenv, dirname);
104
/* Now do the same thing over again, only with a commit this time. */
105
printf("Create a directory in a transaction.\n");
106
memset(&dirnamedbt, 0, sizeof(dirnamedbt));
107
sprintf(dirname, "%s/MYDIRECTORY", home);
108
dirnamedbt.data = dirname;
109
dirnamedbt.size = strlen(dirname) + 1;
110
if ((ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0) {
111
dbenv->err(dbenv, ret, "txn_begin");
112
return (EXIT_FAILURE);
115
memset(&lsn, 0, sizeof(lsn));
117
ex_apprec_mkdir_log(dbenv, txn, &lsn, 0, &dirnamedbt)) != 0) {
118
dbenv->err(dbenv, ret, "mkdir_log");
119
return (EXIT_FAILURE);
121
if (mkdir(dirname, 0755) != 0) {
122
dbenv->err(dbenv, errno, "mkdir");
123
return (EXIT_FAILURE);
126
printf("Verify the directory's presence: ");
127
verify_presence(dbenv, dirname);
130
/* Now abort the transaction and verify that the directory goes away. */
131
printf("Commit the transaction.\n");
132
if ((ret = txn->commit(txn, 0)) != 0) {
133
dbenv->err(dbenv, ret, "txn_commit");
134
return (EXIT_FAILURE);
137
printf("Verify the directory's presence: ");
138
verify_presence(dbenv, dirname);
141
printf("Now remove the directory, then run recovery.\n");
142
if ((ret = dbenv->close(dbenv, 0)) != 0) {
143
fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(ret));
144
return (EXIT_FAILURE);
146
if (rmdir(dirname) != 0) {
148
"%s: rmdir failed with error %s", progname,
151
verify_absence(dbenv, dirname);
153
/* Opening with DB_RECOVER runs recovery. */
154
if ((ret = open_env(home, stderr, progname, &dbenv)) != 0)
155
return (EXIT_FAILURE);
157
printf("Verify the directory's presence: ");
158
verify_presence(dbenv, dirname);
161
/* Close the handle. */
162
if ((ret = dbenv->close(dbenv, 0)) != 0) {
163
fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(ret));
164
return (EXIT_FAILURE);
167
return (EXIT_SUCCESS);
171
open_env(home, errfp, progname, dbenvp)
172
const char *home, *progname;
180
* Create an environment object and initialize it for error
183
if ((ret = db_env_create(&dbenv, 0)) != 0) {
184
fprintf(errfp, "%s: %s\n", progname, db_strerror(ret));
187
dbenv->set_errfile(dbenv, errfp);
188
dbenv->set_errpfx(dbenv, progname);
190
/* Set up our custom recovery dispatch function. */
191
if ((ret = dbenv->set_app_dispatch(dbenv, apprec_dispatch)) != 0) {
192
dbenv->err(dbenv, ret, "set_app_dispatch");
197
* Open the environment with full transactional support, running
201
dbenv->open(dbenv, home, DB_CREATE | DB_RECOVER | DB_INIT_LOCK |
202
DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0)) != 0) {
203
dbenv->err(dbenv, ret, "environment open: %s", home);
204
dbenv->close(dbenv, 0);
213
* Sample application dispatch function to handle user-specified log record
217
apprec_dispatch(dbenv, dbt, lsn, op)
225
/* Pull the record type out of the log record. */
226
memcpy(&rectype, dbt->data, sizeof(rectype));
229
case DB_ex_apprec_mkdir:
230
return (ex_apprec_mkdir_recover(dbenv, dbt, lsn, op, NULL));
233
* We've hit an unexpected, allegedly user-defined record
236
dbenv->errx(dbenv, "Unexpected log record type encountered");
242
verify_absence(dbenv, dirname)
247
if (access(dirname, F_OK) == 0) {
248
dbenv->errx(dbenv, "Error--directory present!");
256
verify_presence(dbenv, dirname)
261
if (access(dirname, F_OK) != 0) {
262
dbenv->errx(dbenv, "Error--directory not present!");