Properly intiiatiise force_stop
[oweals/dinit.git] / service.cc
1 #include "service.h"
2 #include <cstring>
3 #include <cerrno>
4 #include <sstream>
5 #include <iterator>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10
11 // Tokenize a string, allow quoting
12 // TODO doesn't yet allow quoting...
13 static std::vector<std::string> tokenize(std::string arg)
14 {
15     // TODO rewrite to be more efficient.
16     using namespace std;
17     istringstream iss(arg);
18     return vector<string>(istream_iterator<string>(iss), istream_iterator<string>());
19 }
20
21 // Find the requested service by name
22 static ServiceRecord * findService(const std::list<ServiceRecord *> & records,
23                                     const char *name)
24 {
25     using std::list;
26     list<ServiceRecord *>::const_iterator i = records.begin();
27     for ( ; i != records.end(); i++ ) {
28         if (strcmp((*i)->getServiceName(), name) == 0) {
29             return *i;
30         }
31     }
32     return (ServiceRecord *)0;
33 }
34
35 ServiceRecord * ServiceSet::findService(std::string name)
36 {
37     return ::findService(records, name.c_str());
38 }
39
40 void ServiceSet::startService(const char *name)
41 {
42     using namespace std;
43     ServiceRecord *record = loadServiceRecord(name);
44     
45     record->start();
46 }
47
48 void ServiceSet::stopService(const std::string & name)
49 {
50     ServiceRecord *record = findService(name);
51     if (record != nullptr) {
52         record->stop();
53     }
54 }
55
56 // Called when a service has actually stopped.
57 void ServiceRecord::stopped()
58 {
59     service_state = SVC_STOPPED;
60     force_stop = false;
61     
62     // Stop any dependencies whose desired state is SVC_STOPPED:
63     for (sr_iter i = depends_on.begin(); i != depends_on.end(); i++) {
64         (*i)->dependentStopped();
65     }
66
67     service_set->service_inactive(this);
68     
69     // TODO inform listeners.
70     if (desired_state == SVC_STARTED) {
71         // Desired state is "started".
72         start();
73     }
74 }
75
76 void ServiceRecord::process_child_callback(struct ev_loop *loop, ev_child *w, int revents)
77 {    
78     ServiceRecord *sr = (ServiceRecord *) w->data;
79
80     sr->pid = -1;
81     ev_child_stop(ev_default_loop(EVFLAG_AUTO), &sr->child_listener);
82     
83     // Ok, for a process service, any process death which we didn't rig
84     // ourselves is a bit... unexpected. Probably, the child died because
85     // we asked it to (sr->service_state == SVC_STOPPING). But even if
86     // we didn't, there's not much we can do.
87     
88     if (sr->service_type == SVC_PROCESS) {
89         // TODO log non-zero rstatus?
90         if (sr->service_state == SVC_STOPPING) {
91             sr->stopped();
92         }
93         else {
94             sr->forceStop();
95             sr->stop();
96         }
97         
98         if (sr->auto_restart && sr->service_set->get_auto_restart()) {
99             sr->start();
100         }
101     }
102     else {  // SVC_SCRIPTED
103         if (sr->service_state == SVC_STOPPING) {
104             if (w->rstatus == 0) {
105                 sr->stopped();
106             }
107             else {
108                 // TODO
109                 // ??? failed to stop!
110                 // For now just pretend we stopped, so that any dependencies
111                 // can be stopped:
112                 sr->stopped();
113             }
114         }
115         else { // SVC_STARTING
116             if (w->rstatus == 0) {
117                 sr->started();
118             }
119             else {
120                 // failed to start
121                 sr->failed_to_start();
122             }
123         }
124     }
125 }
126
127 void ServiceRecord::start()
128 {
129     if ((service_state == SVC_STARTING || service_state == SVC_STARTED)
130             && desired_state == SVC_STOPPED) {
131         // This service was starting, or started, but was set to be stopped.
132         // Cancel the stop (and continue starting/running).
133         // TODO any listeners waiting for stop should be notified of
134         //      its cancellation
135     }
136     
137     desired_state = SVC_STARTED;
138
139     if (service_state != SVC_STOPPED) {
140         // Either we need do nothing (service is already started/starting)
141         // or the service is currently being stopped and we must wait for
142         // that to complete.
143         return;
144     }
145     
146     // Service state is SVC_STOPPED. Start the service.
147     
148     // First, start dependencies
149     bool all_deps_started = true;
150     for (sr_iter i = depends_on.begin(); i != depends_on.end(); ++i) {
151         // Note, we cannot treat a dependency as started if its force_stop
152         // flag is set.
153         if ((*i)->service_state != SVC_STARTED || (*i)->force_stop) {
154             all_deps_started = false;
155             (*i)->start();
156         }
157     }
158     
159     if (! all_deps_started) {
160         // The dependencies will notify this service once they've started.
161         return;
162     }
163     
164     // Actually start this service.
165     service_state = SVC_STARTING;
166     service_set->service_active(this);
167     
168     if (service_type == SVC_PROCESS) {
169         bool start_success = start_ps_process();
170         if (start_success) {
171             started();
172         }
173         else {
174             failed_to_start();
175         }
176     }
177     else {
178         // Script-controlled service
179         bool start_success = start_ps_process(std::vector<std::string>(1, "start"));
180         if (! start_success) {
181             failed_to_start();
182         }
183     }
184 }
185
186 void ServiceRecord::started()
187 {
188     service_state = SVC_STARTED;
189     // TODO - inform listeners
190
191     if (desired_state == SVC_STARTED) {
192         // Start any dependents whose desired state is SVC_STARTED:
193         for (sr_iter i = dependents.begin(); i != dependents.end(); i++) {
194             if ((*i)->desired_state == SVC_STARTED) {
195                 (*i)->start();
196             }
197         }
198     }
199     else {
200         stop();
201     }
202 }
203
204 void ServiceRecord::failed_to_start()
205 {
206     service_state = SVC_STOPPED;
207     desired_state = SVC_STOPPED;
208     service_set->service_inactive(this);
209     // failure to start
210     // TODO - inform listeners of failure
211     // Cancel start of dependents:
212     for (sr_iter i = dependents.begin(); i != dependents.end(); i++) {
213         if ((*i)->desired_state == SVC_STARTED) {
214             (*i)->failed_dependency();
215         }
216     }    
217 }
218
219 bool ServiceRecord::start_ps_process()
220 {
221     // BIG FAT NOTE: We rely on linux semantics of vfork() here.
222     // Specifically:
223     // * Parent process execution is suspended until the forked child
224     //   successfully exec's another program, or it exits
225     // * Memory is shared between the two processes until exec()
226     //   succeeds.
227     // Both of the above mean that we can determine in the parent process
228     // whether or not the exec succeeded. If vfork instead is implemented
229     // as an alias of fork, it will look like the exec always succeeded.
230     
231     /*
232     volatile int exec_status = 0;
233     pid_t forkpid = vfork();
234     if (forkpid == 0) {
235         // Child process
236         // ev_default_destroy(); // won't need that on this side, free up fds.
237         // Hmm. causes segfault. Of course. Memory is shared due to vfork.
238         
239         // Re-set stdin, stdout, stderr
240         close(0); close(1); close(2);
241         string logfile = this->logfile;
242         if (logfile.length() == 0) {
243             logfile = "/dev/null";
244         }
245         
246         if (open("/dev/null", O_RDONLY) == 0) {
247           // stdin = 0. That's what we should have; proceed with opening
248           // stdout and stderr.
249           open(logfile.c_str(), O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
250           dup2(1, 2);
251         }
252         
253         const char * pname = program_name.c_str();
254         char const * args[2] = { pname, 0 };
255         execvp(pname, (char ** const) args);
256         // If we got here, the exec failed
257         exec_status = errno;
258         _exit(0);
259     }
260     else {
261         // Parent process - we only reach here once the exec() above
262         // has succeeded, or _exit() above was called (because vfork()
263         // suspends the parent until either of those occurs).
264         if (exec_status == 0) {
265             // success
266             pid = forkpid;
267
268             // Add a process listener so we can detect when the
269             // service stops
270             ev_child_init(&child_listener, process_child_callback, pid, 0);
271             child_listener.data = this;
272             ev_child_start(ev_default_loop(EVFLAG_AUTO), &child_listener);
273
274             service_state = SVC_STARTED;
275             return true;
276         }
277         else {
278             return false;
279         }
280     }
281     */
282     
283     return start_ps_process(std::vector<std::string>());
284 }
285
286
287 bool ServiceRecord::start_ps_process(const std::vector<std::string> &pargs)
288 {
289     // In general, you can't tell whether fork/exec is successful. We use a pipe to communicate
290     // success/failure from the child to the parent. The pipe is set CLOEXEC so a successful
291     // exec closes the pipe, and the parent sees EOF. If the exec is unsuccessful, the errno
292     // is written to the pipe, and the parent can read it.
293     
294     using std::vector;
295     using std::string;
296     
297     int pipefd[2];
298     if (pipe2(pipefd, O_CLOEXEC)) {
299         // TODO log error
300         return false;
301     }
302     
303     // TODO make sure pipefd's are not 0/1/2 (STDIN/OUT/ERR) - if they are, dup them
304     // until they are not.
305     
306     pid_t forkpid = fork();
307     if (forkpid == -1) {
308         // TODO log error
309         close(pipefd[0]);
310         close(pipefd[1]);
311         return false;
312     }
313     
314     if (forkpid == 0) {
315         // Child process
316         ev_default_destroy(); // won't need that on this side, free up fds.
317         
318         // Re-set stdin, stdout, stderr
319         close(0); close(1); close(2);
320         string logfile = this->logfile;
321         if (logfile.length() == 0) {
322             logfile = "/dev/null";
323         }
324         
325         // TODO rethink this logic. If we open it at not-0, shouldn't we just dup it to 0?:
326         if (open("/dev/null", O_RDONLY) == 0) {
327           // stdin = 0. That's what we should have; proceed with opening
328           // stdout and stderr.
329           open(logfile.c_str(), O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
330           dup2(1, 2);
331         }
332         
333         // Tokenize the command, and add additional arguments from pargs:
334         vector<string> progAndArgs = tokenize(program_name);
335         progAndArgs.insert(progAndArgs.end(), pargs.begin(), pargs.end());
336         
337         const char * pname = progAndArgs[0].c_str();
338         const char ** args = new const char *[progAndArgs.size() + 1];
339         
340         for (std::vector<std::string>::size_type i = 0; i < progAndArgs.size(); i++) {
341             args[i] = progAndArgs[i].c_str();
342         }
343         args[progAndArgs.size()] = nullptr;
344         
345         execvp(pname, (char ** const) args);
346         
347         // If we got here, the exec failed:        
348         int exec_status = errno;
349         write(pipefd[1], &exec_status, sizeof(int));
350         exit(0);
351     }
352     else {
353         // Parent process - we only reach here once the exec() above
354         // has succeeded, or _exit() above was called (because vfork()
355         // suspends the parent until either of those occurs).
356         
357         close(pipefd[1]); // close the 'other end' fd
358
359         int exec_status;        
360         if (read(pipefd[0], &exec_status, sizeof(int)) == 0) {
361             // pipe closed; success
362             pid = forkpid;
363
364             // Add a process listener so we can detect when the
365             // service stops
366             ev_child_init(&child_listener, process_child_callback, pid, 0);
367             child_listener.data = this;
368             ev_child_start(ev_default_loop(EVFLAG_AUTO), &child_listener);
369
370             close(pipefd[0]);
371             return true;
372         }
373         else {
374             // TODO log error
375             close(pipefd[0]);
376             return false;
377         }
378     }
379 }
380
381
382
383
384 // Mark this and all dependent services as force-stopped.
385 void ServiceRecord::forceStop()
386 {
387     force_stop = true;
388     for (sr_iter i = dependents.begin(); i != dependents.end(); i++) {
389         (*i)->forceStop();
390     }        
391 }
392
393 // A dependency of this service failed to start.
394 void ServiceRecord::failed_dependency()
395 {
396     // TODO notify listeners
397     desired_state = SVC_STOPPED;
398     
399     // Presumably, we were starting. So now we're not.
400     service_state = SVC_STOPPED;
401     
402     // Notify dependents of this service also
403     for (sr_iter i = dependents.begin(); i != dependents.end(); i++) {
404         if ((*i)->desired_state == SVC_STARTED) {
405             (*i)->failed_dependency();
406         }
407     }    
408 }
409
410 void ServiceRecord::dependentStopped()
411 {
412     if (desired_state == SVC_STOPPED || force_stop) {
413         bool all_deps_stopped = true;
414         for (sr_iter i = dependents.begin(); i != dependents.end(); ++i) {
415             if ((*i)->service_state != SVC_STOPPED) {
416                 all_deps_stopped = false;
417                 break;
418             }
419         }
420         
421         if (all_deps_stopped) {
422             stopping();
423         }
424     }
425 }
426
427 void ServiceRecord::stop()
428 {
429     if ((service_state == SVC_STOPPING || service_state == SVC_STOPPED)
430             && desired_state == SVC_STARTED) {
431         // The service *was* stopped/stopping, but it was going to restart.
432         // Now, we'll cancel the restart.
433         // TODO inform listeners waiting for start of cancellation
434     }
435     
436     desired_state = SVC_STOPPED;
437
438     if (service_state != SVC_STARTED) {
439         // If we're starting we need to wait for that to complete.
440         // If we're already stopping/stopped there's nothing to do.
441         return;
442     }
443
444     // Make sure all dependents have stopped.
445     
446     bool all_deps_stopped = true;
447     for (sr_iter i = dependents.begin(); i != dependents.end(); ++i) {
448         if ((*i)->service_state != SVC_STOPPED) {
449             all_deps_stopped = false;
450             (*i)->stop();
451         }
452     }
453     
454     if (! all_deps_stopped) {
455         // The dependents will notify this service once they've stopped.
456         return;
457     }
458     
459     // Ok, dependents have stopped. We can stop ourselves.
460     stopping();
461 }
462
463 // Dependency stopped or is stopping; we must stop too.
464 void ServiceRecord::stopping()
465 {
466     service_state = SVC_STOPPING;
467
468     if (service_type == SVC_PROCESS) {
469         if (pid != -1) {
470           // The process is still kicking on - must actually kill it.
471           kill(pid, SIGTERM);
472           // Now we wait; the rest is done in process_child_callback
473         }
474         else {
475             // The process is already dead.
476             stopped();
477         }
478     }
479     else {
480         // Scripted service.
481         start_ps_process(std::vector<string>(1, "stop"));
482     }    
483 }
484
485 void ServiceSet::service_active(ServiceRecord *sr)
486 {
487     active_services++;
488 }
489
490 void ServiceSet::service_inactive(ServiceRecord *sr)
491 {
492     active_services--;
493 }