diff --git a/init/service.cpp b/init/service.cpp index f7318cba4..f6dd9b9fa 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -397,6 +397,14 @@ Result Service::ExecStart() { return {}; } +static void ClosePipe(const std::array* pipe) { + for (const auto fd : *pipe) { + if (fd >= 0) { + close(fd); + } + } +} + Result Service::Start() { auto reboot_on_failure = make_scope_guard([this] { if (on_failure_reboot_target_) { @@ -428,6 +436,12 @@ Result Service::Start() { return {}; } + std::unique_ptr, decltype(&ClosePipe)> pipefd(new std::array{-1, -1}, + ClosePipe); + if (pipe(pipefd->data()) < 0) { + return ErrnoError() << "pipe()"; + } + bool needs_console = (flags_ & SVC_CONSOLE); if (needs_console) { if (proc_attr_.console.empty()) { @@ -532,6 +546,13 @@ Result Service::Start() { LOG(ERROR) << "failed to write pid to files: " << result.error(); } + // Wait until the cgroups have been created and until the cgroup controllers have been + // activated. + if (std::byte byte; read((*pipefd)[0], &byte, 1) < 0) { + PLOG(ERROR) << "failed to read from notification channel"; + } + pipefd.reset(); + if (task_profiles_.size() > 0 && !SetTaskProfiles(getpid(), task_profiles_)) { LOG(ERROR) << "failed to set task profiles"; } @@ -618,6 +639,10 @@ Result Service::Start() { LmkdRegister(name_, proc_attr_.uid, pid_, oom_score_adjust_); } + if (write((*pipefd)[1], "", 1) < 0) { + return ErrnoError() << "sending notification failed"; + } + NotifyStateChange("running"); reboot_on_failure.Disable(); return {};