Logging and comment fixes
[oweals/dinit.git] / service.cc
1 #include <cstring>
2 #include <cerrno>
3 #include <sstream>
4 #include <iterator>
5 #include <memory>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include "service.h"
11 #include "dinit-log.h"
12
13 // from dinit.cc:
14 void open_control_socket(struct ev_loop *loop);
15
16
17 // Find the requested service by name
18 static ServiceRecord * findService(const std::list<ServiceRecord *> & records,
19                                     const char *name)
20 {
21     using std::list;
22     list<ServiceRecord *>::const_iterator i = records.begin();
23     for ( ; i != records.end(); i++ ) {
24         if (strcmp((*i)->getServiceName(), name) == 0) {
25             return *i;
26         }
27     }
28     return (ServiceRecord *)0;
29 }
30
31 ServiceRecord * ServiceSet::findService(std::string name)
32 {
33     return ::findService(records, name.c_str());
34 }
35
36 void ServiceSet::startService(const char *name)
37 {
38     using namespace std;
39     ServiceRecord *record = loadServiceRecord(name);
40     
41     record->start();
42 }
43
44 void ServiceSet::stopService(const std::string & name)
45 {
46     ServiceRecord *record = findService(name);
47     if (record != nullptr) {
48         record->stop();
49     }
50 }
51
52 // Called when a service has actually stopped.
53 void ServiceRecord::stopped()
54 {
55     logServiceStopped(service_name);
56     service_state = ServiceState::STOPPED;
57     force_stop = false;
58     
59     // Stop any dependencies whose desired state is STOPPED:
60     for (sr_iter i = depends_on.begin(); i != depends_on.end(); i++) {
61         (*i)->dependentStopped();
62     }
63
64     service_set->service_inactive(this);
65     
66     // TODO inform listeners.
67     if (desired_state == ServiceState::STARTED) {
68         // Desired state is "started".
69         start();
70     }
71 }
72
73 void ServiceRecord::process_child_callback(struct ev_loop *loop, ev_child *w, int revents)
74 {    
75     ServiceRecord *sr = (ServiceRecord *) w->data;
76
77     sr->pid = -1;
78     ev_child_stop(ev_default_loop(EVFLAG_AUTO), &sr->child_listener);
79     
80     // Ok, for a process service, any process death which we didn't rig
81     // ourselves is a bit... unexpected. Probably, the child died because
82     // we asked it to (sr->service_state == STOPPING). But even if
83     // we didn't, there's not much we can do.
84     
85     if (sr->service_type == ServiceType::PROCESS) {
86         // TODO log non-zero rstatus?
87         if (sr->service_state == ServiceState::STOPPING) {
88             sr->stopped();
89         }
90         else {
91             sr->forceStop();
92         }
93         
94         if (sr->auto_restart && sr->service_set->get_auto_restart()) {
95             sr->start();
96         }
97     }
98     else {  // SCRIPTED
99         if (sr->service_state == ServiceState::STOPPING) {
100             if (w->rstatus == 0) {
101                 sr->stopped();
102             }
103             else {
104                 // ??? failed to stop! Let's log it as info:
105                 log(LogLevel::INFO, "service ", sr->service_name, " stop command failed with exit code ", w->rstatus);
106                 // Just assume that we stopped, so that any dependencies
107                 // can be stopped:
108                 sr->stopped();
109             }
110         }
111         else { // STARTING
112             if (w->rstatus == 0) {
113                 sr->started();
114             }
115             else {
116                 // failed to start
117                 sr->failed_to_start();
118             }
119         }
120     }
121 }
122
123 void ServiceRecord::start()
124 {
125     if ((service_state == ServiceState::STARTING || service_state == ServiceState::STARTED)
126             && desired_state == ServiceState::STOPPED) {
127         // This service was starting, or started, but was set to be stopped.
128         // Cancel the stop (and continue starting/running).
129         // TODO any listeners waiting for stop should be notified of
130         //      its cancellation
131     }
132
133     auto old_desired_state = desired_state;
134     desired_state = ServiceState::STARTED;
135     
136     if (service_state == ServiceState::STARTED || service_state == ServiceState::STARTING) {
137         // We couldn't be started or starting unless all dependencies have
138         // already started: so there's nothing left to do.
139         return;
140     }
141     
142     bool all_deps_started = true;
143
144     // Ask dependencies to start, mark them as being waited on.
145     
146     for (sr_iter i = depends_on.begin(); i != depends_on.end(); ++i) {
147         // Note, we cannot treat a dependency as started if its force_stop
148         // flag is set.
149         if ((*i)->service_state != ServiceState::STARTED || (*i)->force_stop) {
150             all_deps_started = false;
151             (*i)->start();
152         }
153     }
154     
155     if (old_desired_state != ServiceState::STARTED) {
156         // This is a fresh start, so we mark all soft dependencies as 'waiting on' and ask them
157         // to start:
158         for (auto i = soft_deps.begin(); i != soft_deps.end(); ++i) {
159             if (i->getTo()->service_state != ServiceState::STARTED) {
160                 all_deps_started = false;
161                 i->getTo()->start();
162                 i->waiting_on = true;
163             }
164         }
165     }
166     else {
167         // This is (or at least may be) a notification that a dependency is ready; let's
168         // just check them:
169         for (auto i = soft_deps.begin(); i != soft_deps.end(); ++i) {
170             ServiceRecord * to = i->getTo();
171             if (i->waiting_on) {
172                 if ((to->desired_state != ServiceState::STARTED && to->service_state != ServiceState::STARTING) || to->service_state == ServiceState::STARTED) {
173                     // Service has either started or is no longer starting
174                     i->waiting_on = false;
175                 }
176                 else {
177                     all_deps_started = false;
178                 }
179             }
180         }
181     }
182
183     if (! all_deps_started) {
184         // The dependencies will notify this service once they've started.
185         return;
186     }
187     
188     // Actually start this service.
189     service_state = ServiceState::STARTING;
190     service_set->service_active(this);
191     
192     if (service_type == ServiceType::PROCESS) {
193         bool start_success = start_ps_process();
194         if (start_success) {
195             started();
196         }
197         else {
198             failed_to_start();
199         }
200     }
201     else if (service_type == ServiceType::SCRIPTED) {
202         // Script-controlled service
203         bool start_success = start_ps_process(std::vector<std::string>(1, "start"));
204         if (! start_success) {
205             failed_to_start();
206         }
207     }
208     else {
209         // "internal" service
210         started();
211     }
212 }
213
214 void ServiceRecord::started()
215 {
216     logServiceStarted(service_name);
217     service_state = ServiceState::STARTED;
218     // TODO - inform listeners
219
220     if (onstart_flags.release_console) {
221         log_to_console = false;
222     }
223
224     if (onstart_flags.rw_ready) {
225         open_control_socket(ev_default_loop(EVFLAG_AUTO));
226     }
227
228     if (desired_state == ServiceState::STARTED) {
229         // Start any dependents whose desired state is STARTED:
230         for (auto i = dependents.begin(); i != dependents.end(); i++) {
231             if ((*i)->desired_state == ServiceState::STARTED) {
232                 (*i)->start();
233             }
234         }
235         for (auto i = soft_dpts.begin(); i != soft_dpts.end(); i++) {
236             if ((*i)->getFrom()->desired_state == ServiceState::STARTED) {
237                 (*i)->getFrom()->start();
238             }
239         }
240     }
241     else {
242         stop();
243     }
244 }
245
246 void ServiceRecord::failed_to_start()
247 {
248     logServiceFailed(service_name);
249     service_state = ServiceState::STOPPED;
250     desired_state = ServiceState::STOPPED;
251     service_set->service_inactive(this);
252     // failure to start
253     // Cancel start of dependents:
254     for (sr_iter i = dependents.begin(); i != dependents.end(); i++) {
255         if ((*i)->desired_state == ServiceState::STARTED) {
256             (*i)->failed_dependency();
257         }
258     }    
259     for (auto i = soft_dpts.begin(); i != soft_dpts.end(); i++) {
260         if ((*i)->getFrom()->desired_state == ServiceState::STARTED) {
261             // We can send 'start', because this is only a soft dependency.
262             // Our startup failure means that they don't have to wait for us.
263             (*i)->getFrom()->start();
264         }
265     }
266 }
267
268 bool ServiceRecord::start_ps_process() noexcept
269 {
270     try {
271         return start_ps_process(std::vector<std::string>());
272     }
273     catch (std::bad_alloc & bad_alloc_exc) {
274         // TODO log error
275         return false;
276     }
277 }
278
279 bool ServiceRecord::start_ps_process(const std::vector<std::string> &pargs) noexcept
280 {
281     // In general, you can't tell whether fork/exec is successful. We use a pipe to communicate
282     // success/failure from the child to the parent. The pipe is set CLOEXEC so a successful
283     // exec closes the pipe, and the parent sees EOF. If the exec is unsuccessful, the errno
284     // is written to the pipe, and the parent can read it.
285
286     // TODO should NOT wait for the exec to succeed or fail here, as that could (when/if we allow
287     // running child processes with lower priority) result in priority inversion.
288
289     using std::vector;
290     using std::string;
291     
292     int pipefd[2];
293     if (pipe2(pipefd, O_CLOEXEC)) {
294         // TODO log error
295         return false;
296     }
297     
298     // Set up the argument array and other data now (before fork), in case memory allocation fails.
299
300     try {
301         //auto argsv = std::vector<const char *>(num_args + pargs.size() + 1);
302         auto argsv = std::vector<const char *>(num_args + pargs.size() + 1);
303         auto args = argsv.data();
304         int i;
305         for (i = 0; i < num_args; i++) {
306             args[i] = exec_arg_parts[i];
307         }
308         for (auto progarg : pargs) {
309             args[i] = progarg.c_str();
310             i++;
311         }
312         args[i] = nullptr;
313         
314         string logfile = this->logfile;
315         if (logfile.length() == 0) {
316             logfile = "/dev/null";
317         }
318
319         // TODO make sure pipefd's are not 0/1/2 (STDIN/OUT/ERR) - if they are, dup them
320         // until they are not.
321
322         pid_t forkpid = fork();
323         if (forkpid == -1) {
324             // TODO log error
325             close(pipefd[0]);
326             close(pipefd[1]);
327             return false;
328         }
329
330         if (forkpid == 0) {
331             // Child process. Must not allocate memory (or otherwise risk throwing any exception)
332             // from here until exit().
333             ev_default_destroy(); // won't need that on this side, free up fds.
334
335             // Re-set stdin, stdout, stderr
336             close(0); close(1); close(2);
337
338             // TODO rethink this logic. If we open it at not-0, shouldn't we just dup it to 0?:
339             if (open("/dev/null", O_RDONLY) == 0) {
340               // stdin = 0. That's what we should have; proceed with opening
341               // stdout and stderr.
342               open(logfile.c_str(), O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
343               dup2(1, 2);
344             }
345
346             execvp(exec_arg_parts[0], const_cast<char **>(args));
347
348             // If we got here, the exec failed:
349             int exec_status = errno;
350             write(pipefd[1], &exec_status, sizeof(int));
351             exit(0);
352         }
353         else {
354             // Parent process
355             close(pipefd[1]); // close the 'other end' fd
356
357             int exec_status;
358             if (read(pipefd[0], &exec_status, sizeof(int)) == 0) {
359                 // pipe closed; success
360                 pid = forkpid;
361
362                 // Add a process listener so we can detect when the
363                 // service stops
364                 ev_child_init(&child_listener, process_child_callback, pid, 0);
365                 child_listener.data = this;
366                 ev_child_start(ev_default_loop(EVFLAG_AUTO), &child_listener);
367
368                 close(pipefd[0]);
369                 return true;
370             }
371             else {
372                 // TODO log error
373                 close(pipefd[0]);
374                 return false;
375             }
376         }
377     }
378     catch (std::bad_alloc &bad_alloc_exc) {
379         log(LogLevel::ERROR, "Out of memory");
380         return false;
381     }
382 }
383
384 // Mark this and all dependent services as force-stopped.
385 void ServiceRecord::forceStop()
386 {
387     force_stop = true;
388     stop();
389     for (sr_iter i = dependents.begin(); i != dependents.end(); i++) {
390         (*i)->forceStop();
391     }
392     // We don't want to force stop soft dependencies, however.
393 }
394
395 // A dependency of this service failed to start.
396 void ServiceRecord::failed_dependency()
397 {
398     desired_state = ServiceState::STOPPED;
399     
400     // Presumably, we were starting. So now we're not.
401     service_state = ServiceState::STOPPED;
402     
403     // Notify dependents of this service also
404     for (auto i = dependents.begin(); i != dependents.end(); i++) {
405         if ((*i)->desired_state == ServiceState::STARTED) {
406             (*i)->failed_dependency();
407         }
408     }
409     for (auto i = soft_dpts.begin(); i != soft_dpts.end(); i++) {
410         if ((*i)->getFrom()->desired_state == ServiceState::STARTED) {
411             // It's a soft dependency, so send them 'started' rather than
412             // 'failed dep'.
413             (*i)->getFrom()->started();
414         }
415     }    
416 }
417
418 void ServiceRecord::dependentStopped()
419 {
420     if (service_state != ServiceState::STOPPED && (desired_state == ServiceState::STOPPED || force_stop)) {
421         // Check the other dependents before we stop.
422         if (stopCheckDependents()) {
423             stopping();
424         }
425     }
426 }
427
428 void ServiceRecord::stop()
429 {
430     if ((service_state == ServiceState::STOPPING || service_state == ServiceState::STOPPED)
431             && desired_state == ServiceState::STARTED) {
432         // The service *was* stopped/stopping, but it was going to restart.
433         // Now, we'll cancel the restart.
434         // TODO inform listeners waiting for start of cancellation
435     }
436     
437     if (desired_state == ServiceState::STOPPED) return;
438     
439     desired_state = ServiceState::STOPPED;
440
441     if (service_state != ServiceState::STARTED) {
442         if (service_state == ServiceState::STARTING) {
443             // Well this is awkward: we're going to have to continue
444             // starting, but we don't want any dependents to think that
445             // they are still waiting to start.
446             // Make sure they remain stopped:
447             stopDependents();
448         }
449         
450         // If we're starting we need to wait for that to complete.
451         // If we're already stopping/stopped there's nothing to do.
452         return;
453     }
454     
455     // If we get here, we are in STARTED state; stop all dependents.
456     if (stopCheckDependents()) {
457         stopping();
458     }
459 }
460
461 bool ServiceRecord::stopCheckDependents()
462 {
463     bool all_deps_stopped = true;
464     for (sr_iter i = dependents.begin(); i != dependents.end(); ++i) {
465         if ((*i)->service_state != ServiceState::STOPPED) {
466             all_deps_stopped = false;
467             break;
468         }
469     }
470     
471     return all_deps_stopped;
472 }
473
474 bool ServiceRecord::stopDependents()
475 {
476     bool all_deps_stopped = true;
477     for (sr_iter i = dependents.begin(); i != dependents.end(); ++i) {
478         if ((*i)->service_state != ServiceState::STOPPED) {
479             all_deps_stopped = false;
480             (*i)->stop();
481         }
482     }
483     
484     return all_deps_stopped;
485 }
486
487
488
489 // Dependency stopped or is stopping; we must stop too.
490 void ServiceRecord::stopping()
491 {
492     service_state = ServiceState::STOPPING;
493
494     if (service_type == ServiceType::PROCESS) {
495         if (pid != -1) {
496           // The process is still kicking on - must actually kill it.
497           kill(pid, SIGTERM);
498           // Now we wait; the rest is done in process_child_callback
499         }
500         else {
501             // The process is already dead.
502             stopped();
503         }
504     }
505     else if (service_type == ServiceType::SCRIPTED) {
506         // Scripted service.
507         start_ps_process(std::vector<string>(1, "stop"));
508     }
509     else {
510         stopped();
511     }
512 }
513
514 void ServiceSet::service_active(ServiceRecord *sr)
515 {
516     active_services++;
517 }
518
519 void ServiceSet::service_inactive(ServiceRecord *sr)
520 {
521     active_services--;
522 }