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

Commit 2a2a8d9e authored by Tom Cherry's avatar Tom Cherry Committed by Gerrit Code Review
Browse files

Merge changes Ibd57c103,I81f1e8ac,Ia6e546fe

* changes:
  init: rename ServiceManager to ServiceList and clean it up
  init: move reaping from ServiceManager to signal_handler.cpp
  init: move exec operations out of ServiceManager
parents eb3fa921 911b9b1d
Loading
Loading
Loading
Loading
+40 −20
Original line number Diff line number Diff line
@@ -124,31 +124,32 @@ static int reboot_into_recovery(const std::vector<std::string>& options) {
    return 0;
}

template <typename F>
static void ForEachServiceInClass(const std::string& classname, F function) {
    for (const auto& service : ServiceList::GetInstance()) {
        if (service->classnames().count(classname)) std::invoke(function, service);
    }
}

static int do_class_start(const std::vector<std::string>& args) {
        /* Starting a class does not start services
         * which are explicitly disabled.  They must
         * be started individually.
         */
    ServiceManager::GetInstance().
        ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
    // Starting a class does not start services which are explicitly disabled.
    // They must  be started individually.
    ForEachServiceInClass(args[1], &Service::StartIfNotDisabled);
    return 0;
}

static int do_class_stop(const std::vector<std::string>& args) {
    ServiceManager::GetInstance().
        ForEachServiceInClass(args[1], [] (Service* s) { s->Stop(); });
    ForEachServiceInClass(args[1], &Service::Stop);
    return 0;
}

static int do_class_reset(const std::vector<std::string>& args) {
    ServiceManager::GetInstance().
        ForEachServiceInClass(args[1], [] (Service* s) { s->Reset(); });
    ForEachServiceInClass(args[1], &Service::Reset);
    return 0;
}

static int do_class_restart(const std::vector<std::string>& args) {
    ServiceManager::GetInstance().
        ForEachServiceInClass(args[1], [] (Service* s) { s->Restart(); });
    ForEachServiceInClass(args[1], &Service::Restart);
    return 0;
}

@@ -162,7 +163,7 @@ static int do_domainname(const std::vector<std::string>& args) {
}

