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