37 |
|
|
38 |
|
|
39 |
/* Private Prototypes */ |
/* Private Prototypes */ |
40 |
|
static void control_process(Process_T p, char *action); |
41 |
static void atomic_control_process(Process_T p, char *action); |
static void atomic_control_process(Process_T p, char *action); |
42 |
static void atomic_dcontrol_process(Process_T p, char *action); |
static void control_dependant_process(Process_T p, char *action); |
43 |
static void control_dependant_process(Process_T p, char *action, int daemon); |
static void mark_dependants(Process_T p); |
|
|
|
44 |
|
|
45 |
/** |
/** |
46 |
* Methods for controlling processes managed by monit. |
* Methods for controlling processes managed by monit. |
53 |
* @file |
* @file |
54 |
*/ |
*/ |
55 |
|
|
|
|
|
56 |
/* ------------------------------------------------------------------ Public */ |
/* ------------------------------------------------------------------ Public */ |
57 |
|
|
58 |
|
|
59 |
/** |
/** |
|
* Execute an action for the submited process |
|
|
* @param p A Process object |
|
|
* @param action A string describing the action to execute |
|
|
* @param daemon Flag indicating if the monit daemon should execute the action |
|
|
*/ |
|
|
void control_process(Process_T p, char *action, int daemon) { |
|
|
|
|
|
/* Stop dependant processes */ |
|
|
control_dependant_process(p, "stop", daemon); |
|
|
|
|
|
/* Start/stop the process we asked for */ |
|
|
if(daemon) |
|
|
atomic_dcontrol_process(p, action); |
|
|
else |
|
|
atomic_control_process(p, action); |
|
|
|
|
|
/* Restart dependant processes if needed */ |
|
|
if(is(action, "start")) { |
|
|
control_dependant_process(p, action, daemon); |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
60 |
* Start/stop all processes in process list |
* Start/stop all processes in process list |
61 |
* @param action A string describing the action to execute |
* @param action A string describing the action to execute |
62 |
*/ |
*/ |
63 |
void control(char *action) { |
void control(char *action) { |
64 |
|
|
65 |
Process_T p; |
Process_T p; |
66 |
|
|
67 |
|
setup_dependants(); |
68 |
|
|
69 |
for(p= processlist; p; p= p->next) { |
for(p= processlist; p; p= p->next) { |
70 |
check_process(p->name, action); |
check_process(p->name, action, TRUE); |
71 |
} |
} |
72 |
|
|
73 |
} |
} |
82 |
|
|
83 |
Process_T p; |
Process_T p; |
84 |
|
|
85 |
|
setup_dependants(); |
86 |
|
|
87 |
for(p= processlist; p; p= p->next) { |
for(p= processlist; p; p= p->next) { |
88 |
if(is(p->group, G)) { |
if(is(p->group, G)) { |
89 |
check_process(p->name, action); |
check_process(p->name, action, TRUE); |
90 |
} |
} |
91 |
} |
} |
92 |
|
|
99 |
* @param name A process name as stated in the config file |
* @param name A process name as stated in the config file |
100 |
* @param action A string describing the action to execute |
* @param action A string describing the action to execute |
101 |
*/ |
*/ |
102 |
void check_process(char *P, char *action) { |
void check_process(char *P, char *action, int toggle_validate_flag) { |
103 |
|
|
104 |
Process_T p; |
Process_T p; |
105 |
int pid; |
int pid; |
110 |
return; |
return; |
111 |
} |
} |
112 |
|
|
113 |
|
|
114 |
|
if( toggle_validate_flag ) { |
115 |
|
|
116 |
|
if( is(action, "start")) { |
117 |
|
LOCK(Run.mutex) |
118 |
|
p->do_validate= TRUE; |
119 |
|
END_LOCK; |
120 |
|
} |
121 |
|
|
122 |
|
if( is(action, "stop")) { |
123 |
|
LOCK(Run.mutex) |
124 |
|
p->do_validate= FALSE; |
125 |
|
END_LOCK; |
126 |
|
} |
127 |
|
|
128 |
|
} |
129 |
|
|
130 |
|
if( p->visited == TRUE ) { |
131 |
|
return; |
132 |
|
} |
133 |
|
|
134 |
|
if( p->parent != NULL ) { |
135 |
|
check_process(p->parent, action, toggle_validate_flag); |
136 |
|
} |
137 |
|
|
138 |
if(is(action, "start")) { |
if(is(action, "start")) { |
139 |
LOCK(Run.mutex) |
|
|
p->do_validate= TRUE; |
|
|
END_LOCK; |
|
140 |
if ( (pid= is_process_running(p)) ) { |
if ( (pid= is_process_running(p)) ) { |
141 |
error("%s: '%s' is already running with pid%d\n", prog, P, pid); |
error("%s: '%s' is already running with pid%d\n", prog, P, pid); |
142 |
return; |
return; |
147 |
} |
} |
148 |
} |
} |
149 |
else if(is(action, "stop")) { |
else if(is(action, "stop")) { |
150 |
LOCK(Run.mutex) |
|
|
p->do_validate= FALSE; |
|
|
END_LOCK; |
|
151 |
if(! is_process_running(p)) { |
if(! is_process_running(p)) { |
152 |
error("%s: '%s' is not running\n", prog, P); |
error("%s: '%s' is not running\n", prog, P); |
153 |
return; |
return; |
158 |
} |
} |
159 |
} |
} |
160 |
|
|
161 |
control_process(p, action, exist_daemon()); |
control_process(p, action); |
162 |
|
|
163 |
|
p->visited= TRUE; |
164 |
|
|
165 |
} |
} |
166 |
|
|
167 |
|
|
168 |
/* ----------------------------------------------------------------- Private */ |
/** |
169 |
|
* Setup dependant processes for checking |
|
|
|
|
/* |
|
|
* Request that the monit daemon execute the action |
|
|
* @param p A Process_T object |
|
|
* @param action A string describing the action to execute |
|
170 |
*/ |
*/ |
|
static void atomic_dcontrol_process(Process_T p, char *action) { |
|
171 |
|
|
172 |
int s; |
void setup_dependants() { |
|
char req[2*STRLEN]; |
|
|
char *auth= get_basic_authentication_header(); |
|
|
ssl_connection * ssl= NULL; |
|
173 |
|
|
174 |
if ( Run.httpdssl ) { |
Process_T p; |
175 |
|
|
176 |
|
for (p= processlist; p; p= p->next) { |
177 |
|
|
178 |
ssl = new_ssl_connection(Run.httpsslpem); |
p->visited= FALSE; |
179 |
|
p->parent= NULL; |
180 |
|
|
181 |
} |
} |
182 |
|
|
183 |
s= create_socket(Run.bind_addr?Run.bind_addr:"localhost", |
for (p= processlist; p; p= p->next) { |
|
Run.httpdport, SOCK_STREAM); |
|
184 |
|
|
185 |
if(s<0) { |
if( p->dependantlist != NULL ) { |
186 |
error("%s: Cannot connect to the monit daemon. " |
log("Marking outside\n"); |
|
"Did you start it with http support?\n", prog); |
|
|
return; |
|
|
} |
|
|
else { |
|
|
snprintf(req, sizeof(req), |
|
|
"GET /%s?action=%s HTTP/1.0\r\n%s\r\n", p->name, action, auth); |
|
187 |
|
|
188 |
if ( ssl != NULL ) { |
mark_dependants(p); |
189 |
|
|
190 |
if (!embed_ssl_socket(ssl, s)) { |
} |
|
|
|
|
fprintf(stdout, "Failed establish SSL communication to monit" |
|
|
" server\n"); |
|
191 |
|
|
192 |
return; |
} |
|
} |
|
193 |
|
|
194 |
send_ssl_socket(ssl, req, sizeof(req)); |
} |
|
|
|
|
close_ssl_socket(ssl); |
|
|
close_socket(s); |
|
195 |
|
|
196 |
} else { |
/* ----------------------------------------------------------------- Private */ |
197 |
|
|
|
sock_send(s, req, sizeof(req), 0); |
|
|
close_socket(s); |
|
198 |
|
|
199 |
} |
/** |
200 |
free(auth); |
* Execute an action for the submited process |
201 |
} |
* @param p A Process object |
202 |
|
* @param action A string describing the action to execute |
203 |
if ( Run.httpdssl ) { |
* @param daemon Flag indicating if the monit daemon should execute the action |
204 |
|
*/ |
205 |
|
void control_process(Process_T p, char *action) { |
206 |
|
|
207 |
delete_ssl_socket(ssl); |
/* Stop dependant processes */ |
208 |
|
control_dependant_process(p, "stop"); |
209 |
|
|
210 |
|
/* Start/stop the process we asked for */ |
211 |
|
atomic_control_process(p, action); |
212 |
|
|
213 |
|
/* Restart dependant processes if needed */ |
214 |
|
if(is(action, "start")) { |
215 |
|
control_dependant_process(p, action); |
216 |
} |
} |
217 |
|
|
218 |
} |
} |
219 |
|
|
220 |
|
|
229 |
if(! is_process_running(p)) { |
if(! is_process_running(p)) { |
230 |
log("%s: (%s) %s\n", action, p->name, p->start->arg[0]); |
log("%s: (%s) %s\n", action, p->name, p->start->arg[0]); |
231 |
spawn(p, p->start); |
spawn(p, p->start); |
232 |
|
|
233 |
} |
} |
234 |
} |
} |
235 |
else if(is(action, "stop")) { |
else if(is(action, "stop")) { |
247 |
* @param p A Process_T object @param action A start/stop action |
* @param p A Process_T object @param action A start/stop action |
248 |
* @param daemon Flag indicating if the monit daemon should execute the action |
* @param daemon Flag indicating if the monit daemon should execute the action |
249 |
*/ |
*/ |
250 |
static void control_dependant_process(Process_T p, char *action, int daemon) { |
static void control_dependant_process(Process_T p, char *action) { |
251 |
|
|
252 |
Dependant_T d; |
Dependant_T d; |
253 |
|
|
255 |
if(d->dependant == NULL) { |
if(d->dependant == NULL) { |
256 |
break; |
break; |
257 |
} |
} |
258 |
control_process(get_process(d->dependant), action, daemon); |
control_process(get_process(d->dependant), action); |
259 |
if (d->next == NULL) { |
if (d->next == NULL) { |
260 |
break; |
break; |
261 |
} |
} |
262 |
} |
} |
263 |
|
|
264 |
} |
} |
265 |
|
|
266 |
|
/** |
267 |
|
* Mark the visited flag on dependant so we don't visit them more than once |
268 |
|
*/ |
269 |
|
|
270 |
|
void mark_dependants(Process_T p) { |
271 |
|
|
272 |
|
Dependant_T d; |
273 |
|
|
274 |
|
log("Marking\n"); |
275 |
|
for (d= p->dependantlist; d; d= p->dependantlist->next ) { |
276 |
|
|
277 |
|
if( d->dependant == NULL ) { |
278 |
|
break; |
279 |
|
|
280 |
|
} |
281 |
|
|
282 |
|
get_process(d->dependant)->parent= p->name; |
283 |
|
log("Process: %s parent: %s\n", get_process(d->dependant)->name, |
284 |
|
get_process(d->dependant)->parent); |
285 |
|
|
286 |
|
if( d->next == NULL ) { |
287 |
|
break; |
288 |
|
} |
289 |
|
|
290 |
|
} |
291 |
|
|
292 |
|
} |