Jak mogę utworzyć katalog „blackhole” podobny do / dev / null?

81

Chciałbym utworzyć /dev/nullkatalog „ ” (lub katalog „blackhole”), tak aby wszelkie zapisane w nim pliki nie były tak naprawdę zapisane, ale po prostu zniknęły.

Mam aplikację, która zapisuje duże pliki tymczasowe do katalogu. Nie mam kontroli nad nazwami plików i tak naprawdę nie dbam o ich zawartość. Mógłbym napisać skrypt, który okresowo blokuje te pliki, ale pliki są zapisywane bardzo szybko i zapełniają mój dysk. Szukam czegoś mądrzejszego. Chcę, aby aplikacja „myślała”, że zapisuje te pliki, podczas gdy w rzeczywistości zapisy są po prostu odrzucane na drugim końcu.

Zobacz także ten stary powiązany wątek.

dogbane
źródło
Wygląda na to, że FUSE może być opcją: kerneltrap.org/mailarchive/linux-kernel/2008/2/15/868564/thread
Stefan Lasiewski
właśnie zadałem sobie to samo pytanie i użyłem tej samej nazwy dla katalogu, którego nie udało mi się utworzyć.
ixtmixilix

Odpowiedzi:

48

Nie jest to obsługiwane od razu po zainstalowaniu na żadnym unixie, który znam, ale z FUSE możesz zrobić prawie wszystko . Istnieje co najmniej jedna implementacja nullfs¹ , systemu plików, w którym każdy plik istnieje i zachowuje się tak /dev/null(nie jest to jedyna implementacja, jaką kiedykolwiek widziałem).

¹ Nie należy mylić z nullfs * BSD , który jest analogiczny do bindfs .

Gilles
źródło
Fantastycznie - wykorzystałem to jako część odpowiedzi na SO
Phila Lello
1
uwaga dla osób, które kończą się błędami kompilacji w tym programie: g++ -Wall -o nullfs nullfs.c++ `pkg-config fuse --cflags --libs`pracowała dla mnie.
ixtmixilix
Czy możesz wskazać mi inne wdrożenia? Ponieważ nie mogę znaleźć żadnego
Freedo
@Freedo Podejrzewam, że wiele osób uczyniło to jako ćwiczenie edukacyjne i pozwoliło, aby pozostało niezauważone. Mogą już nie być w sieci.
Gilles
7

Innym podejściem byłoby opakowanie LD_PRELOAD; w zasadzie mała biblioteka współdzielona, ​​która jest ładowana przed libc.so i przechwytuje wywołania „open” z czymś, co sprawdza przyszłą ścieżkę do pliku i zastępuje „/ dev / null”, jeśli byłaby w katalogu docelowym.

Ma to tę zaletę, że (a) jest całkowicie w przestrzeni użytkownika - nie wymaga hakowania jądra; oraz (b) wpływ tylko na jeden błędny wniosek.

Prostym przykładem jest http://www.noah.org/wiki/LD_PRELOAD_notes , ale w twoim przypadku będziesz chciał przechwycić wywołania systemowe „otwarte” i „twórcze”.

Martin Kealey
źródło
3
... zakładając, że aplikacja wykonuje wywołania systemowe przez libc, a nie bezpośrednio przez int 0x80/ syscall/ sysenter/ cokolwiek innego.
Ruslan
1

Jeśli program jest tak głupi, że nie pozwala ci wyłączyć tych logów, to może nie sprawdza też błędów po otwarciu pliku dziennika? Spróbowałbym zamontować fikcyjny system plików tylko do odczytu (np mount -o loop. Używając .)

alex
źródło
to podejście nie działa niestety. Aplikacja umiera, jeśli nie może zapisać do tego pliku.
dogbane
1

Mówisz, że okresowe usuwanie plików za pomocą skryptu nie jest wystarczająco szybkie. Czy możesz żyć z wyzwalaczem, który usuwa plik tymczasowy za każdym razem, gdy aplikacja kończy zapisywanie i zamyka go? Jeśli tak, możesz skorzystać z interfejsu API „inotify”.

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

Elliot Nelson
źródło
1
W wielu systemach usunięcie pliku otwartego przez proces powoduje usunięcie pozycji katalogu, ale sam plik pozostaje na dysku, dopóki nie zostanie zamknięty przez ostatni proces, który go użyje. Procesy mogą zapisywać pliki, a następnie wyszukiwać na początku i czytać je z powrotem, więc system operacyjny nie może po prostu wyrzucić danych.
zakłócają
0

stworzyłem moduł jądra oparty na przykładzie ramfs w jądrze Linuksa, jest to w zasadzie system plików blackhole o nazwie nullfsvfs. Implementacja systemu FUSE musi kopiować dane od użytkownika do przestrzeni jądra i jest dość wolna, w porównaniu do prostej implementacji jako modułu jądra. Widzieć:

https://github.com/abbbi/nullfsvfs

Michael
źródło
-8

Wystarczy dowiązać symbolicznie do tego katalogu /dev/null

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

/dev/null, nie musi być katalogiem. Jeśli program próbuje pisać do ~/.logs/log1.dump, nadal działa /dev/null.
Robię to dla pamięci podręcznej przeglądarki Google Chrome, ponieważ po chwili staje się ona tak duża, że ​​jej uruchomienie zajmie kilka minut.

jonescb
źródło
3
To nie działałoby, ponieważ dowiązania symboliczne to pliki, a nie katalogi. Próbowanie echo hello > ~/.logs/log1.dumpdaje ~/.logs/log1.dump: Not a directory. echo hello > ~/.logsDziała jednak, ponieważ .logs jest plikiem.
dogbane
2
Żartujesz sobie z nas. $ ln -s /dev/null dev-null; touch dev-null/zzzdaje mitouch: cannot touch 'dev-null/zzz': Not a directory
Alex
1
Tak jak powiedziałem, działa dla Chrome. Zapobiega to zapisywaniu do pamięci podręcznej. Jeśli powoduje awarię programu pytającego, to oczywiście nie sprawdza, czy wskaźniki plików mają wartość NULL.
jonescb,
6
Prawdopodobnie oznacza to, że Chrome pomija pisanie, jeśli wystąpi błąd podczas otwierania pliku. Ten sam efekt można osiągnąć, usuwając zezwolenie na zapis z pliku zrzutu lub katalogu, w którym się zapisuje.
KeithB
To prawda, że ​​zmiana uprawnień do katalogu prawdopodobnie miałaby większy sens.
jonescb,