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

Commit ebe6598a authored by Xin Li's avatar Xin Li
Browse files

Merge tm-dev-plus-aosp-without-vendor@8763363

Bug: 236760014
Merged-In: Ia927c19f544536f78c20ccef5830bd1be0cebf9b
Change-Id: I0267b9eaad470a56db68f3a0b99abfc41192c6d7
parents 2619a7e9 9c3f5a2a
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include <functional>
#include <map>

#include <android-base/logging.h>

namespace android {
namespace init {

@@ -42,8 +44,11 @@ Result<void> Epoll::RegisterHandler(int fd, Handler handler, uint32_t events) {
    if (!events) {
        return Error() << "Must specify events";
    }
    auto sp = std::make_shared<decltype(handler)>(std::move(handler));
    auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(sp));

    Info info;
    info.events = events;
    info.handler = std::make_shared<decltype(handler)>(std::move(handler));
    auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(info));
    if (!inserted) {
        return Error() << "Cannot specify two epoll handlers for a given FD";
    }
@@ -84,8 +89,14 @@ Result<std::vector<std::shared_ptr<Epoll::Handler>>> Epoll::Wait(
    }
    std::vector<std::shared_ptr<Handler>> pending_functions;
    for (int i = 0; i < num_events; ++i) {
        auto sp = *reinterpret_cast<std::shared_ptr<Handler>*>(ev[i].data.ptr);
        pending_functions.emplace_back(std::move(sp));
        auto& info = *reinterpret_cast<Info*>(ev[i].data.ptr);
        if ((info.events & (EPOLLIN | EPOLLPRI)) == (EPOLLIN | EPOLLPRI) &&
            (ev[i].events & EPOLLIN) != ev[i].events) {
            // This handler wants to know about exception events, and just got one.
            // Log something informational.
            LOG(ERROR) << "Received unexpected epoll event set: " << ev[i].events;
        }
        pending_functions.emplace_back(info.handler);
    }

    return pending_functions;
+6 −1
Original line number Diff line number Diff line
@@ -46,8 +46,13 @@ class Epoll {
            std::optional<std::chrono::milliseconds> timeout);

  private:
    struct Info {
        std::shared_ptr<Handler> handler;
        uint32_t events;
    };

    android::base::unique_fd epoll_fd_;
    std::map<int, std::shared_ptr<Handler>> epoll_handlers_;
    std::map<int, Info> epoll_handlers_;
};

}  // namespace init
+47 −4
Original line number Diff line number Diff line
@@ -33,7 +33,10 @@
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/_system_properties.h>

#include <filesystem>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <mutex>
@@ -632,10 +635,10 @@ static void HandleSigtermSignal(const signalfd_siginfo& siginfo) {

static constexpr std::chrono::milliseconds kDiagnosticTimeout = 10s;

static void HandleSignalFd() {
static void HandleSignalFd(bool one_off) {
    signalfd_siginfo siginfo;
    auto started = std::chrono::steady_clock::now();
    for (;;) {
    do {
        ssize_t bytes_read = TEMP_FAILURE_RETRY(read(signal_fd, &siginfo, sizeof(siginfo)));
        if (bytes_read < 0 && errno == EAGAIN) {
            auto now = std::chrono::steady_clock::now();
@@ -653,7 +656,7 @@ static void HandleSignalFd() {
            return;
        }
        break;
    }
    } while (!one_off);

    switch (siginfo.ssi_signo) {
        case SIGCHLD:
@@ -713,7 +716,9 @@ static void InstallSignalFdHandler(Epoll* epoll) {
        PLOG(FATAL) << "failed to create signalfd";
    }

    if (auto result = epoll->RegisterHandler(signal_fd, HandleSignalFd); !result.ok()) {
    constexpr int flags = EPOLLIN | EPOLLPRI;
    auto handler = std::bind(HandleSignalFd, false);
    if (auto result = epoll->RegisterHandler(signal_fd, handler, flags); !result.ok()) {
        LOG(FATAL) << result.error();
    }
}
@@ -842,6 +847,32 @@ static Result<void> ConnectEarlyStageSnapuserdAction(const BuiltinArguments& arg
    return {};
}

static void DumpPidFds(const std::string& prefix, pid_t pid) {
    std::error_code ec;
    std::string proc_dir = "/proc/" + std::to_string(pid) + "/fd";
    for (const auto& entry : std::filesystem::directory_iterator(proc_dir)) {
        std::string target;
        if (android::base::Readlink(entry.path(), &target)) {
            LOG(ERROR) << prefix << target;
        } else {
            LOG(ERROR) << prefix << entry.path();
        }
    }
}

static void DumpFile(const std::string& prefix, const std::string& file) {
    std::ifstream fp(file);
    if (!fp) {
        LOG(ERROR) << "Could not open " << file;
        return;
    }

    std::string line;
    while (std::getline(fp, line)) {
        LOG(ERROR) << prefix << line;
    }
}

int SecondStageMain(int argc, char** argv) {
    if (REBOOT_BOOTLOADER_ON_PANIC) {
        InstallRebootSignalHandlers();
@@ -1051,11 +1082,23 @@ int SecondStageMain(int argc, char** argv) {
                (*function)();
            }
        } else if (Service::is_exec_service_running()) {
            static bool dumped_diagnostics = false;
            std::chrono::duration<double> waited =
                    std::chrono::steady_clock::now() - Service::exec_service_started();
            if (waited >= kDiagnosticTimeout) {
                LOG(ERROR) << "Exec service is hung? Waited " << waited.count()
                           << " without SIGCHLD";
                if (!dumped_diagnostics) {
                    DumpPidFds("exec service opened: ", Service::exec_service_pid());

                    std::string status_file =
                            "/proc/" + std::to_string(Service::exec_service_pid()) + "/status";
                    DumpFile("exec service: ", status_file);
                    dumped_diagnostics = true;

                    LOG(INFO) << "Attempting to handle any stuck SIGCHLDs...";
                    HandleSignalFd(true);
                }
            }
        }
        if (!IsShuttingDown()) {
+2 −0
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@ static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigsto

unsigned long Service::next_start_order_ = 1;
bool Service::is_exec_service_running_ = false;
pid_t Service::exec_service_pid_ = -1;
std::chrono::time_point<std::chrono::steady_clock> Service::exec_service_started_;

Service::Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
@@ -393,6 +394,7 @@ Result<void> Service::ExecStart() {

    flags_ |= SVC_EXEC;
    is_exec_service_running_ = true;
    exec_service_pid_ = pid_;
    exec_service_started_ = std::chrono::steady_clock::now();

    LOG(INFO) << "SVC_EXEC service '" << name_ << "' pid " << pid_ << " (uid " << proc_attr_.uid
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ class Service {
    size_t CheckAllCommands() const { return onrestart_.CheckAllCommands(); }

    static bool is_exec_service_running() { return is_exec_service_running_; }
    static pid_t exec_service_pid() { return exec_service_pid_; }
    static std::chrono::time_point<std::chrono::steady_clock> exec_service_started() {
        return exec_service_started_;
    }
Loading