Merge "init: shutdown services in the opposite order that they started"
This commit is contained in:
commit
8e7942cbd1
3 changed files with 27 additions and 3 deletions
|
@ -398,7 +398,7 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
|
|||
LOG(INFO) << "terminating init services";
|
||||
|
||||
// Ask all services to terminate except shutdown critical ones.
|
||||
ServiceManager::GetInstance().ForEachService([](Service* s) {
|
||||
ServiceManager::GetInstance().ForEachServiceShutdownOrder([](Service* s) {
|
||||
if (!s->IsShutdownCritical()) s->Terminate();
|
||||
});
|
||||
|
||||
|
@ -434,7 +434,7 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
|
|||
|
||||
// minimum safety steps before restarting
|
||||
// 2. kill all services except ones that are necessary for the shutdown sequence.
|
||||
ServiceManager::GetInstance().ForEachService([](Service* s) {
|
||||
ServiceManager::GetInstance().ForEachServiceShutdownOrder([](Service* s) {
|
||||
if (!s->IsShutdownCritical()) s->Stop();
|
||||
});
|
||||
ServiceManager::GetInstance().ReapAnyOutstandingChildren();
|
||||
|
@ -448,7 +448,7 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
|
|||
LOG(INFO) << "vold not running, skipping vold shutdown";
|
||||
}
|
||||
// logcat stopped here
|
||||
ServiceManager::GetInstance().ForEachService([&kill_after_apps](Service* s) {
|
||||
ServiceManager::GetInstance().ForEachServiceShutdownOrder([&kill_after_apps](Service* s) {
|
||||
if (kill_after_apps.count(s->name())) s->Stop();
|
||||
});
|
||||
// 4. sync, try umount, and optionally run fsck for user shutdown
|
||||
|
|
|
@ -155,6 +155,8 @@ ServiceEnvironmentInfo::ServiceEnvironmentInfo(const std::string& name,
|
|||
: name(name), value(value) {
|
||||
}
|
||||
|
||||
unsigned long Service::next_start_order_ = 1;
|
||||
|
||||
Service::Service(const std::string& name, const std::vector<std::string>& args)
|
||||
: Service(name, 0, 0, 0, {}, 0, 0, "", args) {}
|
||||
|
||||
|
@ -182,6 +184,7 @@ Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
|
|||
swappiness_(-1),
|
||||
soft_limit_in_bytes_(-1),
|
||||
limit_in_bytes_(-1),
|
||||
start_order_(0),
|
||||
args_(args) {
|
||||
onrestart_.InitSingleTrigger("onrestart");
|
||||
}
|
||||
|
@ -283,6 +286,7 @@ void Service::Reap() {
|
|||
|
||||
pid_ = 0;
|
||||
flags_ &= (~SVC_RUNNING);
|
||||
start_order_ = 0;
|
||||
|
||||
// Oneshot processes go into the disabled state on exit,
|
||||
// except when manually restarted.
|
||||
|
@ -805,6 +809,7 @@ bool Service::Start() {
|
|||
time_started_ = boot_clock::now();
|
||||
pid_ = pid;
|
||||
flags_ |= SVC_RUNNING;
|
||||
start_order_ = next_start_order_++;
|
||||
process_cgroup_empty_ = false;
|
||||
|
||||
errno = -createProcessGroup(uid_, pid_);
|
||||
|
@ -1096,6 +1101,19 @@ void ServiceManager::ForEachService(const std::function<void(Service*)>& callbac
|
|||
}
|
||||
}
|
||||
|
||||
// Shutdown services in the opposite order that they were started.
|
||||
void ServiceManager::ForEachServiceShutdownOrder(const std::function<void(Service*)>& callback) const {
|
||||
std::vector<Service*> shutdown_services;
|
||||
for (const auto& service : services_) {
|
||||
if (service->start_order() > 0) shutdown_services.emplace_back(service.get());
|
||||
}
|
||||
std::sort(shutdown_services.begin(), shutdown_services.end(),
|
||||
[](const auto& a, const auto& b) { return a->start_order() > b->start_order(); });
|
||||
for (const auto& service : shutdown_services) {
|
||||
callback(service);
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceManager::ForEachServiceInClass(const std::string& classname,
|
||||
void (*func)(Service* svc)) const {
|
||||
for (const auto& s : services_) {
|
||||
|
|
|
@ -108,6 +108,7 @@ class Service {
|
|||
int priority() const { return priority_; }
|
||||
int oom_score_adjust() const { return oom_score_adjust_; }
|
||||
bool process_cgroup_empty() const { return process_cgroup_empty_; }
|
||||
unsigned long start_order() const { return start_order_; }
|
||||
const std::vector<std::string>& args() const { return args_; }
|
||||
|
||||
private:
|
||||
|
@ -149,6 +150,8 @@ class Service {
|
|||
template <typename T>
|
||||
bool AddDescriptor(const std::vector<std::string>& args, std::string* err);
|
||||
|
||||
static unsigned long next_start_order_;
|
||||
|
||||
std::string name_;
|
||||
std::set<std::string> classnames_;
|
||||
std::string console_;
|
||||
|
@ -190,6 +193,8 @@ class Service {
|
|||
|
||||
bool process_cgroup_empty_ = false;
|
||||
|
||||
unsigned long start_order_;
|
||||
|
||||
std::vector<std::string> args_;
|
||||
};
|
||||
|
||||
|
@ -209,6 +214,7 @@ class ServiceManager {
|
|||
Service* FindServiceByPid(pid_t pid) const;
|
||||
Service* FindServiceByKeychord(int keychord_id) const;
|
||||
void ForEachService(const std::function<void(Service*)>& callback) const;
|
||||
void ForEachServiceShutdownOrder(const std::function<void(Service*)>& callback) const;
|
||||
void ForEachServiceInClass(const std::string& classname,
|
||||
void (*func)(Service* svc)) const;
|
||||
void ForEachServiceWithFlags(unsigned matchflags,
|
||||
|
|
Loading…
Reference in a new issue