Як я можу створити каталог / dev / null-подібний “blackhole”?


81

Я хотів би створити /dev/nullкаталог " " (або каталог "чорний отвір") таким, що будь-які файли, записані до нього, насправді не записуються, а просто зникають.

У мене є додаток, який записує великі тимчасові файли в каталог. Я не маю контролю над назвою файлів, і я не дуже переймаюся вмістом цих файлів. Я міг би написати сценарій, який періодично клобує ці файли, але файли виписуються дуже швидко і заповнюють мій диск. Я шукаю щось розумніше. Я хочу, щоб програма "подумала", що вони виписують ці файли, коли насправді записи просто відкидаються на іншому кінці.

Також дивіться цю стару пов’язану нитку.


Здається, FUSE може бути варіантом: kerneltrap.org/mailarchive/linux-kernel/2008/2/15/868564/thread
Стефан Ласєвський

Я просто задав собі те саме питання і використав те саме ім'я для каталогу, який я не зміг створити.
ixtmixilix

Відповіді:


48

Це не підтримується поза межами коробки в будь-якому Unix, який я знаю, але ви можете зробити багато чого за допомогою FUSE . Існує принаймні одна реалізація nullfs¹ , файлова система, де кожен файл існує і веде себе так /dev/null(це не єдина реалізація, яку я бачив).

¹ Не плутати з нульфами * BSD , що є аналогом bindfs .


Фантастичний - я використав це як частина відповіді на SO
Phil Lello

1
примітка для людей, які стикаються з помилками компіляції в цій програмі: g++ -Wall -o nullfs nullfs.c++ `pkg-config fuse --cflags --libs`працював для мене.
ixtmixilix

Чи можете ви вказати мені на інші реалізації? Тому що я не можу знайти жодного
Freedo

@Freedo Я підозрюю, що багато людей зробили це як навчальну вправу і відпустили його без збереження. Вони більше не можуть бути в Інтернеті.
Жиль

7

Іншим підходом буде обгортання LD_PRELOAD; в основному невелика спільна бібліотека, яка завантажується перед libc.so, і перехоплює дзвінки на "відкриття" з чимось, що перевіряє потенційний шлях до файлу та замінює "/ dev / null", якби це було в цільовому каталозі.

Це має перевагу в тому, що (a) повністю в просторі користувача - не потрібно злому ядра; та (b) стосується лише однієї заявки на помилку.

Простий приклад - за адресою http://www.noah.org/wiki/LD_PRELOAD_notes , але у вашому випадку ви хочете перехопити системні виклики "відкрити" та "створити".


3
... припускаючи, що програма здійснює системні дзвінки через libc, а не безпосередньо через int 0x80/ syscall/ sysenter/ що б там не було.
Руслан

1

Якщо програма настільки дурна, що не дозволяє вам вимикати ці журнали, може, вона також не перевіряє помилки після відкриття файлу журналу? Я б спробував встановити якусь фіктивну файлову систему для читання (наприклад, використовуючи mount -o loop.)


цей підхід, на жаль, не працює. Програма загине, якщо вона не може записати в цей файл.
dogbane

1

Ви кажете, що періодично видаляти файли за допомогою сценарію не досить швидко. Чи можете ви жити за допомогою тригера, який видаляє тимчасовий файл будь-коли, коли ваша програма закінчить писати та закриває його? Якщо це так, ви можете скористатися API "ініціювати".

(Див. Http://en.wikipedia.org/wiki/Inotify та https://github.com/rvoicilas/inotify-tools/wiki/ )


1
У багатьох системах видалення файлу, який відкрив процес, видаляє його запис у каталозі, але сам файл залишається на диску, поки не закриється останнім процесом, що використовує його. Процеси можуть записувати файли, а потім шукати до початку і читати їх назад, і тому ОС не може просто викинути дані.
втручатися

0

Я створив модуль ядра на основі прикладу ramfs в ядрі Linux, це в основному файлова система чорного отвору під назвою nullfsvfs. Реалізація системи FUSE потребує копіювання даних від користувача до простору ядра та є досить повільною, порівняно з прямою реалізацією як модулем ядра. Побачити:

https://github.com/abbbi/nullfsvfs


-8

Просто посилання на цей каталог /dev/null

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

/dev/null, не повинно бути каталогом. Якщо програма спробує записатись ~/.logs/log1.dump, вона все одно переходить безпосередньо /dev/null.
Я роблю це для кешу Google Chrome, оскільки через деякий час він стає настільки великим, що Chrome потребує хвилин.


3
Це не працює, оскільки символьні посилання - це файли, а не каталоги. Спробує echo hello > ~/.logs/log1.dumpдає ~/.logs/log1.dump: Not a directory. Однак echo hello > ~/.logsпрацює, тому що .logs - це файл.
собачка

2
Ти мусиш нас жартувати. $ ln -s /dev/null dev-null; touch dev-null/zzzдає меніtouch: cannot touch 'dev-null/zzz': Not a directory
alex

1
Як я вже сказав, він працює для Chrome. Це перешкоджає запису в кеш. Якщо це спричинить збій програми запитувача, очевидно, вона не перевіряє, чи покажчики файлів NULL.
jonescb

6
Це, ймовірно, означає, що Chrome пропускає запис, якщо є помилка відкриття файлу.
Такого

Щоправда, зміна дозволів каталогу, мабуть, матиме більше сенсу.
jonescb
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.