Come posso creare una directory "blackhole" simile a / dev / null?


81

Vorrei creare una " /dev/null" directory (o una directory "blackhole") in modo tale che qualsiasi file scritto su di essa non sia realmente scritto, ma scompaia.

Ho un'applicazione che scrive file temporanei di grandi dimensioni in una directory. Non ho alcun controllo sul nome dei file e non mi interessa davvero il contenuto di questi file. Potrei scrivere uno script che periodicamente blocca questi file, ma i file vengono scritti molto rapidamente e riempiono il mio disco. Sto cercando qualcosa di più intelligente. Voglio che l'applicazione "pensi" che sta scrivendo questi file, mentre in realtà le scritture vengono scartate dall'altra parte.

Vedi anche questo vecchio thread correlato.



mi sono appena posto la stessa domanda e ho usato lo stesso nome per la directory che non sono riuscito a creare.
ixtmixilix

Risposte:


48

Questo non è supportato e pronto all'uso su qualsiasi unix che conosco, ma puoi fare praticamente qualsiasi cosa con FUSE . C'è almeno un'implementazione di nullfs¹ , un filesystem in cui ogni file esiste e si comporta come /dev/null(questa non è l'unica implementazione che abbia mai visto).

¹ Da non confondere con il * BSD nullfs , che è analogo ai bindfs .


Fantastico - l'ho usato come parte di una risposta su SO
Phil Lello,

1
una nota per le persone che finiscono con errori di compilazione su quel programma: ha g++ -Wall -o nullfs nullfs.c++ `pkg-config fuse --cflags --libs`funzionato per me.
ixtmixilix

Puoi indicarmi altre implementazioni? Perché non ne trovo nessuno
Freedo il

@Freedo Sospetto che molte persone l'hanno fatto come un esercizio di apprendimento e lo hanno lasciato intatto. Potrebbero non essere più sul Web.
Gilles,

7

Un altro approccio sarebbe un wrapper LD_PRELOAD; fondamentalmente una piccola libreria condivisa che viene caricata prima di libc.so e intercetta le chiamate per "aprire" con qualcosa che controlla il percorso del file futuro e sostituisce "/ dev / null" se fosse nella directory di destinazione.

Questo ha il vantaggio di essere (a) interamente nello spazio utente - non è richiesto l'hacking del kernel; e (b) riguarda solo la singola domanda errante.

Un semplice esempio è disponibile all'indirizzo http://www.noah.org/wiki/LD_PRELOAD_notes , ma nel tuo caso vorrai intercettare le chiamate di sistema "open" e "creat".


3
... supponendo che l'applicazione esegua chiamate di sistema tramite libc, non direttamente tramite int 0x80/ syscall/ sysenter/ qualunque altra cosa.
Ruslan,

1

Se il programma è così stupido da non consentire di disattivare quei log, potrebbe anche non verificare la presenza di errori dopo l'apertura di un file di log? Proverei a montare un file system fittizio di sola lettura (ad es mount -o loop. Usando .)


questo approccio purtroppo non funziona. L'applicazione muore se non è possibile scrivere su questo file.
dogbane,

1

Dici che la rimozione periodica dei file con uno script non è abbastanza veloce. Potresti vivere con un trigger che elimina un file temporaneo ogni volta che l'applicazione termina di scrivere e lo chiude? In tal caso, è possibile utilizzare l'API "inotify".

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


1
Su molti sistemi, l'eliminazione di un file aperto da un processo rimuove la sua voce di directory, ma il file stesso rimane sul disco fino a quando non viene chiuso dall'ultimo processo che lo utilizza. I processi potrebbero scrivere file e quindi cercare all'inizio e rileggerli, quindi il sistema operativo non può semplicemente eliminare i dati.
Interfaccia il

0

ho creato un modulo del kernel basato sull'esempio di ramfs nel kernel di Linux, è fondamentalmente un filesystem blackhole chiamato nullfsvfs. L'implementazione del sistema FUSE deve copiare i dati dall'utente nel kernelspace ed è piuttosto lenta, rispetto a un'implementazione diretta come modulo kernel. Vedere:

https://github.com/abbbi/nullfsvfs


-8

Basta collegare simbolicamente quella directory a /dev/null

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

/dev/null, non deve essere una directory. Se il programma prova a scrivere ~/.logs/log1.dump, continua comunque /dev/null.
Lo faccio per la cache di Google Chrome perché dopo un po 'diventa così grande che Chrome impiegherà pochi minuti per iniziare.


3
Questo non funzionerebbe perché i collegamenti simbolici sono file, non directory. Provare echo hello > ~/.logs/log1.dump~/.logs/log1.dump: Not a directory. Tuttavia, echo hello > ~/.logsfunziona perché .logs è un file.
dogbane,

2
Ci stai prendendo in giro. $ ln -s /dev/null dev-null; touch dev-null/zzzmi dàtouch: cannot touch 'dev-null/zzz': Not a directory
alex

1
Come ho detto, funziona per Chrome. Impedisce che scriva nella cache. Se provoca l'arresto anomalo del programma del richiedente, ovviamente non controlla se i puntatori di file sono NULL.
jonescb,

6
Probabilmente significa che Chrome salta la scrittura in caso di errore durante l'apertura del file. È possibile ottenere lo stesso effetto rimuovendo il permesso di scrittura dal file di dump o dalla directory in cui è scritto.
KeithB

È vero, cambiare le autorizzazioni della directory avrebbe probabilmente più senso.
jonescb,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.