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