File: gtmsource_mode_change.c

package info (click to toggle)
fis-gtm 7.1-006-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 32,908 kB
  • sloc: ansic: 344,906; asm: 5,184; csh: 4,859; sh: 2,000; awk: 294; makefile: 73; sed: 13
file content (132 lines) | stat: -rwxr-xr-x 5,909 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/****************************************************************
 *								*
 * Copyright (c) 2006-2017 Fidelity National Information	*
 * Services, Inc. and/or its subsidiaries. All rights reserved.	*
 *								*
 *	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_time.h"
#include "gtm_fcntl.h"
#include "gtm_unistd.h"
#include "gtm_inet.h"
#include "gtm_string.h"
#include "gtmio.h"
#include "repl_sp.h"
#include <errno.h>
#include "gdsroot.h"
#include "gdsblk.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "repl_msg.h"
#include "gtmsource.h"
#include "repl_dbg.h"
#include "gtm_stdio.h"
#include "repl_shutdcode.h"
#include "repl_sem.h"
#include "repl_log.h"
#include "repl_instance.h"

GBLREF	jnlpool_addrs_ptr_t	jnlpool;
GBLREF	gtmsource_options_t	gtmsource_options;
GBLREF	boolean_t		holds_sem[NUM_SEM_SETS][NUM_SRC_SEMS];
error_def(ERR_REPLLOGOPN);

int gtmsource_mode_change(int to_mode)
{
	uint4		savepid;
	int		exit_status;
	int		status, detach_status, remove_status;
	int 	        log_fd = 0, close_status = 0;
	char*           err_code;
	int	        save_errno;
	sgmnt_addrs	*repl_csa;

	assert(holds_sem[SOURCE][JNL_POOL_ACCESS_SEM]);
	repl_log(stdout, TRUE, TRUE, "Initiating %s operation on source server pid [%d] for secondary instance [%s]\n",
		(GTMSOURCE_MODE_ACTIVE_REQUESTED == to_mode) ? "ACTIVATE" : "DEACTIVATE",
		jnlpool->gtmsource_local->gtmsource_pid, jnlpool->gtmsource_local->secondary_instname);
	if ((jnlpool->gtmsource_local->mode == GTMSOURCE_MODE_ACTIVE_REQUESTED)
		|| (jnlpool->gtmsource_local->mode == GTMSOURCE_MODE_PASSIVE_REQUESTED))
	{
		repl_log(stderr, FALSE, TRUE, "Source Server %s already requested, not changing mode\n",
				(to_mode == GTMSOURCE_MODE_ACTIVE_REQUESTED) ? "ACTIVATE" : "DEACTIVATE");
		return (ABNORMAL_SHUTDOWN);
	}
	if (((GTMSOURCE_MODE_ACTIVE == jnlpool->gtmsource_local->mode) && (GTMSOURCE_MODE_ACTIVE_REQUESTED == to_mode))
		|| ((GTMSOURCE_MODE_PASSIVE == jnlpool->gtmsource_local->mode) && (GTMSOURCE_MODE_PASSIVE_REQUESTED == to_mode)))
	{
		repl_log(stderr, FALSE, TRUE, "Source Server already %s, not changing mode\n",
				(to_mode == GTMSOURCE_MODE_ACTIVE_REQUESTED) ? "ACTIVE" : "PASSIVE");
		return (ABNORMAL_SHUTDOWN);
	}
	assert(ROOTPRIMARY_UNSPECIFIED != gtmsource_options.rootprimary);
	/*check if the new log file is writable*/
	if ('\0' != gtmsource_options.log_file[0] && 0 != STRCMP(jnlpool->gtmsource_local->log_file, gtmsource_options.log_file))
	{
		OPENFILE3_CLOEXEC(gtmsource_options.log_file,
			      O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, log_fd);
		if (log_fd < 0)
		{
			save_errno = ERRNO;
			err_code = STRERROR(save_errno);
			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_REPLLOGOPN, 6,
					   LEN_AND_STR(gtmsource_options.log_file),
					   LEN_AND_STR(err_code),
					   LEN_AND_STR(NULL_DEVICE));
			return (ABNORMAL_SHUTDOWN);
		}
		CLOSEFILE_IF_OPEN(log_fd, close_status);
		assert(close_status==0);
	}
	if ((GTMSOURCE_MODE_ACTIVE_REQUESTED == to_mode)
			&& (ROOTPRIMARY_SPECIFIED == gtmsource_options.rootprimary) && jnlpool->jnlpool_ctl->upd_disabled)
	{	/* ACTIVATE is specified with ROOTPRIMARY on a journal pool that was created with PROPAGATEPRIMARY. This is a
		 * case of transition from propagating primary to root primary. Enable updates in this journal pool and append
		 * a histinfo record to the replication instance file. The function "gtmsource_rootprimary_init" does just that.
		 */
		gtmsource_rootprimary_init(jnlpool->jnlpool_ctl->jnl_seqno);
	}
	DEBUG_ONLY(repl_csa = &FILE_INFO(jnlpool->jnlpool_dummy_reg)->s_addrs;)
	assert(!repl_csa->hold_onto_crit);	/* so it is ok to invoke "grab_lock" and "rel_lock" unconditionally */
	grab_lock(jnlpool->jnlpool_dummy_reg, TRUE, ASSERT_NO_ONLINE_ROLLBACK);
	/* Any ACTIVATE/DEACTIVATE versus ROOTPRIMARY/PROPAGATE incompatibilities have already been checked in the
	 * function "jnlpool_init" so go ahead and document the impending activation/deactivation and return.
	 * This flag will be eventually detected by the concurrently running source server which will then change mode.
	 */
	if (GTMSOURCE_MODE_ACTIVE_REQUESTED == to_mode)
	{
		jnlpool->gtmsource_local->secondary_port = gtmsource_options.secondary_port;
		STRCPY(jnlpool->gtmsource_local->secondary_host, gtmsource_options.secondary_host);
		jnlpool->gtmsource_local->secondary_port = gtmsource_options.secondary_port;
		memcpy(&jnlpool->gtmsource_local->connect_parms[0], &gtmsource_options.connect_parms[0],
				SIZEOF(gtmsource_options.connect_parms));
	}
	if ('\0' != gtmsource_options.log_file[0] && 0 != STRCMP(jnlpool->gtmsource_local->log_file, gtmsource_options.log_file))
	{
		repl_log(stdout, FALSE, TRUE, "Signaling change in log file from %s to %s\n",
				jnlpool->gtmsource_local->log_file, gtmsource_options.log_file);
		STRCPY(jnlpool->gtmsource_local->log_file, gtmsource_options.log_file);
		jnlpool->gtmsource_local->changelog |= REPLIC_CHANGE_LOGFILE;
	}
	if (0 != gtmsource_options.src_log_interval && jnlpool->gtmsource_local->log_interval != gtmsource_options.src_log_interval)
	{
		repl_log(stdout, FALSE, TRUE, "Signaling change in log interval from %u to %u\n",
				jnlpool->gtmsource_local->log_interval, gtmsource_options.src_log_interval);
		jnlpool->gtmsource_local->log_interval = gtmsource_options.src_log_interval;
		jnlpool->gtmsource_local->changelog |= REPLIC_CHANGE_LOGINTERVAL;
	}
	jnlpool->gtmsource_local->mode = to_mode;
	rel_lock(jnlpool->jnlpool_dummy_reg);
	REPL_DPRINT1("Change mode signalled\n");
	return (NORMAL_SHUTDOWN);
}