36 |
#include "net.h" |
#include "net.h" |
37 |
|
|
38 |
|
|
39 |
|
/* Private Prototypes */ |
40 |
|
static void atomic_control_process(Process_T p, char *action); |
41 |
|
static void atomic_dcontrol_process(Process_T p, char *action); |
42 |
|
static void control_dependant_process(Process_T p, char *action, int daemon); |
43 |
|
|
44 |
|
|
45 |
/** |
/** |
46 |
* Methods for controlling processes managed by monit. |
* Methods for controlling processes managed by monit. |
47 |
* |
* |
58 |
|
|
59 |
|
|
60 |
/** |
/** |
61 |
* Start all processes in the process list |
* Execute an action for the submited process |
62 |
*/ |
* @param p A Process object |
63 |
void start() { |
* @param action A string describing the action to execute |
64 |
|
* @param daemon Flag indicating if the monit daemon should execute the action |
|
Process_T p; |
|
|
|
|
|
for(p= processlist; p; p= p->next) { |
|
|
|
|
|
if(p->start) dstart_process(p->name); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
* Start all processes in the group |
|
65 |
*/ |
*/ |
66 |
void start_group(char *G) { |
void control_process(Process_T p, char *action, int daemon) { |
|
|
|
|
Process_T p; |
|
|
|
|
|
for(p= processlist; p; p= p->next) { |
|
67 |
|
|
68 |
if(is(p->group, G) ) { |
/* stop dependant processes */ |
69 |
|
control_dependant_process(p, "stop", daemon); |
70 |
|
|
71 |
if(p->start) dstart_process(p->name); |
/* Start/stop the process we asked for */ |
72 |
|
if(daemon) |
73 |
|
atomic_dcontrol_process(p, action); |
74 |
|
else |
75 |
|
atomic_control_process(p, action); |
76 |
|
|
77 |
} |
/* Restart dependant processes if needed */ |
78 |
|
if(is(action, "start")) { |
79 |
|
control_dependant_process(p, action, daemon); |
80 |
} |
} |
81 |
|
|
82 |
} |
} |
|
|
|
83 |
|
|
84 |
|
|
85 |
/** |
/** |
86 |
* Start the given process |
* Start/stop all processes in process list |
87 |
* @param p A Process_T object |
* @param action A string describing the action to execute |
88 |
*/ |
*/ |
89 |
void start_process(Process_T p) { |
void control(char *action) { |
90 |
|
|
91 |
pid_t pid= -1; |
Process_T p; |
|
|
|
|
if(!p->start) { |
|
|
|
|
|
error("Start: '%s' the start program is not defined\n", p->name); |
|
|
return; |
|
|
|
|
|
} |
|
92 |
|
|
93 |
if((pid= is_process_running(p))) { |
for(p= processlist; p; p= p->next) { |
94 |
|
check_process(p->name, action); |
|
error("Start: '%s' is already started with pid=%d\n", |
|
|
p->name, (int)pid); |
|
|
|
|
|
return; |
|
|
|
|
95 |
} |
} |
|
|
|
|
log("Start: (%s) %s\n", p->name, p->start->arg[0]); |
|
|
|
|
|
spawn(p, p->start); |
|
96 |
|
|
97 |
} |
} |
98 |
|
|
99 |
|
|
100 |
/** |
/* |
101 |
* Request the monit deamon to start the process P |
* Start/stop all processes in a group |
102 |
* @param P A process name as stated in the config file |
* @param name group name |
103 |
|
* @param action A string describing the action to execute |
104 |
*/ |
*/ |
105 |
void dstart_process(char *P) { |
void control_group(char *G, char *action) { |
106 |
|
|
107 |
Process_T p; |
Process_T p; |
|
int pid; |
|
|
|
|
|
if ( ! exist_process(P) ) { |
|
|
|
|
|
error("%s: Cannot start program '%s' -- not found in %s\n", |
|
|
prog, P, Run.controlfile); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
p= get_process(P); |
|
|
|
|
|
if ( (pid= is_process_running(p))) { |
|
|
|
|
|
error("%s: '%s' is already running with pid=%d\n", prog, P, pid); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
control_process(P, PSTART); |
|
|
|
|
|
} |
|
|
|
|
|
/** |
|
|
* Stop all processes in the process list |
|
|
*/ |
|
|
void stop() { |
|
108 |
|
|
|
Process_T p; |
|
|
|
|
109 |
for(p= processlist; p; p= p->next) { |
for(p= processlist; p; p= p->next) { |
110 |
|
if(is(p->group, G)) { |
111 |
if(p->stop) dstop_process(p->name); |
check_process(p->name, action); |
112 |
|
} |
113 |
} |
} |
114 |
|
|
115 |
} |
} |
116 |
|
|
117 |
|
|
118 |
/** |
/** |
119 |
* Stop all processes in the group |
* Check to see if we should try to start/stop process and by what method |
120 |
|
* (monit daemon or force) |
121 |
|
* @param name A process name as stated in the config file |
122 |
|
* @param action A string describing the action to execute |
123 |
*/ |
*/ |
124 |
void stop_group(char *G) { |
void check_process(char *P, char *action) { |
125 |
|
|
126 |
Process_T p; |
Process_T p; |
127 |
|
int pid; |
|
for(p= processlist; p; p= p->next) { |
|
128 |
|
|
129 |
if(is(p->group, G)) { |
if(NULL==(p= get_process(P))) { |
130 |
|
error("%s: Cannot %s program '%s' -- not found in %s\n", |
131 |
|
prog, action, P, Run.controlfile); |
132 |
|
return; |
133 |
|
} |
134 |
|
|
135 |
if(p->stop) dstop_process(p->name); |
if(is(action, "start")) { |
136 |
|
if ( (pid= is_process_running(p)) ) { |
137 |
|
error("%s: '%s' is already running with pid%d\n", prog, P, pid); |
138 |
|
return; |
139 |
|
} |
140 |
|
if(! p->start) { |
141 |
|
error("start: '%s' the start program is not defined\n", p->name); |
142 |
|
return; |
143 |
|
} |
144 |
|
} |
145 |
|
else if(is(action, "stop")) { |
146 |
|
if(! is_process_running(p)) { |
147 |
|
error("%s: '%s' is not running\n", prog, P); |
148 |
|
return; |
149 |
|
} |
150 |
|
if(! p->stop) { |
151 |
|
error("stop: '%s' the stop program is not defined\n", p->name); |
152 |
|
return; |
153 |
} |
} |
|
|
|
154 |
} |
} |
155 |
|
|
156 |
|
control_process(p, action, exist_daemon()); |
157 |
|
|
158 |
} |
} |
159 |
|
|
|
/** |
|
|
* stop the process |
|
|
* @param p A Process_T object |
|
|
*/ |
|
|
void stop_process(Process_T p) { |
|
|
|
|
|
pid_t pid= -1; |
|
|
|
|
|
if(!p->stop) { |
|
160 |
|
|
161 |
error("Stop: '%s' the stop program is not defined\n", p->name); |
/* ----------------------------------------------------------------- Private */ |
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
if(!(pid= is_process_running(p))) { |
|
|
|
|
|
error("Stop: '%s' is not running\n", p->name); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
log("Stop: (%s) %s\n", p->name, p->stop->arg[0]); |
|
|
|
|
|
spawn(p, p->stop); |
|
|
|
|
|
} |
|
162 |
|
|
163 |
|
|
164 |
/** |
/* |
165 |
* Request the monit deamon to stop the process P |
* Request that the monit daemon execute the action |
166 |
* @param P A process name as stated in the config file |
* @param p A Process_T object |
167 |
|
* @param action A string describing the action to execute |
168 |
*/ |
*/ |
169 |
void dstop_process(char *P) { |
static void atomic_dcontrol_process(Process_T p, char *action) { |
170 |
|
|
171 |
Process_T p; |
int s; |
172 |
|
char req[2*STRLEN]; |
173 |
|
char *auth= get_basic_authentication_header(); |
174 |
|
|
175 |
if ( ! exist_process(P) ) { |
s= create_socket(Run.bind_addr?Run.bind_addr:"localhost", |
176 |
|
Run.httpdport, SOCK_STREAM); |
|
error("%s: Cannot stop program '%s' -- not found in %s\n", |
|
|
prog, P, Run.controlfile); |
|
177 |
|
|
178 |
|
if(s<0) { |
179 |
|
error("%s: Cannot connect to the monit daemon. " |
180 |
|
"Did you start it with http support?\n", prog); |
181 |
return; |
return; |
|
|
|
182 |
} |
} |
183 |
|
else { |
184 |
p= get_process(P); |
snprintf(req, sizeof(req), |
185 |
|
"GET /%s?action=%s HTTP/1.0\r\n%s\r\n", p->name, action, auth); |
186 |
if ( ! is_process_running(p) ) { |
sock_send(s, req, sizeof(req), 0); |
187 |
|
close_socket(s); |
188 |
error("%s: '%s' is not running\n", prog, P); |
free(auth); |
|
|
|
|
return; |
|
|
|
|
189 |
} |
} |
190 |
|
|
|
control_process(P, PSTOP); |
|
|
|
|
191 |
} |
} |
192 |
|
|
|
/* Start/stop processes with dependency code */ |
|
|
void control_process(char *P, int action) { |
|
|
|
|
|
Process_T p; |
|
|
Dependant_T d; |
|
193 |
|
|
194 |
p= get_process(P); |
/* |
195 |
|
* Execute the given action for the process |
196 |
if ( exist_daemon() ) { |
* @param p A Process_T object |
197 |
|
* @param action A string describing the action to execute |
198 |
/* If a monit daemon exist we request that the daemon start the |
*/ |
199 |
program in case the daemon timed out the program. This way any |
static void atomic_control_process(Process_T p, char *action) { |
|
process timeout lock in the daemon is removed */ |
|
|
|
|
|
|
|
|
|
|
|
/* stop dependant processes - we do this no matter what */ |
|
|
for(d= p->dependantlist; d; d= p->dependantlist->next) { |
|
|
if(d->dependant == NULL) { |
|
|
break; |
|
|
} |
|
|
dcontrol_process(d->dependant, PSTOP); |
|
|
if(d->next == NULL) { |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
/* Now start/stop the process we asked for */ |
|
|
dcontrol_process(P, action); |
|
200 |
|
|
201 |
/* Start dependant processes again */ |
log("%s: (%s) %s\n", action, p->name, p->start->arg[0]); |
202 |
if(action == PSTART) { |
if(is(action, "start")) { |
203 |
for(d= p->dependantlist; d; d= p->dependantlist->next) { |
spawn(p, p->start); |
204 |
if(d->dependant == NULL) { |
} |
205 |
break; |
else if(is(action, "stop")) { |
206 |
} |
spawn(p, p->stop); |
|
dcontrol_process(d->dependant, PSTART); |
|
|
if(d->next == NULL) { |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} else { |
|
|
|
|
|
/* No monit daemon */ |
|
|
force_process(p, action); |
|
207 |
} |
} |
208 |
|
|
209 |
} |
} |
210 |
|
|
211 |
/* Just start/stop the programs */ |
|
212 |
void force_process(Process_T p, int action) { |
/* |
213 |
|
* Start/stop dependant processes |
214 |
|
* @param p A Process_T object @param action A start/stop action |
215 |
|
* @param daemon Flag indicating if the monit daemon should execute the action |
216 |
|
*/ |
217 |
|
static void control_dependant_process(Process_T p, char *action, int daemon) { |
218 |
|
|
219 |
Dependant_T d; |
Dependant_T d; |
220 |
|
|
|
/* stop dependant processes - we need to do this no matter what*/ |
|
221 |
for(d= p->dependantlist; d; d= p->dependantlist->next) { |
for(d= p->dependantlist; d; d= p->dependantlist->next) { |
222 |
if(d->dependant == NULL) { |
if(d->dependant == NULL) { |
223 |
break; |
break; |
224 |
} |
} |
225 |
stop_process(get_process(d->dependant)); |
control_process(get_process(d->dependant), action, daemon); |
226 |
if(d->next == NULL) { |
if (d->next == NULL) { |
227 |
break; |
break; |
228 |
} |
} |
229 |
} |
} |
230 |
|
|
|
/* Now start/stop the process we asked for */ |
|
|
if(action == PSTART) { |
|
|
start_process(p); |
|
|
} else { |
|
|
stop_process(p); |
|
|
} |
|
|
|
|
|
/* Restart dependant processes */ |
|
|
if(action == PSTART) { |
|
|
for(d= p->dependantlist; d; d= p->dependantlist->next) { |
|
|
if(d->dependant == NULL) { |
|
|
break; |
|
|
} |
|
|
start_process(get_process(d->dependant)); |
|
|
if(d->next == NULL) { |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
/* Start/stop processes via monit http interface */ |
|
|
void dcontrol_process(char *P, int action) { |
|
|
|
|
|
int s; |
|
|
char req[2*STRLEN]; |
|
|
char command[8]; |
|
|
char *auth= get_basic_authentication_header(); |
|
|
Process_T p; |
|
|
|
|
|
p= get_process(P); |
|
|
|
|
|
if(action == PSTOP) { |
|
|
snprintf(command, sizeof(command), "stop"); |
|
|
} else { |
|
|
snprintf(command, sizeof(command), "start"); |
|
|
} |
|
|
|
|
|
s= create_socket(Run.bind_addr?Run.bind_addr:"localhost", |
|
|
Run.httpdport, SOCK_STREAM); |
|
|
if(s<0) { |
|
|
error("%s: Cannot connect to the monit daemon. " |
|
|
"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, command, auth); |
|
|
sock_send(s, req, sizeof(req), 0); |
|
|
close_socket(s); |
|
|
free(auth); |
|
|
} |
|
231 |
} |
} |