Wie kann ich ein / dev / null-ähnliches "blackhole" -Verzeichnis erstellen?

81

Ich möchte ein " /dev/null" Verzeichnis (oder ein "blackhole" -Verzeichnis) erstellen, so dass alle darauf geschriebenen Dateien nicht wirklich geschrieben werden, sondern einfach verschwinden.

Ich habe eine Anwendung, die große temporäre Dateien in ein Verzeichnis schreibt. Ich habe keine Kontrolle über den Namen der Dateien und kümmere mich nicht wirklich um den Inhalt dieser Dateien. Ich könnte ein Skript schreiben, das diese Dateien regelmäßig blockiert, aber die Dateien werden sehr schnell ausgeschrieben und füllen meine Festplatte. Ich suche etwas Klügeres. Ich möchte, dass die Anwendung "denkt", dass sie diese Dateien ausschreibt, während die Schreibvorgänge am anderen Ende einfach verworfen werden.

Siehe auch diesen alten verwandten Thread.

Dogbane
quelle
Es hört sich so an, als wäre FUSE eine Option: kerneltrap.org/mailarchive/linux-kernel/2008/2/15/868564/thread
Stefan Lasiewski
Ich habe mir nur die gleiche Frage gestellt und den gleichen Namen für das Verzeichnis verwendet, das ich nicht erstellt habe.
ixtmixilix

Antworten:

48

Dies wird von Haus aus unter keinem mir bekannten Unix unterstützt, aber Sie können mit FUSE so ziemlich alles machen . Es gibt mindestens eine Implementierung von nullfs¹ , einem Dateisystem, in dem jede Datei existiert und sich so verhält /dev/null(dies ist nicht die einzige Implementierung, die ich jemals gesehen habe).

¹ Nicht zu verwechseln mit * BSD nullfs , analog zu bindfs .

Gilles
quelle
Fantastisch - ich habe dies als Teil einer Antwort auf SO verwendet
Phil Lello
1
Ein Hinweis für Leute, die am Ende Kompilierungsfehler in diesem Programm haben: g++ -Wall -o nullfs nullfs.c++ `pkg-config fuse --cflags --libs`Hat für mich gearbeitet.
ixtmixilix
Können Sie mich auf andere Implementierungen verweisen? Weil ich keinen finde
Freedo
@Freedo Ich vermute, viele Leute haben es als Lernübung gemacht und lassen es unbeaufsichtigt. Sie sind möglicherweise nicht mehr im Web.
Gilles
7

Ein anderer Ansatz wäre ein LD_PRELOAD-Wrapper. Im Grunde genommen eine kleine gemeinsam genutzte Bibliothek, die vor libc.so geladen wird und Aufrufe zum "Öffnen" mit etwas abfängt, das den potenziellen Dateipfad überprüft und "/ dev / null" ersetzt, wenn es sich im Zielverzeichnis befindet.

Dies hat den Vorteil, (a) vollständig im User-Space zu sein - kein Kernel-Hacking erforderlich; und (b) nur die einzelne fehlerhafte Anwendung betreffen.

Ein einfaches Beispiel finden Sie unter http://www.noah.org/wiki/LD_PRELOAD_notes . In Ihrem Fall möchten Sie jedoch die Systemaufrufe "open" und "creat" abfangen.

Martin Kealey
quelle
3
... die Anwendung unter der Annahme , tut Systemaufrufe über libc, nicht direkt über int 0x80/ syscall/ sysenter/ was auch immer.
Ruslan
1

Wenn das Programm so dumm ist, dass Sie diese Protokolle nicht ausschalten können, prüft es möglicherweise auch nicht nach Fehlern, nachdem Sie eine Protokolldatei geöffnet haben? Ich würde versuchen, ein Dummy-Nur-Lese-Dateisystem zu mounten (z mount -o loop. B. mit .)

Alex
quelle
Dieser Ansatz funktioniert leider nicht. Die Anwendung stirbt, wenn sie nicht in diese Datei schreiben kann.
Dogbane
1

Sie sagen, dass das regelmäßige Entfernen der Dateien mit einem Skript nicht schnell genug ist. Könnten Sie mit einem Auslöser leben, der eine temporäre Datei jedes Mal löscht, wenn Ihre Anwendung mit dem Schreiben fertig ist und sie schließt? In diesem Fall können Sie die API "inotify" verwenden.

(Siehe http://en.wikipedia.org/wiki/Inotify und https://github.com/rvoicilas/inotify-tools/wiki/ )

Elliot Nelson
quelle
1
Auf vielen Systemen wird beim Löschen einer von einem Prozess geöffneten Datei der Verzeichniseintrag entfernt, die Datei selbst bleibt jedoch auf dem Datenträger, bis sie vom letzten Prozess geschlossen wird, der sie verwendet. Prozesse schreiben möglicherweise Dateien und suchen dann nach dem Anfang und lesen sie zurück, sodass das Betriebssystem die Daten nicht einfach wegwerfen kann.
Interfect
0

Ich habe ein Kernel-Modul basierend auf dem RAMFS-Beispiel im Linux-Kernel erstellt. Es ist im Grunde ein Blackhole-Dateisystem mit dem Namen nullfsvfs. Die Implementierung des FUSE-Systems muss Daten vom Benutzer in den Kernelspeicher kopieren und ist im Vergleich zu einer direkten Implementierung als Kernelmodul recht langsam. Sehen:

https://github.com/abbbi/nullfsvfs

michael
quelle
-8

Verknüpfen Sie einfach dieses Verzeichnis mit /dev/null

rm -rf ~/.logs
ln -s /dev/null ~/.logs

/dev/nullmuss kein Verzeichnis sein. Wenn das Programm versucht zu schreiben, ~/.logs/log1.dumpgeht es trotzdem richtig hinein /dev/null.
Ich mache das für den Cache von Google Chrome, weil er nach einer Weile so groß wird, dass Chrome Minuten braucht, um zu starten.

jonescb
quelle
3
Dies würde nicht funktionieren, da Symlinks Dateien und keine Verzeichnisse sind. Der Versuch echo hello > ~/.logs/log1.dumpgibt ~/.logs/log1.dump: Not a directory. Funktioniert jedoch, echo hello > ~/.logsda .logs eine Datei ist.
Dogbane
2
Sie müssen uns veräppeln. $ ln -s /dev/null dev-null; touch dev-null/zzzgibt mirtouch: cannot touch 'dev-null/zzz': Not a directory
alex
1
Wie gesagt, es funktioniert für Chrome. Es verhindert, dass es in den Cache schreibt. Wenn das Programm des Fragestellers abstürzt, wird offensichtlich nicht überprüft, ob die Dateizeiger NULL sind.
Jonescb
6
Dies bedeutet wahrscheinlich, dass Chrome das Schreiben überspringt, wenn beim Öffnen der Datei ein Fehler auftritt. Sie können den gleichen Effekt erzielen, indem Sie die Schreibberechtigung aus der
Speicherauszugsdatei
Richtig, das Ändern der Berechtigungen des Verzeichnisses wäre wahrscheinlich sinnvoller.
Jonescb