• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/db-4.7.25.NC/examples_c/ex_apprec/
1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1996,2008 Oracle.  All rights reserved.
5 *
6 * $Id: ex_apprec_rec.c,v 12.7 2008/01/08 20:58:24 bostic Exp $
7 */
8
9/*
10 * This file is based on the template file ex_apprec_template.  Note that
11 * because ex_apprec_mkdir, like most application-specific recovery functions,
12 * does not make use of DB-private structures, it has actually been simplified
13 * significantly.
14 */
15
16#include <sys/stat.h>
17#include <sys/types.h>
18#include <errno.h>
19#include <stdlib.h>
20
21#include <db.h>
22
23#include "ex_apprec.h"
24
25/*
26 * ex_apprec_mkdir_recover --
27 *	Recovery function for mkdir.
28 *
29 * PUBLIC: int ex_apprec_mkdir_recover
30 * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops));
31 */
32int
33ex_apprec_mkdir_recover(dbenv, dbtp, lsnp, op)
34	DB_ENV *dbenv;
35	DBT *dbtp;
36	DB_LSN *lsnp;
37	db_recops op;
38{
39	ex_apprec_mkdir_args *argp;
40	int ret;
41
42	argp = NULL;
43
44#ifdef DEBUG_RECOVER
45	ex_apprec_mkdir_print(dbenv, dbtp, lsnp, op);
46#endif
47	if ((ret = ex_apprec_mkdir_read(dbenv, dbtp->data, &argp)) != 0)
48		goto out;
49
50	switch (op) {
51	case DB_TXN_ABORT:
52	case DB_TXN_BACKWARD_ROLL:
53		/*
54		 * If we're aborting, we need to remove the directory if it
55		 * exists.  We log the trailing zero in pathnames, so we can
56		 * simply pass the data part of the DBT into rmdir as a string.
57		 * (Note that we don't have any alignment guarantees, but for
58		 * a char * this doesn't matter.)
59		 *
60		 * Ignore all errors other than ENOENT;  DB may attempt to undo
61		 * or redo operations without knowing whether they have already
62		 * been done or undone, so we should never assume in a recovery
63		 * function that the task definitely needs doing or undoing.
64		 */
65		ret = rmdir(argp->dirname.data);
66		if (ret != 0 && errno != ENOENT)
67			dbenv->err(dbenv, ret, "Error in abort of mkdir");
68		else
69			ret = 0;
70		break;
71	case DB_TXN_FORWARD_ROLL:
72		/*
73		 * The forward direction is just the opposite;  here, we ignore
74		 * EEXIST, because the directory may already exist.
75		 */
76		ret = mkdir(argp->dirname.data, 0755);
77		if (ret != 0 && errno != EEXIST)
78			dbenv->err(dbenv,
79			    ret, "Error in roll-forward of mkdir");
80		else
81			ret = 0;
82		break;
83	default:
84		/*
85		 * We might want to handle DB_TXN_PRINT or DB_TXN_APPLY here,
86		 * too, but we don't try to print the log records and aren't
87		 * using replication, so there's no need to in this example.
88		 */
89		dbenv->errx(dbenv, "Unexpected operation type\n");
90		return (EINVAL);
91	}
92
93	/*
94	 * The recovery function is responsible for returning the LSN of the
95	 * previous log record in this transaction, so that transaction aborts
96	 * can follow the chain backwards.
97	 *
98	 * (If we'd wanted the LSN of this record earlier, we could have
99	 * read it from lsnp, as well--but because we weren't working with
100	 * pages or other objects that store their LSN and base recovery
101	 * decisions on it, we didn't need to.)
102	 */
103	*lsnp = argp->prev_lsn;
104
105out:	if (argp != NULL)
106		free(argp);
107	return (ret);
108}
109