{ FIX_NONZERO_FREE_UPDATE_PID(csa, jb); } lcl_freeaddr = jb->freeaddr; lcl_free = jb->free; lcl_size = jb->size; lcl_buff = &jb->buff[jb->buff_off]; DBG_CHECK_JNL_BUFF_FREEADDR(jb); ++jb->reccnt[rectype]; assert(NULL != jnl_rec); rlen = jnl_rec->prefix.forwptr; /* Do high-level check on rlen */ assert(rlen <= jb->max_jrec_len); /* Do fine-grained checks on rlen */ GTMTRIG_ONLY(assert(!IS_ZTWORM(rectype) || (MAX_ZTWORM_JREC_LEN >= rlen));) /* ZTWORMHOLE */ assert(!IS_SET_KILL_ZKILL_ZTRIG(rectype) || (JNL_MAX_SET_KILL_RECLEN(csd) >= rlen)); /* SET, KILL, ZKILL */ assert((NULL == blk_ptr) || (JNL_MAX_PBLK_RECLEN(csd) >= rlen)); /* PBLK and AIMG */ jb->bytcnt += rlen; assert (0 == rlen % JNL_REC_START_BNDRY); rlen_with_align = rlen + (int4)MIN_ALIGN_RECLEN; assert(0 == rlen_with_align % JNL_REC_START_BNDRY); assert((uint4)rlen_with_align < ((uint4)1 << jb->log2_of_alignsize)); if ((lcl_freeaddr >> jb->log2_of_alignsize) == ((lcl_freeaddr + rlen_with_align - 1) >> jb->log2_of_alignsize)) rlen_with_align = rlen; else { align_rec.align_str.length = ROUND_UP2(lcl_freeaddr, ((uint4)1 << jb->log2_of_alignsize)) - lcl_freeaddr - (uint4)MIN_ALIGN_RECLEN; align_rec_len = (int4)(MIN_ALIGN_RECLEN + align_rec.align_str.length); assert (0 == align_rec_len % JNL_REC_START_BNDRY); rlen_with_align = rlen + align_rec_len;
mv.str.len = 0; mv.str.addr = NULL; op_tstart(IMPLICIT_TSTART, TRUE, &mv, -1); DEBUG_ONLY(jgbl.max_tp_ztp_jnl_upd_num = 0;) } tp_set_sgm(); /* needed to set "sgm_info_ptr" to correspond to "rctl" */ } /* For extract, if database was present we would have done gvcst_init(). * For recover/rollback gvcst_init() should definitely have been done. * In both cases rctl->gd->open will be non-NULL. Note that rctl->csa could be non-NULL * (set in mur_forward) even if rctl->gd->open is non-NULL. So dont use that. * Only then can we call gvcst_root_search() to find out collation set up for this global. */ assert(gv_cur_region == rctl->gd); assert(!mur_options.update || (gv_cur_region->open && (NULL != rctl->csa))); is_set_kill_zkill_ztrig = (boolean_t)(IS_SET_KILL_ZKILL_ZTRIG(rectype)); if (is_set_kill_zkill_ztrig) { assert(NULL != keystr); memcpy(gv_currkey->base, &keystr->text[0], keystr->length); gv_currkey->base[keystr->length] = '\0'; gv_currkey->end = keystr->length; if (gv_cur_region->open) { /* find out collation of key in the jnl-record from the database corresponding to the jnl file */ gvent.var_name.addr = (char *)gv_currkey->base; gvent.var_name.len = STRLEN((char *)gv_currkey->base); COMPUTE_HASH_MNAME(&gvent); if (NULL != (tabent = lookup_hashtab_mname(&rctl->gvntab, &gvent))) /* WARNING ASSIGNMENT */ { gvnh_reg = (gvnh_reg_t *)tabent->value; assert(NULL != gvnh_reg);
boolean_t mur_select_rec(jnl_ctl_list *jctl) { boolean_t exc_item_seen, inc_item_seen, inc_seen, wildcard_match; char key_buff[MAX_KEY_SZ + 1 + SIZEOF(uint4) * 2], asc_key_buff[MAX_ZWR_KEY_SZ], *ptr; int i, key_len, pat_pos, subs_pos; uint4 pini_addr; gv_key *key; jnl_record *rec; pini_list_struct *plst; jnl_process_vector *pv; enum jnl_record_type rectype; long_list *ll_ptr; select_list *sl_ptr; jnl_string *keystr; uint4 status; int4 pv_len, sl_len; assert(mur_options.selection); rec = jctl->reg_ctl->mur_desc->jnlrec; rectype = (enum jnl_record_type)rec->prefix.jrec_type; pini_addr = rec->prefix.pini_addr; key = NULL; if (JRT_NULL == rectype || JRT_ALIGN == rectype) return TRUE; status = mur_get_pini(jctl, pini_addr, &plst); if (SS_NORMAL != status) return TRUE; pv = &plst->jpv; if (IS_SET_KILL_ZKILL_ZTRIG(rectype)) { /* Translate internal format of jnl_record key to ascii */ keystr = (jnl_string *)&rec->jrec_set_kill.mumps_node; key = (gv_key *)key_buff; key->top = MAX_KEY_SZ; key->end = keystr->length; assert(key->end <= key->top); memcpy(key->base, &keystr->text[0], keystr->length); key->base[key->end] = '\0'; key_len = INTCAST((format_targ_key((uchar_ptr_t)asc_key_buff, MAX_ZWR_KEY_SZ, key, FALSE) - (unsigned char *)asc_key_buff)); } /* Check this record against the various selection lists */ if (NULL != mur_options.user) { inc_seen = inc_item_seen = exc_item_seen = FALSE; for (sl_ptr = mur_options.user; NULL != sl_ptr; sl_ptr = sl_ptr->next) { wildcard_match = FALSE; if (!sl_ptr->exclude) inc_seen = TRUE; if (sl_ptr->has_wildcard) wildcard_match = mur_do_wildcard(pv->jpv_user, sl_ptr->buff, JPV_LEN_USER, sl_ptr->len); if (!wildcard_match) { pv_len = real_len(JPV_LEN_USER, (uchar_ptr_t)pv->jpv_user); sl_len = MIN(sl_ptr->len, JPV_LEN_USER); } if (wildcard_match || (pv_len == sl_len) && (0 == memcmp(pv->jpv_user, sl_ptr->buff, sl_len))) { if (sl_ptr->exclude) exc_item_seen = TRUE; else inc_item_seen = TRUE; } } if (exc_item_seen || (inc_seen && !inc_item_seen)) return FALSE; } if ((NULL != mur_options.global) && (NULL != key)) { inc_seen = inc_item_seen = exc_item_seen = FALSE; for (sl_ptr = mur_options.global; NULL != sl_ptr; sl_ptr = sl_ptr->next) { wildcard_match = FALSE; if (!sl_ptr->exclude) inc_seen = TRUE; if (sl_ptr->has_wildcard) wildcard_match = mur_do_wildcard(asc_key_buff, sl_ptr->buff, key_len, sl_ptr->len); i = sl_ptr->len; if (sl_ptr->buff[i - 1] == ')') --i; if (wildcard_match || (key_len == i) && (0 == memcmp(asc_key_buff, sl_ptr->buff, i)) || (key_len > i) && (0 == memcmp(asc_key_buff, sl_ptr->buff, i)) && (('(' == asc_key_buff[i]) || (')' == asc_key_buff[i]) || (',' == asc_key_buff[i]))) { if (sl_ptr->exclude) exc_item_seen = TRUE; else inc_item_seen = TRUE; } } if (exc_item_seen || (inc_seen && !inc_item_seen)) return FALSE; } if (NULL != mur_options.process) { inc_seen = inc_item_seen = exc_item_seen = FALSE; for (sl_ptr = mur_options.process; NULL != sl_ptr; sl_ptr = sl_ptr->next) { wildcard_match = FALSE; if (!sl_ptr->exclude) inc_seen = TRUE; if (sl_ptr->has_wildcard) wildcard_match = mur_do_wildcard(pv->jpv_prcnam, sl_ptr->buff, JPV_LEN_PRCNAM, sl_ptr->len); if (!wildcard_match) { pv_len = real_len(JPV_LEN_PRCNAM, (uchar_ptr_t)pv->jpv_prcnam); sl_len = MIN(sl_ptr->len, JPV_LEN_PRCNAM); } if (wildcard_match || (pv_len == sl_len) && (0 == memcmp(pv->jpv_prcnam, sl_ptr->buff, sl_len))) { if (sl_ptr->exclude) exc_item_seen = TRUE; else inc_item_seen = TRUE; } } if (exc_item_seen || (inc_seen && !inc_item_seen)) return FALSE; } if (NULL != mur_options.id) { inc_seen = inc_item_seen = exc_item_seen = FALSE; for (ll_ptr = mur_options.id; NULL != ll_ptr; ll_ptr = ll_ptr->next) { if (!ll_ptr->exclude) inc_seen = TRUE; if (ll_ptr->num == pv->jpv_pid) { if (ll_ptr->exclude) exc_item_seen = TRUE; else inc_item_seen = TRUE; } } if (exc_item_seen || (inc_seen && !inc_item_seen)) return FALSE; } if (IS_SET_KILL_ZKILL_ZTRIG(rectype)) { if (IS_SET(rectype)) return mur_options.transaction != TRANS_KILLS; else return mur_options.transaction != TRANS_SETS; } return TRUE; }
/* This routine formats and outputs journal extract records corresponding to M SET, KILL, ZKILL, TSTART, ZTSTART, and ZTRIGGER commands, $ZTRIGGER function (LGTRIG) and $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 or LGTRIG or ZTRIG 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_LGTRIG(rectype)) { EXT2BYTES(&muext_code[MUEXT_LGTRIG][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_ZTWORM_LGTRIG_ZTRIG(rectype)); assert(&rec->jrec_set_kill.strm_seqno == &rec->jrec_ztworm.strm_seqno); assert(&rec->jrec_set_kill.strm_seqno == &rec->jrec_lgtrig.strm_seqno); EXT_STRM_SEQNO(rec->jrec_set_kill.strm_seqno); assert(&rec->jrec_set_kill.update_num == &rec->jrec_ztworm.update_num); assert(&rec->jrec_set_kill.update_num == &rec->jrec_lgtrig.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) || IS_LGTRIG(rectype)) { assert(&rec->jrec_ztworm.ztworm_str == &rec->jrec_lgtrig.lgtrig_str); 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_csa(CSA_ARG(NULL) 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_csa(CSA_ARG(NULL) 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_csa(CSA_ARG(NULL) 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); }