static int do_enable(const std::vector<std::string>& args) {
    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
    Service* svc = ServiceList::GetInstance().FindService(args[1]);
    if (!svc) {
        return -1;
    }
@@ -170,11 +171,30 @@ static int do_enable(const std::vector<std::string>& args) {
}

static int do_exec(const std::vector<std::string>& args) {
    return ServiceManager::GetInstance().Exec(args) ? 0 : -1;
    auto service = Service::MakeTemporaryOneshotService(args);
    if (!service) {
        LOG(ERROR) << "Failed to create exec service: " << android::base::Join(args, " ");
        return -1;
    }
    if (!service->ExecStart()) {
        LOG(ERROR) << "Failed to Start exec service";
        return -1;
    }
    ServiceList::GetInstance().AddService(std::move(service));
    return 0;
}

static int do_exec_start(const std::vector<std::string>& args) {
    return ServiceManager::GetInstance().ExecStart(args[1]) ? 0 : -1;
    Service* service = ServiceList::GetInstance().FindService(args[1]);
    if (!service) {
        LOG(ERROR) << "ExecStart(" << args[1] << "): Service not found";
        return -1;
    }
    if (!service->ExecStart()) {
        LOG(ERROR) << "ExecStart(" << args[1] << "): Could not start Service";
        return -1;
    }
    return 0;
}

static int do_export(const std::vector<std::string>& args) {
@@ -389,8 +409,8 @@ exit_success:
 */
static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {
    auto& action_manager = ActionManager::GetInstance();
    auto& service_manager = ServiceManager::GetInstance();
    Parser parser = CreateParser(action_manager, service_manager);
    auto& service_list = ServiceList::GetInstance();
    Parser parser = CreateParser(action_manager, service_list);
    if (end_index <= start_index) {
        // Fallbacks for partitions on which early mount isn't enabled.
        for (const auto& path : late_import_paths) {
@@ -580,7 +600,7 @@ static int do_setrlimit(const std::vector<std::string>& args) {
}

static int do_start(const std::vector<std::string>& args) {
    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
    Service* svc = ServiceList::GetInstance().FindService(args[1]);
    if (!svc) {
        LOG(ERROR) << "do_start: Service " << args[1] << " not found";
        return -1;
@@ -591,7 +611,7 @@ static int do_start(const std::vector<std::string>& args) {
}

static int do_stop(const std::vector<std::string>& args) {
    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
    Service* svc = ServiceList::GetInstance().FindService(args[1]);
    if (!svc) {
        LOG(ERROR) << "do_stop: Service " << args[1] << " not found";
        return -1;
@@ -601,7 +621,7 @@ static int do_stop(const std::vector<std::string>& args) {
}

static int do_restart(const std::vector<std::string>& args) {
    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
    Service* svc = ServiceList::GetInstance().FindService(args[1]);
    if (!svc) {
        LOG(ERROR) << "do_restart: Service " << args[1] << " not found";
        return -1;
+12 −12
Original line number Diff line number Diff line
@@ -98,22 +98,22 @@ static bool shutting_down;
std::vector<std::string> late_import_paths;

void DumpState() {
    ServiceManager::GetInstance().DumpState();
    ServiceList::GetInstance().DumpState();
    ActionManager::GetInstance().DumpState();
}

Parser CreateParser(ActionManager& action_manager, ServiceManager& service_manager) {
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser;

    parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_manager));
    parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list));
    parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager));
    parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));

    return parser;
}

static void LoadBootScripts(ActionManager& action_manager, ServiceManager& service_manager) {
    Parser parser = CreateParser(action_manager, service_manager);
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser = CreateParser(action_manager, service_list);

    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
@@ -221,8 +221,8 @@ void property_changed(const std::string& name, const std::string& value) {

static std::optional<boot_clock::time_point> RestartProcesses() {
    std::optional<boot_clock::time_point> next_process_restart_time;
    ServiceManager::GetInstance().ForEachService([&next_process_restart_time](Service* s) {
        if (!(s->flags() & SVC_RESTARTING)) return;
    for (const auto& s : ServiceList::GetInstance()) {
        if (!(s->flags() & SVC_RESTARTING)) continue;

        auto restart_time = s->time_started() + 5s;
        if (boot_clock::now() > restart_time) {
@@ -232,12 +232,12 @@ static std::optional<boot_clock::time_point> RestartProcesses() {
                next_process_restart_time = restart_time;
            }
        }
    });
    }
    return next_process_restart_time;
}

void handle_control_message(const std::string& msg, const std::string& name) {
    Service* svc = ServiceManager::GetInstance().FindServiceByName(name);
    Service* svc = ServiceList::GetInstance().FindService(name);
    if (svc == nullptr) {
        LOG(ERROR) << "no such service '" << name << "'";
        return;
@@ -1139,7 +1139,7 @@ int main(int argc, char** argv) {
    Action::set_function_map(&function_map);

    ActionManager& am = ActionManager::GetInstance();
    ServiceManager& sm = ServiceManager::GetInstance();
    ServiceList& sm = ServiceList::GetInstance();

    LoadBootScripts(am, sm);

@@ -1180,10 +1180,10 @@ int main(int argc, char** argv) {
        // By default, sleep until something happens.
        int epoll_timeout_ms = -1;

        if (!(waiting_for_prop || sm.IsWaitingForExec())) {
        if (!(waiting_for_prop || Service::is_exec_service_running())) {
            am.ExecuteOneCommand();
        }
        if (!(waiting_for_prop || sm.IsWaitingForExec())) {
        if (!(waiting_for_prop || Service::is_exec_service_running())) {
            if (!shutting_down) {
                auto next_process_restart_time = RestartProcesses();

+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ extern struct selabel_handle *sehandle_prop;

extern std::vector<std::string> late_import_paths;

Parser CreateParser(ActionManager& action_manager, ServiceManager& service_manager);
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list);

void handle_control_message(const std::string& msg, const std::string& arg);

+4 −2
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ static void handle_keychord() {
    // Only handle keychords if adb is enabled.
    std::string adb_enabled = android::base::GetProperty("init.svc.adbd", "");
    if (adb_enabled == "running") {
        Service* svc = ServiceManager::GetInstance().FindServiceByKeychord(id);
        Service* svc = ServiceList::GetInstance().FindService(id, &Service::keychord_id);
        if (svc) {
            LOG(INFO) << "Starting service " << svc->name() << " from keychord " << id;
            svc->Start();
@@ -92,7 +92,9 @@ static void handle_keychord() {
}

void keychord_init() {
    ServiceManager::GetInstance().ForEachService(add_service_keycodes);
    for (const auto& service : ServiceList::GetInstance()) {
        add_service_keycodes(service.get());
    }

    // Nothing to do if no services require keychords.
    if (!keychords) {
+23 −21
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@
#include "init.h"
#include "property_service.h"
#include "service.h"
#include "signal_handler.h"

using android::base::StringPrintf;
using android::base::Timer;
@@ -373,7 +374,7 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
    const std::set<std::string> kill_after_apps{"tombstoned", "logd", "adbd"};
    // watchdogd is a vendor specific component but should be alive to complete shutdown safely.
    const std::set<std::string> to_starts{"watchdogd"};
    ServiceManager::GetInstance().ForEachService([&kill_after_apps, &to_starts](Service* s) {
    for (const auto& s : ServiceList::GetInstance()) {
        if (kill_after_apps.count(s->name())) {
            s->SetShutdownCritical();
        } else if (to_starts.count(s->name())) {
@@ -382,14 +383,15 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
        } else if (s->IsShutdownCritical()) {
            s->Start();  // start shutdown critical service if not started
        }
    });
    }

    Service* bootAnim = ServiceManager::GetInstance().FindServiceByName("bootanim");
    Service* surfaceFlinger = ServiceManager::GetInstance().FindServiceByName("surfaceflinger");
    Service* bootAnim = ServiceList::GetInstance().FindService("bootanim");
    Service* surfaceFlinger = ServiceList::GetInstance().FindService("surfaceflinger");
    if (bootAnim != nullptr && surfaceFlinger != nullptr && surfaceFlinger->IsRunning()) {
        ServiceManager::GetInstance().ForEachServiceInClass("animation", [](Service* s) {
            s->SetShutdownCritical();  // will not check animation class separately
        });
        // will not check animation class separately
        for (const auto& service : ServiceList::GetInstance()) {
            if (service->classnames().count("animation")) service->SetShutdownCritical();
        }
    }

    // optional shutdown step
@@ -398,18 +400,18 @@ 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().ForEachServiceShutdownOrder([](Service* s) {
        for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
            if (!s->IsShutdownCritical()) s->Terminate();
        });
        }

        int service_count = 0;
        // Only wait up to half of timeout here
        auto termination_wait_timeout = shutdown_timeout / 2;
        while (t.duration() < termination_wait_timeout) {
            ServiceManager::GetInstance().ReapAnyOutstandingChildren();
            ReapAnyOutstandingChildren();

            service_count = 0;
            ServiceManager::GetInstance().ForEachService([&service_count](Service* s) {
            for (const auto& s : ServiceList::GetInstance()) {
                // Count the number of services running except shutdown critical.
                // Exclude the console as it will ignore the SIGTERM signal
                // and not exit.
@@ -418,7 +420,7 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
                if (!s->IsShutdownCritical() && s->pid() != 0 && (s->flags() & SVC_CONSOLE) == 0) {
                    service_count++;
                }
            });
            }

            if (service_count == 0) {
                // All terminable services terminated. We can exit early.
@@ -434,13 +436,13 @@ 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().ForEachServiceShutdownOrder([](Service* s) {
    for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
        if (!s->IsShutdownCritical()) s->Stop();
    });
    ServiceManager::GetInstance().ReapAnyOutstandingChildren();
    }
    ReapAnyOutstandingChildren();

    // 3. send volume shutdown to vold
    Service* voldService = ServiceManager::GetInstance().FindServiceByName("vold");
    Service* voldService = ServiceList::GetInstance().FindService("vold");
    if (voldService != nullptr && voldService->IsRunning()) {
        ShutdownVold();
        voldService->Stop();
@@ -448,9 +450,9 @@ 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().ForEachServiceShutdownOrder([&kill_after_apps](Service* s) {
    for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
        if (kill_after_apps.count(s->name())) s->Stop();
    });
    }
    // 4. sync, try umount, and optionally run fsck for user shutdown
    sync();
    UmountStat stat = TryUmountAndFsck(runFsck, shutdown_timeout - t.duration());
@@ -524,9 +526,9 @@ bool HandlePowerctlMessage(const std::string& command) {
    // Skip wait for prop if it is in progress
    ResetWaitForProp();

    // Skip wait for exec if it is in progress
    if (ServiceManager::GetInstance().IsWaitingForExec()) {
        ServiceManager::GetInstance().ClearExecWait();
    // Clear EXEC flag if there is one pending
    for (const auto& s : ServiceList::GetInstance()) {
        s->UnSetExec();
    }

    return true;
Loading