So bereinigen Sie den tmp-Ordner sicher unter Linux

15

Ich benutze RAM für meine tmpfs / tmp, 2 GB, um genau zu sein. Normalerweise reicht dies aus, aber manchmal erstellen Prozesse dort Dateien und können nicht nach sich selbst bereinigen. Dies kann passieren, wenn sie abstürzen. Ich muss diese verwaisten tmp-Dateien löschen, sonst wird der zukünftige Prozess auf / tmp nicht mehr genügend Speicherplatz haben.

Wie kann ich sicher Müll sammeln / tmp? Einige Leute tun dies, indem sie den Zeitstempel der letzten Änderung überprüfen. Dieser Ansatz ist jedoch unsicher, da es lang laufende Prozesse geben kann, die diese Dateien noch benötigen. Ein sicherer Ansatz besteht darin, die Zeitstempelbedingung für die letzte Änderung mit der Bedingung zu kombinieren, dass kein Prozess ein Dateihandle für die Datei hat. Gibt es ein Programm / Skript / usw., das diesen Ansatz verkörpert, oder einen anderen Ansatz, der ebenfalls sicher ist?

Ermöglicht Linux / Unix übrigens einen Modus zum Öffnen von Dateien mit der Erstellung, bei dem die erstellte Datei gelöscht wird, wenn der Erstellungsprozess beendet wird, selbst wenn es sich um einen Absturz handelt?

Synkopiert
quelle
Überprüfen Sie, ob Sie tmpfs anstelle von / tmp verwenden können: kernel.org/doc/Documentation/filesystems/tmpfs.txt
ott--
Siehe auch
Ciro Santilli 法轮功 病毒 审查 六四 事件 法轮功

Antworten:

15

Vielleicht möchten Sie so etwas ausprobieren:

find /tmp -mtime +7 -and -not -exec fuser -s {} ';' -and -exec echo {} ';'

find wird verwendet, um Dateien zu finden, die bestimmten Kriterien entsprechen.

  • -mtime +7 Wählt nur Dateien aus, die älter als 7 Tage sind (Sie können einen anderen Wert verwenden).
  • -exec fuser -s {} ';'Ruft die Fixiereinheit im unbeaufsichtigten Modus für jede Datei auf, die den Alterungskriterien entspricht. fuser gibt 0 (= true) für jede Datei zurück, auf die gerade zugegriffen wird, und 1 (= false) für die Dateien, auf die nicht zugegriffen wird. Da wir nur an den Unzugänglichen interessiert sind, stellen wir eine -notdavor-exec
  • -exec echo {} ';'druckt einfach alle Dateinamen, die den Kriterien entsprechen. Vielleicht möchten Sie -exec rm {} ';'stattdessen hier verwenden, aber da dadurch möglicherweise einige noch verwendete Dateien gelöscht werden, ist es meiner Meinung nach sicherer, zuerst ein einfaches Echo zu erstellen.
  • Bearbeiten: Möglicherweise möchten Sie etwas hinzufügen -name 'foo*.bar'oder -uid 123die Auswirkungen der Bereinigung auf bestimmte Dateimuster oder Benutzer-IDs beschränken, um versehentliche Auswirkungen zu vermeiden.

Zum letzten Punkt: Bedenken Sie, dass es möglicherweise Dateien gibt, die nur einmal geschrieben werden (z. B. beim Systemstart), aber häufig gelesen werden (z. B. ein X-Session-Cookie). Daher empfehle ich, einige Namensprüfungen hinzuzufügen, um nur Dateien zu beeinflussen, die von Ihren fehlerhaften Programmen erstellt wurden.

edit2: Zu Ihrer letzten Frage: Eine Datei wird erst von der Festplatte gelöscht, wenn kein Prozess ein offenes Handle hat (zumindest für native Linux-Dateisysteme). Das Problem ist, dass der Verzeichniseintrag sofort entfernt wird, was bedeutet, dass ab dem Zeitpunkt des Entfernens der Datei keine neuen Prozesse mehr die Datei öffnen können (da kein Dateiname daran angehängt ist).

Weitere Informationen finden Sie unter: /programming/3181641/how-can-i-delete-a-file-upon-its-close-in-c-on-linux

edit3: Aber was ist, wenn ich den gesamten Prozess automatisieren wollte?

Wie gesagt, es kann Dateien geben, die einmal geschrieben und dann ab und zu gelesen werden (z. B. X-Sitzungscookies, PID-Dateien usw.). Diese werden von diesem kleinen Entfernungsskript nicht ausgeschlossen (aus diesem Grund möchten Sie möglicherweise zuerst einen Testlauf durchführen, echobevor Sie Dateien tatsächlich löschen).

Eine Möglichkeit, eine sichere Lösung zu implementieren, ist die Verwendung atime.
atimespeichert die Zeit, zu der auf jede Datei zuletzt zugegriffen wurde. Diese Dateisystemoption ist jedoch häufig deaktiviert, da sie erhebliche Auswirkungen auf die Leistung hat (laut diesem Blog irgendwo in der Region von 20 bis 30%). Es gibt relatime, aber dieser schreibt nur die Zugriffszeit, wenn mtimesich geändert hat, so dass dieser uns nicht hilft.

Wenn Sie verwenden möchten atime, würde ich empfehlen, /tmpeine separate Partition (idealerweise eine Ramdisk) zu verwenden, damit die Auswirkungen auf die Leistung des gesamten Systems nicht zu groß werden.

Nach der atimeAktivierung müssen Sie lediglich den -mtimeParameter in der obigen Befehlszeile durch ersetzen -atime.
Möglicherweise können Sie das entfernen -not -exec fuser -s {} ';', aber ich würde es dort behalten, nur um sicherzugehen (falls Anwendungen Dateien für einen langen Zeitraum offen halten).

