llkd: ignore frozen processes

verify a process frozen state by reading its frezer cgroup value and
don't consider it as loop-locked if frozen.

Bug: 145698592
Test: llkd_unit_test
Test: Manually froze a few processes and waited for llkd timeout, verifying that
      no processes are killed, no reboot or ramdump occur and no llkd events are
      logged.
Change-Id: Iea02cd86dbd1df0e6658d02581aa4bb9b658f107
This commit is contained in:
Marco Ballesio 2019-12-27 13:43:29 -08:00
parent 62f35129d4
commit 38c735e6ef

View file

@ -304,10 +304,13 @@ struct proc {
bool cmdlineValid; // cmdline has been cached
bool updated; // cleared before monitoring pass.
bool killed; // sent a kill to this thread, next panic...
bool frozen; // process is in frozen cgroup.
void setComm(const char* _comm) { strncpy(comm + 1, _comm, sizeof(comm) - 2); }
proc(pid_t tid, pid_t pid, pid_t ppid, const char* _comm, int time, char state)
void setFrozen(bool _frozen) { frozen = _frozen; }
proc(pid_t tid, pid_t pid, pid_t ppid, const char* _comm, int time, char state, bool frozen)
: tid(tid),
schedUpdate(0),
nrSwitches(0),
@ -327,7 +330,8 @@ struct proc {
exeMissingValid(false),
cmdlineValid(false),
updated(true),
killed(!llkTestWithKill) {
killed(!llkTestWithKill),
frozen(frozen) {
memset(comm, '\0', sizeof(comm));
setComm(_comm);
}
@ -373,6 +377,8 @@ struct proc {
return uid;
}
bool isFrozen() { return frozen; }
void reset(void) { // reset cache, if we detected pid rollover
uid = -1;
state = '?';
@ -592,8 +598,9 @@ void llkTidRemove(pid_t tid) {
tids.erase(tid);
}
proc* llkTidAlloc(pid_t tid, pid_t pid, pid_t ppid, const char* comm, int time, char state) {
auto it = tids.emplace(std::make_pair(tid, proc(tid, pid, ppid, comm, time, state)));
proc* llkTidAlloc(pid_t tid, pid_t pid, pid_t ppid, const char* comm, int time, char state,
bool frozen) {
auto it = tids.emplace(std::make_pair(tid, proc(tid, pid, ppid, comm, time, state, frozen)));
return &it.first->second;
}
@ -1039,12 +1046,18 @@ milliseconds llkCheck(bool checkRunning) {
continue;
}
// Get the process cgroup
auto cgroup = ReadFile(piddir + "/cgroup");
auto frozen = cgroup.find(":freezer:/frozen") != std::string::npos;
auto procp = llkTidLookup(tid);
if (procp == nullptr) {
procp = llkTidAlloc(tid, pid, ppid, pdir, utime + stime, state);
procp = llkTidAlloc(tid, pid, ppid, pdir, utime + stime, state, frozen);
} else {
// comm can change ...
procp->setComm(pdir);
// frozen can change, too...
procp->setFrozen(frozen);
procp->updated = true;
// pid/ppid/tid wrap?
if (((procp->update != prevUpdate) && (procp->update != llkUpdate)) ||
@ -1084,6 +1097,9 @@ milliseconds llkCheck(bool checkRunning) {
if ((tid == myTid) || llkSkipPid(tid)) {
continue;
}
if (procp->isFrozen()) {
break;
}
if (llkSkipPpid(ppid)) {
break;
}
@ -1101,7 +1117,7 @@ milliseconds llkCheck(bool checkRunning) {
auto pprocp = llkTidLookup(ppid);
if (pprocp == nullptr) {
pprocp = llkTidAlloc(ppid, ppid, 0, "", 0, '?');
pprocp = llkTidAlloc(ppid, ppid, 0, "", 0, '?', false);
}
if (pprocp) {
if (llkSkipPproc(pprocp, procp)) break;