/**************************************************************** * * * Copyright 2001, 2011 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 "gtm_string.h" #include "mdef.h" #include "gdsroot.h" #include "gtm_facility.h" #include "fileinfo.h" #include "gdsbt.h" #include "gdsfhead.h" #include "gdsblk.h" #include "min_max.h" /* needed for gdsblkops.h */ #include "gdsblkops.h" #include "gdscc.h" #include "dse.h" #include "cli.h" #include "init_root_gv.h" #include "filestruct.h" #include "jnl.h" #include "util.h" /* Include prototypes */ #include "t_qread.h" #include "t_write.h" #include "t_end.h" #include "t_begin_crit.h" #include "gvcst_blk_build.h" #include "t_abort.h" #define MAX_UTIL_LEN 80 GBLREF char *update_array, *update_array_ptr; GBLREF uint4 update_array_size; GBLREF srch_hist dummy_hist; GBLREF gd_region *gv_cur_region; GBLREF gd_addr *gd_header; GBLREF block_id patch_curr_blk; GBLREF save_strct patch_save_set[PATCH_SAVE_SIZE]; GBLREF unsigned short int patch_save_count; GBLREF sgmnt_addrs *cs_addrs; GBLREF sgmnt_data_ptr_t cs_data; GBLREF gd_addr *original_header; GBLREF cw_set_element cw_set[]; GBLREF unsigned char *non_tp_jfb_buff_ptr; void dse_rest(void) { block_id to, from; gd_region *region; int i, util_len; uchar_ptr_t lbp; char util_buff[MAX_UTIL_LEN], rn[MAX_RN_LEN + 1]; blk_segment *bs1, *bs_ptr; int4 blk_seg_cnt, blk_size; unsigned short rn_len; uint4 version; gd_addr *temp_gdaddr; gd_binding *map; boolean_t found; srch_blk_status blkhist; error_def(ERR_DBRDONLY); error_def(ERR_DSEBLKRDFAIL); error_def(ERR_DSEFAIL); if (gv_cur_region->read_only) rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region)); CHECK_AND_RESET_UPDATE_ARRAY; /* reset update_array_ptr to update_array */ if (cli_present("VERSION") != CLI_PRESENT) { util_out_print("Error: save version number must be specified.", TRUE); return; } if (!cli_get_int("VERSION", (int4 *)&version)) return; if (cli_present("BLOCK") == CLI_PRESENT) { if (!cli_get_hex("BLOCK", (uint4 *)&to)) return; if (to < 0 || to >= cs_addrs->ti->total_blks) { util_out_print("Error: invalid block number.", TRUE); return; } patch_curr_blk = to; } else to = patch_curr_blk; if (cli_present("FROM") == CLI_PRESENT) { if (!cli_get_hex("FROM", (uint4 *)&from)) return; if (from < 0 || from >= cs_addrs->ti->total_blks) { util_out_print("Error: invalid block number.", TRUE); return; } } else from = to; if (cli_present("REGION") == CLI_PRESENT) { rn_len = SIZEOF(rn); if (!cli_get_str("REGION", rn, &rn_len)) return; for (i = rn_len; i < MAX_RN_LEN + 1; i++) rn[i] = 0; found = FALSE; temp_gdaddr = gd_header; gd_header = original_header; for (i=0, region = gd_header->regions; i < gd_header->n_regions ;i++, region++) if (found = !memcmp(®ion->rname[0], &rn[0], MAX_RN_LEN)) break; GET_SAVED_GDADDR(gd_header, temp_gdaddr, map, gv_cur_region); if (!found) { util_out_print("Error: region not found.", TRUE); return; } if (!region->open) { util_out_print("Error: that region was not opened because it is not bound to any namespace.", TRUE); return; } } else region = gv_cur_region; found = FALSE; for (i = 0; i < patch_save_count; i++) if (patch_save_set[i].blk == from && patch_save_set[i].region == region && (found = version == patch_save_set[i].ver)) break; if (!found) { util_out_print("Error: no such version.", TRUE); return; } memcpy(util_buff, "!/Restoring block ", 18); util_len = 18; util_len += i2hex_nofill(to, (uchar_ptr_t)&util_buff[util_len], 8); memcpy(&util_buff[util_len]," from version !UL", 17); util_len += 17; util_buff[util_len] = 0; util_out_print(util_buff,FALSE,version); if (to != from) { memcpy(util_buff, " of block ", 10); util_len = 10; util_len += i2hex_nofill(from, (uchar_ptr_t)&util_buff[util_len], 8); util_buff[util_len] = 0; util_out_print(util_buff, FALSE); } if (region != gv_cur_region) util_out_print(" in region !AD", FALSE, LEN_AND_STR(rn)); util_out_print("!/",TRUE); if (to > cs_addrs->ti->total_blks) rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL); t_begin_crit(ERR_DSEFAIL); blk_size = cs_addrs->hdr->blk_size; blkhist.blk_num = to; if (!(blkhist.buffaddr = t_qread(blkhist.blk_num, &blkhist.cycle, &blkhist.cr))) rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL); lbp = (uchar_ptr_t)patch_save_set[i].bp; BLK_INIT(bs_ptr, bs1); BLK_SEG(bs_ptr, (uchar_ptr_t)lbp + SIZEOF(blk_hdr), (int)((blk_hdr_ptr_t)lbp)->bsiz - SIZEOF(blk_hdr)); if (!BLK_FINI(bs_ptr, bs1)) { util_out_print("Error: bad blk build.", TRUE); t_abort(gv_cur_region, cs_addrs); return; } t_write(&blkhist, (unsigned char *)bs1, 0, 0, ((blk_hdr_ptr_t)lbp)->levl, TRUE, FALSE, GDS_WRITE_KILLTN); BUILD_AIMG_IF_JNL_ENABLED(cs_data, non_tp_jfb_buff_ptr, cs_addrs->ti->curr_tn); t_end(&dummy_hist, NULL, TN_NOT_SPECIFIED); return; }