1*84d9c625SLionel Sambuc #include "db_config.h"
2*84d9c625SLionel Sambuc
3*84d9c625SLionel Sambuc #ifndef NO_SYSTEM_INCLUDES
4*84d9c625SLionel Sambuc #include <sys/types.h>
5*84d9c625SLionel Sambuc
6*84d9c625SLionel Sambuc #include <string.h>
7*84d9c625SLionel Sambuc #endif
8*84d9c625SLionel Sambuc
9*84d9c625SLionel Sambuc #include "common.h"
10*84d9c625SLionel Sambuc
11*84d9c625SLionel Sambuc #include "db_int.h"
12*84d9c625SLionel Sambuc #include "db_page.h"
13*84d9c625SLionel Sambuc #include <log.h>
14*84d9c625SLionel Sambuc #include "hash.h"
15*84d9c625SLionel Sambuc #include "btree.h"
16*84d9c625SLionel Sambuc
17*84d9c625SLionel Sambuc #define LOG_CURSOR_HIT -1000
18*84d9c625SLionel Sambuc
19*84d9c625SLionel Sambuc /*
20*84d9c625SLionel Sambuc * PUBLIC: #ifdef USE_DB4_LOGGING
21*84d9c625SLionel Sambuc */
22*84d9c625SLionel Sambuc /*
23*84d9c625SLionel Sambuc * __vi_marker_recover --
24*84d9c625SLionel Sambuc * Recovery function for marker.
25*84d9c625SLionel Sambuc *
26*84d9c625SLionel Sambuc * PUBLIC: int __vi_marker_recover
27*84d9c625SLionel Sambuc * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
28*84d9c625SLionel Sambuc */
29*84d9c625SLionel Sambuc int
__vi_marker_recover(dbenv,dbtp,lsnp,op,info)30*84d9c625SLionel Sambuc __vi_marker_recover(dbenv, dbtp, lsnp, op, info)
31*84d9c625SLionel Sambuc DB_ENV *dbenv;
32*84d9c625SLionel Sambuc DBT *dbtp;
33*84d9c625SLionel Sambuc DB_LSN *lsnp;
34*84d9c625SLionel Sambuc db_recops op;
35*84d9c625SLionel Sambuc void *info;
36*84d9c625SLionel Sambuc {
37*84d9c625SLionel Sambuc __vi_marker_args *argp;
38*84d9c625SLionel Sambuc int ret;
39*84d9c625SLionel Sambuc
40*84d9c625SLionel Sambuc REC_PRINT(__vi_marker_print);
41*84d9c625SLionel Sambuc REC_NOOP_INTRO(__vi_marker_read);
42*84d9c625SLionel Sambuc
43*84d9c625SLionel Sambuc *lsnp = argp->prev_lsn;
44*84d9c625SLionel Sambuc ret = 0;
45*84d9c625SLionel Sambuc
46*84d9c625SLionel Sambuc REC_NOOP_CLOSE;
47*84d9c625SLionel Sambuc }
48*84d9c625SLionel Sambuc
49*84d9c625SLionel Sambuc /*
50*84d9c625SLionel Sambuc * __vi_cursor_recover --
51*84d9c625SLionel Sambuc * Recovery function for cursor.
52*84d9c625SLionel Sambuc *
53*84d9c625SLionel Sambuc * PUBLIC: int __vi_cursor_recover
54*84d9c625SLionel Sambuc * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
55*84d9c625SLionel Sambuc */
56*84d9c625SLionel Sambuc int
__vi_cursor_recover(dbenv,dbtp,lsnp,op,info)57*84d9c625SLionel Sambuc __vi_cursor_recover(dbenv, dbtp, lsnp, op, info)
58*84d9c625SLionel Sambuc DB_ENV *dbenv;
59*84d9c625SLionel Sambuc DBT *dbtp;
60*84d9c625SLionel Sambuc DB_LSN *lsnp;
61*84d9c625SLionel Sambuc db_recops op;
62*84d9c625SLionel Sambuc void *info;
63*84d9c625SLionel Sambuc {
64*84d9c625SLionel Sambuc __vi_cursor_args *argp;
65*84d9c625SLionel Sambuc int ret;
66*84d9c625SLionel Sambuc SCR *sp;
67*84d9c625SLionel Sambuc
68*84d9c625SLionel Sambuc REC_PRINT(__vi_cursor_print);
69*84d9c625SLionel Sambuc REC_NOOP_INTRO(__vi_cursor_read);
70*84d9c625SLionel Sambuc
71*84d9c625SLionel Sambuc sp = (SCR *)dbenv->app_private;
72*84d9c625SLionel Sambuc
73*84d9c625SLionel Sambuc *lsnp = argp->prev_lsn;
74*84d9c625SLionel Sambuc if (sp->state.undo == UNDO_SETLINE) {
75*84d9c625SLionel Sambuc /* Why the check for ep->l_cur ? (copied from log.c)
76*84d9c625SLionel Sambuc */
77*84d9c625SLionel Sambuc ret = (argp->lno != sp->lno ||
78*84d9c625SLionel Sambuc (argp->opcode == LOG_CURSOR_INIT && sp->ep->l_cur == 1))
79*84d9c625SLionel Sambuc ? LOG_CURSOR_HIT : 0;
80*84d9c625SLionel Sambuc }
81*84d9c625SLionel Sambuc else {
82*84d9c625SLionel Sambuc ret = argp->opcode ==
83*84d9c625SLionel Sambuc (DB_UNDO(op) ? LOG_CURSOR_INIT : LOG_CURSOR_END)
84*84d9c625SLionel Sambuc ? LOG_CURSOR_HIT : 0;
85*84d9c625SLionel Sambuc if (ret) {
86*84d9c625SLionel Sambuc sp->state.pos.lno = argp->lno;
87*84d9c625SLionel Sambuc sp->state.pos.cno = argp->cno;
88*84d9c625SLionel Sambuc }
89*84d9c625SLionel Sambuc }
90*84d9c625SLionel Sambuc
91*84d9c625SLionel Sambuc REC_NOOP_CLOSE;
92*84d9c625SLionel Sambuc }
93*84d9c625SLionel Sambuc
94*84d9c625SLionel Sambuc /*
95*84d9c625SLionel Sambuc * __vi_mark_recover --
96*84d9c625SLionel Sambuc * Recovery function for mark.
97*84d9c625SLionel Sambuc *
98*84d9c625SLionel Sambuc * PUBLIC: int __vi_mark_recover
99*84d9c625SLionel Sambuc * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
100*84d9c625SLionel Sambuc */
101*84d9c625SLionel Sambuc int
__vi_mark_recover(dbenv,dbtp,lsnp,op,info)102*84d9c625SLionel Sambuc __vi_mark_recover(dbenv, dbtp, lsnp, op, info)
103*84d9c625SLionel Sambuc DB_ENV *dbenv;
104*84d9c625SLionel Sambuc DBT *dbtp;
105*84d9c625SLionel Sambuc DB_LSN *lsnp;
106*84d9c625SLionel Sambuc db_recops op;
107*84d9c625SLionel Sambuc void *info;
108*84d9c625SLionel Sambuc {
109*84d9c625SLionel Sambuc __vi_mark_args *argp;
110*84d9c625SLionel Sambuc int ret;
111*84d9c625SLionel Sambuc MARK m;
112*84d9c625SLionel Sambuc SCR *sp;
113*84d9c625SLionel Sambuc
114*84d9c625SLionel Sambuc REC_PRINT(__vi_mark_print);
115*84d9c625SLionel Sambuc REC_NOOP_INTRO(__vi_mark_read);
116*84d9c625SLionel Sambuc
117*84d9c625SLionel Sambuc sp = (SCR *)dbenv->app_private;
118*84d9c625SLionel Sambuc *lsnp = argp->prev_lsn;
119*84d9c625SLionel Sambuc m.lno = argp->lmp.lno;
120*84d9c625SLionel Sambuc m.cno = argp->lmp.cno;
121*84d9c625SLionel Sambuc ret = mark_set(sp, argp->lmp.name, &m, 0);
122*84d9c625SLionel Sambuc
123*84d9c625SLionel Sambuc REC_NOOP_CLOSE;
124*84d9c625SLionel Sambuc }
125*84d9c625SLionel Sambuc
126*84d9c625SLionel Sambuc /*
127*84d9c625SLionel Sambuc * __vi_change_recover --
128*84d9c625SLionel Sambuc * Recovery function for change.
129*84d9c625SLionel Sambuc *
130*84d9c625SLionel Sambuc * PUBLIC: int __vi_change_recover
131*84d9c625SLionel Sambuc * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
132*84d9c625SLionel Sambuc */
133*84d9c625SLionel Sambuc int
__vi_change_recover(dbenv,dbtp,lsnp,op,info)134*84d9c625SLionel Sambuc __vi_change_recover(dbenv, dbtp, lsnp, op, info)
135*84d9c625SLionel Sambuc DB_ENV *dbenv;
136*84d9c625SLionel Sambuc DBT *dbtp;
137*84d9c625SLionel Sambuc DB_LSN *lsnp;
138*84d9c625SLionel Sambuc db_recops op;
139*84d9c625SLionel Sambuc void *info;
140*84d9c625SLionel Sambuc {
141*84d9c625SLionel Sambuc __vi_change_args *argp;
142*84d9c625SLionel Sambuc int ret;
143*84d9c625SLionel Sambuc SCR *sp;
144*84d9c625SLionel Sambuc
145*84d9c625SLionel Sambuc REC_PRINT(__vi_change_print);
146*84d9c625SLionel Sambuc REC_NOOP_INTRO(__vi_change_read);
147*84d9c625SLionel Sambuc
148*84d9c625SLionel Sambuc ret = 0;
149*84d9c625SLionel Sambuc
150*84d9c625SLionel Sambuc sp = (SCR *)dbenv->app_private;
151*84d9c625SLionel Sambuc if (DB_UNDO(op) != (argp->opcode & 1))
152*84d9c625SLionel Sambuc switch (argp->opcode) {
153*84d9c625SLionel Sambuc case LOG_LINE_RESET_B:
154*84d9c625SLionel Sambuc case LOG_LINE_RESET_F:
155*84d9c625SLionel Sambuc ret = line_insdel(sp, LINE_RESET, argp->lno);
156*84d9c625SLionel Sambuc update_cache(sp, LINE_RESET, argp->lno);
157*84d9c625SLionel Sambuc ret = scr_update(sp, argp->lno, LINE_RESET, 1) || ret;
158*84d9c625SLionel Sambuc break;
159*84d9c625SLionel Sambuc case LOG_LINE_APPEND_B:
160*84d9c625SLionel Sambuc case LOG_LINE_DELETE_F:
161*84d9c625SLionel Sambuc ret = line_insdel(sp, LINE_DELETE, argp->lno);
162*84d9c625SLionel Sambuc update_cache(sp, LINE_DELETE, argp->lno);
163*84d9c625SLionel Sambuc ret = scr_update(sp, argp->lno, LINE_DELETE, 1) || ret;
164*84d9c625SLionel Sambuc break;
165*84d9c625SLionel Sambuc case LOG_LINE_DELETE_B:
166*84d9c625SLionel Sambuc case LOG_LINE_APPEND_F:
167*84d9c625SLionel Sambuc ret = line_insdel(sp, LINE_INSERT, argp->lno);
168*84d9c625SLionel Sambuc update_cache(sp, LINE_INSERT, argp->lno);
169*84d9c625SLionel Sambuc ret = scr_update(sp, argp->lno, LINE_INSERT, 1) || ret;
170*84d9c625SLionel Sambuc break;
171*84d9c625SLionel Sambuc }
172*84d9c625SLionel Sambuc
173*84d9c625SLionel Sambuc *lsnp = argp->prev_lsn;
174*84d9c625SLionel Sambuc
175*84d9c625SLionel Sambuc REC_NOOP_CLOSE;
176*84d9c625SLionel Sambuc }
177*84d9c625SLionel Sambuc
178*84d9c625SLionel Sambuc /*
179*84d9c625SLionel Sambuc *
180*84d9c625SLionel Sambuc * PUBLIC: int __vi_log_truncate __P((EXF *ep));
181*84d9c625SLionel Sambuc */
182*84d9c625SLionel Sambuc int
__vi_log_truncate(EXF * ep)183*84d9c625SLionel Sambuc __vi_log_truncate(EXF *ep)
184*84d9c625SLionel Sambuc {
185*84d9c625SLionel Sambuc DB_LSN ckplsn;
186*84d9c625SLionel Sambuc
187*84d9c625SLionel Sambuc ZERO_LSN(ckplsn);
188*84d9c625SLionel Sambuc return __log_vtruncate(ep->env, &ep->lsn_cur, &ckplsn);
189*84d9c625SLionel Sambuc /*return __log_vtruncate(ep->env, &ep->lsn_cur, &ep->lsn_first);*/
190*84d9c625SLionel Sambuc }
191*84d9c625SLionel Sambuc
192*84d9c625SLionel Sambuc /*
193*84d9c625SLionel Sambuc *
194*84d9c625SLionel Sambuc * PUBLIC: int __vi_log_dispatch __P((DB_ENV *dbenv, DBT *data, DB_LSN *lsn, db_recops ops));
195*84d9c625SLionel Sambuc */
196*84d9c625SLionel Sambuc int
__vi_log_dispatch(DB_ENV * dbenv,DBT * data,DB_LSN * lsn,db_recops ops)197*84d9c625SLionel Sambuc __vi_log_dispatch(DB_ENV *dbenv, DBT *data, DB_LSN *lsn, db_recops ops)
198*84d9c625SLionel Sambuc {
199*84d9c625SLionel Sambuc u_int32_t rectype;
200*84d9c625SLionel Sambuc char s[100];
201*84d9c625SLionel Sambuc
202*84d9c625SLionel Sambuc memcpy(&rectype, data->data, sizeof(rectype));
203*84d9c625SLionel Sambuc snprintf(s,100,"%d\n", rectype);
204*84d9c625SLionel Sambuc return dbenv->dtab[rectype](dbenv, data, lsn, ops, NULL);
205*84d9c625SLionel Sambuc }
206*84d9c625SLionel Sambuc
207*84d9c625SLionel Sambuc static int
vi_log_get(SCR * sp,DB_LOGC * logc,DBT * data,u_int32_t which)208*84d9c625SLionel Sambuc vi_log_get(SCR *sp, DB_LOGC *logc, DBT *data, u_int32_t which)
209*84d9c625SLionel Sambuc {
210*84d9c625SLionel Sambuc size_t nlen;
211*84d9c625SLionel Sambuc EXF *ep;
212*84d9c625SLionel Sambuc
213*84d9c625SLionel Sambuc ep = sp->ep;
214*84d9c625SLionel Sambuc
215*84d9c625SLionel Sambuc nlen = 1024;
216*84d9c625SLionel Sambuc retry:
217*84d9c625SLionel Sambuc BINC_GOTO(sp, sp->wp->l_lp, sp->wp->l_len, nlen);
218*84d9c625SLionel Sambuc memset(data, 0, sizeof(*data));
219*84d9c625SLionel Sambuc data->data = sp->wp->l_lp;
220*84d9c625SLionel Sambuc data->ulen = sp->wp->l_len;
221*84d9c625SLionel Sambuc data->flags = DB_DBT_USERMEM;
222*84d9c625SLionel Sambuc switch ((sp->db_error = logc->get(logc, &ep->lsn_cur, data, which))) {
223*84d9c625SLionel Sambuc case ENOMEM:
224*84d9c625SLionel Sambuc nlen = data->size;
225*84d9c625SLionel Sambuc goto retry;
226*84d9c625SLionel Sambuc default:
227*84d9c625SLionel Sambuc alloc_err:
228*84d9c625SLionel Sambuc msgq(sp, M_DBERR, "logc->get");
229*84d9c625SLionel Sambuc F_SET(ep, F_NOLOG);
230*84d9c625SLionel Sambuc return (1);
231*84d9c625SLionel Sambuc case 0:
232*84d9c625SLionel Sambuc ;
233*84d9c625SLionel Sambuc }
234*84d9c625SLionel Sambuc return 0;
235*84d9c625SLionel Sambuc }
236*84d9c625SLionel Sambuc
237*84d9c625SLionel Sambuc /*
238*84d9c625SLionel Sambuc *
239*84d9c625SLionel Sambuc * PUBLIC: int __vi_log_traverse __P((SCR *sp, undo_t undo, MARK *));
240*84d9c625SLionel Sambuc */
241*84d9c625SLionel Sambuc int
__vi_log_traverse(SCR * sp,undo_t undo,MARK * rp)242*84d9c625SLionel Sambuc __vi_log_traverse(SCR *sp, undo_t undo, MARK *rp)
243*84d9c625SLionel Sambuc {
244*84d9c625SLionel Sambuc DB_LOGC *logc;
245*84d9c625SLionel Sambuc DBT data;
246*84d9c625SLionel Sambuc EXF *ep;
247*84d9c625SLionel Sambuc int ret;
248*84d9c625SLionel Sambuc DB_LSN lsn;
249*84d9c625SLionel Sambuc u_int32_t which;
250*84d9c625SLionel Sambuc db_recops ops;
251*84d9c625SLionel Sambuc
252*84d9c625SLionel Sambuc ep = sp->ep;
253*84d9c625SLionel Sambuc
254*84d9c625SLionel Sambuc F_SET(ep, F_NOLOG); /* Turn off logging. */
255*84d9c625SLionel Sambuc
256*84d9c625SLionel Sambuc sp->state.undo = undo;
257*84d9c625SLionel Sambuc ep->env->app_private = sp;
258*84d9c625SLionel Sambuc if ((sp->db_error = ep->env->log_cursor(ep->env, &logc, 0))
259*84d9c625SLionel Sambuc != 0) {
260*84d9c625SLionel Sambuc msgq(sp, M_DBERR, "env->log_cursor");
261*84d9c625SLionel Sambuc return (1);
262*84d9c625SLionel Sambuc }
263*84d9c625SLionel Sambuc if (vi_log_get(sp, logc, &data, DB_SET))
264*84d9c625SLionel Sambuc return 1;
265*84d9c625SLionel Sambuc if (undo == UNDO_FORWARD) {
266*84d9c625SLionel Sambuc ops = DB_TXN_FORWARD_ROLL;
267*84d9c625SLionel Sambuc which = DB_NEXT;
268*84d9c625SLionel Sambuc if (vi_log_get(sp, logc, &data, DB_NEXT))
269*84d9c625SLionel Sambuc return 1;
270*84d9c625SLionel Sambuc } else {
271*84d9c625SLionel Sambuc ops = DB_TXN_BACKWARD_ROLL;
272*84d9c625SLionel Sambuc which = DB_PREV;
273*84d9c625SLionel Sambuc }
274*84d9c625SLionel Sambuc
275*84d9c625SLionel Sambuc for (;;) {
276*84d9c625SLionel Sambuc MEMCPY(&lsn, &ep->lsn_cur, 1);
277*84d9c625SLionel Sambuc ret = __vi_log_dispatch(ep->env, &data, &lsn, ops);
278*84d9c625SLionel Sambuc if (ret != 0) {
279*84d9c625SLionel Sambuc if (ret == LOG_CURSOR_HIT)
280*84d9c625SLionel Sambuc break;
281*84d9c625SLionel Sambuc }
282*84d9c625SLionel Sambuc
283*84d9c625SLionel Sambuc if (vi_log_get(sp, logc, &data, which))
284*84d9c625SLionel Sambuc return 1;
285*84d9c625SLionel Sambuc if (undo == UNDO_SETLINE &&
286*84d9c625SLionel Sambuc log_compare(&ep->lsn_cur, &ep->lsn_first) <= 0) {
287*84d9c625SLionel Sambuc /* Move to previous record without dispatching. */
288*84d9c625SLionel Sambuc undo = UNDO_BACKWARD;
289*84d9c625SLionel Sambuc break;
290*84d9c625SLionel Sambuc }
291*84d9c625SLionel Sambuc }
292*84d9c625SLionel Sambuc if (undo == UNDO_BACKWARD)
293*84d9c625SLionel Sambuc if (vi_log_get(sp, logc, &data, DB_PREV))
294*84d9c625SLionel Sambuc return 1;
295*84d9c625SLionel Sambuc
296*84d9c625SLionel Sambuc logc->close(logc, 0);
297*84d9c625SLionel Sambuc
298*84d9c625SLionel Sambuc ep->env->app_private = NULL;
299*84d9c625SLionel Sambuc
300*84d9c625SLionel Sambuc MEMMOVE(rp, &sp->state.pos, 1);
301*84d9c625SLionel Sambuc
302*84d9c625SLionel Sambuc F_CLR(ep, F_NOLOG);
303*84d9c625SLionel Sambuc
304*84d9c625SLionel Sambuc return 0;
305*84d9c625SLionel Sambuc }
306*84d9c625SLionel Sambuc
307*84d9c625SLionel Sambuc int
vi_db_init_recover(DB_ENV * dbenv)308*84d9c625SLionel Sambuc vi_db_init_recover(DB_ENV *dbenv)
309*84d9c625SLionel Sambuc {
310*84d9c625SLionel Sambuc int ret;
311*84d9c625SLionel Sambuc
312*84d9c625SLionel Sambuc if ((ret = __db_init_recover(dbenv)) != 0)
313*84d9c625SLionel Sambuc return (ret);
314*84d9c625SLionel Sambuc if ((ret = __bam_init_recover(dbenv)) != 0)
315*84d9c625SLionel Sambuc return (ret);
316*84d9c625SLionel Sambuc
317*84d9c625SLionel Sambuc return 0;
318*84d9c625SLionel Sambuc }
319*84d9c625SLionel Sambuc /*
320*84d9c625SLionel Sambuc * PUBLIC: #endif
321*84d9c625SLionel Sambuc */
322