00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <sys/types.h>
00011 #include <sys/stat.h>
00012
00013 #include <errno.h>
00014 #include <stddef.h>
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <unistd.h>
00019
00020 #include <db.h>
00021
00022 #include "ex_apprec.h"
00023
00024 int apprec_dispatch __P((DB_ENV *, DBT *, DB_LSN *, db_recops));
00025 int open_env __P((const char *, FILE *, const char *, DB_ENV **));
00026 int verify_absence __P((DB_ENV *, const char *));
00027 int verify_presence __P((DB_ENV *, const char *));
00028
00029 int
00030 main(argc, argv)
00031 int argc;
00032 char *argv[];
00033 {
00034 extern char *optarg;
00035 DB_ENV *dbenv;
00036 DB_LSN lsn;
00037 DB_TXN *txn;
00038 DBT dirnamedbt;
00039 int ret;
00040 const char *home;
00041 char ch, dirname[256];
00042 const char *progname = "ex_apprec";
00043
00044
00045 home = "TESTDIR";
00046
00047 while ((ch = getopt(argc, argv, "h:")) != EOF)
00048 switch (ch) {
00049 case 'h':
00050 home = optarg;
00051 break;
00052 default:
00053 fprintf(stderr, "usage: %s [-h home]", progname);
00054 exit(EXIT_FAILURE);
00055 }
00056
00057 printf("Set up environment.\n");
00058 if ((ret = open_env(home, stderr, progname, &dbenv)) != 0)
00059 return (EXIT_FAILURE);
00060
00061 printf("Create a directory in a transaction.\n");
00062
00063
00064
00065
00066 memset(&dirnamedbt, 0, sizeof(dirnamedbt));
00067 sprintf(dirname, "%s/MYDIRECTORY", home);
00068 dirnamedbt.data = dirname;
00069 dirnamedbt.size = strlen(dirname) + 1;
00070
00071 if ((ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0) {
00072 dbenv->err(dbenv, ret, "txn_begin");
00073 return (EXIT_FAILURE);
00074 }
00075
00076
00077 memset(&lsn, 0, sizeof(lsn));
00078 if ((ret =
00079 ex_apprec_mkdir_log(dbenv, txn, &lsn, 0, &dirnamedbt)) != 0) {
00080 dbenv->err(dbenv, ret, "mkdir_log");
00081 return (EXIT_FAILURE);
00082 }
00083 if (mkdir(dirname, 0755) != 0) {
00084 dbenv->err(dbenv, errno, "mkdir");
00085 return (EXIT_FAILURE);
00086 }
00087
00088 printf("Verify the directory's presence: ");
00089 verify_presence(dbenv, dirname);
00090 printf("check.\n");
00091
00092
00093 printf("Abort the transaction.\n");
00094 if ((ret = txn->abort(txn)) != 0) {
00095 dbenv->err(dbenv, ret, "txn_abort");
00096 return (EXIT_FAILURE);
00097 }
00098
00099 printf("Verify the directory's absence: ");
00100 verify_absence(dbenv, dirname);
00101 printf("check.\n");
00102
00103
00104 printf("Create a directory in a transaction.\n");
00105 memset(&dirnamedbt, 0, sizeof(dirnamedbt));
00106 sprintf(dirname, "%s/MYDIRECTORY", home);
00107 dirnamedbt.data = dirname;
00108 dirnamedbt.size = strlen(dirname) + 1;
00109 if ((ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0) {
00110 dbenv->err(dbenv, ret, "txn_begin");
00111 return (EXIT_FAILURE);
00112 }
00113
00114 memset(&lsn, 0, sizeof(lsn));
00115 if ((ret =
00116 ex_apprec_mkdir_log(dbenv, txn, &lsn, 0, &dirnamedbt)) != 0) {
00117 dbenv->err(dbenv, ret, "mkdir_log");
00118 return (EXIT_FAILURE);
00119 }
00120 if (mkdir(dirname, 0755) != 0) {
00121 dbenv->err(dbenv, errno, "mkdir");
00122 return (EXIT_FAILURE);
00123 }
00124
00125 printf("Verify the directory's presence: ");
00126 verify_presence(dbenv, dirname);
00127 printf("check.\n");
00128
00129
00130 printf("Commit the transaction.\n");
00131 if ((ret = txn->commit(txn, 0)) != 0) {
00132 dbenv->err(dbenv, ret, "txn_commit");
00133 return (EXIT_FAILURE);
00134 }
00135
00136 printf("Verify the directory's presence: ");
00137 verify_presence(dbenv, dirname);
00138 printf("check.\n");
00139
00140 printf("Now remove the directory, then run recovery.\n");
00141 if ((ret = dbenv->close(dbenv, 0)) != 0) {
00142 fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(ret));
00143 return (EXIT_FAILURE);
00144 }
00145 if (rmdir(dirname) != 0) {
00146 fprintf(stderr,
00147 "%s: rmdir failed with error %s", progname,
00148 strerror(errno));
00149 }
00150 verify_absence(dbenv, dirname);
00151
00152
00153 if ((ret = open_env(home, stderr, progname, &dbenv)) != 0)
00154 return (EXIT_FAILURE);
00155
00156 printf("Verify the directory's presence: ");
00157 verify_presence(dbenv, dirname);
00158 printf("check.\n");
00159
00160
00161 if ((ret = dbenv->close(dbenv, 0)) != 0) {
00162 fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(ret));
00163 return (EXIT_FAILURE);
00164 }
00165
00166 return (EXIT_SUCCESS);
00167 }
00168
00169 int
00170 open_env(home, errfp, progname, dbenvp)
00171 const char *home, *progname;
00172 FILE *errfp;
00173 DB_ENV **dbenvp;
00174 {
00175 DB_ENV *dbenv;
00176 int ret;
00177
00178
00179
00180
00181
00182 if ((ret = db_env_create(&dbenv, 0)) != 0) {
00183 fprintf(errfp, "%s: %s\n", progname, db_strerror(ret));
00184 return (ret);
00185 }
00186 dbenv->set_errfile(dbenv, errfp);
00187 dbenv->set_errpfx(dbenv, progname);
00188
00189
00190 if ((ret = dbenv->set_app_dispatch(dbenv, apprec_dispatch)) != 0) {
00191 dbenv->err(dbenv, ret, "set_app_dispatch");
00192 return (ret);
00193 }
00194
00195
00196
00197
00198
00199 if ((ret =
00200 dbenv->open(dbenv, home, DB_CREATE | DB_RECOVER | DB_INIT_LOCK |
00201 DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0)) != 0) {
00202 dbenv->err(dbenv, ret, "environment open: %s", home);
00203 dbenv->close(dbenv, 0);
00204 return (ret);
00205 }
00206
00207 *dbenvp = dbenv;
00208 return (0);
00209 }
00210
00211
00212
00213
00214
00215 int
00216 apprec_dispatch(dbenv, dbt, lsn, op)
00217 DB_ENV *dbenv;
00218 DBT *dbt;
00219 DB_LSN *lsn;
00220 db_recops op;
00221 {
00222 u_int32_t rectype;
00223
00224
00225 memcpy(&rectype, dbt->data, sizeof(rectype));
00226
00227 switch (rectype) {
00228 case DB_ex_apprec_mkdir:
00229 return (ex_apprec_mkdir_recover(dbenv, dbt, lsn, op, NULL));
00230 default:
00231
00232
00233
00234
00235 dbenv->errx(dbenv, "Unexpected log record type encountered");
00236 return (EINVAL);
00237 }
00238 }
00239
00240 int
00241 verify_absence(dbenv, dirname)
00242 DB_ENV *dbenv;
00243 const char *dirname;
00244 {
00245
00246 if (access(dirname, F_OK) == 0) {
00247 dbenv->errx(dbenv, "Error--directory present!");
00248 exit(EXIT_FAILURE);
00249 }
00250
00251 return (0);
00252 }
00253
00254 int
00255 verify_presence(dbenv, dirname)
00256 DB_ENV *dbenv;
00257 const char *dirname;
00258 {
00259
00260 if (access(dirname, F_OK) != 0) {
00261 dbenv->errx(dbenv, "Error--directory not present!");
00262 exit(EXIT_FAILURE);
00263 }
00264
00265 return (0);
00266 }