Denken Sie jedoch daran, den Befehl mit zu testen, echobevor Sie Dinge entfernen, die Ihr System noch benötigt!

Mreithub
quelle
nett. Was ist mit Dateien, die durch einen lang laufenden Prozess geschlossen wurden, während sie nicht aktualisiert werden? Wenn es sich um Kontextdateien handelt, können Sie den Prozesskontext verlieren (dies ist zwar kein sehr intelligenter Prozess, aber man muss die erwarteten Nebenwirkungen einer "seitlichen" /tmp/Bereinigung kennen).
Nik
Das ist das Problem dieses Ansatzes (wie ich im letzten Absatz betont habe). Der beste Ansatz hier wäre afaik, uid / gid oder Dateimusterprüfungen hinzuzufügen (die Antwort entsprechend bearbeitet)
mreithub
Sollte dies in ein Cron-Skript eingefügt werden ...?
CMCDragonkai
@CMCDragonkai Natürlich können Sie dies in crontab setzen. Aber wie bereits erwähnt, gibt es möglicherweise Dateien, auf die zugegriffen wird, die jedoch nicht geschrieben wurden und die daher möglicherweise nicht von diesem kleinen Skript herausgefiltert werden. Aus diesem Grund ist es sicherer, zuerst die Liste der betroffenen Dateien auszudrucken und dann selbst zu entscheiden, ob Sie sie löschen möchten oder nicht. Wenn Sie /tmpsich auf einer separaten Partition befinden (z. B. einer Ramdisk), können Sie diese aktivieren atimeund den -atimeParameter von verwenden find.
Mreithub
Ich plane dies auf einem Server zu tun. Daher kann ich nicht immer da sein, um alle Dateien in tmp zu zählen. Würde es irgendwelche Probleme geben? Auch dachte ich, wir sollten relatime nicht atime verwenden?
CMCDragonkai
4

Rollen Sie nicht Ihre eigenen.

Debian / Ubuntu haben tmpreaper, es ist wahrscheinlich auch in anderen Dists verfügbar.

# tmpreaper - cleans up files in directories based on their age

sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 
Gringo Suave
quelle
Können Sie in der /etc/tmpreaper.confDatei, wenn ich beide /tmpund /var/tmpals Bereinigungsverzeichnisse festlege , lange empfehlen, den TMPREAPER_TIMEParameter oder die maximale Anzahl der tmp-Dateien zu entfernen? Ich habe gehört, es ist besser, ein längeres Alter für /var/tmpDateien als /tmpDateien beizubehalten. Aber wenn sie nur mit dem gleichen Höchstalter eingerichtet werden können, habe ich keine Ahnung.
Xiaodong Qi
2

Zum letzten Teil Ihrer Frage:

Obwohl ich nicht glaube, dass ein Öffnungs- / Erstellungsmodus zum Löschen dieses Falls vorhanden ist, kann ein Prozess eine Datei direkt nach dem Erstellen sicher löschen, solange ein Handle für diese Datei geöffnet bleibt. Der Kernel behält dann die Datei auf der Festplatte und sobald der letzte Prozess, der die Datei geöffnet hat, beendet wird (sei es durch Absturz oder normal), wird der von der Datei belegte Speicherplatz freigegeben.

Um das Problem zu umgehen, dass einige Prozesse / tmp manchmal nicht bereinigen, würde ich empfehlen, sich die hier oder hier beschriebenen Mount-Namespaces anzuschauen . Wenn es sich bei dem fraglichen Prozess um einen Systemdämon handelt, sind möglicherweise systemd und seine native Funktion zum Zulassen von privaten / tmp-Dateisystemen von Interesse.

Claudius
quelle
0

Erhalten Sie eine Liste von Dateien, die älter als diese sind, und schließen Sie Dateien, die von irgendetwas geöffnet wurden, aus dieser Liste aus:

find /tmp -mtime +7 |\
    egrep -v "`lsof -n +D /tmp | awk 'NR>1 {print $9}'| tr \\n \|`" 

lsof -n +D /tmp: Suche nach geöffneten Dateien in / tmp
awk 'NR>1 {print $9}': Drucke nur die neunte Spalte der Ausgabe von lsof, ausgenommen die Überschriften
tr \\n \|: Ersetze neue Zeile durch Balken (ODER in egrep)
egrep -v "foo|moo|bar": Drucke Zeilen, die KEIN foo oder moo oder bar enthalten

Ярослав Рахматуллин
quelle
0

Ich stimme dem oben Gesagten zu, um es zu ergänzen. Ich führe immer lsof +L1 | grep tmpdie Prozesse aus, die an "gelöschten" tmp-Dateien festhalten, und töte sie entweder neu oder starte sie neu: BEISPIEL-

# lsof +L1 | grep tmp
xfce4-ter  1699  user   32u   REG    8,6      192     0 818552 /tmp/vte966VLX (deleted)
chrome     3301  user  138u   REG    8,6    16400     0 818547 /tmp/etilqs_Z0guKD7p6ork9iG (deleted)
SeaPhor
quelle
2
SU ordnet Beiträge nach dem Zufallsprinzip an - es gibt also kein Oben oder Unten. Auf welchen Beitrag beziehen Sie sich?
Geselle Geek
0

Sie könnten einfach tun rm -rf /tmp/*und hoffen, dass nichts kaputt geht ...

Solomon Ucko
quelle
1
Wenn
@bertieb Guter Punkt. Ich denke, es ist wahrscheinlich sicher, wenn es nicht als root ausgeführt wird, aber ...
Solomon Ucko