Comment créer un répertoire “trou noir” de type / dev / null?

81

Je souhaite créer un /dev/nullrépertoire " " (ou un "trou noir") tel que tous les fichiers qui y sont écrits ne soient pas écrits, mais disparaissent.

J'ai une application qui écrit de gros fichiers temporaires dans un répertoire. Je n'ai aucun contrôle sur le nom des fichiers et je ne me soucie pas vraiment du contenu de ces fichiers. Je pourrais écrire un script qui clobe périodiquement ces fichiers, mais ceux-ci sont écrits très rapidement et remplissent mon disque. Je cherche quelque chose d'intelligent. Je veux que l'application "pense" qu'elle est en train d'écrire ces fichiers, alors qu'en réalité, les écritures sont en train d'être ignorées à l'autre bout.

Voir aussi cet ancien fil de discussion.

dogbane
la source
Il semble que FUSE pourrait être une option: kerneltrap.org/mailarchive/linux-kernel/2008/2/15/868564/thread
Stefan Lasiewski
Je viens de me poser la même question et d'utiliser le même nom pour le répertoire que je n'ai pas réussi à créer.
ixtmixilix

Réponses:

48

Ce n'est pas pris en charge immédiatement sur les Unix que je connais, mais vous pouvez faire à peu près n'importe quoi avec FUSE . Il y a au moins une implémentation de nullfs¹ , un système de fichiers dans lequel chaque fichier existe et se comporte comme tel /dev/null(ce n'est pas la seule implémentation que j'ai jamais vue).

¹ Ne pas confondre avec * BSD nullfs , analogue à bindfs .

Gilles
la source
Fantastique - j'ai utilisé cela dans le cadre d'une réponse à SO
Phil Lello
1
une note aux personnes qui finissent avec des erreurs de compilation sur ce programme: a g++ -Wall -o nullfs nullfs.c++ `pkg-config fuse --cflags --libs`travaillé pour moi.
ixtmixilix
Pouvez-vous m'indiquer d'autres implémentations? Parce que je n'en trouve pas
Freedo
@ Freedo Je soupçonne que beaucoup de gens l'ont fait comme un exercice d'apprentissage et l'ont laissé rester sans être maintenus. Ils pourraient ne plus être sur le web.
Gilles
7

Une autre approche serait un wrapper LD_PRELOAD; En gros, une petite bibliothèque partagée chargée avant libc.so intercepte les appels à "open" avec quelque chose qui vérifie le chemin du fichier prospectif et substitue "/ dev / null" s'il se trouvait dans le répertoire cible.

Cela a l’avantage d’être (a) entièrement dans l’espace utilisateur - aucun piratage du noyau n’est requis; et b) n’affectant que la demande unique errante.

Un exemple simple est à http://www.noah.org/wiki/LD_PRELOAD_notes , mais dans votre cas, vous voudrez intercepter les appels système "ouverts" & "creat".

Martin Kealey
la source
3
... en supposant que l'application effectue des appels système via la libc, pas directement via int 0x80/ syscall/ sysenter/ quoi que ce soit d'autre.
Ruslan
1

Si le programme est tellement stupide de ne pas vous permettre de désactiver ces journaux, peut-être qu'il ne vérifie pas non plus les erreurs après avoir ouvert un fichier journal? Je voudrais essayer de monter un système de fichiers factice en lecture seule (par exemple, en utilisant mount -o loop.)

alex
la source
cette approche ne fonctionne pas malheureusement. L'application meurt si elle ne peut pas écrire dans ce fichier.
Dogbane
1

Vous dites que supprimer les fichiers périodiquement avec un script n'est pas assez rapide. Pourriez-vous vivre avec un déclencheur qui supprime un fichier temporaire chaque fois que votre application termine l'écriture et le ferme? Si tel est le cas, vous pouvez utiliser l’API "inotify".

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

Elliot Nelson
la source
1
Sur de nombreux systèmes, la suppression d'un fichier ouvert par un processus supprime son entrée de répertoire, mais le fichier lui-même reste sur le disque jusqu'à sa fermeture par le dernier processus l'utilisant. Les processus peuvent écrire des fichiers, puis chercher au début et les relire. Le système d'exploitation ne peut donc pas simplement jeter les données.
interfect
0

J'ai créé un module de noyau basé sur l'exemple ramfs du noyau linux, il s'agit essentiellement d'un système de fichiers blackhole appelé nullfsvfs. L'implémentation du système FUSE doit copier les données de l'utilisateur vers l'espace noyau et est assez lente, comparée à une implémentation directe sous forme de module noyau. Voir:

https://github.com/abbbi/nullfsvfs

Michael
la source
-8

Il suffit de faire un lien symbolique vers ce répertoire /dev/null

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

/dev/null, ne doit pas nécessairement être un répertoire. Si le programme essaie d'écrire ~/.logs/log1.dump, il continue tout de suite /dev/null.
Je fais cela pour le cache de Google Chrome, car après un certain temps, il devient si gros qu'il ne faudra que quelques minutes à Chrome pour démarrer.

jonescb
la source
3
Cela ne fonctionnerait pas car les liens symboliques sont des fichiers, pas des répertoires. Essayer echo hello > ~/.logs/log1.dumpdonne ~/.logs/log1.dump: Not a directory. Cependant, cela echo hello > ~/.logsfonctionne car .logs est un fichier.
Dogbane
2
Vous devez être en train de vous moquer de nous. $ ln -s /dev/null dev-null; touch dev-null/zzzme donnetouch: cannot touch 'dev-null/zzz': Not a directory
alex
1
Comme je l'ai dit, cela fonctionne pour Chrome. Cela l'empêche d'écrire dans le cache. Si cela provoque le blocage du programme du demandeur, il ne vérifie évidemment pas si les pointeurs de fichier sont NULL.
jonescb
6
Cela signifie probablement que Chrome ignore l'écriture en cas d'erreur lors de l'ouverture du fichier. Vous pouvez obtenir le même effet en supprimant l’autorisation d’écriture du fichier de vidage ou du répertoire dans
lequel
Il est vrai que modifier les autorisations du répertoire aurait probablement plus de sens.
jonescb