void DoExit(UserContext *context) { if (1 == current_process->id) { TracePrintf(1, "Do Exit: init program exiting. Now calling halt.\n"); Halt(); } if (current_process->parent) { current_process->status = context->regs[0]; } TracePrintf(2, "DoExit\n"); KillProc(current_process); TracePrintf(2, "DoExit: Finished the murder\n"); LoadNextProc(context, BLOCK); }
//! Kill process which is eating most void ProcessManager::KillHighest(bool hard) { PROCTAB* proc = openproc(PROC_FILLARG | PROC_FILLSTAT | PROC_FILLMEM); proc_t* proc_info; // zero out the allocated proc_info memory //memset(&proc_info, 0, sizeof(proc_info)); proc_t highest; long current_highest = 0; int current_score = -100; Core::DebugLog("Looking for a best candidate"); while (true) { proc_info = readproc(proc, NULL); if (proc_info == NULL) { break; } if (!Configuration::KillRoot && (int)proc_info->euid == 0) { if (Configuration::Verbosity >= 6) { Core::DebugLog("Ignoring " + Core::int2String(proc_info->tid) + " owned by root", 6); } freeproc(proc_info); continue; } if (IgnoredId(proc_info->euid)) { Core::DebugLog("Ignoring " + Core::int2String(proc_info->tid) + " owned by ignored account: " + Core::int2String(proc_info->euid), 2); freeproc(proc_info); continue; } if (proc_info->tid == Configuration::pid && !Configuration::KillSelf) { Core::DebugLog("Ignoring " + Core::int2String(proc_info->tid) + " which is current instance of this daemon", 6); freeproc(proc_info); continue; } int score = 0; // if it's a root process, decrease the score by 10 if (proc_info->euser == 0) { score -= 10; } score = score + (int)proc_info->nice; int badness_score = Core::GetOom(proc_info->tid); if (badness_score <= -17) { // ignore process freeproc(proc_info); continue; } if (badness_score != 0) { score = score + badness_score; } // check if this process is using most memory if ( proc_info->resident * 4 > current_highest ) { current_highest = proc_info->resident * 4; score += 10; } // if this process has highest score, we flag it for kill if ( score >= current_score ) { highest = *proc_info; current_score = score; } else { if (Configuration::Verbosity >= 12) { Core::DebugLog("Process " + Name(proc_info) + "is eating less than highest candidate", 12); } } freeproc(proc_info); } if (current_score == -100) { Core::ErrorLog("Unable to find any process to kill. System is running OOM and I can't do anything to fix it."); closeproc(proc); return; } Core::Log("Most preferred process has score " + Core::int2String(current_score) + " : " + Name(&highest) + " killing now"); if (KillExec(&highest) == 0) { KillProc((pid_t)highest.tid, hard); Exec(&highest); }else { Core::Log("Not killed " + Name(&highest) + " because the test command returned different value"); } closeproc(proc); return; }
//! Kill processes that are exceeding the limits void ProcessManager::KillExcess() { PROCTAB* proc = openproc(PROC_FILLARG | PROC_FILLSTAT | PROC_FILLMEM); Core::DebugLog("Looking for processes that exceed the hard or soft limit", 10); proc_t *proc_info; while (true) { proc_info = readproc(proc, NULL); if (proc_info == NULL) { break; } if (proc_info->tid == Configuration::pid && !Configuration::KillSelf) { Core::DebugLog("Ignoring " + Core::int2String(proc_info->tid) + " which is current instance of this daemon", 8); freeproc(proc_info); continue; } if (!Configuration::KillRoot && (int)proc_info->euid == 0) { if (Configuration::Verbosity >= 6) { Core::DebugLog("Ignoring " + Core::int2String(proc_info->tid) + " owned by root", 6); } freeproc(proc_info); continue; } if (IgnoredId(proc_info->euid)) { Core::DebugLog("Ignoring " + Core::int2String(proc_info->tid) + " owned by ignored account: " + Core::int2String(proc_info->euid), 3); freeproc(proc_info); continue; } // check if this process is using most memory if ( proc_info->resident * 4 > ((long)Configuration::HardMemoryLimitMB * 1024) ) { Core::Log("Exceeded hard limit - process " + Name(proc_info) + " killing now"); KillProc((pid_t)proc_info->tid, true); Exec(proc_info); } else if ( proc_info->resident * 4 > ((long)Configuration::SoftMemoryLimitMB * 1024 )) { Core::Log("Exceeded soft limit - process " + Name(proc_info) + " killing now"); if (KillExec(proc_info) == 0) { KillProc((pid_t)proc_info->tid, false); Exec(proc_info); }else { Core::Log("Not killed " + Name(proc_info) + " because the test command returned different value"); } } else { if (Configuration::Verbosity > 12) { Core::DebugLog("Not exceeded any limit " + Name(proc_info)); } } freeproc(proc_info); } closeproc(proc); return; }