File: desired_db_format_set.c

package info (click to toggle)
fis-gtm 6.3-007-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 36,284 kB
  • sloc: ansic: 328,861; asm: 5,182; csh: 5,102; sh: 1,918; awk: 291; makefile: 69; sed: 13
file content (195 lines) | stat: -rw-r--r-- 7,057 bytes parent folder | download
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/****************************************************************
 *								*
 * Copyright (c) 2005-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_string.h"

#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "gdscc.h"
#include "gdskill.h"
#include "jnl.h"
#include "iosp.h"		/* for SS_NORMAL */
#include "util.h"

/* Prototypes */
#include "gtmmsg.h"		/* for gtm_putmsg prototype */
#include "desired_db_format_set.h"
#include "send_msg.h"		/* for send_msg */
#include "wcs_phase2_commit_wait.h"

#define	WCS_PHASE2_COMMIT_WAIT_LIT	"wcb_phase2_commit_wait"

LITREF	char			*gtm_dbversion_table[];

GBLREF	inctn_opcode_t		inctn_opcode;
GBLREF	jnl_gbls_t		jgbl;
GBLREF	uint4			process_id;
GBLREF	inctn_detail_t		inctn_detail;			/* holds detail to fill in to inctn jnl record */

error_def(ERR_ASYNCIONOV4);
error_def(ERR_COMMITWAITSTUCK);
error_def(ERR_CRYPTNOV4);
error_def(ERR_DBDSRDFMTCHNG);
error_def(ERR_MMNODYNDWNGRD);
error_def(ERR_MUDWNGRDTN);
error_def(ERR_MUNOACTION);
error_def(ERR_SNAPSHOTNOV4);
error_def(ERR_WCBLOCKED);

