File: mutex_sock_init.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 (185 lines) | stat: -rw-r--r-- 7,505 bytes parent folder | download | duplicates (3)
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
/****************************************************************
 *								*
 * Copyright (c) 2001-2021 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"

#ifndef MUTEX_MSEM_WAKE
#include "gtm_ipc.h"
#include "gtm_socket.h"
#include "gtm_un.h"
#include <sys/time.h>
#include <errno.h>
#include "gtm_fcntl.h"
#include "gtm_unistd.h"
#include "gtm_stdio.h"
#include "gtm_stat.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 "mutex.h"
#include "io.h"
#include "secshr_client.h"
#include "gtmsecshr.h"
#include "iosp.h"
#include "gtm_logicals.h"
#include "eintr_wrappers.h"
#include "send_msg.h"
#include "trans_log_name.h"

GBLREF uint4			process_id;
GBLREF int			mutex_sock_fd;
GBLREF struct sockaddr_un	mutex_sock_address;
GBLREF struct sockaddr_un	mutex_wake_this_proc;
GBLREF int			mutex_wake_this_proc_len;
GBLREF int			mutex_wake_this_proc_prefix_len;
GBLREF fd_set			mutex_wait_on_descs;

static readonly char hex_table[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

error_def(ERR_MUTEXERR);
error_def(ERR_MUTEXRSRCCLNUP);
error_def(ERR_TEXT);

void mutex_sock_init(void)
{
	mstr		mutex_sock_dir_lognam, mutex_sock_dir_transnam;
	int		mutex_sock_path_len;
	uint4		mutex_sock_trans_status;
	char		mutex_sock_path[MAX_TRANS_NAME_LEN];
	int		mutex_sock_len, save_errno;
	struct stat	mutex_sock_stat_buf;
	int		status;
	unsigned char   pid_str[2 * SIZEOF(pid_t) + 1];
	DEBUG_ONLY(boolean_t existed;)
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	if (FD_INVALID != mutex_sock_fd) /* Initialization done already */
		return;
	/* Create the socket used for sending and receiving mutex wake mesgs */
	if (FD_INVALID == (mutex_sock_fd = socket(AF_UNIX, SOCK_DGRAM, 0)))
		RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(7) ERR_MUTEXERR, 0, ERR_TEXT, 2,
			RTS_ERROR_TEXT("Error with mutex socket create"), errno);
	memset((char *)&mutex_sock_address, 0, SIZEOF(mutex_sock_address));
	/* Get the socket path */
	mutex_sock_dir_lognam.len = SIZEOF(MUTEX_SOCK_DIR) - 1;
	mutex_sock_dir_lognam.addr = MUTEX_SOCK_DIR;
	mutex_sock_trans_status = TRANS_LOG_NAME(&mutex_sock_dir_lognam, &mutex_sock_dir_transnam,
						 mutex_sock_path, SIZEOF(mutex_sock_path), do_sendmsg_on_log2long);
	if (mutex_sock_trans_status != SS_NORMAL)
	{
		strcpy(mutex_sock_path, DEFAULT_MUTEX_SOCK_DIR);
		mutex_sock_path_len = SIZEOF(DEFAULT_MUTEX_SOCK_DIR) - 1;
	} else
		mutex_sock_path_len = mutex_sock_dir_transnam.len;
	/* If the path doesn't already end with a '/' pad a '/' */
	if (mutex_sock_path[mutex_sock_path_len - 1] != '/')
	{
		mutex_sock_path[mutex_sock_path_len++] = '/';
		mutex_sock_path[mutex_sock_path_len] = '\0';
	}
	if ((mutex_sock_path_len + MAX_MUTEX_SOCKFILE_NAME_LEN) > SIZEOF(mutex_sock_address.sun_path))
		RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(6) ERR_MUTEXERR, 0, ERR_TEXT, 2,
			RTS_ERROR_TEXT("Mutex socket path too long"));
	strcpy(mutex_sock_path + mutex_sock_path_len, MUTEX_SOCK_FILE_PREFIX);
	mutex_sock_path_len += (SIZEOF(MUTEX_SOCK_FILE_PREFIX) - 1);
	mutex_wake_this_proc_prefix_len = mutex_sock_path_len;
	/* Extend mutex_sock_path with pid */
	strcpy(mutex_sock_path + mutex_sock_path_len, (char *)pid2ascx(pid_str, process_id));
	mutex_sock_path_len += STRLEN((char *)pid_str);
	if (mutex_sock_path_len > SIZEOF(mutex_sock_address.sun_path))
		RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(6) ERR_MUTEXERR, 0, ERR_TEXT, 2,
			RTS_ERROR_TEXT("Mutex socket path too long"));
	mutex_sock_address.sun_family = AF_UNIX;
	strcpy(mutex_sock_address.sun_path, mutex_sock_path);
	mutex_sock_len = SIZEOF(mutex_sock_address.sun_family) + mutex_sock_path_len + 1; /* Include NULL byte in length */
	DEBUG_ONLY(if (!TREF(gtm_usesecshr)))
	{
		status = UNLINK(mutex_sock_address.sun_path);	/* in case it was left from last time */
		save_errno = (-1 == status) ? errno : 0;
	} DEBUG_ONLY(else save_errno = -1);	/* Non-zero and non-ENOENT value so uses gtmsecshr */
	if (0 != save_errno)
	{	/* Separate checks for unlink success vs no file removal needed */
		if (ENOENT != save_errno)
		{
#			ifdef DEBUG
			/* If using gtm_usesecshr, can get a log of bogus MUTEXRSRCCLNUP messages so see if the socket
			 * actually exists or not so can supress the message if not (but still push it through secshr).
			 */
			if (TREF(gtm_usesecshr))
			{
				STAT_FILE(mutex_sock_address.sun_path, &mutex_sock_stat_buf, status);
				existed = (0 == status) ? TRUE : FALSE;
			} else
				existed = TRUE;		/* If no gtm_usesecshr, wouldn't be here unless existed */
#			endif
			if (0 == (status = send_mesg2gtmsecshr(REMOVE_FILE, (unsigned int)-1, mutex_sock_address.sun_path,
							       mutex_sock_path_len + 1)))
			{
				DEBUG_ONLY(if (existed))	/* Avoid mesg unless socket existed */
					send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_MUTEXRSRCCLNUP, 2, mutex_sock_path_len,
						     mutex_sock_path, ERR_TEXT, 2, LEN_AND_LIT("Resource removed by gtmsecshr"));
			} else if (ENOENT != status)
				RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(10) ERR_MUTEXERR, 0, ERR_TEXT, 2,
					LEN_AND_LIT("gtmsecshr failed to remove leftover mutex resource"),
					ERR_TEXT, 2, mutex_sock_path_len, mutex_sock_path);
			/* else don't bother if somebody removed the file before gtmsecshr got to it */
		}
	} else  /* unlink succeeded - socket must have existed - now cleaned up */
		send_msg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUTEXRSRCCLNUP, 2, mutex_sock_path_len, mutex_sock_path);
	if (0 > BIND(mutex_sock_fd, (struct sockaddr *)&mutex_sock_address, mutex_sock_len))
		RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(7) ERR_MUTEXERR, 0, ERR_TEXT, 2,
			RTS_ERROR_TEXT("Error with mutex socket bind"), errno);
	/* Set the socket permissions to override any umask settings.
	 * Allow owner and group read and write access.
	 */
	STAT_FILE(mutex_sock_address.sun_path, &mutex_sock_stat_buf, status);
	if (-1 == status)
		RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(7) ERR_MUTEXERR, 0, ERR_TEXT, 2,
			RTS_ERROR_TEXT("Error with mutex socket stat"),
			errno);
	mutex_sock_stat_buf.st_mode |= (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
	if (-1 == CHMOD(mutex_sock_address.sun_path, mutex_sock_stat_buf.st_mode))
		RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(7) ERR_MUTEXERR, 0, ERR_TEXT, 2,
			RTS_ERROR_TEXT("Error with mutex socket chmod"),
			errno);
	/* Clear the descriptor set used to sense wake up message */
	FD_ZERO(&mutex_wait_on_descs);
	/* To make mutex_wake_proc faster, pre-initialize portions of
	 * mutex_wake_this_proc which are invariant of the pid to be woken up.
	 */
	memset((char *)&mutex_wake_this_proc, 0, SIZEOF(mutex_wake_this_proc));
	mutex_wake_this_proc.sun_family = AF_UNIX;
	strcpy(mutex_wake_this_proc.sun_path, mutex_sock_path);
	mutex_wake_this_proc_len = mutex_sock_len;
}

unsigned char *pid2ascx(unsigned char *pid_str, pid_t pid)
{	/* pid_str should accommodate atleast 2*SIZEOF(pid_t) + 1 characters */
	register unsigned char *cp;

	cp = &pid_str[2*SIZEOF(pid_t)];
	*cp = '\0'; /* Null terminate the string */
	while(cp > pid_str)
	{
		*--cp = hex_table[pid & 0xF];
		pid >>= 4;
	}
	return(pid_str);
}

#endif /*MUTEX_MSEM_WAKE*/