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

Commit e89c4571 authored by Jooyung Han's avatar Jooyung Han Committed by Gerrit Code Review
Browse files

Merge "init starts servicemanagers in "default" mount ns"

parents 45545c68 c5fa15e0
Loading
Loading
Loading
Loading
+36 −25
Original line number Diff line number Diff line
@@ -315,7 +315,9 @@ void Service::Reap(const siginfo_t& siginfo) {
#else
    static bool is_apex_updatable = false;
#endif
    const bool is_process_updatable = !use_bootstrap_ns_ && is_apex_updatable;
    const bool use_default_mount_ns =
            mount_namespace_.has_value() && *mount_namespace_ == NS_DEFAULT;
    const bool is_process_updatable = use_default_mount_ns && is_apex_updatable;

    // If we crash > 4 times in 'fatal_crash_window_' minutes or before boot_completed,
    // reboot into bootloader or set crashing property
@@ -474,10 +476,9 @@ void Service::ConfigureMemcg() {
}

// Enters namespaces, sets environment variables, writes PID files and runs the service executable.
void Service::RunService(const std::optional<MountNamespace>& override_mount_namespace,
                         const std::vector<Descriptor>& descriptors,
void Service::RunService(const std::vector<Descriptor>& descriptors,
                         std::unique_ptr<std::array<int, 2>, decltype(&ClosePipe)> pipefd) {
    if (auto result = EnterNamespaces(namespaces_, name_, override_mount_namespace); !result.ok()) {
    if (auto result = EnterNamespaces(namespaces_, name_, mount_namespace_); !result.ok()) {
        LOG(FATAL) << "Service '" << name_ << "' failed to set up namespaces: " << result.error();
    }

@@ -581,26 +582,9 @@ Result<void> Service::Start() {
        scon = *result;
    }

    // APEXd is always started in the "current" namespace because it is the process to set up
    // the current namespace.
    const bool is_apexd = args_[0] == "/system/bin/apexd";

    if (!IsDefaultMountNamespaceReady() && !is_apexd) {
        // If this service is started before APEXes and corresponding linker configuration
        // get available, mark it as pre-apexd one. Note that this marking is
        // permanent. So for example, if the service is re-launched (e.g., due
        // to crash), it is still recognized as pre-apexd... for consistency.
        use_bootstrap_ns_ = true;
    }

    // For pre-apexd services, override mount namespace as "bootstrap" one before starting.
    // Note: "ueventd" is supposed to be run in "default" mount namespace even if it's pre-apexd
    // to support loading firmwares from APEXes.
    std::optional<MountNamespace> override_mount_namespace;
    if (name_ == "ueventd") {
        override_mount_namespace = NS_DEFAULT;
    } else if (use_bootstrap_ns_) {
        override_mount_namespace = NS_BOOTSTRAP;
    if (!mount_namespace_.has_value()) {
        // remember from which mount namespace the service should start
        SetMountNamespace();
    }

    post_data_ = ServiceList::GetInstance().IsPostData();
@@ -633,7 +617,7 @@ Result<void> Service::Start() {

    if (pid == 0) {
        umask(077);
        RunService(override_mount_namespace, descriptors, std::move(pipefd));
        RunService(descriptors, std::move(pipefd));
        _exit(127);
    }

@@ -684,6 +668,33 @@ Result<void> Service::Start() {
    return {};
}

// Set mount namespace for the service.
// The reason why remember the mount namespace:
//   If this service is started before APEXes and corresponding linker configuration
//   get available, mark it as pre-apexd one. Note that this marking is
//   permanent. So for example, if the service is re-launched (e.g., due
//   to crash), it is still recognized as pre-apexd... for consistency.
void Service::SetMountNamespace() {
    // APEXd is always started in the "current" namespace because it is the process to set up
    // the current namespace. So, leave mount_namespace_ as empty.
    if (args_[0] == "/system/bin/apexd") {
        return;
    }
    // Services in the following list start in the "default" mount namespace.
    // Note that they should use bootstrap bionic if they start before APEXes are ready.
    static const std::set<std::string> kUseDefaultMountNamespace = {
            "ueventd",           // load firmwares from APEXes
            "hwservicemanager",  // load VINTF fragments from APEXes
            "servicemanager",    // load VINTF fragments from APEXes
    };
    if (kUseDefaultMountNamespace.find(name_) != kUseDefaultMountNamespace.end()) {
        mount_namespace_ = NS_DEFAULT;
        return;
    }
    // Use the "default" mount namespace only if it's ready
    mount_namespace_ = IsDefaultMountNamespaceReady() ? NS_DEFAULT : NS_BOOTSTRAP;
}

void Service::SetStartedInFirstStage(pid_t pid) {
    LOG(INFO) << "adding first-stage service '" << name_ << "'...";

+3 −3
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include "action.h"
#include "capabilities.h"
#include "keyword_map.h"
#include "mount_namespace.h"
#include "parser.h"
#include "service_utils.h"
#include "subcontext.h"
@@ -151,10 +152,9 @@ class Service {
    Result<void> CheckConsole();
    void ConfigureMemcg();
    void RunService(
            const std::optional<MountNamespace>& override_mount_namespace,
            const std::vector<Descriptor>& descriptors,
            std::unique_ptr<std::array<int, 2>, void (*)(const std::array<int, 2>* pipe)> pipefd);

    void SetMountNamespace();
    static unsigned long next_start_order_;
    static bool is_exec_service_running_;
    static std::chrono::time_point<std::chrono::steady_clock> exec_service_started_;
@@ -219,7 +219,7 @@ class Service {

    std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_;

    bool use_bootstrap_ns_ = false;
    std::optional<MountNamespace> mount_namespace_;

    bool post_data_ = false;