Merge "init: fix process restarting"
This commit is contained in:
commit
eb3fa92191
3 changed files with 25 additions and 39 deletions
|
|
@ -53,6 +53,7 @@
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "bootchart.h"
|
#include "bootchart.h"
|
||||||
|
|
@ -84,7 +85,6 @@ static int property_triggers_enabled = 0;
|
||||||
static char qemu[32];
|
static char qemu[32];
|
||||||
|
|
||||||
std::string default_console = "/dev/console";
|
std::string default_console = "/dev/console";
|
||||||
static time_t process_needs_restart_at;
|
|
||||||
|
|
||||||
const char *ENV[32];
|
const char *ENV[32];
|
||||||
|
|
||||||
|
|
@ -219,12 +219,21 @@ void property_changed(const std::string& name, const std::string& value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void restart_processes()
|
static std::optional<boot_clock::time_point> RestartProcesses() {
|
||||||
{
|
std::optional<boot_clock::time_point> next_process_restart_time;
|
||||||
process_needs_restart_at = 0;
|
ServiceManager::GetInstance().ForEachService([&next_process_restart_time](Service* s) {
|
||||||
ServiceManager::GetInstance().ForEachServiceWithFlags(SVC_RESTARTING, [](Service* s) {
|
if (!(s->flags() & SVC_RESTARTING)) return;
|
||||||
s->RestartIfNeeded(&process_needs_restart_at);
|
|
||||||
|
auto restart_time = s->time_started() + 5s;
|
||||||
|
if (boot_clock::now() > restart_time) {
|
||||||
|
s->Start();
|
||||||
|
} else {
|
||||||
|
if (!next_process_restart_time || restart_time < *next_process_restart_time) {
|
||||||
|
next_process_restart_time = restart_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
return next_process_restart_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_control_message(const std::string& msg, const std::string& name) {
|
void handle_control_message(const std::string& msg, const std::string& name) {
|
||||||
|
|
@ -1175,12 +1184,16 @@ int main(int argc, char** argv) {
|
||||||
am.ExecuteOneCommand();
|
am.ExecuteOneCommand();
|
||||||
}
|
}
|
||||||
if (!(waiting_for_prop || sm.IsWaitingForExec())) {
|
if (!(waiting_for_prop || sm.IsWaitingForExec())) {
|
||||||
if (!shutting_down) restart_processes();
|
if (!shutting_down) {
|
||||||
|
auto next_process_restart_time = RestartProcesses();
|
||||||
|
|
||||||
// If there's a process that needs restarting, wake up in time for that.
|
// If there's a process that needs restarting, wake up in time for that.
|
||||||
if (process_needs_restart_at != 0) {
|
if (next_process_restart_time) {
|
||||||
epoll_timeout_ms = (process_needs_restart_at - time(nullptr)) * 1000;
|
epoll_timeout_ms = std::chrono::ceil<std::chrono::milliseconds>(
|
||||||
if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
|
*next_process_restart_time - boot_clock::now())
|
||||||
|
.count();
|
||||||
|
if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there's more work to do, wake up again immediately.
|
// If there's more work to do, wake up again immediately.
|
||||||
|
|
|
||||||
|
|
@ -890,22 +890,6 @@ void Service::Restart() {
|
||||||
} /* else: Service is restarting anyways. */
|
} /* else: Service is restarting anyways. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void Service::RestartIfNeeded(time_t* process_needs_restart_at) {
|
|
||||||
boot_clock::time_point now = boot_clock::now();
|
|
||||||
boot_clock::time_point next_start = time_started_ + 5s;
|
|
||||||
if (now > next_start) {
|
|
||||||
flags_ &= (~SVC_RESTARTING);
|
|
||||||
Start();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t next_start_time_t = time(nullptr) +
|
|
||||||
time_t(std::chrono::duration_cast<std::chrono::seconds>(next_start - now).count());
|
|
||||||
if (next_start_time_t < *process_needs_restart_at || *process_needs_restart_at == 0) {
|
|
||||||
*process_needs_restart_at = next_start_time_t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The how field should be either SVC_DISABLED, SVC_RESET, or SVC_RESTART.
|
// The how field should be either SVC_DISABLED, SVC_RESET, or SVC_RESTART.
|
||||||
void Service::StopOrReset(int how) {
|
void Service::StopOrReset(int how) {
|
||||||
// The service is still SVC_RUNNING until its process exits, but if it has
|
// The service is still SVC_RUNNING until its process exits, but if it has
|
||||||
|
|
@ -1123,15 +1107,6 @@ void ServiceManager::ForEachServiceInClass(const std::string& classname,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceManager::ForEachServiceWithFlags(unsigned matchflags,
|
|
||||||
void (*func)(Service* svc)) const {
|
|
||||||
for (const auto& s : services_) {
|
|
||||||
if (s->flags() & matchflags) {
|
|
||||||
func(s.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServiceManager::RemoveService(const Service& svc) {
|
void ServiceManager::RemoveService(const Service& svc) {
|
||||||
auto svc_it = std::find_if(services_.begin(), services_.end(),
|
auto svc_it = std::find_if(services_.begin(), services_.end(),
|
||||||
[&svc] (const std::unique_ptr<Service>& s) {
|
[&svc] (const std::unique_ptr<Service>& s) {
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,6 @@ class Service {
|
||||||
void Stop();
|
void Stop();
|
||||||
void Terminate();
|
void Terminate();
|
||||||
void Restart();
|
void Restart();
|
||||||
void RestartIfNeeded(time_t* process_needs_restart_at);
|
|
||||||
void Reap();
|
void Reap();
|
||||||
void DumpState() const;
|
void DumpState() const;
|
||||||
void SetShutdownCritical() { flags_ |= SVC_SHUTDOWN_CRITICAL; }
|
void SetShutdownCritical() { flags_ |= SVC_SHUTDOWN_CRITICAL; }
|
||||||
|
|
@ -94,6 +93,7 @@ class Service {
|
||||||
const std::set<std::string>& classnames() const { return classnames_; }
|
const std::set<std::string>& classnames() const { return classnames_; }
|
||||||
unsigned flags() const { return flags_; }
|
unsigned flags() const { return flags_; }
|
||||||
pid_t pid() const { return pid_; }
|
pid_t pid() const { return pid_; }
|
||||||
|
android::base::boot_clock::time_point time_started() const { return time_started_; }
|
||||||
int crash_count() const { return crash_count_; }
|
int crash_count() const { return crash_count_; }
|
||||||
uid_t uid() const { return uid_; }
|
uid_t uid() const { return uid_; }
|
||||||
gid_t gid() const { return gid_; }
|
gid_t gid() const { return gid_; }
|
||||||
|
|
@ -217,8 +217,6 @@ class ServiceManager {
|
||||||
void ForEachServiceShutdownOrder(const std::function<void(Service*)>& callback) const;
|
void ForEachServiceShutdownOrder(const std::function<void(Service*)>& callback) const;
|
||||||
void ForEachServiceInClass(const std::string& classname,
|
void ForEachServiceInClass(const std::string& classname,
|
||||||
void (*func)(Service* svc)) const;
|
void (*func)(Service* svc)) const;
|
||||||
void ForEachServiceWithFlags(unsigned matchflags,
|
|
||||||
void (*func)(Service* svc)) const;
|
|
||||||
void ReapAnyOutstandingChildren();
|
void ReapAnyOutstandingChildren();
|
||||||
void RemoveService(const Service& svc);
|
void RemoveService(const Service& svc);
|
||||||
void DumpState() const;
|
void DumpState() const;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue