File: kkill.c

package info (click to toggle)
lam 7.1.4-8
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 56,404 kB
  • sloc: ansic: 156,541; sh: 9,991; cpp: 7,699; makefile: 5,621; perl: 488; fortran: 260; asm: 83
file content (228 lines) | stat: -rw-r--r-- 5,093 bytes parent folder | download | duplicates (10)
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/*
 * Copyright (c) 2001-2003 The Trustees of Indiana University.  
 *                         All rights reserved.
 * Copyright (c) 1998-2001 University of Notre Dame. 
 *                         All rights reserved.
 * Copyright (c) 1994-1998 The Ohio State University.  
 *                         All rights reserved.
 * 
 * This file is part of the LAM/MPI software package.  For license
 * information, see the LICENSE file in the top level directory of the
 * LAM/MPI source distribution.
 * 
 * $HEADER$
 *
 * $Id: kkill.c,v 6.9 2003/05/21 19:16:15 jsquyres Exp $
 * 
 *	Function:	- supports client cleanup by the kernel and by tkill(1)
 *			- OTB specific code
 */

#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
               
#include <kreq.h>
#include <typical.h>
#include <priority.h>

/*
 * global functions
 */
void kkillall(void);
int kkillclose(void);
int kkillopen(char *f_kill);
int kkillrewrite(struct kproc kptable[]);
int kkillwrite(int4 pid);


/*
 * external variables
 */
extern struct kproc	*pready;
extern struct kproc	*pblock;


/*
 * local variables
 */
static FILE		*fp_kill;	/* kill file ptr */
static int		fd_kill;	/* kill file desc. */


/*
 *	kkillall
 *
 *	Function:	- catches SIGTERM and SIGHUP
 *			- kills all attached processes
 */
void
kkillall(void)
{
	struct kproc	*p;

	for (p = pready; p; p = p->kp_next) {

		if (!(p->kp_flags & KIPROC)) {
			kill(p->kp_pid, SIGCONT);
			kill(p->kp_pid, SIGHUP);
		}
	}

	for (p = pblock; p; p = p->kp_next) {

		if (!(p->kp_flags & KIPROC)) {
			kill(p->kp_pid, SIGCONT);
			kill(p->kp_pid, SIGHUP);
		}
	}
}


/*
 *	kkillopen
 *
 *	Function:	- opens the kill file
 *			- locates the kill directory and constructs
 *			  the full kill pathname by appending the
 *			  userid to the kill directory
 *			- writes the kernel's own pid in the first
 *			  entry of the kill file
 *	Accepts:	- kill filename
 *	Returns:	- 0 or LAMERROR
 */
int
kkillopen(char *f_kill)
{
	fd_kill = open(f_kill, O_WRONLY | O_CREAT | O_EXCL, 0600);
	if (fd_kill < 0)
	  return(LAMERROR);

	/* Make this be close-on-exec so that forked children don't
	   inherit it.  Here's a corner case where it matters: the LAM
	   session directory is actually located on NFS (e.g.,
	   /tmp/lam-username@hostname is on NFS).  When the user
	   invokes lamhalt, which invokes the haltd, which forks off
	   tkill, tkill will go unlink all files in the session
	   directory.  Unfortunately, tkill will have inherited this
	   open file, which is now just removed.  Hence, when tkill
	   tries to remove the directory itself, NFS will complain
	   that the directory is not empty because NFS will
	   automatically create a .nfsXXXXX cache/placeholder file in
	   the directory when the kill file was unlinked but someone
	   (tkill) still had it open.  End result: the session
	   directory is not removed.  And this is bad.  I'm annoyed
	   because it took me so long to track this down! */

	if (fcntl(fd_kill, F_SETFD, 1) != 0)
	  return LAMERROR;

	fp_kill = fdopen(fd_kill, "w");

	if (! fp_kill)
	  return(LAMERROR);
	
	setvbuf(fp_kill, (char *) 0, _IOLBF, 0);
	
	if (fprintf(fp_kill, "%d\n", (int) getpid()) == EOF)
	  return(LAMERROR);
	
	return(0);
}


/*
 *	kkillwrite
 *
 *	Function:	- writes pid into lock file
 *	Accepts:	- pid
 *	Returns:	- 0 or LAMERROR
 */
int
kkillwrite(int4 pid)
{
	if (fprintf(fp_kill, "%d\n", pid) == EOF) {
		return(LAMERROR);
	} else {
		return(0);
	}
}


/*
 *	kkillrewrite
 *
 *	Function:	- rewrites entire kill file from current process list
 *	Accepts:	- kernel process table
 *	Returns:	- 0 or LAMERROR
 */
int
kkillrewrite(struct kproc kptable[])
{
	int		i;
/*
 * Rewind the stdio descriptor.
 */
	rewind(fp_kill);
/*
 * Write the kernel pid first.
 */
	if (fprintf(fp_kill, "%d\n", (int) getpid()) == EOF) {
		return(LAMERROR);
	}
/*
 * Write every current client pid.
 */
	for (i = 0; i < KPMAX; ++i) {

            /* this is a fairly significant misuse of the priority
               field, but lamhalt can't show up in the kill file or it
               will be killed by tkill launched by the haltd, which is
               not what we want to have happen.  So we set lamhalt's
               priority to a special value, and don't write the pid of
               any processes with the "sacred" priority into the kill
               file. */
		if ((kptable[i].kp_state != KSFREE) &&
                    !(kptable[i].kp_flags & KIPROC) &&
                    !(kptable[i].kp_priority == PRLAMHALT)) {

			if (fprintf(fp_kill, "%d\n", kptable[i].kp_pid)
					== EOF) {
				return(LAMERROR);
			}
		}
	}
/*
 * Truncate file to new length.
 */
#ifdef SCO
	if (chsize(fd_kill, ftell(fp_kill)))
#else
	if (ftruncate(fd_kill, ftell(fp_kill)))
#endif
	  return(LAMERROR);

	return(0);
}


/*
 *	kkillclose
 *
 *	Function:	- Flush and close the kill file.
 *	Returns:	- 0 or LAMERROR
 */
int
kkillclose(void)
{
	if (fclose(fp_kill) == EOF) {
		return(LAMERROR);
	} else {
		return(0);
	}
}