Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e7942cb authored by Tom Cherry's avatar Tom Cherry Committed by Gerrit Code Review
Browse files

Merge "init: shutdown services in the opposite order that they started"

parents 4e822742 5938379e
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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
+18 −0
Original line number Diff line number Diff line
@@ -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_) {
+6 −0
Original line number Diff line number Diff line
@@ -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,