200 lines
5.2 KiB
C
200 lines
5.2 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2001, 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_stdio.h"
|
|
|
|
#ifdef VMS
|
|
# include <descrip.h>
|
|
# include <ssdef.h>
|
|
#endif
|
|
#ifdef VVMS_GTCX
|
|
# include <iodef.h>
|
|
# include <fab.h>
|
|
# include <efndef.h>
|
|
#endif
|
|
|
|
#include "gdsroot.h"
|
|
#include "gtm_facility.h"
|
|
#include "fileinfo.h"
|
|
#include "gdsbt.h"
|
|
#include "gdsfhead.h"
|
|
#include "filestruct.h"
|
|
#ifdef VVMS_GTCX
|
|
# include "ccp.h"
|
|
# include "ccpact.h"
|
|
# include "iosp.h"
|
|
#endif
|
|
#include "send_msg.h"
|
|
#include "caller_id.h"
|
|
#include "sleep_cnt.h"
|
|
#include "interlock.h"
|
|
#include "add_inter.h"
|
|
#include "wcs_sleep.h"
|
|
#include "gtm_time.h"
|
|
#include "gtm_string.h"
|
|
#include "cli.h"
|
|
#include "util.h"
|
|
#include "wbox_test_init.h"
|
|
|
|
GBLREF bool caller_id_flag;
|
|
GBLREF bool in_mupip_freeze;
|
|
GBLREF uint4 process_id;
|
|
GBLREF boolean_t debug_mupip;
|
|
#ifdef UNIX
|
|
# define FREEZE_ID (0 == TREF(user_id) ? FROZEN_BY_ROOT : TREF(user_id))
|
|
# define FREEZE_MATCH process_id
|
|
# define OWNERSHIP (in_mupip_freeze ? (csd->freeze == freeze_id) : (csd->image_count == FREEZE_MATCH))
|
|
#elif defined VMS
|
|
GBLREF uint4 image_count;
|
|
# define FREEZE_ID process_id
|
|
# define FREEZE_MATCH image_count
|
|
# define OWNERSHIP ((csd->freeze == process_id) && (in_mupip_freeze || (csd->image_count == FREEZE_MATCH)))
|
|
#else
|
|
# error Unsupported Platform
|
|
#endif
|
|
|
|
#define SEND_FREEZEID(state) \
|
|
{ \
|
|
caller_id_flag = FALSE; \
|
|
send_msg(VARLSTCNT(9) ERR_FREEZEID, 7, LEN_AND_STR(state), \
|
|
DB_LEN_STR(region), \
|
|
freeze_id, FREEZE_MATCH, caller_id()); \
|
|
caller_id_flag = TRUE; \
|
|
}
|
|
|
|
error_def(ERR_FREEZEID);
|
|
|
|
freeze_status region_freeze(gd_region *region, boolean_t freeze, boolean_t override, boolean_t wait_for_kip)
|
|
{
|
|
uint4 freeze_id, sleep_counter;
|
|
sgmnt_addrs *csa;
|
|
sgmnt_data_ptr_t csd;
|
|
now_t now; /* for GET_CUR_TIME macro */
|
|
char *time_ptr, time_str[CTIME_BEFORE_NL + 2]; /* for GET_CUR_TIME macro */
|
|
boolean_t was_crit;
|
|
DCL_THREADGBL_ACCESS;
|
|
|
|
SETUP_THREADGBL_ACCESS;
|
|
freeze_id = FREEZE_ID;
|
|
csa = &FILE_INFO(region)->s_addrs;
|
|
csd = csa->hdr;
|
|
if (freeze)
|
|
{
|
|
was_crit = csa->now_crit;
|
|
if (!was_crit)
|
|
grab_crit(region); /* really need this to be sure in UNIX, shouldn't be frequent anyway */
|
|
INCR_INHIBIT_KILLS(csa->nl);
|
|
if (OWNERSHIP)
|
|
{
|
|
DECR_INHIBIT_KILLS(csa->nl);
|
|
if (!was_crit)
|
|
rel_crit(region);
|
|
return REG_FREEZE_SUCCESS;
|
|
}
|
|
if (!override && csd->freeze)
|
|
{
|
|
DECR_INHIBIT_KILLS(csa->nl);
|
|
if (!was_crit)
|
|
rel_crit(region);
|
|
return REG_ALREADY_FROZEN;
|
|
}
|
|
/* If override is TRUE we need not wait for KIP to become zero */
|
|
sleep_counter = 1;
|
|
if (!override && wait_for_kip && (0 < csd->kill_in_prog))
|
|
{
|
|
if (!was_crit)
|
|
rel_crit(region);
|
|
/* MUPIP FREEZE/INTEG and BACKUP's DBG qualifier prints extra debug messages while waiting for KIP */
|
|
if (debug_mupip)
|
|
{
|
|
GET_CUR_TIME;
|
|
util_out_print("!/MUPIP INFO: !AD : Start kill-in-prog wait for database !AD", TRUE,
|
|
CTIME_BEFORE_NL, time_ptr, DB_LEN_STR(region));
|
|
}
|
|
do
|
|
{
|
|
if (!was_crit)
|
|
grab_crit(region);
|
|
if (!csd->kill_in_prog)
|
|
break;
|
|
if (!was_crit)
|
|
rel_crit(region);
|
|
wcs_sleep(sleep_counter);
|
|
} while (MAX_CRIT_TRY > sleep_counter++);
|
|
if (debug_mupip)
|
|
{
|
|
GET_CUR_TIME;
|
|
util_out_print("!/MUPIP INFO: !AD : Done with kill-in-prog wait on region", TRUE,
|
|
CTIME_BEFORE_NL, time_ptr);
|
|
}
|
|
}
|
|
/* if can't ever be true when override is true. */
|
|
if (MAX_CRIT_TRY <= sleep_counter)
|
|
{
|
|
DECR_INHIBIT_KILLS(csa->nl);
|
|
if (!was_crit)
|
|
rel_crit(region);
|
|
return REG_HAS_KIP;
|
|
}
|
|
csd->freeze = freeze_id; /* the order of this line and the next is important */
|
|
csd->image_count = FREEZE_MATCH;
|
|
csa->freeze = TRUE;
|
|
DECR_INHIBIT_KILLS(csa->nl);
|
|
if (!was_crit)
|
|
rel_crit(region);
|
|
# ifdef VVMS_GTCX
|
|
if (csd->clustered)
|
|
{
|
|
unsigned short iosb[4];
|
|
|
|
(void)sys$qiow(EFN$C_ENF, FILE_INFO(region)->fab->fab$l_stv, IO$_WRITEVBLK, iosb, NULL, 0,
|
|
csd, (MM_BLOCK - 1) * DISK_BLOCK_SIZE, 1, 0, 0, 0);
|
|
}
|
|
# endif
|
|
# ifdef DEBUG_FREEZE
|
|
SEND_FREEZEID("FREEZE");
|
|
# endif
|
|
return REG_FREEZE_SUCCESS;
|
|
}
|
|
if (0 == csd->freeze)
|
|
return REG_FREEZE_SUCCESS;
|
|
if (override || OWNERSHIP)
|
|
{
|
|
csd->image_count = 0; /* the order of this line and the next is important */
|
|
csd->freeze = 0;
|
|
csa->freeze = FALSE;
|
|
# ifdef VVMS_GTCX
|
|
if (csd->clustered)
|
|
{
|
|
ccp_action_aux_value msg;
|
|
unsigned short iosb[4];
|
|
void ccp_sendmsg();
|
|
|
|
(void)sys$qiow(EFN$C_ENF, FILE_INFO(region)->fab->fab$l_stv, IO$_WRITEVBLK, iosb, NULL, 0,
|
|
csd, (MM_BLOCK - 1) * DISK_BLOCK_SIZE, 1, 0, 0, 0);
|
|
if (csa->nl->ccp_crit_blocked)
|
|
{
|
|
msg.exreq.fid = FILE_INFO(region)->file_id;
|
|
msg.exreq.cycle = csa->nl->ccp_cycle;
|
|
ccp_sendmsg(CCTR_EXITWM, &msg);
|
|
}
|
|
}
|
|
# endif
|
|
# ifdef DEBUG_FREEZE
|
|
SEND_FREEZEID("UNFREEZE");
|
|
# endif
|
|
return REG_FREEZE_SUCCESS;
|
|
}
|
|
return REG_ALREADY_FROZEN;
|
|
}
|