File: mu_rndwn_rlnkctl.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 (157 lines) | stat: -rw-r--r-- 6,196 bytes parent folder | download | duplicates (2)
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
/****************************************************************
 *								*
 * Copyright (c) 2014-2024 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"

#ifdef AUTORELINK_SUPPORTED
#include "gtm_string.h"
#include "gtm_stat.h"
#include "gtm_stdlib.h"
#include "gtm_limits.h"

#include "relinkctl.h"
#include "util.h"
#include <rtnhdr.h>		/* needed for zroutines.h */
#include "zroutines.h"
#include "cli.h"
#include "cliif.h"
#include "cli_parse.h"
#include "eintr_wrappers.h"
#include "gtmmsg.h"
#endif
#include "mu_rndwn_rlnkctl.h"	/* for mupip_rctldump prototype */
#include "mupip_rundown.h"
#include "mupip_exit.h"

GBLDEF	boolean_t	in_relinkctl;
GBLREF	boolean_t	in_rundown;

#ifdef AUTORELINK_SUPPORTED
error_def(ERR_FILEPARSE);
error_def(ERR_MUPCLIERR);
error_def(ERR_RLNKCTLRNDWNSUC);
#endif

/* Implements MUPIP RUNDOWN -RELINKCTL */
void mu_rndwn_rlnkctl(void)
{
#	ifdef AUTORELINK_SUPPORTED
	open_relinkctl_sgm	*linkctl;
	relinkshm_hdr_t		*shm_hdr;
	relinkrec_t		*linkrec;
	relinkctl_data		*hdr;
	rtnobjshm_hdr_t		*rtnobj_shm_hdr;
	char			objdir[GTM_PATH_MAX];
	int			i, j, recnum, n_records, shmid, shm_stat, save_errno, objcnt, stat_res, params_cnt;
	unsigned short		param_len;
	mstr			dir;
	zro_ent			*op;
	boolean_t		region, file, relink_dir, file_or_region, is_what;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	TREF(is_mu_rndwn_rlnkctl) = TRUE;	/* relinkctl_open and relinkctl_rundown check this flag to act differently.
						 * No need to have condition handler to reset this in case of error because
						 * this is invoked from MUPIP RUNDOWN -RELINKCTL which is the only action
						 * that the calling process will do in its lifetime.
						 */
	file = (CLI_PRESENT == cli_present("FILE"));
	region = (CLI_PRESENT == cli_present("REGION")) || (CLI_PRESENT == cli_present("R"));
	relink_dir = FALSE;
	file_or_region = (file || region);
	params_cnt = TREF(parms_cnt);
	in_relinkctl = TRUE;
	/* relink_dir is set to true when two parameters are present,
	 * or when one parameter is passed to the relinkctl function only.
	 * If a region or file qualifier is present, and there is only one parameter, used it as region or file.
	 */
	if (2 == params_cnt || (1 == params_cnt && !file_or_region))
    	relink_dir = TRUE;
	if (!file_or_region && (1 < params_cnt))
	{
		util_out_print("%GTM-E-CLIERR, Too many parameters", TRUE);
		mupip_exit(ERR_MUPCLIERR);
	}
	if (relink_dir)
	{
		param_len = SIZEOF(objdir) - 1;
		is_what = (TREF(parms_cnt) == 2 && !in_rundown);
		if (!cli_get_str(is_what ? "WHAT": "R_OR_F_NAME", objdir, &param_len))
			RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(1) ERR_MUPCLIERR);
		objdir[param_len] = '\0';
		dir.addr = objdir;
		dir.len = param_len;
		linkctl = relinkctl_attach(&dir, NULL, SIZEOF(objdir));
		assert(dir.len <= SIZEOF(objdir) - 1);
		assert(('\0' == dir.addr[dir.len]) || (0 == dir.len));
		assert(linkctl == TREF(open_relinkctl_list));
		assert((NULL == linkctl) || (NULL == linkctl->next));
		if (NULL == linkctl)
		{
			if (0 == dir.len)
			{	/* If relinkctl_attach() did not find the object directory corresponding to the user's argument,
				 * dir.len is set to 0; in that case we want to print an error containing the argument, and so the
				 * proper length needs to be restored.
				 */
				dir.len = param_len;
				RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(5) ERR_FILEPARSE, 2, RTS_ERROR_MSTR(&dir), errno);
			} else
				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_RLNKCTLRNDWNSUC, 2, RTS_ERROR_MSTR(&dir));
		} else
			relinkctl_rundown(TRUE, FALSE);	/* Runs down the relinkctl file opened above. */
	} else
	{	/* Unlike other callers of zro_init(), MUPIP RUNDOWN -RELINKCTL does not want it to do relinkctl_attach() on all
		 * relinkctl files at once because we leave the attach logic holding the linkctl lock, which might potentially cause
		 * a deadlock if multiple processes are run concurrently with different $gtmroutines. So, zro_init() / zro_load()
		 * set the count field of each autorelink-enabled object directory to a negative number based on the
		 * TREF(is_mu_rndwn_rlnkctl) global, and we look at the count to decide whether to attach to an individual segment.
		 */
		zro_init();
		objcnt = (TREF(zro_root))->count;
		assert(0 < objcnt);
		for (op = TREF(zro_root) + 1; (0 < objcnt--);)
		{	/* Go through each object directory in our array to run down its relinkctl file. */
			assert((ZRO_TYPE_OBJECT == op->type) || (ZRO_TYPE_OBJLIB == op->type));
			if (ZRO_TYPE_OBJLIB == op->type)
				continue;			/* We only deal with object directories in this loop */
			/* Currently the count field of object directory entries is either unused (with the value of 0) or marked as
			 * autorelink-enabled (only in case of MUPIP RUNDOWN -RELINKCTL). Assert that.
			 */
			assert(0 >= op->count);
			if (0 > op->count)
			{	/* Third parameter is 0 because the object directories are stored in fully resolved format in the
				 * gtmroutines object, so there is no need to update the string.
				 */
				linkctl = relinkctl_attach(&op->str, NULL, 0);
				assert(linkctl == TREF(open_relinkctl_list));
				assert((NULL == linkctl) || (NULL == linkctl->next));
				if (NULL == linkctl)
				{	/* We do not do a check of whether the object directory exists, unlike with an argument,
					 * because zro_init() would have errored out on a non-existent path.
					 */
					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_RLNKCTLRNDWNSUC, 2,
						       RTS_ERROR_MSTR(&op->str));
				} else
					relinkctl_rundown(TRUE, FALSE);	/* Runs down the relinkctl file opened above. */
			}
			/* Bump past source entries to next object entry */
			op++;
			assert(ZRO_TYPE_COUNT == op->type);
			op += op->count;
			op++;
		}
	}
	if (in_relinkctl && !in_rundown)
		mupip_rundown();
	TREF(is_mu_rndwn_rlnkctl) = FALSE;
#	endif	/* AUTORELINK_SUPPORTED */
}