Beispiel #1
0
void gtcm_exit()
{
	op_lkinit();
	op_unlock();
	gv_rundown();
#ifdef GTCM_RC
	rc_delete_cpt();
	rc_rundown();
#endif
	exit(gtcm_exi_condition);
}
void util_exit_handler()
{
	int		stat;
	gd_region	*r_top, *reg;
	sgmnt_addrs	*csa;
	gd_addr		*addr_ptr;

	if (exit_handler_active)	/* Don't recurse if exit handler exited */
		return;
	exit_handler_active = TRUE;
	SET_PROCESS_EXITING_TRUE;	/* set this BEFORE canceling timers as wcs_phase2_commit_wait relies on this */
	if (IS_DSE_IMAGE)
	{	/* Need to clear csa->hold_onto_crit in case it was set */
		for (addr_ptr = get_next_gdr(NULL); addr_ptr; addr_ptr = get_next_gdr(addr_ptr))
		{
			for (reg = addr_ptr->regions, r_top = reg + addr_ptr->n_regions; reg < r_top; reg++)
			{
				if (reg->open && !reg->was_open)
				{
					csa = &FILE_INFO(reg)->s_addrs;
					csa->hold_onto_crit = FALSE;	/* need to do this before the rel_crit */
					if (csa->now_crit)
						rel_crit(reg);
				}
			}
		}
	}
	CANCEL_TIMERS;		/* Cancel all unsafe timers - No unpleasant surprises */
	secshr_db_clnup(NORMAL_TERMINATION);
	assert(!dollar_tlevel);	/* MUPIP and GT.M are the only ones which can run TP and they have their own exit handlers.
				 * So no need to run op_trollback here like mupip_exit_handler and gtm_exit_handler. */
	gv_rundown();
	print_exit_stats();
	util_out_close();
	GTMCRYPT_CLOSE;
	if (need_core && !created_core)
		DUMP_CORE;
}
void mupip_exit_handler(void)
{
	char		err_log[1024];
	FILE		*fp;
	boolean_t	files_closed = TRUE;

	if (exit_handler_active)	/* Don't recurse if exit handler exited */
		return;
	exit_handler_active = TRUE;
	SET_PROCESS_EXITING_TRUE;
	if (jgbl.mupip_journal)
	{
		files_closed = mur_close_files();
		mupip_jnl_recover = FALSE;
	}
	jgbl.dont_reset_gbl_jrec_time = jgbl.forw_phase_recovery = FALSE;
	CANCEL_TIMERS;			/* Cancel all unsafe timers - No unpleasant surprises */
	secshr_db_clnup(NORMAL_TERMINATION);
	if (dollar_tlevel)
		OP_TROLLBACK(0);
	if (is_updhelper && NULL != helper_entry) /* haven't had a chance to cleanup, must be an abnormal exit */
	{
		helper_entry->helper_shutdown = ABNORMAL_SHUTDOWN;
		helper_entry->helper_pid = 0; /* vacate my slot */
		helper_entry = NULL;
	}
	if (recvpool.recvpool_ctl)
	{
		SHMDT(recvpool.recvpool_ctl);
		recvpool.recvpool_ctl = NULL;
	}
	gv_rundown(); /* also takes care of detaching from the journal pool */
	relinkctl_rundown(TRUE, TRUE);	/* decrement relinkctl-attach & rtnobj-reference counts */
	/* Log the exit of replication servers. In case they are exiting abnormally, their log file pointers
	 * might not be set up. In that case, use "stderr" for logging.
	 */
	if (is_src_server)
	{
		fp = (NULL != gtmsource_log_fp) ? gtmsource_log_fp : stderr;
		repl_log(fp, TRUE, TRUE, "Source server exiting...\n\n");
	} else if (is_rcvr_server)
	{
		fp = (NULL != gtmrecv_log_fp) ? gtmrecv_log_fp : stderr;
		repl_log(fp, TRUE, TRUE, "Receiver server exiting...\n\n");
	} else if (is_updproc)
	{
		fp = (NULL != updproc_log_fp) ? updproc_log_fp : stderr;
		repl_log(fp, TRUE, TRUE, "Update process exiting...\n\n");
	} else if (is_updhelper)
	{
		fp = (NULL != updhelper_log_fp) ? updhelper_log_fp : stderr;
		repl_log(fp, TRUE, TRUE, "Helper exiting...\n\n");
	} else
		mu_reset_term_characterstics(); /* the replication servers use files for output/error, not terminal */
	flush_pio();
	util_out_close();
	close_repl_logfiles();
	print_exit_stats();
	io_rundown(RUNDOWN_EXCEPT_STD);
	GTMCRYPT_CLOSE;
	if (need_core && !created_core)
	{
		++core_in_progress;
		DUMP_CORE;	/* This will not return */
	}
	if (!files_closed)
		_exit(EXIT_FAILURE);
}