/* input parameter "command_name" is a string that is either "MUPIP REORG UPGRADE/DOWNGRADE" or "MUPIP SET VERSION" */
int4	desired_db_format_set(gd_region *reg, enum db_ver new_db_format, char *command_name)
{
	boolean_t		was_crit;
	char			*db_fmt_str;
	char			*wcblocked_ptr;
	int4			status;
	uint4			jnl_status;
	inctn_opcode_t		save_inctn_opcode;
	sgmnt_addrs		*csa;
	sgmnt_data_ptr_t	csd;
	trans_num		curr_tn;
	jnl_private_control	*jpc;
	jnl_buffer_ptr_t	jbp;

	assert(reg->open);
	csa = &FILE_INFO(reg)->s_addrs;
	csd = csa->hdr;
	/* We do not allow databases to be encrypted if the version is V4. */
	if (USES_ENCRYPTION(csd->is_encrypted) && (GDSV4 == new_db_format))
	{
		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_CRYPTNOV4, 2, DB_LEN_STR(reg));
		return ERR_CRYPTNOV4;
	}
	/* We do not allow databases in ASYNCIO mode if the block format is V4 */
	if (csd->asyncio && (GDSV4 == new_db_format))
	{
		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_ASYNCIONOV4, 6, DB_LEN_STR(reg),
			LEN_AND_LIT("ASYNCIO enabled"), LEN_AND_LIT("downgrade to V4"));
		return ERR_ASYNCIONOV4;
	}
	/* We don't allow databases to be downgraded when snapshots are in progress */
	if (SNAPSHOTS_IN_PROG(csa->nl) && (GDSV4 == new_db_format))
	{
		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(5) ERR_SNAPSHOTNOV4,
			3, csa->nl->num_snapshots_in_effect, DB_LEN_STR(reg));
		return ERR_SNAPSHOTNOV4;
	}
	was_crit = csa->now_crit;
	if (FALSE == was_crit)
		grab_crit(reg);
	/* if MM and desired_db_format is not V5, gvcst_init would have issued MMNODYNDWNGRD error. assert that. */
	assert((dba_bg == csd->acc_meth) || ((dba_mm == csd->acc_meth) && (GDSV6 == csd->desired_db_format)));
	if (csd->desired_db_format == new_db_format)
	{	/* no change in db_format. fix max_tn_warn if necessary and return right away. */
		status = ERR_MUNOACTION;
		assert(csd->trans_hist.curr_tn <= csd->max_tn);
		if ((GDSV4 == new_db_format) && (MAX_TN_V4 < csd->max_tn))
		{	/* reset max_tn to MAX_TN_V4 only if V4 format and the new value will still be greater than curr_tn */
			assertpro(MAX_TN_V4 >= csd->trans_hist.curr_tn);
			csd->max_tn = MAX_TN_V4;
			/* since max_tn changed above, max_tn_warn might also need to correspondingly change */
			SET_TN_WARN(csd, csd->max_tn_warn);
		}
		if (FALSE == was_crit)
			rel_crit(reg);
		return status;
	}
	if (dba_mm == csd->acc_meth)
	{
		status = ERR_MMNODYNDWNGRD;
		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) status, 2, REG_LEN_STR(reg));
		if (FALSE == was_crit)
			rel_crit(reg);
		return status;
	}
	/* check if curr_tn is too high to downgrade */
	curr_tn = csd->trans_hist.curr_tn;
	if ((GDSV4 == new_db_format) && (MAX_TN_V4 <= curr_tn))
	{
		status = ERR_MUDWNGRDTN;
		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(5) status, 3, &curr_tn, DB_LEN_STR(reg));
		if (FALSE == was_crit)
			rel_crit(reg);
		return status;
	}
	/* Wait for concurrent phase2 commits to complete before switching the desired db format */
	if (csa->nl->wcs_phase2_commit_pidcnt && !wcs_phase2_commit_wait(csa, NULL))
	{	/* Set wc_blocked so next process to get crit will trigger cache-recovery */
		SET_TRACEABLE_VAR(csa->nl->wc_blocked, TRUE);
		wcblocked_ptr = WCS_PHASE2_COMMIT_WAIT_LIT;
		send_msg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_WCBLOCKED, 6, LEN_AND_STR(wcblocked_ptr),
			process_id, &csd->trans_hist.curr_tn, DB_LEN_STR(reg));
		status = ERR_COMMITWAITSTUCK;
		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(7) status, 5, process_id,
				1, csa->nl->wcs_phase2_commit_pidcnt, DB_LEN_STR(reg));
		if (FALSE == was_crit)
			rel_crit(reg);
		return status;
	}
	if (JNL_ENABLED(csd))
	{
		SET_GBL_JREC_TIME;	/* needed for jnl_ensure_open, jnl_write_pini and jnl_write_aimg_rec */
		jpc = csa->jnl;
		jbp = jpc->jnl_buff;
		/* Before writing to jnlfile, adjust jgbl.gbl_jrec_time if needed to maintain time order of jnl records.
		 * This needs to be done BEFORE the jnl_ensure_open as that could write journal records
		 * (if it decides to switch to a new journal file)
		 */
		ADJUST_GBL_JREC_TIME(jgbl, jbp);
		jnl_status = jnl_ensure_open(reg, csa);
		if (0 == jnl_status)
		{
			save_inctn_opcode = inctn_opcode;
			inctn_opcode = inctn_db_format_change;
			inctn_detail.blks2upgrd_struct.blks_to_upgrd_delta = csd->blks_to_upgrd;
			if (0 == jpc->pini_addr)
				jnl_write_pini(csa);
			jnl_write_inctn_rec(csa);
			inctn_opcode = save_inctn_opcode;
		} else
			gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(csd), DB_LEN_STR(reg));
	}
	csd->desired_db_format = new_db_format;
	csd->fully_upgraded = FALSE;
	csd->desired_db_format_tn = curr_tn;
	switch (new_db_format)
	{
		case GDSV4:
			csd->max_tn = MAX_TN_V4;
			break;
		case GDSV6:
			csd->max_tn = MAX_TN_V6;
			break;
		default:
			assertpro((GDSV4 == new_db_format) || (GDSV6 == new_db_format));
	}
	SET_TN_WARN(csd, csd->max_tn_warn);	/* if max_tn changed above, max_tn_warn also needs a corresponding change */
	assert(curr_tn < csd->max_tn);	/* ensure CHECK_TN macro below will not issue TNTOOLARGE rts_error */
	CHECK_TN(csa, csd, curr_tn);	/* can issue rts_error TNTOOLARGE */
	/* increment csd->trans_hist.curr_tn */
	assert(csd->trans_hist.early_tn == csd->trans_hist.curr_tn);
	csd->trans_hist.early_tn = csd->trans_hist.curr_tn + 1;
	INCREMENT_CURR_TN(csd);
	if (FALSE == was_crit)
		rel_crit(reg);
	status = SS_NORMAL;
	send_msg_csa(CSA_ARG(csa) VARLSTCNT(11) ERR_DBDSRDFMTCHNG, 9, DB_LEN_STR(reg),
		LEN_AND_STR(gtm_dbversion_table[new_db_format]), LEN_AND_STR(command_name), process_id, process_id, &curr_tn);
	return status;
}