129 lines
4.2 KiB
C
129 lines
4.2 KiB
C
|
/****************************************************************
|
||
|
* *
|
||
|
* Copyright 2003, 2010 Fidelity Information Services, Inc *
|
||
|
* *
|
||
|
* This source code contains the intellectual property *
|
||
|
* of its copyright holder(s), and is made available *
|
||
|
* under a license. If you do not know the terms of *
|
||
|
* the license, please stop and do not read further. *
|
||
|
* *
|
||
|
****************************************************************/
|
||
|
|
||
|
#include "mdef.h"
|
||
|
|
||
|
#include "error.h"
|
||
|
#include "gdsroot.h"
|
||
|
#include "gdsblk.h"
|
||
|
#include "gdsbt.h"
|
||
|
#include "gtm_facility.h"
|
||
|
#include "fileinfo.h"
|
||
|
#include "gdsfhead.h"
|
||
|
#include "filestruct.h"
|
||
|
#include "jnl.h"
|
||
|
#include "buddy_list.h"
|
||
|
#include "hashtab_int4.h" /* needed for muprec.h */
|
||
|
#include "hashtab_int8.h" /* needed for muprec.h */
|
||
|
#include "hashtab_mname.h" /* needed for muprec.h */
|
||
|
#include "muprec.h"
|
||
|
#include "iosp.h"
|
||
|
#include "jnl_typedef.h"
|
||
|
#include "gtmmsg.h" /* for gtm_putmsg() prototype */
|
||
|
#include "mur_validate_checksum.h" /* for "mur_validate_checksum" */
|
||
|
|
||
|
GBLREF reg_ctl_list *mur_ctl;
|
||
|
GBLREF mur_gbls_t murgbl;
|
||
|
GBLREF mur_opt_struct mur_options;
|
||
|
|
||
|
boolean_t mur_ztp_lookback(void)
|
||
|
{
|
||
|
multi_struct *multi;
|
||
|
reg_ctl_list *rctl, *rctl_top;
|
||
|
jnl_ctl_list *jctl;
|
||
|
uint4 status;
|
||
|
int4 rec_image_count = 0; /* This is a dummy variable for UNIX */
|
||
|
jnl_record *jrec;
|
||
|
pini_list_struct *plst;
|
||
|
enum jnl_record_type rectype;
|
||
|
token_num token;
|
||
|
|
||
|
error_def(ERR_NOPREVLINK);
|
||
|
error_def(ERR_MUINFOUINT4);
|
||
|
error_def(ERR_MUINFOUINT8);
|
||
|
error_def(ERR_MUINFOSTR);
|
||
|
error_def(ERR_TEXT);
|
||
|
|
||
|
assert(FENCE_NONE != mur_options.fences);
|
||
|
for (rctl = mur_ctl, rctl_top = mur_ctl + murgbl.reg_total; rctl < rctl_top; rctl++)
|
||
|
{
|
||
|
jctl = rctl->jctl;
|
||
|
assert(jctl->reg_ctl == rctl);
|
||
|
assert(NULL != rctl->jctl_turn_around);
|
||
|
assert(jctl == rctl->jctl_turn_around);
|
||
|
assert(jctl->rec_offset == jctl->turn_around_offset);
|
||
|
status = mur_prev(jctl, jctl->rec_offset);
|
||
|
assert(SS_NORMAL == status);
|
||
|
for ( ; SS_NORMAL == status; )
|
||
|
{
|
||
|
status = mur_prev_rec(&jctl); /* scan journal file in reverse order */
|
||
|
if (SS_NORMAL != status)
|
||
|
break;
|
||
|
jrec = jctl->reg_ctl->mur_desc->jnlrec;
|
||
|
rectype = (enum jnl_record_type)jrec->prefix.jrec_type;
|
||
|
if (mur_options.verify && !mur_validate_checksum(jctl))
|
||
|
{
|
||
|
gtm_putmsg(VARLSTCNT(4) ERR_TEXT, 2, LEN_AND_LIT("Checksum validation failed"));
|
||
|
return FALSE;
|
||
|
}
|
||
|
if (mur_options.lookback_time_specified && jrec->prefix.time <= mur_options.lookback_time)
|
||
|
break;
|
||
|
if (mur_options.lookback_opers_specified)
|
||
|
{
|
||
|
if (IS_FUPD_TUPD(rectype) || (!IS_FENCED(rectype) && IS_SET_KILL_ZKILL_ZTRIG(rectype)))
|
||
|
{
|
||
|
rctl->lookback_count++;
|
||
|
if (rctl->lookback_count > mur_options.lookback_opers)
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (IS_FUPD(rectype))
|
||
|
{
|
||
|
VMS_ONLY(
|
||
|
MUR_GET_IMAGE_COUNT(jctl, jrec, rec_image_count, status);
|
||
|
if (SS_NORMAL != status)
|
||
|
break;
|
||
|
)
|
||
|
token = ((struct_jrec_upd *)jrec)->token_seq.token;
|
||
|
if ((NULL != (multi = MUR_TOKEN_LOOKUP(token, rec_image_count, 0, ZTPFENCE)))
|
||
|
&& (0 < multi->partner))
|
||
|
{ /* this transaction has already been identified as broken */
|
||
|
/* see turn-around-point code in mur_back_process/mur_apply_pblk for the fields to clear */
|
||
|
rctl->jctl_turn_around->turn_around_offset = 0;
|
||
|
rctl->jctl_turn_around->turn_around_time = 0;
|
||
|
rctl->jctl_turn_around->turn_around_seqno = 0;
|
||
|
rctl->jctl_turn_around->turn_around_tn = 0;
|
||
|
/* Now save new turn around point.
|
||
|
* Force the entire Z transaction beginning from ZTSTART (FUPD actually)
|
||
|
* to be reported as broken and undo this transaction from the db */
|
||
|
rctl->jctl_turn_around = jctl;
|
||
|
jctl->turn_around_offset = jctl->rec_offset;
|
||
|
if (multi->time > jrec->prefix.time)
|
||
|
multi->time = jrec->prefix.time;
|
||
|
if (mur_options.verbose)
|
||
|
PRINT_VERBOSE_STAT(jctl, "mur_ztp_lookback");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (ERR_NOPREVLINK == status)
|
||
|
{
|
||
|
if (mur_options.lookback_time_specified)
|
||
|
{
|
||
|
gtm_putmsg(VARLSTCNT(4) ERR_NOPREVLINK, 2, jctl->jnl_fn_len, jctl->jnl_fn);
|
||
|
return FALSE;
|
||
|
}
|
||
|
gtm_putmsg(VARLSTCNT(4) MAKE_MSG_INFO(ERR_NOPREVLINK), 2, jctl->jnl_fn_len, jctl->jnl_fn);
|
||
|
} else if (SS_NORMAL != status)
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|