Split service.cc into multiple files.
[oweals/dinit.git] / src / service.cc
1 #include <cstring>
2 #include <cerrno>
3 #include <sstream>
4 #include <iterator>
5 #include <memory>
6 #include <cstddef>
7
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <sys/ioctl.h>
11 #include <sys/un.h>
12 #include <sys/socket.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include <termios.h>
16
17 #include "service.h"
18 #include "dinit-log.h"
19 #include "dinit-socket.h"
20 #include "dinit-util.h"
21
22 /*
23  * service.cc - Service management.
24  * See service.h for details.
25  */
26
27 // from dinit.cc:
28 void open_control_socket(bool report_ro_failure = true) noexcept;
29 void setup_external_log() noexcept;
30
31 using clock_type = dasynq::clock_type;
32 using rearm = dasynq::rearm;
33 using time_val = dasynq::time_val;
34
35 // Find the requested service by name
36 static service_record * find_service(const std::list<service_record *> & records,
37                                     const char *name) noexcept
38 {
39     using std::list;
40     list<service_record *>::const_iterator i = records.begin();
41     for ( ; i != records.end(); i++ ) {
42         if (strcmp((*i)->get_name().c_str(), name) == 0) {
43             return *i;
44         }
45     }
46     return nullptr;
47 }
48
49 service_record * service_set::find_service(const std::string &name) noexcept
50 {
51     return ::find_service(records, name.c_str());
52 }
53
54 void service_set::stop_service(const std::string & name) noexcept
55 {
56     service_record *record = find_service(name);
57     if (record != nullptr) {
58         record->stop();
59         process_queues();
60     }
61 }
62
63 // Called when a service has actually stopped; dependents have stopped already, unless this stop
64 // is due to an unexpected process termination.
65 void service_record::stopped() noexcept
66 {
67     if (onstart_flags.runs_on_console) {
68         tcsetpgrp(0, getpgrp());
69         discard_console_log_buffer();
70         release_console();
71     }
72
73     force_stop = false;
74
75     // If we are a soft dependency of another target, break the acquisition from that target now:
76     for (auto & dependent : dependents) {
77         if (dependent->dep_type != dependency_type::REGULAR) {
78             if (dependent->holding_acq) {
79                 dependent->holding_acq = false;
80                 release();
81             }
82         }
83     }
84
85     bool will_restart = (desired_state == service_state_t::STARTED)
86             && services->get_auto_restart();
87
88     for (auto dependency : depends_on) {
89         // we signal dependencies in case they are waiting for us to stop:
90         dependency.get_to()->dependent_stopped();
91     }
92
93     service_state = service_state_t::STOPPED;
94
95     if (will_restart) {
96         // Desired state is "started".
97         restarting = true;
98         start(false);
99     }
100     else {
101         if (socket_fd != -1) {
102             close(socket_fd);
103             socket_fd = -1;
104         }
105         
106         if (start_explicit) {
107             start_explicit = false;
108             release();
109         }
110         else if (required_by == 0) {
111             services->service_inactive(this);
112         }
113     }
114
115     log_service_stopped(service_name);
116     notify_listeners(service_event_t::STOPPED);
117 }
118
119
120 bool service_record::do_auto_restart() noexcept
121 {
122     if (auto_restart) {
123         return services->get_auto_restart();
124     }
125     return false;
126 }
127
128 void service_record::emergency_stop() noexcept
129 {
130     if (! do_auto_restart() && start_explicit) {
131         start_explicit = false;
132         release();
133     }
134     forced_stop();
135     stop_dependents();
136     stopped();
137 }
138
139
140 void service_record::require() noexcept
141 {
142     if (required_by++ == 0) {
143         prop_require = !prop_release;
144         prop_release = false;
145         services->add_prop_queue(this);
146     }
147 }
148
149 void service_record::release() noexcept
150 {
151     if (--required_by == 0) {
152         desired_state = service_state_t::STOPPED;
153
154         // Can stop, and can release dependencies now. We don't need to issue a release if
155         // the require was pending though:
156         prop_release = !prop_require;
157         prop_require = false;
158         services->add_prop_queue(this);
159
160         if (service_state == service_state_t::STOPPED) {
161             services->service_inactive(this);
162         }
163         else {
164             do_stop();
165         }
166     }
167 }
168
169 void service_record::release_dependencies() noexcept
170 {
171     for (auto & dependency : depends_on) {
172         service_record * dep_to = dependency.get_to();
173         if (dependency.holding_acq) {
174             dep_to->release();
175             dependency.holding_acq = false;
176         }
177     }
178 }
179
180 void service_record::start(bool activate) noexcept
181 {
182     if (activate && ! start_explicit) {
183         require();
184         start_explicit = true;
185     }
186     
187     if (desired_state == service_state_t::STARTED && service_state != service_state_t::STOPPED) return;
188
189     bool was_active = service_state != service_state_t::STOPPED || desired_state != service_state_t::STOPPED;
190     desired_state = service_state_t::STARTED;
191     
192     if (service_state != service_state_t::STOPPED) {
193         // We're already starting/started, or we are stopping and need to wait for
194         // that the complete.
195         if (service_state != service_state_t::STOPPING || ! can_interrupt_stop()) {
196             return;
197         }
198         // We're STOPPING, and that can be interrupted. Our dependencies might be STOPPING,
199         // but if so they are waiting (for us), so they too can be instantly returned to
200         // STARTING state.
201         notify_listeners(service_event_t::STOPCANCELLED);
202     }
203     else if (! was_active) {
204         services->service_active(this);
205     }
206
207     service_state = service_state_t::STARTING;
208     waiting_for_deps = true;
209
210     if (start_check_dependencies()) {
211         services->add_transition_queue(this);
212     }
213 }
214
215 void service_record::do_propagation() noexcept
216 {
217     if (prop_require) {
218         // Need to require all our dependencies
219         for (auto & dep : depends_on) {
220             dep.get_to()->require();
221             dep.holding_acq = true;
222         }
223         prop_require = false;
224     }
225     
226     if (prop_release) {
227         release_dependencies();
228         prop_release = false;
229     }
230     
231     if (prop_failure) {
232         prop_failure = false;
233         failed_to_start(true);
234     }
235     
236     if (prop_start) {
237         prop_start = false;
238         start(false);
239     }
240
241     if (prop_stop) {
242         prop_stop = false;
243         do_stop();
244     }
245 }
246
247 void service_record::execute_transition() noexcept
248 {
249     // state is STARTED with restarting set true if we are running a smooth recovery.
250     if (service_state == service_state_t::STARTING || (service_state == service_state_t::STARTED
251             && restarting)) {
252         if (check_deps_started()) {
253             bool have_console = service_state == service_state_t::STARTED && onstart_flags.runs_on_console;
254             all_deps_started(have_console);
255         }
256     }
257     else if (service_state == service_state_t::STOPPING) {
258         if (stop_check_dependents()) {
259             bring_down();
260         }
261     }
262 }
263
264 void service_record::do_start() noexcept
265 {
266     if (pinned_stopped) return;
267     
268     if (service_state != service_state_t::STARTING) {
269         return;
270     }
271     
272     service_state = service_state_t::STARTING;
273
274     waiting_for_deps = true;
275
276     // Ask dependencies to start, mark them as being waited on.
277     if (check_deps_started()) {
278         // Once all dependencies are started, we start properly:
279         all_deps_started();
280     }
281 }
282
283 void service_record::dependency_started() noexcept
284 {
285     if ((service_state == service_state_t::STARTING || service_state == service_state_t::STARTED)
286             && waiting_for_deps) {
287         services->add_transition_queue(this);
288     }
289 }
290
291 bool service_record::start_check_dependencies() noexcept
292 {
293     bool all_deps_started = true;
294
295     for (auto & dep : depends_on) {
296         service_record * to = dep.get_to();
297         if (to->service_state != service_state_t::STARTED) {
298             if (to->service_state != service_state_t::STARTING) {
299                 to->prop_start = true;
300                 services->add_prop_queue(to);
301             }
302             dep.waiting_on = true;
303             all_deps_started = false;
304         }
305     }
306     
307     return all_deps_started;
308 }
309
310 bool service_record::check_deps_started() noexcept
311 {
312     for (auto & dep : depends_on) {
313         if (dep.waiting_on) {
314             return false;
315         }
316     }
317
318     return true;
319 }
320
321 bool service_record::open_socket() noexcept
322 {
323     if (socket_path.empty() || socket_fd != -1) {
324         // No socket, or already open
325         return true;
326     }
327     
328     const char * saddrname = socket_path.c_str();
329     
330     // Check the specified socket path
331     struct stat stat_buf;
332     if (stat(saddrname, &stat_buf) == 0) {
333         if ((stat_buf.st_mode & S_IFSOCK) == 0) {
334             // Not a socket
335             log(loglevel_t::ERROR, service_name, ": Activation socket file exists (and is not a socket)");
336             return false;
337         }
338     }
339     else if (errno != ENOENT) {
340         // Other error
341         log(loglevel_t::ERROR, service_name, ": Error checking activation socket: ", strerror(errno));
342         return false;
343     }
344
345     // Remove stale socket file (if it exists).
346     // We won't test the return from unlink - if it fails other than due to ENOENT, we should get an
347     // error when we try to create the socket anyway.
348     unlink(saddrname);
349
350     uint sockaddr_size = offsetof(struct sockaddr_un, sun_path) + socket_path.length() + 1;
351     struct sockaddr_un * name = static_cast<sockaddr_un *>(malloc(sockaddr_size));
352     if (name == nullptr) {
353         log(loglevel_t::ERROR, service_name, ": Opening activation socket: out of memory");
354         return false;
355     }
356
357     name->sun_family = AF_UNIX;
358     strcpy(name->sun_path, saddrname);
359
360     int sockfd = dinit_socket(AF_UNIX, SOCK_STREAM, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
361     if (sockfd == -1) {
362         log(loglevel_t::ERROR, service_name, ": Error creating activation socket: ", strerror(errno));
363         free(name);
364         return false;
365     }
366
367     if (bind(sockfd, (struct sockaddr *) name, sockaddr_size) == -1) {
368         log(loglevel_t::ERROR, service_name, ": Error binding activation socket: ", strerror(errno));
369         close(sockfd);
370         free(name);
371         return false;
372     }
373     
374     free(name);
375     
376     // POSIX (1003.1, 2013) says that fchown and fchmod don't necessarily work on sockets. We have to
377     // use chown and chmod instead.
378     if (chown(saddrname, socket_uid, socket_gid)) {
379         log(loglevel_t::ERROR, service_name, ": Error setting activation socket owner/group: ", strerror(errno));
380         close(sockfd);
381         return false;
382     }
383     
384     if (chmod(saddrname, socket_perms) == -1) {
385         log(loglevel_t::ERROR, service_name, ": Error setting activation socket permissions: ", strerror(errno));
386         close(sockfd);
387         return false;
388     }
389
390     if (listen(sockfd, 128) == -1) { // 128 "seems reasonable".
391         log(loglevel_t::ERROR, ": Error listening on activation socket: ", strerror(errno));
392         close(sockfd);
393         return false;
394     }
395     
396     socket_fd = sockfd;
397     return true;
398 }
399
400 void service_record::all_deps_started(bool has_console) noexcept
401 {
402     if (onstart_flags.starts_on_console && ! has_console) {
403         waiting_for_deps = true;
404         queue_for_console();
405         return;
406     }
407     
408     waiting_for_deps = false;
409
410     if (! can_proceed_to_start()) {
411         waiting_for_deps = true;
412         return;
413     }
414
415     if (! open_socket()) {
416         failed_to_start();
417     }
418
419     bool start_success = bring_up();
420     if (! start_success) {
421         failed_to_start();
422     }
423 }
424
425 void service_record::acquired_console() noexcept
426 {
427     if (service_state != service_state_t::STARTING) {
428         // We got the console but no longer want it.
429         release_console();
430     }
431     else if (check_deps_started()) {
432         all_deps_started(true);
433     }
434     else {
435         // We got the console but can't use it yet.
436         release_console();
437     }
438 }
439
440
441 void service_record::started() noexcept
442 {
443     if (onstart_flags.starts_on_console && ! onstart_flags.runs_on_console) {
444         tcsetpgrp(0, getpgrp());
445         release_console();
446     }
447
448     log_service_started(get_name());
449     service_state = service_state_t::STARTED;
450     notify_listeners(service_event_t::STARTED);
451
452     if (onstart_flags.rw_ready) {
453         open_control_socket();
454     }
455     if (onstart_flags.log_ready) {
456         setup_external_log();
457     }
458
459     if (force_stop || desired_state == service_state_t::STOPPED) {
460         // We must now stop.
461         do_stop();
462         return;
463     }
464
465     // Notify any dependents whose desired state is STARTED:
466     for (auto dept : dependents) {
467         dept->get_from()->dependency_started();
468         dept->waiting_on = false;
469     }
470 }
471
472 void service_record::failed_to_start(bool depfailed) noexcept
473 {
474     if (!depfailed && onstart_flags.starts_on_console) {
475         tcsetpgrp(0, getpgrp());
476         release_console();
477     }
478     
479     log_service_failed(get_name());
480     service_state = service_state_t::STOPPED;
481     if (start_explicit) {
482         start_explicit = false;
483         release();
484     }
485     notify_listeners(service_event_t::FAILEDSTART);
486     
487     // Cancel start of dependents:
488     for (auto & dept : dependents) {
489         switch (dept->dep_type) {
490         case dependency_type::REGULAR:
491         case dependency_type::MILESTONE:
492             if (dept->get_from()->service_state == service_state_t::STARTING) {
493                 dept->get_from()->prop_failure = true;
494                 services->add_prop_queue(dept->get_from());
495             }
496             break;
497         case dependency_type::WAITS_FOR:
498         case dependency_type::SOFT:
499             if (dept->waiting_on) {
500                 dept->waiting_on = false;
501                 dept->get_from()->dependency_started();
502             }
503             if (dept->holding_acq) {
504                 dept->holding_acq = false;
505                 release();
506             }
507         }
508     }
509 }
510
511 bool service_record::bring_up() noexcept
512 {
513     // default implementation: there is no process, so we are started.
514     started();
515     return true;
516 }
517
518
519 void service_record::run_child_proc(const char * const *args, const char *logfile, bool on_console,
520         int wpipefd, int csfd) noexcept
521 {
522     // Child process. Must not allocate memory (or otherwise risk throwing any exception)
523     // from here until exit().
524
525     // If the console already has a session leader, presumably it is us. On the other hand
526     // if it has no session leader, and we don't create one, then control inputs such as
527     // ^C will have no effect.
528     bool do_set_ctty = (tcgetsid(0) == -1);
529     
530     // Copy signal mask, but unmask signals that we masked on startup. For the moment, we'll
531     // also block all signals, since apparently dup() can be interrupted (!!! really, POSIX??).
532     sigset_t sigwait_set;
533     sigset_t sigall_set;
534     sigfillset(&sigall_set);
535     sigprocmask(SIG_SETMASK, &sigall_set, &sigwait_set);
536     sigdelset(&sigwait_set, SIGCHLD);
537     sigdelset(&sigwait_set, SIGINT);
538     sigdelset(&sigwait_set, SIGTERM);
539     sigdelset(&sigwait_set, SIGQUIT);
540     
541     constexpr int bufsz = ((CHAR_BIT * sizeof(pid_t)) / 3 + 2) + 11;
542     // "LISTEN_PID=" - 11 characters; the expression above gives a conservative estimate
543     // on the maxiumum number of bytes required for LISTEN=nnn, including nul terminator,
544     // where nnn is a pid_t in decimal (i.e. one decimal digit is worth just over 3 bits).
545     char nbuf[bufsz];
546     
547     // "DINIT_CS_FD=" - 12 bytes. (we -1 from sizeof(int) in account of sign bit).
548     constexpr int csenvbufsz = ((CHAR_BIT * sizeof(int) - 1) / 3 + 2) + 12;
549     char csenvbuf[csenvbufsz];
550     
551     int minfd = (socket_fd == -1) ? 3 : 4;
552
553     // Move wpipefd/csfd to another fd if necessary
554     if (wpipefd < minfd) {
555         wpipefd = fcntl(wpipefd, F_DUPFD_CLOEXEC, minfd);
556         if (wpipefd == -1) goto failure_out;
557     }
558     
559     if (csfd != -1 && csfd < minfd) {
560         csfd = fcntl(csfd, F_DUPFD, minfd);
561         if (csfd == -1) goto failure_out;
562     }
563     
564     if (socket_fd != -1) {
565         
566         if (dup2(socket_fd, 3) == -1) goto failure_out;
567         if (socket_fd != 3) {
568             close(socket_fd);
569         }
570         
571         if (putenv(const_cast<char *>("LISTEN_FDS=1"))) goto failure_out;
572         snprintf(nbuf, bufsz, "LISTEN_PID=%jd", static_cast<intmax_t>(getpid()));
573         if (putenv(nbuf)) goto failure_out;
574     }
575     
576     if (csfd != -1) {
577         snprintf(csenvbuf, csenvbufsz, "DINIT_CS_FD=%d", csfd);
578         if (putenv(csenvbuf)) goto failure_out;
579     }
580
581     if (! on_console) {
582         // Re-set stdin, stdout, stderr
583         close(0); close(1); close(2);
584
585         if (open("/dev/null", O_RDONLY) == 0) {
586             // stdin = 0. That's what we should have; proceed with opening
587             // stdout and stderr.
588             if (open(logfile, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR) != 1) {
589                 goto failure_out;
590             }
591             if (dup2(1, 2) != 2) {
592                 goto failure_out;
593             }
594         }
595         else goto failure_out;
596         
597         // We have the option of creating a session and process group, or just a new process
598         // group. If we just create a new process group, the child process cannot make itself
599         // a session leader if it wants to do that (eg getty/login will generally want this).
600         // If we do neither, and we are running with a controlling terminal, a ^C or similar
601         // will also affect the child process (which probably isn't so bad, though since we
602         // will handle the shutdown ourselves it's not necessary). Creating a new session
603         // (and a new process group as part of that) seems like a safe bet, and has the
604         // advantage of letting us signal the process as part of a process group.
605         setsid();
606     }
607     else {
608         // "run on console" - run as a foreground job on the terminal/console device
609         
610         // if do_set_ctty is false, we are the session leader; we are probably running
611         // as a user process. Don't create a new session leader in that case, and run
612         // as part of the parent session. Otherwise, the new session cannot claim the
613         // terminal as a controlling terminal (it is already claimed), meaning that it
614         // will not see control signals from ^C etc.
615         
616         if (do_set_ctty) {
617             // Disable suspend (^Z) (and on some systems, delayed suspend / ^Y)
618             signal(SIGTSTP, SIG_IGN);
619             
620             // Become session leader
621             setsid();
622             ioctl(0, TIOCSCTTY, 0);
623         }
624         setpgid(0,0);
625         tcsetpgrp(0, getpgrp());
626     }
627     
628     sigprocmask(SIG_SETMASK, &sigwait_set, nullptr);
629     
630     execvp(args[0], const_cast<char **>(args));
631     
632     // If we got here, the exec failed:
633     failure_out:
634     int exec_status = errno;
635     write(wpipefd, &exec_status, sizeof(int));
636     _exit(0);
637 }
638
639 // Mark this and all dependent services as force-stopped.
640 void service_record::forced_stop() noexcept
641 {
642     if (service_state != service_state_t::STOPPED) {
643         force_stop = true;
644         services->add_transition_queue(this);
645     }
646 }
647
648 void service_record::dependent_stopped() noexcept
649 {
650     if (service_state == service_state_t::STOPPING && waiting_for_deps) {
651         services->add_transition_queue(this);
652     }
653 }
654
655 void service_record::stop(bool bring_down) noexcept
656 {
657     if (start_explicit) {
658         start_explicit = false;
659         release();
660     }
661
662     if (bring_down) {
663         do_stop();
664     }
665 }
666
667 void service_record::do_stop() noexcept
668 {
669     if (pinned_started) return;
670
671     if (start_explicit && ! do_auto_restart()) {
672         start_explicit = false;
673         release();
674         if (required_by == 0) return; // release will re-call us anyway
675     }
676
677     bool all_deps_stopped = stop_dependents();
678
679     if (service_state != service_state_t::STARTED) {
680         if (service_state == service_state_t::STARTING) {
681             if (! waiting_for_deps) {
682                 if (! can_interrupt_start()) {
683                     // Well this is awkward: we're going to have to continue starting. We can stop once we've
684                     // reached the started state.
685                     return;
686                 }
687
688                 if (! interrupt_start()) {
689                     // Now wait for service startup to actually end; we don't need to handle it here.
690                     return;
691                 }
692             }
693
694             // We must have had desired_state == STARTED.
695             notify_listeners(service_event_t::STARTCANCELLED);
696
697             // Reaching this point, we are starting interruptibly - so we
698             // stop now (by falling through to below).
699         }
700         else {
701             // If we're starting we need to wait for that to complete.
702             // If we're already stopping/stopped there's nothing to do.
703             return;
704         }
705     }
706
707     service_state = service_state_t::STOPPING;
708     waiting_for_deps = true;
709     if (all_deps_stopped) {
710         services->add_transition_queue(this);
711     }
712 }
713
714 bool service_record::stop_check_dependents() noexcept
715 {
716     bool all_deps_stopped = true;
717     for (auto dept : dependents) {
718         if (dept->dep_type == dependency_type::REGULAR && ! dept->get_from()->is_stopped()) {
719             all_deps_stopped = false;
720             break;
721         }
722     }
723     
724     return all_deps_stopped;
725 }
726
727 bool service_record::stop_dependents() noexcept
728 {
729     bool all_deps_stopped = true;
730     for (auto dept : dependents) {
731         if (dept->dep_type == dependency_type::REGULAR) {
732             if (! dept->get_from()->is_stopped()) {
733                 // Note we check *first* since if the dependent service is not stopped,
734                 // 1. We will issue a stop to it shortly and
735                 // 2. It will notify us when stopped, at which point the stop_check_dependents()
736                 //    check is run anyway.
737                 all_deps_stopped = false;
738             }
739
740             if (force_stop) {
741                 // If this service is to be forcefully stopped, dependents must also be.
742                 dept->get_from()->forced_stop();
743             }
744
745             dept->get_from()->prop_stop = true;
746             services->add_prop_queue(dept->get_from());
747         }
748     }
749
750     return all_deps_stopped;
751 }
752
753 // All dependents have stopped; we can stop now, too. Only called when STOPPING.
754 void service_record::bring_down() noexcept
755 {
756     waiting_for_deps = false;
757     stopped();
758 }
759
760 void service_record::unpin() noexcept
761 {
762     if (pinned_started) {
763         pinned_started = false;
764         if (desired_state == service_state_t::STOPPED || force_stop) {
765             do_stop();
766             services->process_queues();
767         }
768     }
769     if (pinned_stopped) {
770         pinned_stopped = false;
771         if (desired_state == service_state_t::STARTED) {
772             do_start();
773             services->process_queues();
774         }
775     }
776 }
777
778 void service_record::queue_for_console() noexcept
779 {
780     services->append_console_queue(this);
781 }
782
783 void service_record::release_console() noexcept
784 {
785     services->pull_console_queue();
786 }
787
788 bool service_record::interrupt_start() noexcept
789 {
790     services->unqueue_console(this);
791     return true;
792 }
793
794 void service_set::service_active(service_record *sr) noexcept
795 {
796     active_services++;
797 }
798
799 void service_set::service_inactive(service_record *sr) noexcept
800 {
801     active_services--;
802 }