예제 #1
0
void	jnl_oper_user_ast(gd_region *reg)
{
	jnl_private_control	*jpc;
	uint4			status;
	int			close_res;

	if (reg && reg->open)
	{
		jpc = FILE_INFO(reg)->s_addrs.jnl;
		if (SS_NORMAL != jpc->status)
		{
			assert(0 != jpc->jnllsb->lockid);
			status = gtm_deq(jpc->jnllsb->lockid, NULL, PSL$C_USER, 0);
			assert(SS$_NORMAL == status);
			jnl_send_oper(jpc, status);

		}
		if ((FALSE == jpc->qio_active) && (NOJNL != jpc->old_channel))
		{
			JNL_FD_CLOSE(jpc->old_channel, close_res);	/* sets csa->jnl->channel to NOJNL */
			jpc->pini_addr = 0;
			jpc->jnllsb->lockid = 0;
		}
	}
}
예제 #2
0
/* make sure that the journal file is available if appropriate */
uint4   jnl_ensure_open(void)
{
	uint4			jnl_status;
	jnl_private_control	*jpc;
	sgmnt_addrs		*csa;
	sgmnt_data_ptr_t	csd;
	boolean_t		first_open_of_jnl, need_to_open_jnl;
	int			close_res;
#       if defined(VMS)
	static const gds_file_id	file;
	uint4				status;
#       endif

	error_def(ERR_JNLFILOPN);

	csa = cs_addrs;
	csd = csa->hdr;
	assert(csa->now_crit);
	jpc = csa->jnl;
	assert(NULL != jpc);
	assert(JNL_ENABLED(csa->hdr));
	/* The goal is to change the code below to do only one JNL_FILE_SWITCHED(jpc) check instead of the additional
	 * (NOJNL == jpc->channel) check done below. The assert below ensures that the NOJNL check can indeed
	 * be subsumed by the JNL_FILE_SWITCHED check (with the exception of the source-server which has a special case that
	 * needs to be fixed in C9D02-002241). Over time, this has to be changed to one check.
	 */
	assert((NOJNL != jpc->channel) || JNL_FILE_SWITCHED(jpc) || is_src_server);
	need_to_open_jnl = FALSE;
	jnl_status = 0;
	if (NOJNL == jpc->channel)
	{
#               ifdef VMS
		if (NOJNL != jpc->old_channel)
		{
			if (lib$ast_in_prog())          /* called from wcs_wipchk_ast */
				jnl_oper_user_ast(gv_cur_region);
			else
			{
				status = sys$setast(DISABLE);
				jnl_oper_user_ast(gv_cur_region);
				if (SS$_WASSET == status)
					ENABLE_AST;
			}
		}
#               endif
		need_to_open_jnl = TRUE;
	} else if (JNL_FILE_SWITCHED(jpc))
	{       /* The journal file has been changed "on the fly"; close the old one and open the new one */
		VMS_ONLY(assert(FALSE);)        /* everyone having older jnl open should have closed it at time of switch in VMS */
		JNL_FD_CLOSE(jpc->channel, close_res);  /* sets jpc->channel to NOJNL */
		need_to_open_jnl = TRUE;
	}
예제 #3
0
void heartbeat_timer(void)
{
	gd_addr			*addr_ptr;
	sgmnt_addrs		*csa;
	jnl_private_control	*jpc;
	gd_region		*r_local, *r_top;
	int			rc;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;

	/* It will take heartbeat_counter about 1014 years to overflow. */
	heartbeat_counter++;
	DEBUG_ONLY(set_enospc_if_needed());
	/* Check every 1 minute if we have an older generation journal file open. If so, close it.
	 * The only exceptions are
	 *	a) The source server can have older generations open and they should not be closed.
	 *	b) If we are in the process of switching to a new journal file while we get interrupted
	 *		by the heartbeat timer, we should not close the older generation journal file
	 *		as it will anyways be closed by the mainline code. But identifying that we are in
	 *		the midst of a journal file switch is tricky so we check if the process is in
	 *		crit for this region and if so we skip the close this time and wait for the next heartbeat.
	 */
	if ((INTRPT_OK_TO_INTERRUPT == intrpt_ok_state) && !is_src_server
		&& (0 == heartbeat_counter % NUM_HEARTBEATS_FOR_OLDERJNL_CHECK))
	{
		for (addr_ptr = get_next_gdr(NULL); addr_ptr; addr_ptr = get_next_gdr(addr_ptr))
		{
			for (r_local = addr_ptr->regions, r_top = r_local + addr_ptr->n_regions; r_local < r_top; r_local++)
			{
				if (!r_local->open || r_local->was_open)
					continue;
				if ((dba_bg != r_local->dyn.addr->acc_meth) && (dba_mm != r_local->dyn.addr->acc_meth))
					continue;
				csa = &FILE_INFO(r_local)->s_addrs;
				if (csa->now_crit)
					continue;
				jpc = csa->jnl;
				if ((NULL != jpc) && (NOJNL != jpc->channel) && JNL_FILE_SWITCHED(jpc))
				{	/* The journal file we have as open is not the latest generation journal file. Close it */
					/* Assert that we never have an active write on a previous generation journal file. */
					assert(process_id != jpc->jnl_buff->io_in_prog_latch.u.parts.latch_pid);
					JNL_FD_CLOSE(jpc->channel, rc);	/* sets jpc->channel to NOJNL */
					jpc->pini_addr = 0;
				}
			}
		}
	}
	start_timer((TID)heartbeat_timer, HEARTBEAT_INTERVAL, heartbeat_timer, 0, NULL);
}
예제 #4
0
/* make sure that the journal file is available if appropriate */
uint4   jnl_ensure_open(gd_region *reg, sgmnt_addrs *csa)
{
	uint4			jnl_status;
	jnl_private_control	*jpc;
	sgmnt_data_ptr_t	csd;
	boolean_t		first_open_of_jnl, need_to_open_jnl;
	int			close_res;

	csd = csa->hdr;
	assert(csa->now_crit);
	jpc = csa->jnl;
	assert(&FILE_INFO(jpc->region)->s_addrs == csa);
	assert(&FILE_INFO(reg)->s_addrs == csa);
	assert(NULL != jpc);
	assert(JNL_ENABLED(csa->hdr));
	/* The goal is to change the code below to do only one JNL_FILE_SWITCHED(jpc) check instead of the additional
	 * (NOJNL == jpc->channel) check done below. The assert below ensures that the NOJNL check can indeed
	 * be subsumed by the JNL_FILE_SWITCHED check (with the exception of the source-server which has a special case that
	 * needs to be fixed in C9D02-002241). Over time, this has to be changed to one check.
	 */
	assert((NOJNL != jpc->channel) || JNL_FILE_SWITCHED(jpc) || is_src_server);
	need_to_open_jnl = FALSE;
	jnl_status = 0;
	if (NOJNL == jpc->channel)
		need_to_open_jnl = TRUE;
	else if (JNL_FILE_SWITCHED(jpc))
	{       /* The journal file has been changed "on the fly"; close the old one and open the new one */
		JNL_FD_CLOSE(jpc->channel, close_res);  /* sets jpc->channel to NOJNL */
		need_to_open_jnl = TRUE;
	}
	if (need_to_open_jnl)
	{
		/* Whenever journal file get switch, reset the pini_addr and new_freeaddr. */
		jpc->pini_addr = 0;
		jpc->new_freeaddr = 0;
		if (IS_GTCM_GNP_SERVER_IMAGE)
			gtcm_jnl_switched(reg); /* Reset pini_addr of all clients that had any older journal file open */
		first_open_of_jnl = (0 == csa->nl->jnl_file.u.inode);
		jnl_status = jnl_file_open(reg, first_open_of_jnl);
	}
#	ifdef DEBUG
	else
		GTM_WHITE_BOX_TEST(WBTEST_JNL_FILE_OPEN_FAIL, jnl_status, ERR_JNLFILOPN);
#	endif
	assert((0 != jnl_status) || !JNL_FILE_SWITCHED(jpc) || (is_src_server && !JNL_ENABLED(csa) && REPL_WAS_ENABLED(csa)));
	return jnl_status;
}