Como posso criar um diretório "blackhole" do tipo / dev / null?

81

Eu gostaria de criar um /dev/nulldiretório " " (ou um diretório "blackhole") para que os arquivos gravados nele não sejam realmente escritos, mas simplesmente desapareçam.

Eu tenho um aplicativo que grava grandes arquivos temporários em um diretório. Não tenho controle sobre o nome dos arquivos e realmente não me importo com o conteúdo desses arquivos. Eu poderia escrever um script que periodicamente limpe esses arquivos, mas os arquivos são gravados muito rapidamente e preenchem meu disco. Estou procurando por algo mais inteligente. Quero que o aplicativo "pense" que está gravando esses arquivos, quando, de fato, as gravações estão sendo descartadas no outro extremo.

Veja também este tópico relacionado antigo.

dogbane
fonte
Parece que o FUSE pode ser uma opção: kerneltrap.org/mailarchive/linux-kernel/2008/2/15/868564/thread
Stefan Lasiewski
Acabei de me fazer a mesma pergunta e usei o mesmo nome para o diretório que não consegui criar.
Ixtmixilix 03/03

Respostas:

48

Isso não é suportado pronto para uso em nenhum unix que eu conheça, mas você pode fazer praticamente qualquer coisa com o FUSE . Há pelo menos uma implementação do nullfs¹ , um sistema de arquivos em que todos os arquivos existem e se comportam como /dev/null(essa não é a única implementação que eu já vi).

¹ Não deve ser confundido com o * BSD nullfs , que é análogo ao bindfs .

Gilles
fonte
Fantástico - Eu usei isso como parte de uma resposta sobre SO
Phil Lello
1
uma observação para as pessoas que acabam com erros de compilação nesse programa: g++ -Wall -o nullfs nullfs.c++ `pkg-config fuse --cflags --libs`trabalharam para mim.
Ixtmixilix 03/03
Você pode me indicar outras implementações? Porque não consigo encontrar nenhum
Freedo
@ Freedo Eu suspeito que muitas pessoas o tenham feito como um exercício de aprendizado e o deixem sem manutenção. Eles podem não estar mais na web.
Gilles
7

Outra abordagem seria um wrapper LD_PRELOAD; basicamente uma pequena biblioteca compartilhada que é carregada antes da libc.so, e intercepta chamadas para "abrir" com algo que verifique o caminho do arquivo em potencial e substitua "/ dev / null" se estiver no diretório de destino.

Isso tem a vantagem de estar (a) inteiramente no espaço do usuário - não é necessário hackear o kernel; e (b) afetando apenas o pedido único incorreto.

Um exemplo simples está em http://www.noah.org/wiki/LD_PRELOAD_notes , mas no seu caso você deseja interceptar as chamadas do sistema "aberto" e "criativo".

Martin Kealey
fonte
3
... assumindo que o aplicativo faça chamadas pelo sistema via libc, não diretamente via int 0x80/ syscall/ sysenter/ qualquer outra coisa.
Ruslan
1

Se o programa é tão estúpido para não permitir que você desative esses logs, talvez ele também não verifique se há erros após abrir um arquivo de log? Eu tentaria montar algum sistema de arquivos somente leitura fictício (por exemplo, usando mount -o loop.)

alex
fonte
infelizmente, essa abordagem não funciona. O aplicativo morre se não puder gravar neste arquivo.
dogbane
1

Você diz que remover os arquivos periodicamente com um script não é rápido o suficiente. Você poderia conviver com um gatilho que exclui um arquivo temporário a qualquer momento que seu aplicativo termina de gravá-lo e o fecha? Nesse caso, você pode fazer uso da API "inotify".

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

Elliot Nelson
fonte
1
Em muitos sistemas, a exclusão de um arquivo aberto por um processo remove sua entrada de diretório, mas o próprio arquivo permanece no disco até ser fechado pelo último processo que o utiliza. Os processos podem gravar arquivos e, em seguida, procurar o início e lê-los novamente, para que o sistema operacional não possa simplesmente jogar os dados fora.
interfect
0

Eu criei um módulo do kernel baseado no exemplo ramfs no kernel linux, é basicamente um sistema de arquivos blackhole chamado nullfsvfs. A implementação do sistema FUSE precisa copiar dados do usuário para o kernelspace e é bastante lenta, em comparação com uma implementação direta como módulo do kernel. Vejo:

https://github.com/abbbi/nullfsvfs

Michael
fonte
-8

Basta ligar o diretório para /dev/null

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

/dev/null, não precisa ser um diretório. Se o programa tentar gravar ~/.logs/log1.dump, ele continuará direto para /dev/null.
Faço isso no cache do Google Chrome, porque depois de um tempo fica tão grande que o Chrome leva alguns minutos para iniciar.

jonescb
fonte
3
Isso não funcionaria porque links simbólicos são arquivos, não diretórios. Tentar echo hello > ~/.logs/log1.dump~/.logs/log1.dump: Not a directory. No entanto, echo hello > ~/.logsfunciona porque .logs é um arquivo.
dogbane
2
Você deve estar brincando conosco. $ ln -s /dev/null dev-null; touch dev-null/zzzdá-me #touch: cannot touch 'dev-null/zzz': Not a directory
1128 alex
1
Como eu disse, ele funciona no Chrome. Impede que ele grave no cache. Se causar uma falha no programa do solicitante, obviamente não verificará se os ponteiros do arquivo são NULL.
jonescb
6
Provavelmente significa que o Chrome pula a gravação se houver um erro ao abrir o arquivo. Você poderia conseguir o mesmo efeito através da remoção de permissão de escrita a partir do arquivo de despejo ou o diretório sua escrita no.
KeithB
É verdade que alterar as permissões do diretório provavelmente faria mais sentido.
jonescb