Wie gehe ich mit einer speicherhungrigen Gabelbombe unter Linux um?

960
swordfeng

Ich weiß, dass eine Gabelbombe verhindert werden kann, indem die Anzahl der Prozesse eines einzelnen Benutzers begrenzt wird, und wenn ein Speicherleckage auftritt, wird mein Betriebssystem für Linux nicht den OOM-Killer einfrieren. Aber wie wäre es mit einer speicherintensiven Gabelbombe?

#include <vector> #include <unistd.h> #include <ctime> #include <cstdlib>  using namespace std;  int main() { srand(time(NULL)); vector<int> vec; do { try { for (int i=0; i<10000000; i++) vec.push_back(rand()); } catch (bad_alloc e) { } fork(); } while (1); return 0; } 

Mein Linux wurde eingefroren, nachdem ich diesen Code ausprobiert hatte. Kann ich trotzdem verhindern, dass es einfriert?
Der Code wurde unter Archlinux, Linux 4.0.5 getestet

kompilieren Sie den Code einfach mit diesem Befehl: g++ -o test test.cpp

Weitere Informationen: Da der Code mein ganzes Gedächtnis auffressen kann, indem er nur ein paar Mal gegabelt wird, ist er nicht wie eine normale Gabelbombe und das Begrenzen der Anzahl von Prozessen ist nutzlos. Außerdem wird fork () häufig ausgeführt (wenn der Speicher knapp ist), so dass der OOM-Killer viel langsamer ist als die Gabeln. Daher muss ich Alt-SysRq-REI verwenden, um diese Prozesse zu stoppen, aber das ist nicht das, was ich will.

Dies ist mein erstes Mal bei SuperUser. Helfen Sie mir, wenn meine Frage unangemessen ist. Und danke für deine Hilfe.

3
Ich verstehe die Frage nicht ganz. Versuchen Sie, einen schnellen Gedächtnisverlust zu verhindern? Warum würde dies jemals mit einem regulären Programm passieren? (Es sei denn, dies ist eine Unternehmensumgebung und Sie möchten Ihre Workstations überhärten.) oldmud0 vor 8 Jahren 0
@ oldmud0 Ich glaube es sollte nicht mit normalen Programmen passieren. Allerdings haben Firefox mein System mehrmals eingefroren, vielleicht durch Speicherleck (denke ich). Ein normales, speicherintensives Programm wird jedoch immer vom OOM-Killer gestoppt. Also fing ich an, den Grund zu finden. swordfeng vor 8 Jahren 0

1 Antwort auf die Frage

1
Dan Cornilescu

Es muss sich nicht um eine speicherleckende Gabelbombe handeln - selbst wenn beispielsweise make -j(oder mit einem zu hohen jFaktor) eine moderate Codegröße oder ein Prozess, der einen Haufen Nachkommen hervorbringt (weniger als das für einen aktiven Benutzer angemessene Limit) ) kann jedes Kauen einer Menge an Speicher, die für sich allein von Bedeutung ist, aber zu klein ist, um vom OOM-Killer anvisiert zu werden (oder um eine signifikante Erleichterung zu bieten, wenn der OOM-Killer ihn festnagelt), eine ähnliche Wirkung haben.

Es ist möglich, ein benutzerdefiniertes Überwachungsskript / -werkzeug (das von root mit hoher Priorität ausgeführt werden soll) zu schreiben, das auf solche Prozess-Laichmuster achten und sie gegebenenfalls nach pgid oder userid (dh simultan, nicht nacheinander wie das OOM) beenden kann Killer), bevor sie für das System tödlich werden. Würde für vernünftige Laich / Ressource Trockenlegung Raten, aber ich bin nicht sicher, ob möglich, nur irgendwelche Preise.

Der Kernel kann es also nicht verhindern, oder? Vielen Dank für Ihre Antwort. swordfeng vor 8 Jahren 0
Nicht über eine Methode, die ich kenne. Dan Cornilescu vor 8 Jahren 0
Können cgroups des Kernels Ressourcen wie Speicher nicht einschränken, die hier respektiert werden würden? Zu überwachen und dann zu versuchen, es zu fangen, ist eine Art Wettlaufsituation, aber ich denke, dass vorgegebene Grenzwerte viel leichter durchsetzbar sind. ttbek vor 6 Jahren 0
@ttbek mit vorgegebenen Grenzen Es ist schwierig, ein vernünftiges Gleichgewicht zwischen der Unterauslastung des Systems, wenn nur wenige Benutzer / Prozesse aktiv sind, und der Überlastung des Systems zu erreichen, wenn viele solcher Benutzer / Prozesse aktiv sind. Auf einem 32-Kern-System würde ich das Äquivalent von "-j32" wählen, wenn ein Benutzer erstellt, und "-j8", wenn 4 Benutzer bauen. Beide Werte sind in einem Fall OK, im anderen Fall jedoch nicht. Dan Cornilescu vor 6 Jahren 0
@DanCornilescu Das kannst du tun. Den Benutzern können CPU-Anteile (keine Quoten) zu je 250 zugewiesen werden. Nicht verwendete Freigaben sind für jedermann verfügbar, sodass ein Benutzergebäude alle verfügbaren CPU-Zyklen verwenden kann. Wenn jedoch vier ausgeführt werden, erhalten sie jeweils ein Viertel der Zyklen. https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/sect-cpu-Example_Usage.html Mit dem Begriff vorbestimmte Bedeutung hatte der Kernel in der Lage, CPU-Zyklen davon abzuhalten Benutzer auch wenn sein Prozess zuerst gestartet wurde. ttbek vor 6 Jahren 0
In einigen anderen Bereichen ist es üblich, ein härteres Limit zu verwenden. Beispielsweise ist es üblich, HDs für bis zu 5% zu formatieren, um für root / system reserviert zu werden. Wenn Sie mit dem Speichercontroller cgroups (oder cgroups2) einige hundert MB RAM für root reservieren, kann dies möglicherweise gegen das vorgeschlagene Szenario (oder auch nicht, da bin ich mir nicht sicher) helfen. Es sollte das OOM auslösen, wann immer die Grenze überschritten wird. Sie kann jedoch auch benutzerdefinierte Funktionen auslösen, wenn ich mich erinnere. Vielleicht noch ein Rennen, aber ich denke, wenn der Kernel das Rennen nicht gewinnen kann, haben Sie mit etwas anderem kein Glück. ttbek vor 6 Jahren 0