11 #include "dinit-log.h"
14 void open_control_socket(struct ev_loop *loop);
17 // Find the requested service by name
18 static ServiceRecord * findService(const std::list<ServiceRecord *> & records,
22 list<ServiceRecord *>::const_iterator i = records.begin();
23 for ( ; i != records.end(); i++ ) {
24 if (strcmp((*i)->getServiceName(), name) == 0) {
28 return (ServiceRecord *)0;
31 ServiceRecord * ServiceSet::findService(std::string name)
33 return ::findService(records, name.c_str());
36 void ServiceSet::startService(const char *name)
39 ServiceRecord *record = loadServiceRecord(name);
44 void ServiceSet::stopService(const std::string & name)
46 ServiceRecord *record = findService(name);
47 if (record != nullptr) {
52 // Called when a service has actually stopped.
53 void ServiceRecord::stopped()
55 logServiceStopped(service_name);
56 service_state = ServiceState::STOPPED;
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();
64 service_set->service_inactive(this);
66 // TODO inform listeners.
67 if (desired_state == ServiceState::STARTED) {
68 // Desired state is "started".
73 void ServiceRecord::process_child_callback(struct ev_loop *loop, ev_child *w, int revents)
75 ServiceRecord *sr = (ServiceRecord *) w->data;
78 ev_child_stop(ev_default_loop(EVFLAG_AUTO), &sr->child_listener);
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.
85 if (sr->service_type == ServiceType::PROCESS) {
86 // TODO log non-zero rstatus?
87 if (sr->service_state == ServiceState::STOPPING) {
94 if (sr->auto_restart && sr->service_set->get_auto_restart()) {
99 if (sr->service_state == ServiceState::STOPPING) {
100 if (w->rstatus == 0) {
105 // ??? failed to stop!
106 // For now just pretend we stopped, so that any dependencies
112 if (w->rstatus == 0) {
117 sr->failed_to_start();
123 void ServiceRecord::start()
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
133 auto old_desired_state = desired_state;
134 desired_state = ServiceState::STARTED;
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.
142 bool all_deps_started = true;
144 // Ask dependencies to start, mark them as being waited on.
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
149 if ((*i)->service_state != ServiceState::STARTED || (*i)->force_stop) {
150 all_deps_started = false;
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
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;
162 i->waiting_on = true;
167 // This is (or at least may be) a notification that a dependency is ready; let's
169 for (auto i = soft_deps.begin(); i != soft_deps.end(); ++i) {
170 ServiceRecord * to = i->getTo();
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;
177 all_deps_started = false;
183 if (! all_deps_started) {
184 // The dependencies will notify this service once they've started.
188 // Actually start this service.
189 service_state = ServiceState::STARTING;
190 service_set->service_active(this);
192 if (service_type == ServiceType::PROCESS) {
193 bool start_success = start_ps_process();
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) {
209 // "internal" service
214 void ServiceRecord::started()
216 logServiceStarted(service_name);
217 service_state = ServiceState::STARTED;
218 // TODO - inform listeners
220 if (onstart_flags.release_console) {
221 log_to_console = false;
224 if (onstart_flags.rw_ready) {
225 open_control_socket(ev_default_loop(EVFLAG_AUTO));
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) {
235 for (auto i = soft_dpts.begin(); i != soft_dpts.end(); i++) {
236 if ((*i)->getFrom()->desired_state == ServiceState::STARTED) {
237 (*i)->getFrom()->start();
246 void ServiceRecord::failed_to_start()
248 logServiceFailed(service_name);
249 service_state = ServiceState::STOPPED;
250 desired_state = ServiceState::STOPPED;
251 service_set->service_inactive(this);
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();
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();
268 bool ServiceRecord::start_ps_process() noexcept
271 return start_ps_process(std::vector<std::string>());
273 catch (std::bad_alloc & bad_alloc_exc) {
279 // TODO this can currently throw std::bad_alloc, fix that (in the worst case,
280 // return failure instead).
281 bool ServiceRecord::start_ps_process(const std::vector<std::string> &pargs) noexcept
283 // In general, you can't tell whether fork/exec is successful. We use a pipe to communicate
284 // success/failure from the child to the parent. The pipe is set CLOEXEC so a successful
285 // exec closes the pipe, and the parent sees EOF. If the exec is unsuccessful, the errno
286 // is written to the pipe, and the parent can read it.
288 // TODO should NOT wait for the exec to succeed or fail here, as that could (when/if we allow
289 // running child processes with lower priority) result in priority inversion.
295 if (pipe2(pipefd, O_CLOEXEC)) {
300 // Set up the argument array and other data now (before fork), in case memory allocation fails.
303 //auto argsv = std::vector<const char *>(num_args + pargs.size() + 1);
304 auto argsv = std::vector<const char *>(num_args + pargs.size() + 1);
305 auto args = argsv.data();
307 for (i = 0; i < num_args; i++) {
308 args[i] = exec_arg_parts[i];
310 for (auto progarg : pargs) {
311 args[i] = progarg.c_str();
316 string logfile = this->logfile;
317 if (logfile.length() == 0) {
318 logfile = "/dev/null";
321 // TODO make sure pipefd's are not 0/1/2 (STDIN/OUT/ERR) - if they are, dup them
322 // until they are not.
324 pid_t forkpid = fork();
333 // Child process. Must not allocate memory (or otherwise risk throwing any exception)
334 // from here until exit().
335 ev_default_destroy(); // won't need that on this side, free up fds.
337 // Re-set stdin, stdout, stderr
338 close(0); close(1); close(2);
340 // TODO rethink this logic. If we open it at not-0, shouldn't we just dup it to 0?:
341 if (open("/dev/null", O_RDONLY) == 0) {
342 // stdin = 0. That's what we should have; proceed with opening
343 // stdout and stderr.
344 open(logfile.c_str(), O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
348 execvp(exec_arg_parts[0], const_cast<char **>(args));
350 // If we got here, the exec failed:
351 int exec_status = errno;
352 write(pipefd[1], &exec_status, sizeof(int));
357 close(pipefd[1]); // close the 'other end' fd
360 if (read(pipefd[0], &exec_status, sizeof(int)) == 0) {
361 // pipe closed; success
364 // Add a process listener so we can detect when the
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);
380 catch (std::bad_alloc &bad_alloc_exc) {
386 // Mark this and all dependent services as force-stopped.
387 void ServiceRecord::forceStop()
391 for (sr_iter i = dependents.begin(); i != dependents.end(); i++) {
394 // We don't want to force stop soft dependencies, however.
397 // A dependency of this service failed to start.
398 void ServiceRecord::failed_dependency()
400 desired_state = ServiceState::STOPPED;
402 // Presumably, we were starting. So now we're not.
403 service_state = ServiceState::STOPPED;
405 // Notify dependents of this service also
406 for (auto i = dependents.begin(); i != dependents.end(); i++) {
407 if ((*i)->desired_state == ServiceState::STARTED) {
408 (*i)->failed_dependency();
411 for (auto i = soft_dpts.begin(); i != soft_dpts.end(); i++) {
412 if ((*i)->getFrom()->desired_state == ServiceState::STARTED) {
413 // It's a soft dependency, so send them 'started' rather than
415 (*i)->getFrom()->started();
420 void ServiceRecord::dependentStopped()
422 if (service_state != ServiceState::STOPPED && (desired_state == ServiceState::STOPPED || force_stop)) {
423 // Check the other dependents before we stop.
424 if (stopCheckDependents()) {
430 void ServiceRecord::stop()
432 if ((service_state == ServiceState::STOPPING || service_state == ServiceState::STOPPED)
433 && desired_state == ServiceState::STARTED) {
434 // The service *was* stopped/stopping, but it was going to restart.
435 // Now, we'll cancel the restart.
436 // TODO inform listeners waiting for start of cancellation
439 if (desired_state == ServiceState::STOPPED) return;
441 desired_state = ServiceState::STOPPED;
443 if (service_state != ServiceState::STARTED) {
444 if (service_state == ServiceState::STARTING) {
445 // Well this is awkward: we're going to have to continue
446 // starting, but we don't want any dependents to think that
447 // they are still waiting to start.
448 // Make sure they remain stopped:
452 // If we're starting we need to wait for that to complete.
453 // If we're already stopping/stopped there's nothing to do.
457 // If we get here, we are in STARTED state; stop all dependents.
458 if (stopCheckDependents()) {
463 bool ServiceRecord::stopCheckDependents()
465 bool all_deps_stopped = true;
466 for (sr_iter i = dependents.begin(); i != dependents.end(); ++i) {
467 if ((*i)->service_state != ServiceState::STOPPED) {
468 all_deps_stopped = false;
473 return all_deps_stopped;
476 bool ServiceRecord::stopDependents()
478 bool all_deps_stopped = true;
479 for (sr_iter i = dependents.begin(); i != dependents.end(); ++i) {
480 if ((*i)->service_state != ServiceState::STOPPED) {
481 all_deps_stopped = false;
486 return all_deps_stopped;
491 // Dependency stopped or is stopping; we must stop too.
492 void ServiceRecord::stopping()
494 service_state = ServiceState::STOPPING;
496 if (service_type == ServiceType::PROCESS) {
498 // The process is still kicking on - must actually kill it.
500 // Now we wait; the rest is done in process_child_callback
503 // The process is already dead.
507 else if (service_type == ServiceType::SCRIPTED) {
509 start_ps_process(std::vector<string>(1, "stop"));
516 void ServiceSet::service_active(ServiceRecord *sr)
521 void ServiceSet::service_inactive(ServiceRecord *sr)