Set target state to STOPPED when stop is issued
[oweals/dinit.git] / src / service.cc
1 #include <cstring>
2 #include <cerrno>
3 #include <iterator>
4 #include <memory>
5 #include <cstddef>
6
7 #include <sys/ioctl.h>
8 #include <fcntl.h>
9 #include <termios.h>
10
11 #include "dinit.h"
12 #include "service.h"
13 #include "dinit-log.h"
14 #include "dinit-socket.h"
15 #include "dinit-util.h"
16 #include "baseproc-sys.h"
17
18 /*
19  * service.cc - Service management.
20  * See service.h for details.
21  */
22
23 // Find the requested service by name
24 static service_record * find_service(const std::list<service_record *> & records,
25                                     const char *name) noexcept
26 {
27     using std::list;
28     list<service_record *>::const_iterator i = records.begin();
29     for ( ; i != records.end(); ++i ) {
30         if (strcmp((*i)->get_name().c_str(), name) == 0) {
31             return *i;
32         }
33     }
34     return nullptr;
35 }
36
37 service_record * service_set::find_service(const std::string &name) noexcept
38 {
39     return ::find_service(records, name.c_str());
40 }
41
42 // Called when a service has actually stopped; dependents have stopped already, unless this stop
43 // is due to an unexpected process termination.
44 void service_record::stopped() noexcept
45 {
46     if (have_console) {
47         bp_sys::tcsetpgrp(0, bp_sys::getpgrp());
48         release_console();
49     }
50
51     force_stop = false;
52
53     restarting |= auto_restart;
54     bool will_restart = restarting && required_by > 0;
55     if (restarting && ! will_restart) {
56         notify_listeners(service_event_t::STARTCANCELLED);
57     }
58     restarting = false;
59
60     // If we won't restart, break soft dependencies now
61     if (! will_restart) {
62         for (auto dept : dependents) {
63             if (! dept->is_hard()) {
64                 // waits-for or soft dependency:
65                 if (dept->waiting_on) {
66                     dept->waiting_on = false;
67                     dept->get_from()->dependency_started();
68                 }
69                 if (dept->holding_acq) {
70                     dept->holding_acq = false;
71                     // release without issuing stop, since we're called only when this
72                     // service is already stopped/stopping:
73                     release(false);
74                 }
75             }
76         }
77     }
78
79     for (auto & dependency : depends_on) {
80         // we signal dependencies in case they are waiting for us to stop:
81         dependency.get_to()->dependent_stopped();
82     }
83
84     service_state = service_state_t::STOPPED;
85
86     if (will_restart) {
87         // Desired state is "started".
88         restarting = true;
89         start(false);
90     }
91     else {
92         becoming_inactive();
93         
94         if (start_explicit) {
95             // If we were explicitly started, our required_by count must be at least 1. Use
96             // release() to correctly release, mark inactive and release dependencies.
97             start_explicit = false;
98             release();
99         }
100         else if (required_by == 0) {
101             // This can only be the case if we didn't have start_explicit, since required_by would
102             // otherwise by non-zero.
103             prop_release = !prop_require;
104             prop_require = false;
105             services->add_prop_queue(this);
106             services->service_inactive(this);
107         }
108     }
109
110     // Start failure will have been logged already, only log if we are stopped for other reasons:
111     if (! start_failed) {
112         log_service_stopped(service_name);
113
114         // If this service chains to another, start the other service now:
115         if (! will_restart && ! start_on_completion.empty()) {
116             try {
117                 auto chain_to = services->load_service(start_on_completion.c_str());
118                 chain_to->start();
119             }
120             catch (service_load_exc &sle) {
121                 log(loglevel_t::ERROR, "Couldn't chain to service ", start_on_completion, ": ",
122                         "couldn't load ", sle.service_name, ": ", sle.exc_description);
123             }
124             catch (std::bad_alloc &bae) {
125                 log(loglevel_t::ERROR, "Couldn't chain to service ", start_on_completion,
126                         ": Out of memory");
127             }
128         }
129     }
130     notify_listeners(service_event_t::STOPPED);
131 }
132
133 void service_record::require() noexcept
134 {
135     if (required_by++ == 0) {
136         prop_require = !prop_release;
137         prop_release = false;
138         services->add_prop_queue(this);
139         if (service_state != service_state_t::STARTING && service_state != service_state_t::STARTED) {
140             prop_start = true;
141         }
142     }
143 }
144
145 void service_record::release(bool issue_stop) noexcept
146 {
147     if (--required_by == 0) {
148         desired_state = service_state_t::STOPPED;
149         prop_require = false;
150
151         // Can stop, and can release dependencies now. We don't need to issue a release if
152         // the require was pending though:
153         if (service_state != service_state_t::STOPPED && service_state != service_state_t::STOPPING) {
154             prop_release = !prop_require;
155             prop_require = false;
156             services->add_prop_queue(this);
157         }
158
159         if (service_state == service_state_t::STOPPED) {
160             services->service_inactive(this);
161         }
162         else if (issue_stop) {
163                 stop_reason = stopped_reason_t::NORMAL;
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             // We must clear holding_acq before calling release, otherwise the dependency
175             // may decide to stop, check this link and release itself a second time.
176             dependency.holding_acq = false;
177             dep_to->release();
178         }
179     }
180 }
181
182 void service_record::start(bool activate) noexcept
183 {
184     if (activate && ! start_explicit) {
185         require();
186         start_explicit = true;
187     }
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) {
196             return;
197         }
198
199         if (! can_interrupt_stop()) {
200             restarting = true;
201             return;
202         }
203
204         // We're STOPPING, and that can be interrupted. Our dependencies might be STOPPING,
205         // but if so they are waiting (for us), so they too can be instantly returned to
206         // STARTING state.
207         notify_listeners(service_event_t::STOPCANCELLED);
208     }
209     else if (! was_active) {
210         services->service_active(this);
211     }
212
213     start_failed = false;
214     start_skipped = false;
215     service_state = service_state_t::STARTING;
216     waiting_for_deps = true;
217
218     if (start_check_dependencies()) {
219         services->add_transition_queue(this);
220     }
221 }
222
223 void service_record::do_propagation() noexcept
224 {
225     if (prop_require) {
226         // Need to require all our dependencies
227         for (auto & dep : depends_on) {
228             dep.get_to()->require();
229             dep.holding_acq = true;
230         }
231         prop_require = false;
232     }
233     
234     if (prop_release) {
235         release_dependencies();
236         prop_release = false;
237     }
238     
239     if (prop_failure) {
240         prop_failure = false;
241         stop_reason = stopped_reason_t::DEPFAILED;
242         failed_to_start(true);
243     }
244     
245     if (prop_start) {
246         prop_start = false;
247         start(false);
248     }
249
250     if (prop_stop) {
251         prop_stop = false;
252         do_stop();
253     }
254 }
255
256 void service_record::execute_transition() noexcept
257 {
258     // state is STARTED with restarting set true if we are running a smooth recovery.
259     if (service_state == service_state_t::STARTING || (service_state == service_state_t::STARTED
260             && restarting)) {
261         if (check_deps_started()) {
262             all_deps_started();
263         }
264     }
265     else if (service_state == service_state_t::STOPPING) {
266         if (stop_check_dependents()) {
267             waiting_for_deps = false;
268
269             // A service that does actually stop for any reason should have its explicit activation released, unless
270             // it will restart:
271             if (start_explicit && !auto_restart && !restarting) {
272                 start_explicit = false;
273                 release(false);
274             }
275
276             bring_down();
277         }
278     }
279 }
280
281 void service_record::do_start() noexcept
282 {
283     if (pinned_stopped) return;
284     
285     if (service_state != service_state_t::STARTING) {
286         return;
287     }
288     
289     service_state = service_state_t::STARTING;
290
291     waiting_for_deps = true;
292
293     // Ask dependencies to start, mark them as being waited on.
294     if (check_deps_started()) {
295         // Once all dependencies are started, we start properly:
296         all_deps_started();
297     }
298 }
299
300 void service_record::dependency_started() noexcept
301 {
302     // Note that we check for STARTED state here in case the service is in smooth recovery while pinned.
303     // In that case it will wait for dependencies to start before restarting the process.
304     if ((service_state == service_state_t::STARTING || service_state == service_state_t::STARTED)
305             && waiting_for_deps) {
306         services->add_transition_queue(this);
307     }
308 }
309
310 bool service_record::start_check_dependencies() noexcept
311 {
312     bool all_deps_started = true;
313
314     for (auto & dep : depends_on) {
315         service_record * to = dep.get_to();
316         if (to->service_state != service_state_t::STARTED) {
317             if (to->service_state != service_state_t::STARTING) {
318                 to->prop_start = true;
319                 services->add_prop_queue(to);
320             }
321             dep.waiting_on = true;
322             all_deps_started = false;
323         }
324     }
325     
326     return all_deps_started;
327 }
328
329 bool service_record::check_deps_started() noexcept
330 {
331     for (auto & dep : depends_on) {
332         if (dep.waiting_on) {
333             return false;
334         }
335     }
336
337     return true;
338 }
339
340 void service_record::all_deps_started() noexcept
341 {
342     if (onstart_flags.starts_on_console && ! have_console) {
343         queue_for_console();
344         return;
345     }
346     
347     waiting_for_deps = false;
348
349     if (! can_proceed_to_start()) {
350         waiting_for_deps = true;
351         return;
352     }
353
354     bool start_success = bring_up();
355     restarting = false;
356     if (! start_success) {
357         failed_to_start();
358     }
359 }
360
361 void service_record::acquired_console() noexcept
362 {
363     waiting_for_console = false;
364     have_console = true;
365
366     if (service_state != service_state_t::STARTING) {
367         // We got the console but no longer want it.
368         release_console();
369     }
370     else if (check_deps_started()) {
371         all_deps_started();
372     }
373     else {
374         // We got the console but can't use it yet.
375         release_console();
376     }
377 }
378
379 void service_record::started() noexcept
380 {
381     // If we start on console but don't keep it, release it now:
382     if (have_console && ! onstart_flags.runs_on_console) {
383         bp_sys::tcsetpgrp(0, bp_sys::getpgrp());
384         release_console();
385     }
386
387     log_service_started(get_name());
388     service_state = service_state_t::STARTED;
389     notify_listeners(service_event_t::STARTED);
390
391     if (onstart_flags.rw_ready) {
392         rootfs_is_rw();
393     }
394     if (onstart_flags.log_ready) {
395         setup_external_log();
396     }
397
398     if (force_stop || desired_state == service_state_t::STOPPED) {
399         // We must now stop.
400         do_stop();
401         return;
402     }
403
404     // Notify any dependents whose desired state is STARTED:
405     for (auto dept : dependents) {
406         dept->get_from()->dependency_started();
407         dept->waiting_on = false;
408     }
409 }
410
411 void service_record::failed_to_start(bool depfailed, bool immediate_stop) noexcept
412 {
413     if (waiting_for_console) {
414         services->unqueue_console(this);
415         waiting_for_console = false;
416     }
417
418     if (start_explicit) {
419         start_explicit = false;
420         release(false);
421     }
422
423     // Cancel start of dependents:
424     for (auto & dept : dependents) {
425         switch (dept->dep_type) {
426         case dependency_type::REGULAR:
427         case dependency_type::MILESTONE:
428             if (dept->get_from()->service_state == service_state_t::STARTING) {
429                 dept->get_from()->prop_failure = true;
430                 services->add_prop_queue(dept->get_from());
431             }
432             break;
433         case dependency_type::WAITS_FOR:
434         case dependency_type::SOFT:
435             if (dept->waiting_on) {
436                 dept->waiting_on = false;
437                 dept->get_from()->dependency_started();
438             }
439         }
440
441         // Always release now, so that our desired state will be STOPPED before we call
442         // stopped() below (if we do so). Otherwise it may decide to restart us.
443         if (dept->holding_acq) {
444             dept->holding_acq = false;
445             release(false);
446         }
447     }
448
449     start_failed = true;
450     log_service_failed(get_name());
451     notify_listeners(service_event_t::FAILEDSTART);
452
453     if (immediate_stop) {
454         stopped();
455     }
456 }
457
458 bool service_record::bring_up() noexcept
459 {
460     // default implementation: there is no process, so we are started.
461     started();
462     return true;
463 }
464
465 // Mark this and all dependent services as force-stopped.
466 void service_record::forced_stop() noexcept
467 {
468     if (service_state != service_state_t::STOPPED) {
469         force_stop = true;
470         if (! pinned_started) {
471             prop_stop = true;
472             services->add_prop_queue(this);
473         }
474     }
475 }
476
477 void service_record::dependent_stopped() noexcept
478 {
479     if (service_state == service_state_t::STOPPING && waiting_for_deps) {
480         services->add_transition_queue(this);
481     }
482 }
483
484 void service_record::stop(bool bring_down) noexcept
485 {
486     if (start_explicit) {
487         start_explicit = false;
488         required_by--;
489     }
490
491     // If our required_by count is 0, we should treat this as a full manual stop regardless
492     if (required_by == 0) {
493         bring_down = true;
494     }
495
496     desired_state = service_state_t::STOPPED;
497
498     if (bring_down && service_state != service_state_t::STOPPED
499                 && service_state != service_state_t::STOPPING) {
500         stop_reason = stopped_reason_t::NORMAL;
501         do_stop();
502     }
503 }
504
505 bool service_record::restart() noexcept
506 {
507     // Re-start without affecting dependency links/activation.
508
509     if (service_state == service_state_t::STARTED) {
510         restarting = true;
511         stop_reason = stopped_reason_t::NORMAL;
512         do_stop();
513         return true;
514     }
515
516     // Wrong state
517     return false;
518 }
519
520 void service_record::do_stop() noexcept
521 {
522     // Called when we should definitely stop. We may need to restart afterwards, but we
523     // won't know that for sure until the execution transition.
524
525     bool all_deps_stopped = stop_dependents();
526
527     if (service_state != service_state_t::STARTED) {
528         if (service_state == service_state_t::STARTING) {
529             // If waiting for a dependency, or waiting for the console, we can interrupt start. Otherwise,
530             // we need to delegate to can_interrupt_start() (which can be overridden).
531             if (! waiting_for_deps && ! waiting_for_console) {
532                 if (! can_interrupt_start()) {
533                     // Well this is awkward: we're going to have to continue starting. We can stop once
534                     // we've reached the started state.
535                     return;
536                 }
537
538                 if (! interrupt_start()) {
539                     // Now wait for service startup to actually end; we don't need to handle it here.
540                     notify_listeners(service_event_t::STARTCANCELLED);
541                     return;
542                 }
543             }
544             else if (waiting_for_console) {
545                 services->unqueue_console(this);
546                 waiting_for_console = false;
547             }
548
549             // We must have had desired_state == STARTED.
550             notify_listeners(service_event_t::STARTCANCELLED);
551
552             // Reaching this point, we are starting interruptibly - so we
553             // stop now (by falling through to below).
554         }
555         else {
556             // If we're starting we need to wait for that to complete.
557             // If we're already stopping/stopped there's nothing to do.
558             return;
559         }
560     }
561
562     if (pinned_started) return;
563
564     service_state = service_state_t::STOPPING;
565     waiting_for_deps = true;
566     if (all_deps_stopped) {
567         services->add_transition_queue(this);
568     }
569 }
570
571 bool service_record::stop_check_dependents() noexcept
572 {
573     bool all_deps_stopped = true;
574     for (auto dept : dependents) {
575         if (dept->is_hard() && dept->holding_acq) {
576             all_deps_stopped = false;
577             break;
578         }
579     }
580
581     return all_deps_stopped;
582 }
583
584 bool service_record::stop_dependents() noexcept
585 {
586     bool all_deps_stopped = true;
587     for (auto dept : dependents) {
588         if (dept->is_hard() && dept->holding_acq) {
589             if (! dept->get_from()->is_stopped()) {
590                 // Note we check *first* since if the dependent service is not stopped,
591                 // 1. We will issue a stop to it shortly and
592                 // 2. It will notify us when stopped, at which point the stop_check_dependents()
593                 //    check is run anyway.
594                 all_deps_stopped = false;
595             }
596
597             if (force_stop) {
598                 // If this service is to be forcefully stopped, dependents must also be.
599                 dept->get_from()->forced_stop();
600             }
601
602             dept->get_from()->prop_stop = true;
603             services->add_prop_queue(dept->get_from());
604         }
605         // Note that soft dependencies are held (for now). If we restart, we don't want those dependencies
606         // to be broken.
607     }
608
609     return all_deps_stopped;
610 }
611
612 // All dependents have stopped; we can stop now, too. Only called when STOPPING.
613 void service_record::bring_down() noexcept
614 {
615     waiting_for_deps = false;
616     stopped();
617 }
618
619 void service_record::unpin() noexcept
620 {
621     if (pinned_started) {
622         pinned_started = false;
623
624         for (auto &dep : depends_on) {
625             if (dep.is_hard()) {
626                 if (dep.get_to()->get_state() != service_state_t::STARTED) {
627                     desired_state = service_state_t::STOPPED;
628                 }
629             }
630             else if (dep.holding_acq) {
631                 dep.holding_acq = false;
632                 dep.get_to()->release();
633             }
634         }
635
636         if (desired_state == service_state_t::STOPPED || force_stop) {
637             do_stop();
638             services->process_queues();
639         }
640     }
641     if (pinned_stopped) {
642         pinned_stopped = false;
643         if (desired_state == service_state_t::STARTED) {
644             do_start();
645             services->process_queues();
646         }
647     }
648 }
649
650 void service_record::queue_for_console() noexcept
651 {
652     waiting_for_console = true;
653     services->append_console_queue(this);
654 }
655
656 void service_record::release_console() noexcept
657 {
658     have_console = false;
659     services->pull_console_queue();
660 }
661
662 bool service_record::interrupt_start() noexcept
663 {
664     return true;
665 }
666
667 void service_set::service_active(service_record *sr) noexcept
668 {
669     active_services++;
670 }
671
672 void service_set::service_inactive(service_record *sr) noexcept
673 {
674     active_services--;
675 }