/**************************************************************** * * * Copyright 2001, 2009 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 "gdsroot.h" #include "gtm_string.h" #include "gtm_facility.h" #include "fileinfo.h" #include "gdsbt.h" #include "gdsfhead.h" #include "filestruct.h" #include "cli.h" #include "iosp.h" #include "error.h" #include "stp_parms.h" #include "gdscc.h" #include "gdskill.h" #include "jnl.h" #include "buddy_list.h" /* needed for tp.h */ #include "hashtab_int4.h" /* needed for tp.h */ #include "tp.h" #include "util.h" #include "gt_timer.h" #include "mupipbckup.h" #include "gvcst_protos.h" /* for gvcst_init prototype */ #include "change_reg.h" #include "mupip_exit.h" #include "mu_getlst.h" #include "mu_outofband_setup.h" #include "gtmmsg.h" #include "wcs_flu.h" #include "mupip_freeze.h" #include "interlock.h" #include "sleep_cnt.h" GBLREF bool mu_ctrly_occurred; GBLREF bool mu_ctrlc_occurred; GBLREF gd_region *gv_cur_region; GBLREF sgmnt_addrs *cs_addrs; GBLREF tp_region *halt_ptr; GBLREF tp_region *grlist; GBLREF bool in_mupip_freeze; GBLREF bool error_mupip; GBLREF boolean_t debug_mupip; #define INTERRUPTED (mu_ctrly_occurred || mu_ctrlc_occurred) #define PRINT_FREEZEERR \ { \ gtm_putmsg(VARLSTCNT(6) ERR_FREEZEERR, 4, LEN_AND_STR(msg1[freeze]), REG_LEN_STR(gv_cur_region)); \ status = ERR_MUNOFINISH; \ } #define PRINT_UNFROZEN_MSG util_out_print("All regions will be unfrozen", TRUE) void mupip_freeze(void) { int4 status; bool record; tp_region *rptr, *rptr1; boolean_t freeze, override; freeze_status freeze_ret; const char *msg1[] = { "unfreeze", "freeze" } ; const char *msg2[] = { "UNFROZEN", "FROZEN" } ; const char *msg3[] = { "unfrozen", "frozen" } ; error_def(ERR_BUFFLUFAILED); error_def(ERR_DBRDONLY); error_def(ERR_FREEZECTRL); error_def(ERR_MUNOACTION); error_def(ERR_MUPCLIERR); error_def(ERR_MUNOFINISH); error_def(ERR_MUKILLIP); error_def(ERR_KILLABANDONED); error_def(ERR_FREEZEERR); status = SS_NORMAL; in_mupip_freeze = TRUE; mu_outofband_setup(); gvinit(); freeze = (CLI_PRESENT == cli_present("ON")); if (CLI_PRESENT == cli_present("OFF")) { if (TRUE == freeze) { util_out_print("The /ON qualifier is invalid with the /OFF qualifier", TRUE); mupip_exit(ERR_MUPCLIERR); } } if (CLI_PRESENT == cli_present("RECORD")) { record = TRUE; if (FALSE == freeze) { util_out_print("The /RECORD qualifier is invalid with the /OFF qualifier", TRUE); mupip_exit(ERR_MUPCLIERR); } } else record = FALSE; if (CLI_PRESENT == cli_present("OVERRIDE")) { override = TRUE; if (freeze) { util_out_print("The /OVERRIDE qualifier is invalid with the /ON qualifier", TRUE); mupip_exit(ERR_MUPCLIERR); } } else override = FALSE; error_mupip = FALSE; /* DBG qualifier prints extra debug messages while waiting for KIP in region freeze */ debug_mupip = (CLI_PRESENT == cli_present("DBG")); mu_getlst("REG_NAME", SIZEOF(tp_region)); if (error_mupip) { util_out_print("!/MUPIP cannot start freeze with above errors!/", TRUE); mupip_exit(ERR_MUNOACTION); } halt_ptr = grlist; ESTABLISH(mu_freeze_ch); for (rptr = grlist; NULL != rptr; rptr = rptr->fPtr) { if (INTERRUPTED) break; if ((dba_bg != rptr->reg->dyn.addr->acc_meth) && (dba_mm != rptr->reg->dyn.addr->acc_meth)) { util_out_print("Can only FREEZE BG and MM databases", TRUE); PRINT_FREEZEERR; continue; } if (reg_cmcheck(rptr->reg)) { util_out_print("!/Can't FREEZE region !AD across network", TRUE, REG_LEN_STR(rptr->reg)); PRINT_FREEZEERR; continue; } gv_cur_region = rptr->reg; gvcst_init(gv_cur_region); if (gv_cur_region->was_open) /* Already open under another name. Region will not be marked open*/ { gv_cur_region->open = FALSE; util_out_print("FREEZE region !AD is already open under another name", TRUE, REG_LEN_STR(rptr->reg)); continue; } change_reg(); assert(&FILE_INFO(gv_cur_region)->s_addrs == cs_addrs); /* Cannot flush for read-only data files */ if (gv_cur_region->read_only) { gtm_putmsg(VARLSTCNT(4) ERR_DBRDONLY, 2, gv_cur_region->dyn.addr->fname_len, gv_cur_region->dyn.addr->fname); PRINT_FREEZEERR; continue; } if (freeze && (0 != cs_addrs->hdr->abandoned_kills)) { gtm_putmsg(VARLSTCNT(6) ERR_KILLABANDONED, 4, DB_LEN_STR(rptr->reg), LEN_AND_LIT("database could have incorrectly marked busy integrity errors")); PRINT_FREEZEERR; continue; } while (REG_FREEZE_SUCCESS != (freeze_ret = region_freeze(gv_cur_region, freeze, override, TRUE))) { if (REG_ALREADY_FROZEN == freeze_ret) { hiber_start(1000); if (INTERRUPTED) break; } else if (REG_HAS_KIP == freeze_ret) { assert(!override); util_out_print("Kill in progress indicator is set for database file !AD", TRUE, DB_LEN_STR(gv_cur_region)); PRINT_UNFROZEN_MSG; rts_error(VARLSTCNT(1) ERR_MUNOFINISH); } else assert(FALSE); } cs_addrs->persistent_freeze = freeze; /* secshr_db_clnup() shouldn't clear the freeze up */ if (!wcs_flu(WCSFLU_FLUSH_HDR | WCSFLU_WRITE_EPOCH | WCSFLU_SYNC_EPOCH)) { gtm_putmsg(VARLSTCNT(6) ERR_BUFFLUFAILED, 4, LEN_AND_LIT("MUPIP FREEZE"), DB_LEN_STR(gv_cur_region)); PRINT_UNFROZEN_MSG; rts_error(VARLSTCNT(1) ERR_MUNOFINISH); } halt_ptr = rptr->fPtr; if (record && gv_cur_region->open) cs_addrs->hdr->last_rec_backup = cs_addrs->ti->curr_tn; if (REG_FREEZE_SUCCESS == freeze_ret) util_out_print("Region !AD is now !AD", TRUE, REG_LEN_STR(gv_cur_region), LEN_AND_STR(msg2[freeze])); else PRINT_FREEZEERR; } REVERT; if (INTERRUPTED) { for (rptr1 = grlist; rptr1 != rptr; rptr1 = rptr1->fPtr) { gv_cur_region = rptr1->reg; if (FALSE == gv_cur_region->open) continue; region_freeze(gv_cur_region, FALSE, FALSE, FALSE); } gtm_putmsg(VARLSTCNT(1) ERR_FREEZECTRL); status = ERR_MUNOFINISH; } if (SS_NORMAL == status) util_out_print("All requested regions !AD", TRUE, LEN_AND_STR(msg3[freeze])); mupip_exit(status); }