Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /* |
2 | * Copyright 2000, International Business Machines Corporation and others. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * This software has been released under the terms of the IBM Public | |
6 | * License. For details, see the LICENSE file in the top-level source | |
7 | * directory or online at http://www.openafs.org/dl/license10.html | |
8 | */ | |
9 | ||
10 | /* the wrapper nanny process around weblog that would restart it in case it | |
11 | * failed and hopefully log the error somewhere! The need for this nanny | |
12 | * process arises because the pipe descriptors need to be maintained. The | |
13 | * process catches SIGTERM and kills the weblog process and exits. | |
14 | * The following line needs to precede the kill -TERM line for httpd.pid | |
15 | * in the stopd script to stop the server | |
16 | kill -TERM `<cat /local/stronghold/apache/logs/httpd.pid>.afs` | |
17 | * or whatever the pid file | |
18 | */ | |
19 | ||
20 | #include <afs/stds.h> | |
21 | ||
22 | #include <stdio.h> | |
23 | #include <sys/types.h> | |
24 | #include <sys/wait.h> | |
25 | #include <signal.h> | |
26 | #include <fcntl.h> | |
27 | ||
28 | #include "weblog_errors.h" | |
29 | #include "AFS_component_version_number.c" | |
30 | ||
31 | #define WEBLOG_BIN "weblog" | |
32 | ||
33 | /* TODO - set restart_attempts to 0 if not within certain time period */ | |
34 | #define MAX_RESTARTS 3 /* after this many restarts just die */ | |
35 | static int restart_attempts = 0; | |
36 | ||
37 | int error_fd; /* error file descriptor */ | |
38 | ||
39 | void | |
40 | sig_term() | |
41 | { | |
42 | #ifdef AIX | |
43 | pid_t pgrp = getpgrp(); | |
44 | #else | |
45 | pid_t pgrp = getpgrp(0); | |
46 | #endif | |
47 | int n; | |
48 | ||
49 | #ifdef DEBUG | |
50 | write(2, "weblog_starter: caught SIGTERM, shutting down", 43); | |
51 | #endif | |
52 | ||
53 | log_error("weblog_starter: caught SIGTERM, shutting down"); | |
54 | ||
55 | if (pgrp == (pid_t) - 1) { | |
56 | log_error("getpgrp failed - kill weblog manually"); | |
57 | write(2, "getpgrp failed - kill weblog manually", 38); | |
58 | exit(1); | |
59 | } | |
60 | kill(-pgrp, SIGKILL); | |
61 | exit(1); | |
62 | } | |
63 | ||
64 | /* strip out this binary and replace it with the weblog binary's name */ | |
65 | getpath(char *this, char *path) | |
66 | { | |
67 | char *temp = &this[0]; | |
68 | int len = strlen(this); | |
69 | int pos = 0, i = 0, j = 0; | |
70 | char bin_name[] = WEBLOG_BIN; | |
71 | int len1 = strlen(bin_name); | |
72 | ||
73 | strcpy(path, this); | |
74 | temp += (len); | |
75 | pos = len; | |
76 | while (*temp != '/') { | |
77 | temp--; | |
78 | pos--; | |
79 | } | |
80 | for (i = (pos + 1); i < len; i++, j++) { | |
81 | path[i] = bin_name[j]; | |
82 | if (j >= len1) | |
83 | break; | |
84 | } | |
85 | } | |
86 | ||
87 | char * | |
88 | get_time() | |
89 | { | |
90 | time_t t; | |
91 | char *time_string; | |
92 | ||
93 | t = time(NULL); | |
94 | time_string = (char *)ctime(&t); | |
95 | time_string[strlen(time_string) - 1] = '\0'; | |
96 | return (time_string); | |
97 | } | |
98 | ||
99 | log_error(char *msg) | |
100 | { | |
101 | char err_msg[1024]; | |
102 | ||
103 | sprintf(err_msg, "[%s] weblog:%s\n", get_time(), msg); | |
104 | write(error_fd, (void *)err_msg, strlen(err_msg)); | |
105 | } | |
106 | ||
107 | ||
108 | int | |
109 | main(int argc, char **argv) | |
110 | { | |
111 | pid_t weblog_pid; | |
112 | int stat = -1; | |
113 | int exitstatus = 0; | |
114 | char rn[] = "weblog_starter"; | |
115 | char path[1024]; | |
116 | char error_fname[1024]; | |
117 | ||
118 | struct sigaction sa; | |
119 | ||
120 | memset(&sa, 0, sizeof sa); | |
121 | sa.sa_handler = (void (*)())sig_term; | |
122 | if (sigaction(SIGTERM, &sa, NULL) < 0) { | |
123 | perror("sigaction(SIGTERM)"); | |
124 | } | |
125 | ||
126 | getpath(argv[1], path); | |
127 | strcpy(error_fname, argv[2]); | |
128 | ||
129 | error_fd = open(error_fname, O_WRONLY | O_APPEND | O_CREAT); | |
130 | if (error_fd < 0) { | |
131 | fprintf(stderr, "%s:Error opening log file:%s\nExiting\n", rn, | |
132 | error_fname); | |
133 | perror("open"); | |
134 | exit(-1); | |
135 | } | |
136 | ||
137 | log_error("weblog_starter resuming normal operation"); | |
138 | ||
139 | while (restart_attempts < MAX_RESTARTS) { | |
140 | /* fork the weblog process and wait till it exits */ | |
141 | if ((weblog_pid = fork()) < 0) { | |
142 | log_error("Could not fork process"); | |
143 | #ifdef DEBUG | |
144 | perror("apache_afs_weblog:Could not fork process"); | |
145 | #endif | |
146 | exit(-1); | |
147 | } | |
148 | switch (weblog_pid) { | |
149 | case 0: | |
150 | /* the child process - in this case weblog */ | |
151 | execlp(path, "weblog", argv[3], argv[4], argv[5], argv[6], NULL); | |
152 | #ifdef DEBUG | |
153 | perror("apache_afs_weblog:Could not execute weblog"); | |
154 | #endif | |
155 | exit(RESTARTERROR); | |
156 | ||
157 | default: | |
158 | /* parent: just wait for the child */ | |
159 | weblog_pid = waitpid((pid_t) - 1, &stat, 0); | |
160 | ||
161 | if (weblog_pid == -1) { | |
162 | #ifdef DEBUG | |
163 | perror("apache_Afs_weblog: wait error"); | |
164 | #endif | |
165 | log_error("wait error"); | |
166 | kill(getpid(), SIGTERM); | |
167 | } | |
168 | ||
169 | if (WIFEXITED(stat)) { | |
170 | exitstatus = WEXITSTATUS(stat); | |
171 | switch (exitstatus) { | |
172 | case 0: | |
173 | #ifdef DEBUG | |
174 | fprintf(stderr, "%s:No error ... restarting\n", rn); | |
175 | #endif | |
176 | break; | |
177 | ||
178 | case RESTART: | |
179 | #ifdef DEBUG | |
180 | fprintf(stderr, "%s:%s...Exiting\n", rn, RESTARTMSG); | |
181 | #endif | |
182 | log_error(RESTARTMSG); | |
183 | exit(-1); | |
184 | ||
185 | case NULLARGS: | |
186 | #ifdef DEBUG | |
187 | fprintf(stderr, "%s:%s...Exiting\n", rn, NULLARGSMSG); | |
188 | log_error(NULLARGSMSG); | |
189 | #endif | |
190 | exit(-1); | |
191 | ||
192 | case PIPESEND: | |
193 | #ifdef DEBUG | |
194 | fprintf(stderr, "%s:%s...Restarting\n", rn, PIPESENDMSG); | |
195 | #endif | |
196 | log_error(PIPESENDMSG); | |
197 | break; | |
198 | ||
199 | case PIPEREAD: | |
200 | #ifdef DEBUG | |
201 | fprintf(stderr, "%s:%s...Exiting\n", rn, PIPEREADMSG); | |
202 | #endif | |
203 | log_error(PIPEREADMSG); | |
204 | exit(-1); | |
205 | ||
206 | case PARSE: | |
207 | #ifdef DEBUG | |
208 | fprintf(stderr, "%s:%s...Exiting\n", rn, PARSEMSG); | |
209 | #endif | |
210 | log_error(PARSEMSG); | |
211 | exit(-1); | |
212 | ||
213 | case KA: | |
214 | #ifdef DEBUG | |
215 | fprintf(stderr, "%s:%s...Exiting\n", rn, KAMSG); | |
216 | #endif | |
217 | log_error(KAMSG); | |
218 | exit(-1); | |
219 | ||
220 | default: | |
221 | #ifdef DEBUG | |
222 | fprintf(stderr, "%s:Unknown error...Exiting\n", rn); | |
223 | #endif | |
224 | log_error("Unknown error"); | |
225 | exit(-1); | |
226 | } /* switch (exitstatus) */ | |
227 | } | |
228 | /* if weblog exited */ | |
229 | else { /* weblog terminated abnormally */ | |
230 | if (WIFSIGNALED(stat)) { | |
231 | #ifdef DEBUG | |
232 | fprintf(stderr, | |
233 | "%s:The signal that terminated weblog:%d\n" | |
234 | "Restarting weblog ...\n", rn, WTERMSIG(stat)); | |
235 | #endif | |
236 | } | |
237 | #ifndef AIX | |
238 | else if (WCOREDUMP(stat)) { | |
239 | #ifdef DEBUG | |
240 | fprintf(stderr, "%s: weblog dumped core" "Exiting ...\n", | |
241 | rn); | |
242 | #endif | |
243 | log_error("Core dump"); | |
244 | exit(-1); | |
245 | } | |
246 | #endif | |
247 | else { | |
248 | #ifdef DEBUG | |
249 | fprintf(stderr, | |
250 | "%s: weblog died under STRANGE circumstances..." | |
251 | "restarting weblog\n", rn); | |
252 | #endif | |
253 | } | |
254 | } | |
255 | break; | |
256 | } /* switch(weblog_pid) */ | |
257 | restart_attempts++; | |
258 | } /* while */ | |
259 | } |