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) {
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
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 if (desired_state == ServiceState::STARTED) return;
135 desired_state = ServiceState::STARTED;
137 if (service_state != ServiceState::STOPPED) {
138 // We're already starting/started, or we are stopping and need to wait for
139 // that the complete.
143 service_state = ServiceState::STARTING;
144 service_set->service_active(this);
146 // Ask dependencies to start, mark them as being waited on.
147 if (! startCheckDependencies(true)) {
151 // Actually start this service.
155 void ServiceRecord::dependencyStarted()
157 if (service_state != ServiceState::STARTING) {
161 if (startCheckDependencies(false)) {
166 bool ServiceRecord::startCheckDependencies(bool start_deps)
168 bool all_deps_started = true;
170 for (sr_iter i = depends_on.begin(); i != depends_on.end(); ++i) {
171 if ((*i)->service_state != ServiceState::STARTED) {
173 all_deps_started = false;
182 for (auto i = soft_deps.begin(); i != soft_deps.end(); ++i) {
183 ServiceRecord * to = i->getTo();
185 if (to->service_state != ServiceState::STARTED) {
187 i->waiting_on = true;
188 all_deps_started = false;
191 i->waiting_on = false;
194 else if (i->waiting_on) {
195 if (to->service_state != ServiceState::STARTING) {
196 // Service has either started or is no longer starting
197 i->waiting_on = false;
200 // We are still waiting on this service
206 return all_deps_started;
209 void ServiceRecord::allDepsStarted()
211 if (service_type == ServiceType::PROCESS) {
212 bool start_success = start_ps_process();
220 else if (service_type == ServiceType::SCRIPTED) {
221 // Script-controlled service
222 bool start_success = start_ps_process(std::vector<std::string>(1, "start"));
223 if (! start_success) {
228 // "internal" service
233 void ServiceRecord::started()
235 logServiceStarted(service_name);
236 service_state = ServiceState::STARTED;
237 // TODO - inform listeners
239 if (onstart_flags.release_console) {
240 log_to_console = false;
243 if (onstart_flags.rw_ready) {
244 open_control_socket(ev_default_loop(EVFLAG_AUTO));
247 if (force_stop || desired_state == ServiceState::STOPPED) {
253 // Notify any dependents whose desired state is STARTED:
254 for (auto i = dependents.begin(); i != dependents.end(); i++) {
255 if ((*i)->desired_state == ServiceState::STARTED) {
256 (*i)->dependencyStarted();
259 for (auto i = soft_dpts.begin(); i != soft_dpts.end(); i++) {
260 if ((*i)->getFrom()->desired_state == ServiceState::STARTED) {
261 (*i)->getFrom()->dependencyStarted();
266 void ServiceRecord::failed_to_start()
268 logServiceFailed(service_name);
269 service_state = ServiceState::STOPPED;
270 desired_state = ServiceState::STOPPED;
271 service_set->service_inactive(this);
273 // Cancel start of dependents:
274 for (sr_iter i = dependents.begin(); i != dependents.end(); i++) {
275 if ((*i)->desired_state == ServiceState::STARTED) {
276 (*i)->failed_dependency();
279 for (auto i = soft_dpts.begin(); i != soft_dpts.end(); i++) {
280 if ((*i)->getFrom()->desired_state == ServiceState::STARTED) {
281 // We can send 'start', because this is only a soft dependency.
282 // Our startup failure means that they don't have to wait for us.
283 (*i)->getFrom()->start();
288 bool ServiceRecord::start_ps_process() noexcept
291 return start_ps_process(std::vector<std::string>());
293 catch (std::bad_alloc & bad_alloc_exc) {
299 bool ServiceRecord::start_ps_process(const std::vector<std::string> &pargs) noexcept
301 // In general, you can't tell whether fork/exec is successful. We use a pipe to communicate
302 // success/failure from the child to the parent. The pipe is set CLOEXEC so a successful
303 // exec closes the pipe, and the parent sees EOF. If the exec is unsuccessful, the errno
304 // is written to the pipe, and the parent can read it.
306 // TODO should NOT wait for the exec to succeed or fail here, as that could (when/if we allow
307 // running child processes with lower priority) result in priority inversion.
313 if (pipe2(pipefd, O_CLOEXEC)) {
318 // Set up the argument array and other data now (before fork), in case memory allocation fails.
321 //auto argsv = std::vector<const char *>(num_args + pargs.size() + 1);
322 auto argsv = std::vector<const char *>(num_args + pargs.size() + 1);
323 auto args = argsv.data();
325 for (i = 0; i < num_args; i++) {
326 args[i] = exec_arg_parts[i];
328 for (auto progarg : pargs) {
329 args[i] = progarg.c_str();
334 string logfile = this->logfile;
335 if (logfile.length() == 0) {
336 logfile = "/dev/null";
339 // TODO make sure pipefd's are not 0/1/2 (STDIN/OUT/ERR) - if they are, dup them
340 // until they are not.
342 pid_t forkpid = fork();
351 // Child process. Must not allocate memory (or otherwise risk throwing any exception)
352 // from here until exit().
353 ev_default_destroy(); // won't need that on this side, free up fds.
355 // Re-set stdin, stdout, stderr
356 close(0); close(1); close(2);
358 // TODO rethink this logic. If we open it at not-0, shouldn't we just dup it to 0?:
359 if (open("/dev/null", O_RDONLY) == 0) {
360 // stdin = 0. That's what we should have; proceed with opening
361 // stdout and stderr.
362 open(logfile.c_str(), O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
366 execvp(exec_arg_parts[0], const_cast<char **>(args));
368 // If we got here, the exec failed:
369 int exec_status = errno;
370 write(pipefd[1], &exec_status, sizeof(int));
375 close(pipefd[1]); // close the 'other end' fd
378 if (read(pipefd[0], &exec_status, sizeof(int)) == 0) {
379 // pipe closed; success
382 // Add a process listener so we can detect when the
384 ev_child_init(&child_listener, process_child_callback, pid, 0);
385 child_listener.data = this;
386 ev_child_start(ev_default_loop(EVFLAG_AUTO), &child_listener);
398 catch (std::bad_alloc &bad_alloc_exc) {
399 log(LogLevel::ERROR, "Out of memory");
404 // Mark this and all dependent services as force-stopped.
405 void ServiceRecord::forceStop()
409 for (sr_iter i = dependents.begin(); i != dependents.end(); i++) {
412 // We don't want to force stop soft dependencies, however.
415 // A dependency of this service failed to start.
416 void ServiceRecord::failed_dependency()
418 desired_state = ServiceState::STOPPED;
420 // Presumably, we were starting. So now we're not.
421 service_state = ServiceState::STOPPED;
423 // Notify dependents of this service also
424 for (auto i = dependents.begin(); i != dependents.end(); i++) {
425 if ((*i)->desired_state == ServiceState::STARTED) {
426 (*i)->failed_dependency();
429 for (auto i = soft_dpts.begin(); i != soft_dpts.end(); i++) {
430 if ((*i)->getFrom()->desired_state == ServiceState::STARTED) {
431 // It's a soft dependency, so send them 'started' rather than
433 (*i)->getFrom()->started();
438 void ServiceRecord::dependentStopped()
440 if (service_state == ServiceState::STOPPING) {
441 // Check the other dependents before we stop.
442 if (stopCheckDependents()) {
448 void ServiceRecord::stop()
450 if ((service_state == ServiceState::STOPPING || service_state == ServiceState::STOPPED)
451 && desired_state == ServiceState::STARTED) {
452 // The service *was* stopped/stopping, but it was going to restart.
453 // Now, we'll cancel the restart.
454 // TODO inform listeners waiting for start of cancellation
457 if (desired_state == ServiceState::STOPPED) return;
459 desired_state = ServiceState::STOPPED;
461 if (service_state != ServiceState::STARTED) {
462 if (service_state == ServiceState::STARTING) {
463 // Well this is awkward: we're going to have to continue
464 // starting, but we don't want any dependents to think that
465 // they are still waiting to start.
466 // Make sure they remain stopped:
470 // If we're starting we need to wait for that to complete.
471 // If we're already stopping/stopped there's nothing to do.
475 service_state = ServiceState::STOPPING;
476 // If we get here, we are in STARTED state; stop all dependents.
477 if (stopDependents()) {
482 bool ServiceRecord::stopCheckDependents()
484 bool all_deps_stopped = true;
485 for (sr_iter i = dependents.begin(); i != dependents.end(); ++i) {
486 if ((*i)->service_state != ServiceState::STOPPED) {
487 all_deps_stopped = false;
492 return all_deps_stopped;
495 bool ServiceRecord::stopDependents()
497 bool all_deps_stopped = true;
498 for (sr_iter i = dependents.begin(); i != dependents.end(); ++i) {
499 if ((*i)->service_state != ServiceState::STOPPED) {
500 all_deps_stopped = false;
505 return all_deps_stopped;
510 // Dependency stopped or is stopping; we must stop too.
511 void ServiceRecord::allDepsStopped()
513 if (service_type == ServiceType::PROCESS) {
515 // The process is still kicking on - must actually kill it.
517 if (term_signal != -1) {
518 kill(pid, term_signal);
520 // Now we wait; the rest is done in process_child_callback
523 // The process is already dead.
527 else if (service_type == ServiceType::SCRIPTED) {
529 if (! start_ps_process(std::vector<string>(1, "stop"))) {
530 // stop script failed, but there's not much we can do:
539 void ServiceSet::service_active(ServiceRecord *sr)
544 void ServiceSet::service_inactive(ServiceRecord *sr)