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

Commit 5c3e2481 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Kill services even when cgroups is disabled"

parents 67bd5b01 a049a992
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -712,8 +712,6 @@ Result<void> Service::Start() {
        if (use_memcg) {
            ConfigureMemcg();
        }
    } else {
        process_cgroup_empty_ = true;
    }

    if (oom_score_adjust_ != DEFAULT_OOM_SCORE_ADJUST) {
+59 −39
Original line number Diff line number Diff line
@@ -367,8 +367,17 @@ err:
// Returns 0 if there are no processes in the process cgroup left to kill
// Returns -1 on error
static int DoKillProcessGroupOnce(const char* cgroup, uid_t uid, int initialPid, int signal) {
    // We separate all of the pids in the cgroup into those pids that are also the leaders of
    // process groups (stored in the pgids set) and those that are not (stored in the pids set).
    std::set<pid_t> pgids;
    pgids.emplace(initialPid);
    std::set<pid_t> pids;

    std::unique_ptr<FILE, decltype(&fclose)> fd(nullptr, fclose);

    if (CgroupsAvailable()) {
        auto path = ConvertUidPidToPath(cgroup, uid, initialPid) + PROCESSGROUP_CGROUP_PROCS_FILE;
    std::unique_ptr<FILE, decltype(&fclose)> fd(fopen(path.c_str(), "re"), fclose);
        fd.reset(fopen(path.c_str(), "re"));
        if (!fd) {
            if (errno == ENOENT) {
                // This happens when process is already dead
@@ -378,21 +387,15 @@ static int DoKillProcessGroupOnce(const char* cgroup, uid_t uid, int initialPid,
                          << initialPid;
            return -1;
        }

    // We separate all of the pids in the cgroup into those pids that are also the leaders of
    // process groups (stored in the pgids set) and those that are not (stored in the pids set).
    std::set<pid_t> pgids;
    pgids.emplace(initialPid);
    std::set<pid_t> pids;

        pid_t pid;
    int processes = 0;
        bool file_is_empty = true;
        while (fscanf(fd.get(), "%d\n", &pid) == 1 && pid >= 0) {
        processes++;
            file_is_empty = false;
            if (pid == 0) {
                // Should never happen...  but if it does, trying to kill this
                // will boomerang right back and kill us!  Let's not let that happen.
            LOG(WARNING) << "Yikes, we've been told to kill pid 0!  How about we don't do that?";
                LOG(WARNING)
                        << "Yikes, we've been told to kill pid 0!  How about we don't do that?";
                continue;
            }
            pid_t pgid = getpgid(pid);
@@ -403,6 +406,10 @@ static int DoKillProcessGroupOnce(const char* cgroup, uid_t uid, int initialPid,
                pids.emplace(pid);
            }
        }
        if (file_is_empty) {
            // This happens when process is already dead
            return 0;
        }

        // Erase all pids that will be killed when we kill the process groups.
        for (auto it = pids.begin(); it != pids.end();) {
@@ -413,13 +420,17 @@ static int DoKillProcessGroupOnce(const char* cgroup, uid_t uid, int initialPid,
                ++it;
            }
        }
    }

    int processes = 0;
    // Kill all process groups.
    for (const auto pgid : pgids) {
        LOG(VERBOSE) << "Killing process group " << -pgid << " in uid " << uid
                     << " as part of process cgroup " << initialPid;

        if (kill(-pgid, signal) == -1 && errno != ESRCH) {
        if (kill(-pgid, signal) == 0) {
            processes++;
        } else if (errno != ESRCH) {
            PLOG(WARNING) << "kill(" << -pgid << ", " << signal << ") failed";
        }
    }
@@ -429,18 +440,22 @@ static int DoKillProcessGroupOnce(const char* cgroup, uid_t uid, int initialPid,
        LOG(VERBOSE) << "Killing pid " << pid << " in uid " << uid << " as part of process cgroup "
                     << initialPid;

        if (kill(pid, signal) == -1 && errno != ESRCH) {
        if (kill(pid, signal) == 0) {
            processes++;
        } else if (errno != ESRCH) {
            PLOG(WARNING) << "kill(" << pid << ", " << signal << ") failed";
        }
    }

    return feof(fd.get()) ? processes : -1;
    return (!fd || feof(fd.get())) ? processes : -1;
}

static int KillProcessGroup(uid_t uid, int initialPid, int signal, int retries,
                            int* max_processes) {
    std::string hierarchy_root_path;
    if (CgroupsAvailable()) {
        CgroupGetControllerPath(CGROUPV2_CONTROLLER_NAME, &hierarchy_root_path);
    }
    const char* cgroup = hierarchy_root_path.c_str();

    std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
@@ -485,6 +500,11 @@ static int KillProcessGroup(uid_t uid, int initialPid, int signal, int retries,
                      << " in " << static_cast<int>(ms) << "ms";
        }

        if (!CgroupsAvailable()) {
            // nothing to do here, if cgroups isn't available
            return 0;
        }

        // 400 retries correspond to 2 secs max timeout
        int err = RemoveProcessGroup(cgroup, uid, initialPid, 400);