fis-gtm/sr_port/mur_jnl_ext.c

485 lines
14 KiB
C

/****************************************************************
* *
* Copyright 2003, 2012 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 "gtm_string.h"
#include "gtm_stdio.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 "jnl_typedef.h"
#include "copy.h"
#include "init_root_gv.h"
#include "min_max.h" /* needed for init_root_gv.h */
#include "format_targ_key.h" /* needed for init_root_gv.h */
#include "mlkdef.h"
#include "zshow.h"
#include "mur_jnl_ext.h"
#include "op.h"
#include "real_len.h" /* for real_len() prototype */
#include "gtmmsg.h"
GBLREF gv_key *gv_currkey;
GBLREF mur_gbls_t murgbl;
GBLREF mur_opt_struct mur_options;
GBLREF boolean_t is_updproc;
GBLREF mval curr_gbl_root;
GBLREF char muext_code[][2];
LITREF char *jrt_label[JRT_RECTYPES];
error_def(ERR_JNLBADRECFMT);
error_def(ERR_MUINFOUINT4);
error_def(ERR_TEXT);
#define LAB_LEN 7
#define LAB_TERM "\\"
#define LAB_TERM_SZ (SIZEOF(LAB_TERM) - 1)
/* This routine formats and outputs journal extract records
corresponding to M SET, KILL, ZKILL, TSTART, ZTSTART, and ZTRIGGER commands as well as $ZTWORMHOLE */
void mur_extract_set(jnl_ctl_list *jctl, fi_type *fi, jnl_record *rec, pini_list_struct *plst)
{
enum jnl_record_type rectype;
int max_blen, actual, extract_len, val_extr_len, val_len;
char *val_ptr, *ptr, *buff;
jnl_string *keystr;
boolean_t do_format2zwr, is_ztstart;
if (!mur_options.detail)
extract_len = 0;
else
EXT_DET_COMMON_PREFIX(jctl);
rectype = (enum jnl_record_type)rec->prefix.jrec_type;
if (IS_FUPD_TUPD(rectype))
{
if (!mur_options.detail)
{
if (IS_TUPD(rectype))
{
EXT2BYTES(&muext_code[MUEXT_TSTART][0]); /* TSTART */
is_ztstart = FALSE;
} else /* if (IS_FUPD(rectype)) */
{
EXT2BYTES(&muext_code[MUEXT_ZTSTART][0]); /* ZTSTART */
is_ztstart = TRUE;
}
} else
{
if (IS_TUPD(rectype))
{
strcpy(murgbl.extr_buff + extract_len, "TSTART \\");
is_ztstart = FALSE;
} else /* if (IS_FUPD(rectype)) */
{
strcpy(murgbl.extr_buff + extract_len, "ZTSTART\\");
is_ztstart = TRUE;
}
extract_len = STRLEN(murgbl.extr_buff);
}
EXTTIME(rec->prefix.time);
EXTQW(rec->prefix.tn);
if (mur_options.detail)
EXTINT(rec->prefix.checksum);
EXTPID(plst);
EXTQW(rec->jrec_set_kill.token_seq.jnl_seqno);
if (!is_ztstart)
EXT_STRM_SEQNO(rec->jrec_set_kill.strm_seqno);
jnlext_write(fi, murgbl.extr_buff, extract_len);
}
/* Output the SET or KILL or ZKILL or ZTWORMHOLE record */
if (!mur_options.detail)
{
extract_len = 0;
if (IS_SET(rectype))
{
EXT2BYTES(&muext_code[MUEXT_SET][0]);
} else if (IS_KILL(rectype))
{
EXT2BYTES(&muext_code[MUEXT_KILL][0]);
} else if (IS_ZKILL(rectype))
{
EXT2BYTES(&muext_code[MUEXT_ZKILL][0]);
} else if (IS_ZTWORM(rectype))
{
EXT2BYTES(&muext_code[MUEXT_ZTWORM][0]);
} else if (IS_ZTRIG(rectype))
{
EXT2BYTES(&muext_code[MUEXT_ZTRIG][0]);
} else
assert(FALSE); /* The assert will disappear in pro but not the ";" to properly terminate the else */
} else
{
if (IS_FUPD_TUPD(rectype))
{
memcpy(murgbl.extr_buff, " ", 23);
extract_len = 23;
} else
extract_len = STRLEN(murgbl.extr_buff);
strcpy(murgbl.extr_buff + extract_len, " \\");
memcpy(murgbl.extr_buff + extract_len, jrt_label[rectype], LAB_LEN);
extract_len += LAB_LEN;
memcpy(murgbl.extr_buff + extract_len, LAB_TERM, LAB_TERM_SZ);
extract_len += LAB_TERM_SZ;
}
EXTTIME(rec->prefix.time);
EXTQW(rec->prefix.tn);
if (mur_options.detail)
EXTINT(rec->prefix.checksum);
EXTPID(plst);
if (IS_ZTP(rectype))
{
EXTQW(rec->jrec_set_kill.token_seq.token);
} else
EXTQW(rec->jrec_set_kill.token_seq.jnl_seqno);
assert(IS_SET_KILL_ZKILL_ZTRIG_ZTWORM(rectype));
assert(&rec->jrec_set_kill.strm_seqno == &rec->jrec_ztworm.strm_seqno);
EXT_STRM_SEQNO(rec->jrec_set_kill.strm_seqno);
assert(&rec->jrec_set_kill.update_num == &rec->jrec_ztworm.update_num);
EXTINT(rec->jrec_set_kill.update_num);
do_format2zwr = FALSE;
if (IS_SET_KILL_ZKILL_ZTRIG(rectype))
{
keystr = (jnl_string *)&rec->jrec_set_kill.mumps_node;
EXTINT(keystr->nodeflags);
buff = &murgbl.extr_buff[extract_len];
max_blen = MIN(MAX_ZWR_KEY_SZ, murgbl.max_extr_record_length - extract_len);
assert(MAX_ZWR_KEY_SZ == max_blen); /* We allocated enough for key and data expansion for ZWR format */
ptr = (char *)format_targ_key((uchar_ptr_t)buff, max_blen, gv_currkey, TRUE);
assert(NULL != ptr);
if (NULL != ptr)
extract_len += (int)(ptr - &murgbl.extr_buff[extract_len]);
if (IS_SET(rectype))
{
murgbl.extr_buff[extract_len++] = '=';
val_ptr = &keystr->text[keystr->length];
GET_MSTR_LEN(val_len, val_ptr);
val_ptr += SIZEOF(mstr_len_t);
do_format2zwr = TRUE;
}
} else if (IS_ZTWORM(rectype))
{
keystr = (jnl_string *)&rec->jrec_ztworm.ztworm_str;
val_len = keystr->length;
val_ptr = &keystr->text[0];
do_format2zwr = TRUE;
}
if (do_format2zwr)
{
if (ZWR_EXP_RATIO(val_len) <= murgbl.max_extr_record_length - extract_len)
{
ptr = &murgbl.extr_buff[extract_len];
format2zwr((sm_uc_ptr_t)val_ptr, val_len, (unsigned char *)ptr, &val_extr_len);
extract_len += val_extr_len;
} else
{
gtm_putmsg(VARLSTCNT(9) ERR_JNLBADRECFMT,
3, jctl->jnl_fn_len, jctl->jnl_fn, jctl->rec_offset,
ERR_TEXT, 2, LEN_AND_LIT("Length of the record is too high for zwr format"));
if (mur_options.verbose || mur_options.detail)
{
gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4,
LEN_AND_LIT("After max expansion record length"),
ZWR_EXP_RATIO(val_len), ZWR_EXP_RATIO(val_len));
gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("Buffer size"),
murgbl.max_extr_record_length - extract_len,
murgbl.max_extr_record_length - extract_len);
}
assert(FALSE);
}
}
murgbl.extr_buff[extract_len++] = '\\';
jnlext_write(fi, murgbl.extr_buff, extract_len);
}
void mur_extract_null(jnl_ctl_list *jctl, fi_type *fi, jnl_record *rec, pini_list_struct *plst)
{
int extract_len;
char *ptr;
extract_len = 0;
if (!mur_options.detail)
{
EXT2BYTES(&muext_code[MUEXT_NULL][0]);
} else
{
EXT_DET_PREFIX(jctl);
}
EXTTIME(rec->prefix.time);
EXTQW(rec->prefix.tn);
if (mur_options.detail)
EXTINT(rec->prefix.checksum);
EXTPID(plst);
EXTQW(rec->jrec_null.jnl_seqno);
EXT_STRM_SEQNO(rec->jrec_null.strm_seqno);
jnlext_write(fi, murgbl.extr_buff, extract_len);
}
void mur_extract_align(jnl_ctl_list *jctl, fi_type *fi, jnl_record *rec, pini_list_struct *plst)
{
int extract_len;
char *ptr;
if (!mur_options.detail)
return;
EXT_DET_PREFIX(jctl);
EXTTIME(rec->prefix.time);
EXTQW(rec->prefix.tn);
if (mur_options.detail)
EXTINT(rec->prefix.checksum);
EXTPID(plst);
jnlext_write(fi, murgbl.extr_buff, extract_len);
}
void mur_extract_blk(jnl_ctl_list *jctl, fi_type *fi, jnl_record *rec, pini_list_struct *plst)
{
int extract_len;
blk_hdr pblk_head;
char *ptr;
if (!mur_options.detail)
return;
EXT_DET_PREFIX(jctl);
EXTTIME(rec->prefix.time);
EXTQW(rec->prefix.tn);
if (mur_options.detail)
EXTINT(rec->prefix.checksum);
EXTPID(plst);
EXTINT(rec->jrec_pblk.blknum);
EXTINT(rec->jrec_pblk.bsiz);
memcpy((char*)&pblk_head, (char*)&rec->jrec_pblk.blk_contents[0], SIZEOF(blk_hdr));
EXTQW(pblk_head.tn);
EXTINT(rec->jrec_pblk.ondsk_blkver);
jnlext_write(fi, murgbl.extr_buff, extract_len);
}
void mur_extract_epoch(jnl_ctl_list *jctl, fi_type *fi, jnl_record *rec, pini_list_struct *plst)
{
int extract_len, idx;
seq_num strm_seqno;
char *ptr;
if (!mur_options.detail)
return;
EXT_DET_PREFIX(jctl);
EXTTIME(rec->prefix.time);
EXTQW(rec->prefix.tn);
if (mur_options.detail)
EXTINT(rec->prefix.checksum);
EXTPID(plst);
assert((0 == rec->jrec_epoch.fully_upgraded) || (1 == rec->jrec_epoch.fully_upgraded));
EXTQW(rec->jrec_epoch.jnl_seqno);
EXTINT(rec->jrec_epoch.blks_to_upgrd);
EXTINT(rec->jrec_epoch.free_blocks);
EXTINT(rec->jrec_epoch.total_blks);
EXTINT(rec->jrec_epoch.fully_upgraded); /* actually boolean_t */
# ifdef UNIX
/* Extract upto 16 strm_seqno only if they are non-zero */
for (idx = 0; idx < MAX_SUPPL_STRMS; idx++)
{
strm_seqno = rec->jrec_epoch.strm_seqno[idx];
if (strm_seqno)
{
strm_seqno = SET_STRM_INDEX(strm_seqno, idx);
EXT_STRM_SEQNO(strm_seqno);
}
}
# endif
jnlext_write(fi, murgbl.extr_buff, extract_len);
}
void mur_extract_inctn(jnl_ctl_list *jctl, fi_type *fi, jnl_record *rec, pini_list_struct *plst)
{
int extract_len;
char *ptr;
inctn_detail_t *detail;
unsigned short opcode;
if (!mur_options.detail)
return;
EXT_DET_PREFIX(jctl);
EXTTIME(rec->prefix.time);
EXTQW(rec->prefix.tn);
if (mur_options.detail)
EXTINT(rec->prefix.checksum);
EXTPID(plst);
opcode = rec->jrec_inctn.detail.blknum_struct.opcode;
EXTINT(opcode);
/* Any changes to the switch block here (e.g. new inctn opcodes) needs corresponding changes in jnl_write_inctn_rec.c */
switch(opcode)
{
case inctn_bmp_mark_free_gtm:
case inctn_bmp_mark_free_mu_reorg:
case inctn_blkupgrd:
case inctn_blkdwngrd:
case inctn_blkupgrd_fmtchng:
case inctn_blkdwngrd_fmtchng:
case inctn_blkmarkfree:
EXTINT(rec->jrec_inctn.detail.blknum_struct.blknum);
break;
case inctn_gdsfilext_gtm:
case inctn_gdsfilext_mu_reorg:
case inctn_db_format_change:
EXTINT(rec->jrec_inctn.detail.blks2upgrd_struct.blks_to_upgrd_delta);
break;
default:
EXTINT(0); /* nothing to extract in this case */
break;
}
jnlext_write(fi, murgbl.extr_buff, extract_len);
}
void mur_extract_eof(jnl_ctl_list *jctl, fi_type *fi, jnl_record *rec, pini_list_struct *plst)
{
int extract_len = 0;
char *ptr;
if (!mur_options.detail)
{
EXT2BYTES(&muext_code[MUEXT_EOF][0]);
} else
{
EXT_DET_PREFIX(jctl);
}
EXTTIME(rec->jrec_eof.prefix.time);
EXTQW(rec->jrec_eof.prefix.tn);
if (mur_options.detail)
EXTINT(rec->prefix.checksum);
EXTPID(plst);
EXTQW(rec->jrec_eof.jnl_seqno);
jnlext_write(fi, murgbl.extr_buff, extract_len);
}
void mur_extract_trunc(jnl_ctl_list *jctl, fi_type *fi, jnl_record *rec, pini_list_struct *plst)
{
int extract_len = 0;
char *ptr;
if (!mur_options.detail)
return;
EXT_DET_PREFIX(jctl);
EXTTIME(rec->prefix.time);
EXTQW(rec->prefix.tn);
if (mur_options.detail)
EXTINT(rec->prefix.checksum);
EXTPID(plst);
EXTINT(rec->jrec_trunc.orig_total_blks);
EXTINT(rec->jrec_trunc.orig_free_blocks);
EXTINT(rec->jrec_trunc.total_blks_after_trunc);
jnlext_write(fi, murgbl.extr_buff, extract_len);
}
void mur_extract_pfin(jnl_ctl_list *jctl, fi_type *fi, jnl_record *rec, pini_list_struct *plst)
{
int extract_len;
char *ptr;
extract_len = 0;
if (!mur_options.detail)
{
EXT2BYTES(&muext_code[MUEXT_PFIN][0]);
} else
{
EXT_DET_PREFIX(jctl);
}
EXTTIME(rec->jrec_pfin.prefix.time);
EXTQW(rec->jrec_pfin.prefix.tn);
if (mur_options.detail)
EXTINT(rec->prefix.checksum);
EXTPID(plst);
jnlext_write(fi, murgbl.extr_buff, extract_len);
}
void mur_extract_pini(jnl_ctl_list *jctl, fi_type *fi, jnl_record *rec, pini_list_struct *plst)
{
int extract_len = 0;
char *ptr;
if (!mur_options.detail)
{
EXT2BYTES(&muext_code[MUEXT_PINI][0]);
} else
{
EXT_DET_PREFIX(jctl);
}
EXTTIME(rec->prefix.time);
EXTQW(rec->prefix.tn);
if (mur_options.detail)
EXTINT(rec->prefix.checksum);
extract_len = extract_process_vector((jnl_process_vector *)&rec->jrec_pini.process_vector[CURR_JPV], extract_len);
extract_len = extract_process_vector((jnl_process_vector *)&rec->jrec_pini.process_vector[ORIG_JPV], extract_len);
jnlext_write(fi, murgbl.extr_buff, extract_len);
}
/* This routine formats and outputs journal extract records corresponding to M TCOMMIT and ZTCOMMIT commands */
void mur_extract_tcom(jnl_ctl_list *jctl, fi_type *fi, jnl_record *rec, pini_list_struct *plst)
{
int actual, extract_len = 0;
char *ptr;
if (!mur_options.detail)
{
if (rec->prefix.jrec_type == JRT_ZTCOM)
{
EXT2BYTES(&muext_code[MUEXT_ZTCOMMIT][0]);
} else
{
EXT2BYTES(&muext_code[MUEXT_TCOMMIT][0]);
}
} else
{
EXT_DET_PREFIX(jctl);
}
EXTTIME(rec->jrec_tcom.prefix.time);
EXTQW(rec->jrec_tcom.prefix.tn);
if (mur_options.detail)
EXTINT(rec->prefix.checksum);
EXTPID(plst);
assert(offsetof(struct_jrec_ztcom, token) == offsetof(struct_jrec_tcom, token_seq));
EXTQW(rec->jrec_tcom.token_seq.jnl_seqno);
if (JRT_TCOM == rec->prefix.jrec_type)
{
EXT_STRM_SEQNO(rec->jrec_tcom.strm_seqno);
EXTINT(rec->jrec_tcom.num_participants);
EXTTXT((unsigned char *)&rec->jrec_tcom.jnl_tid[0], SIZEOF(rec->jrec_tcom.jnl_tid));
} else
EXTINT(rec->jrec_ztcom.participants);
jnlext_write(fi, murgbl.extr_buff, extract_len);
}
int extract_process_vector(jnl_process_vector *pv, int extract_len)
{
int actual;
char *ptr;
/* EXTTIME(MID_TIME(pv->jpv_time)); */
EXTINT(pv->jpv_pid);
EXTTXT((unsigned char *)&pv->jpv_node[0], JPV_LEN_NODE);
EXTTXT((unsigned char *)&pv->jpv_user[0], JPV_LEN_USER);
EXTTXT((unsigned char *)&pv->jpv_terminal[0], JPV_LEN_TERMINAL);
EXTINTVMS(pv->jpv_mode);
EXTTIMEVMS(MID_TIME(pv->jpv_login_time));
EXTINTVMS(pv->jpv_image_count);
EXTTXTVMS(pv->jpv_prcnam, JPV_LEN_PRCNAM);
return extract_len;
}