示例#1
0
int gtmrecv_changelog(void)
{
	uint4	changelog_desired = 0, changelog_accepted = 0;

	/* Grab the recvpool jnlpool option write lock */
	if (0 > grab_sem(RECV, RECV_SERV_OPTIONS_SEM))
	{
		util_out_print("Error grabbing recvpool option write lock. Could not initiate change log", TRUE);
		return (ABNORMAL_SHUTDOWN);
	}
	if (0 != recvpool.gtmrecv_local->changelog || 0 != recvpool.upd_proc_local->changelog)
	{
		util_out_print("Change log is already in progress. Not initiating change in log file or log interval", TRUE);
		rel_sem(RECV, RECV_SERV_OPTIONS_SEM);
		return (ABNORMAL_SHUTDOWN);
	}
	if ('\0' != gtmrecv_options.log_file[0]) /* trigger change in log file (for both receiver and update process) */
	{
		changelog_desired |= REPLIC_CHANGE_LOGFILE;
		if (0 != strcmp(recvpool.gtmrecv_local->log_file, gtmrecv_options.log_file))
		{
			changelog_accepted |= REPLIC_CHANGE_LOGFILE;
			strcpy(recvpool.gtmrecv_local->log_file, gtmrecv_options.log_file);
			util_out_print("Change log initiated with file !AD", TRUE, LEN_AND_STR(gtmrecv_options.log_file));
		} else
			util_out_print("Log file is already !AD. Not initiating change in log file", TRUE,
					LEN_AND_STR(gtmrecv_options.log_file));
	}
	if (0 != gtmrecv_options.rcvr_log_interval) /* trigger change in receiver log interval */
	{
		changelog_desired |= REPLIC_CHANGE_LOGINTERVAL;
		if (gtmrecv_options.rcvr_log_interval != recvpool.gtmrecv_local->log_interval)
		{
			changelog_accepted |= REPLIC_CHANGE_LOGINTERVAL;
			recvpool.gtmrecv_local->log_interval = gtmrecv_options.rcvr_log_interval;
			util_out_print("Change initiated with receiver log interval !UL", TRUE, gtmrecv_options.rcvr_log_interval);
		} else
			util_out_print("Receiver log interval is already !UL. Not initiating change in log interval", TRUE,
					gtmrecv_options.rcvr_log_interval);
	}
	if (0 != gtmrecv_options.upd_log_interval) /* trigger change in update process log interval */
	{
		changelog_desired |= REPLIC_CHANGE_UPD_LOGINTERVAL;
		if (gtmrecv_options.upd_log_interval != recvpool.upd_proc_local->log_interval)
		{
			changelog_accepted |= REPLIC_CHANGE_UPD_LOGINTERVAL;
			recvpool.upd_proc_local->log_interval = gtmrecv_options.upd_log_interval;
			util_out_print("Change initiated with update process log interval !UL", TRUE,
					gtmrecv_options.upd_log_interval);
		} else
			util_out_print("Update process log interval is already !UL. Not initiating change in log interval", TRUE,
					gtmrecv_options.upd_log_interval);
	}
	if (0 != changelog_accepted)
		recvpool.gtmrecv_local->changelog = changelog_accepted;
	else
		util_out_print("No change to log file or log interval", TRUE);
	rel_sem(RECV, RECV_SERV_OPTIONS_SEM);
	return ((0 != changelog_accepted && changelog_accepted == changelog_desired) ? NORMAL_SHUTDOWN : ABNORMAL_SHUTDOWN);
}
示例#2
0
int gtmrecv_statslog(void)
{
#ifdef VMS
    rts_error(VARLSTCNT(6) ERR_UNIMPLOP, 0, ERR_TEXT, 2, LEN_AND_LIT("Statistics logging not supported on VMS"));
#endif
    /* Grab the recvpool option write lock */
    if (0 > grab_sem(RECV, RECV_SERV_OPTIONS_SEM))
    {
        util_out_print("Error grabbing recvpool option write lock. Could not initiate stats log", TRUE);
        return (ABNORMAL_SHUTDOWN);
    }

    if (gtmrecv_options.statslog == recvpool.gtmrecv_local->statslog)
    {
        util_out_print("STATSLOG is already !AD. Not initiating change in stats log", TRUE, gtmrecv_options.statslog ?
                       strlen("ON") : strlen("OFF"), gtmrecv_options.statslog ? "ON" : "OFF");
        rel_sem_immediate(RECV, RECV_SERV_OPTIONS_SEM);
        return (ABNORMAL_SHUTDOWN);
    }

    if (!gtmrecv_options.statslog)
    {
        recvpool.gtmrecv_local->statslog = FALSE;
        util_out_print("STATSLOG turned OFF", TRUE);
        rel_sem_immediate(RECV, RECV_SERV_OPTIONS_SEM);
        return (NORMAL_SHUTDOWN);
    }

    recvpool.gtmrecv_local->statslog = TRUE;
    util_out_print("Stats log turned on", TRUE);
    rel_sem_immediate(RECV, RECV_SERV_OPTIONS_SEM);
    return (NORMAL_SHUTDOWN);
}
示例#3
0
int gtmsource_secnd_update(boolean_t print_message)
{
	if (grab_sem(SOURCE, SRC_SERV_OPTIONS_SEM) < 0)
	{
		util_out_print("Error grabbing jnlpool option write lock. Could not initiate change log", TRUE);
		return(ABNORMAL_SHUTDOWN);
	}
	grab_lock(jnlpool.jnlpool_dummy_reg, ASSERT_NO_ONLINE_ROLLBACK);
	jnlpool.jnlpool_ctl->upd_disabled = update_disable;
	rel_lock(jnlpool.jnlpool_dummy_reg);
	rel_sem(SOURCE, SRC_SERV_OPTIONS_SEM);
	if (print_message)
		util_out_print("Updates are now !AZ", TRUE, update_disable ? "disabled" : "enabled");
	return(NORMAL_SHUTDOWN);
}
示例#4
0
int gtmrecv_endupd(void)
{
	pid_t 		savepid;
	int		exit_status;
	pid_t		waitpid_res;

	repl_log(stdout, TRUE, TRUE, "Initiating shut down of Update Process\n");
	recvpool.upd_proc_local->upd_proc_shutdown = SHUTDOWN;
	/* Wait for update process to shut down */
	while((SHUTDOWN == recvpool.upd_proc_local->upd_proc_shutdown)
		&& (0 < (savepid = (pid_t)recvpool.upd_proc_local->upd_proc_pid)) && is_proc_alive(savepid, 0))
	{
		SHORT_SLEEP(GTMRECV_WAIT_FOR_UPD_SHUTDOWN);
		WAITPID(savepid, &exit_status, WNOHANG, waitpid_res); /* Release defunct update process if dead */
	}
	exit_status = recvpool.upd_proc_local->upd_proc_shutdown;
	if (SHUTDOWN == exit_status)
	{
		if (0 == savepid) /* No Update Process */
			exit_status = NORMAL_SHUTDOWN;
		else /* Update Process Crashed */
		{
			repl_log(stderr, TRUE, TRUE, "Update Process exited abnormally, INTEGRITY CHECK might be warranted\n");
			exit_status = ABNORMAL_SHUTDOWN;
		}
	}
	/* Wait for the Update Process to detach */
	if (0 == grab_sem(RECV, UPD_PROC_COUNT_SEM))
	{
		if(0 != (errno = rel_sem(RECV, UPD_PROC_COUNT_SEM)))
			repl_log(stderr, TRUE, TRUE, "Error releasing the Update Process Count semaphore : %s\n", REPL_SEM_ERROR);
		repl_log(stdout, TRUE, TRUE, "Update Process exited\n");
	} else
	{
		repl_log(stderr, TRUE, TRUE, "Error in update proc count semaphore : %s\n", REPL_SEM_ERROR);
		exit_status = ABNORMAL_SHUTDOWN;
	}
	return (exit_status);
}
示例#5
0
int	gtmsource_ipc_cleanup(boolean_t auto_shutdown, int *exit_status)
{
	boolean_t	i_am_the_last_user, attempt_ipc_cleanup;
	int		status, detach_status, remove_status, expected_nattach;
	unix_db_info	*udi;
	struct shmid_ds	shm_buf;

	/* Attempt cleaning up the IPCs */
	attempt_ipc_cleanup = TRUE;

	/* Wait for the Source Server to detach and takeover the semaphore */
	if (!auto_shutdown && 0 > grab_sem(SOURCE, SRC_SERV_COUNT_SEM))
	{
		repl_log(stderr, FALSE, TRUE, "Error taking control of source server count semaphore : %s. Shutdown not complete\n",
														REPL_SEM_ERROR);
		*exit_status = ABNORMAL_SHUTDOWN;
		attempt_ipc_cleanup = FALSE;
	}

	udi = (unix_db_info *)FILE_INFO(jnlpool.jnlpool_dummy_reg);

	if (!auto_shutdown || !gtmsource_srv_count)
		expected_nattach = 1; /* Self, or parent */
	else
		expected_nattach = 0;  /* Source server already detached */

	i_am_the_last_user = (((status = shmctl(udi->shmid, IPC_STAT, &shm_buf)) == 0) && (shm_buf.shm_nattch == expected_nattach));
	if (!i_am_the_last_user)
	{
		if (status < 0)
			repl_log(stderr, FALSE, TRUE, "Error in jnlpool shmctl : %s\n", STRERROR(ERRNO));
		else
			repl_log(stderr, FALSE, TRUE, "Not deleting jnlpool ipcs. %d processes still attached to jnlpool\n",
				 shm_buf.shm_nattch - expected_nattach);
		attempt_ipc_cleanup = FALSE;
		*exit_status = ABNORMAL_SHUTDOWN;
	}

	if (attempt_ipc_cleanup)
	{
		if (INVALID_SHMID != udi->shmid && (auto_shutdown || (detach_status = SHMDT(jnlpool.jnlpool_ctl)) == 0)
				   && (remove_status = shm_rmid(udi->shmid)) == 0)
		{
			jnlpool.jnlpool_ctl = jnlpool_ctl = NULL;
			pool_init = FALSE;
			repl_log(stdout, FALSE, FALSE, "Journal pool shared memory removed\n");
			if (0 == (status = remove_sem_set(SOURCE)))
				repl_log(stdout, FALSE, TRUE, "Journal pool semaphore removed\n");
			else
			{
				repl_log(stderr, FALSE, TRUE, "Error removing jnlpool semaphore : %s\n", STRERROR(status));
				*exit_status = ABNORMAL_SHUTDOWN;
			}
		} else if (INVALID_SHMID != udi->shmid)
		{
			if (!auto_shutdown && detach_status < 0)
				repl_log(stderr, FALSE, FALSE,
						"Error detaching from jnlpool shared memory : %s. Shared memory not removed\n",
						STRERROR(ERRNO));
			else if (remove_status != 0)
			{
				if (!auto_shutdown)
				{
					jnlpool.jnlpool_ctl = NULL; /* Detached successfully */
					jnlpool_ctl = NULL;
					pool_init = FALSE;
				}
				repl_log(stderr, FALSE, TRUE, "Error removing jnlpool shared memory : %s\n", STRERROR(ERRNO));
			}
			*exit_status = ABNORMAL_SHUTDOWN;
		}
	}
	return attempt_ipc_cleanup;
}
示例#6
0
int	gtmrecv_ipc_cleanup(boolean_t auto_shutdown, int *exit_status)
{

	boolean_t	i_am_the_last_user, attempt_ipc_cleanup;
	int		status, detach_status, remove_status, expected_nattach;
	struct shmid_ds	shm_buf;

	/* Attempt cleaning up the IPCs */
	attempt_ipc_cleanup = TRUE;

	/*
	 * Wait for the Receiver Server and Update Process to detach and
	 * takeover the semaphores. Note that the Receiver Server has already
	 * waited for the Update Process to detach. It is done here as a
	 * precaution against Receiver Server crashes.
	 */

	if (!auto_shutdown)
		status = grab_sem(RECV, RECV_SERV_COUNT_SEM);
	else
		status = 0;
	if (0 == status && 0 > (status = grab_sem(RECV, UPD_PROC_COUNT_SEM)))
		rel_sem(RECV, RECV_SERV_COUNT_SEM);
	if (status < 0)
	{
		repl_log(stderr, FALSE, TRUE,
			"Error taking control of Receiver Server/Update Process count semaphore : %s. Shutdown not complete\n",
			REPL_SEM_ERROR);
		*exit_status = ABNORMAL_SHUTDOWN;
		attempt_ipc_cleanup = FALSE;
	}

	/* Now we have locked out all users from the receive pool */

	if (!auto_shutdown || !gtmrecv_srv_count)
		expected_nattach = 1; /* Self, or parent */
	else
		expected_nattach = 0; /* Receiver server already detached */

	i_am_the_last_user = (((status = shmctl(recvpool_shmid, IPC_STAT, &shm_buf)) == 0)
		&& (shm_buf.shm_nattch == expected_nattach));
	if (!i_am_the_last_user)
	{
		if (status < 0)
			repl_log(stderr, FALSE, TRUE, "Error in jnlpool shmctl : %s\n", STRERROR(ERRNO));
		else
			repl_log(stderr, FALSE, TRUE,
				"Not deleting receive pool ipcs. %d processes still attached to receive pool\n",
				shm_buf.shm_nattch - expected_nattach);
		attempt_ipc_cleanup = FALSE;
		*exit_status = ABNORMAL_SHUTDOWN;
	}

	if (attempt_ipc_cleanup)
	{
		if (INVALID_SHMID != recvpool_shmid && (auto_shutdown || (detach_status = SHMDT(recvpool.recvpool_ctl)) == 0)
				       && (remove_status = shm_rmid(recvpool_shmid)) == 0)
		{
			recvpool.recvpool_ctl = NULL;
			repl_log(stdout, FALSE, FALSE, "Receive pool shared memory removed\n");
			if (0 == (status = remove_sem_set(RECV)))
				repl_log(stdout, FALSE, TRUE, "Receive pool semaphore removed\n");
			else
			{
				repl_log(stderr, FALSE, TRUE, "Error removing receive pool semaphore : %s\n", STRERROR(status));
				*exit_status = ABNORMAL_SHUTDOWN;
			}
		} else if (INVALID_SHMID != recvpool_shmid)
		{
			if (!auto_shutdown && detach_status < 0)
				repl_log(stderr, FALSE, FALSE,
					"Error detaching from receive pool shared memory : %s. Shared memory not removed\n",
					STRERROR(ERRNO));
			else if (remove_status != 0)
			{
				if (!auto_shutdown)
					recvpool.recvpool_ctl = NULL; /* Detached successfully */
				repl_log(stderr, FALSE, TRUE, "Error removing receive pool shared memory : %s\n", STRERROR(ERRNO));
			}
			*exit_status = ABNORMAL_SHUTDOWN;
		}
	}

	return attempt_ipc_cleanup;
}
示例#7
0
int gtmrecv_shutdown(boolean_t auto_shutdown, int exit_status)
{
	uint4           savepid;
	boolean_t       shut_upd_too = FALSE;
	int             status;
	unix_db_info	*udi;

	error_def(ERR_RECVPOOLSETUP);
	error_def(ERR_TEXT);

	repl_log(stdout, TRUE, TRUE, "Initiating shut down\n");
	call_on_signal = NULL;		/* So we don't reenter on error */
	/* assert that auto shutdown should be invoked only if the current process is a receiver server */
	assert(!auto_shutdown || gtmrecv_srv_count);
	if (auto_shutdown)
	{	/* grab the ftok semaphore and recvpool access control lock IN THAT ORDER (to avoid deadlocks) */
		repl_inst_ftok_sem_lock();
		status = grab_sem(RECV, RECV_POOL_ACCESS_SEM);
		if (0 > status)
		{
			repl_log(stderr, TRUE, TRUE,
				"Error grabbing receive pool control semaphore : %s. Shutdown not complete\n", REPL_SEM_ERROR);
			return (ABNORMAL_SHUTDOWN);
		}
	} else
	{	/* ftok semaphore and recvpool access semaphore should already be held from the previous call to "recvpool_init" */
		DEBUG_ONLY(udi = (unix_db_info *)FILE_INFO(recvpool.recvpool_dummy_reg);)
		assert(udi->grabbed_ftok_sem);
		assert(holds_sem[RECV][RECV_POOL_ACCESS_SEM]);
		/* We do not want to hold the options semaphore to avoid deadlocks with receiver server startup (C9F12-002766) */
		assert(!holds_sem[RECV][RECV_SERV_OPTIONS_SEM]);
		recvpool.gtmrecv_local->shutdown = SHUTDOWN;
		/* Wait for receiver server to die. But release ftok semaphore and recvpool access control semaphore before
		 * waiting as the concurrently running receiver server might need these (e.g. if it is about to call the
		 * function "repl_inst_was_rootprimary").
		 */
		if (0 != rel_sem(RECV, RECV_POOL_ACCESS_SEM))
			gtm_putmsg(VARLSTCNT(7) ERR_TEXT, 2, RTS_ERROR_LITERAL("Error in receiver server shutdown rel_sem"),
				REPL_SEM_ERRNO);
		repl_inst_ftok_sem_release();
		/* Wait for receiver server to shut down */
		while((SHUTDOWN == recvpool.gtmrecv_local->shutdown)
				&& (0 < (savepid = recvpool.gtmrecv_local->recv_serv_pid))
				&& is_proc_alive(savepid, 0))
			SHORT_SLEEP(GTMRECV_WAIT_FOR_SHUTDOWN);
		/* (Re)Grab the ftok semaphore and recvpool access control semaphore IN THAT ORDER (to avoid deadlocks) */
		repl_inst_ftok_sem_lock();
		status = grab_sem(RECV, RECV_POOL_ACCESS_SEM);
		if (0 > status)
		{
			repl_log(stderr, TRUE, TRUE,
				"Error regrabbing receive pool control semaphore : %s. Shutdown not complete\n", REPL_SEM_ERROR);
			return (ABNORMAL_SHUTDOWN);
		}
		exit_status = recvpool.gtmrecv_local->shutdown;
		if (SHUTDOWN == exit_status)
		{
			if (0 == savepid) /* No Receiver Process */
				exit_status = NORMAL_SHUTDOWN;
			else /* Receiver Server Crashed */
			{
				repl_log(stderr, FALSE, TRUE, "Receiver Server exited abnormally\n");
				exit_status = ABNORMAL_SHUTDOWN;
				shut_upd_too = TRUE;
			}
		}
	}