File: gtcm_shmclean.c

package info (click to toggle)
fis-gtm 6.3-007-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, sid
  • 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 (204 lines) | stat: -rwxr-xr-x 5,595 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
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
196
197
198
199
200
201
202
203
204
/****************************************************************
 *								*
 * Copyright (c) 2001-2015 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_string.h"
#include "gtm_stdio.h"
#include "gtm_stdlib.h"		/* for EXIT() */
#include "gtm_unistd.h"		/* for getopt() and read() */
#include "gtm_fcntl.h"
#include "gtm_ipc.h"

#include <sys/types.h>
#include <sys/shm.h>
#include <sys/msg.h>		/* for msgget() and msgctl() prototype */
#include <sys/sem.h>		/* for semget() and semctl() prototype */

#include "iosp.h"
#include "rc_cpt.h"
#include "gdsroot.h"
#include "gdsblk.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "trans_log_name.h"
#include "cli.h"
#include "gtm_threadgbl_init.h"

/* This executable does not have any command tables so initialize command array to NULL. The reason why cmd_ary is needed is
 * because trans_log_name (invoked by this module) in turn pulls in gtm_malloc/gtm_free and in turn a lot of the database
 * runtime logic which in turn (due to triggers) pulls in the compiler as well (op_zcompile etc. require cmd_ary).
 */
GBLDEF	CLI_ENTRY	*cmd_ary = NULL;

int	quiet = 0;

void	clean_mem(char *name);
void	database_clean(char *path);

void	clean_mem(char *name)
{
	mstr	path1, path2;
	int	semid;
	key_t	msg_key;
	char	buff[512];
	int	q_id, s_id, m_id;

	path1.len = STRLEN(name);
	path1.addr = name;
	if (SS_NORMAL != TRANS_LOG_NAME(&path1, &path2, buff, SIZEOF(buff), do_sendmsg_on_log2long))
		FPRINTF(stderr, "Error translating path: %s\n", name);
	else
	{
		path2.addr[path2.len] = '\0';
		if ((msg_key = FTOK(path2.addr, GTM_ID)) == -1)
			perror("shmclean: Error with ftok");
		else
		{
			if ((q_id = msgget(msg_key, 0)) != -1)
			{
				if (!quiet)
					PRINTF("shmclean: removing msg queue %d\n", q_id);
				if (msgctl(q_id, IPC_RMID, 0) == -1)
				{
					FPRINTF(stderr,"shmclean: error removing msg queue %d\n", q_id);
					perror("shmclean");
				}
			}
			if ((semid = semget(msg_key, 2, RWDALL)) != -1)
			{
				if (!quiet)
					PRINTF("shmclean: removing semid %d\n", semid);
				if (semctl(semid, 0, IPC_RMID, 0) == -1)
				{
					FPRINTF(stderr,"shmclean: error removing semid %d\n", semid);
					perror("shmclean");
				}
			} else
				semid = INVALID_SEMID;
			if ((m_id = shmget(msg_key, 10, RWDALL)) != -1)
			{
				if (!quiet)
					PRINTF("shmclean: removing shmid %d\n", m_id);
				if (shmctl(m_id, IPC_RMID, 0) == -1)
				{
					FPRINTF(stderr,"shmclean: error removing shmid %d\n", m_id);
					perror("shmclean");
				}
			} else
				m_id = INVALID_SEMID;
		}
	}
}

void	database_clean(char *path)
{
	key_t	d_key;
	int	shmid;
	int	semid;

	if ((d_key = FTOK(path, GTM_ID)) == -1)
	{
		perror("Error with database ftok");
		PRINTF("File: %s\n", path);
		return;
	}
	if ((shmid = shmget(d_key, 10, RWALL)) != -1)
	{
		if (!quiet)
			PRINTF("shmclean: removing shmid %d\n", shmid);
		if (shmctl(shmid, IPC_RMID, 0) == -1)
		{
			FPRINTF(stderr,"shmclean: error removing shmid %d\n", shmid);
			perror("shmclean");
		}
	} else
		shmid = INVALID_SHMID;
	if ((semid = semget(d_key, 2, 0600)) != -1)
	{
		if (!quiet)
			PRINTF("shmclean: removing semid %d\n", semid);
		if (semctl(semid, 0, IPC_RMID, 0) == -1)
		{
			FPRINTF(stderr,"shmclean: error removing semid %d\n", semid);
			perror("shmclean");
		}
	} else
		semid = INVALID_SEMID;
}

/* On OSF/1 (Digital Unix), pointers are 64 bits wide; the only exception to this is C programs for which one may
 * specify compiler and link editor options in order to use (and allocate) 32-bit pointers.  However, since C is
 * the only exception and, in particular because the operating system does not support such an exception, the argv
 * array passed to the main program is an array of 64-bit pointers.  Thus the C program needs to declare argv[]
 * as an array of 64-bit pointers and needs to do the same for any pointer it sets to an element of argv[].
 */
int main(int argc, char_ptr_t argv[])
{
	key_t	d_msg_key, key, s_msg_key;
	int	q_id, s_id, m_id;
	mstr	dpath1, dpath2, fpath1, fpath2;
	int	server_sem, daemon_sem;
	char	buff[512];
	int	server = 0;
	int	daemon = 0;
	char	resp;
	int	opt, err;
	DCL_THREADGBL_ACCESS;

	GTM_THREADGBL_INIT;
	err = 0;
	while ((opt = getopt(argc, argv, "qds")) != -1)
	{
		switch (opt)
		{
			case 'q':
				quiet = 1;
				break;
			case 'd':
				daemon = 1;
				break;
			case 's':
				server = 1;
				break;
			/* mupip rundown should be used for databases. */
			/*
			 *   case 'D':
			 *    database_clean(optarg);
			 *    break;
			 */
		}
	}
	if (quiet != 1)
	{
		FPRINTF(stderr,"If this program is used to remove shared memory from running\n");
		FPRINTF(stderr,"processes, it will cause the program to fail. Please make\n");
		FPRINTF(stderr,"sure all GTM processes have been shut down cleanly before running\n");
		FPRINTF(stderr,"this program.\n\n");
		FPRINTF(stderr,"Do you want to contine? (y or n)  ");

		if (1 != read(0, &resp, 1))  /*unable to read response*/
		{
			FPRINTF(stderr,"Error while reading response from user. Exiting\n");
			EXIT(0);
		}
		if ((resp != 'y') && (resp != 'Y'))
		{
			EXIT(0);
		}
	}
	if (server == 1 && daemon == 0)
		clean_mem(RC_CPT_PATH);
	return 0;
}