104

I would like to create a "/dev/null" directory (or a "blackhole" directory) such that any files written to it are not really written, but just disappear.

I have an application that writes out large temporary files to a directory. I have no control over the name of the files and I don't really care about the content of these files. I could write a script that periodically clobbers these files, but the files are written out very quickly and fill my disk. I'm looking for something cleverer. I want the application to "think" that it is writing out these files, when in fact, the writes are just being discarded at the other end.

Also see this old related thread.

3

6 Answers 6

55

This isn't supported out-of-the-box on any unix I know, but you can do pretty much anything with FUSE. There's at least one implementation of nullfs¹, a filesystem where every file exists and behaves like /dev/null (this isn't the only implementation I've ever seen).

¹ Not to be confused with the *BSD nullfs, which is analogous to bindfs.

5
  • Fantastic - I've used this as part of an answer on SO
    – Phil Lello
    Commented May 5, 2011 at 21:52
  • 1
    a note to people who end up with compile errors on that program: g++ -Wall -o nullfs nullfs.c++ `pkg-config fuse --cflags --libs` worked for me.
    – ixtmixilix
    Commented Mar 3, 2013 at 7:11
  • Can you point me to other implementations? Because I can't find any
    – Freedo
    Commented Aug 2, 2019 at 4:50
  • @Freedo I suspect many people have done it as a learning exercise and let it go unmaintained. They might not be on the web anymore. Commented Aug 2, 2019 at 6:07
  • It appears to work fine for me (despite throwing compile time warnings) on Ubuntu 18.04. Commented Dec 22, 2021 at 14:08
11

Another approach would be an LD_PRELOAD wrapper; basically a small shared library which is loaded before libc.so, and intercepts calls to open() with something that checks the prospective file path and substitutes /dev/null if it would be in the target directory.

This has the advantage of being (a) entirely in user-space - no kernel hacking required; and (b) only affecting the single errant application.

A simple example is at http://www.noah.org/wiki/LD_PRELOAD_notes, but in your case you will want to intercept the access(), open() & creat() system calls. For a more complete implementation you might also need to intercept chdir(), accessat(), openat(), and possibly others.

1
  • 4
    ...assuming the application does system calls via libc, not directly via int 0x80/syscall/sysenter/whatever else.
    – Ruslan
    Commented Feb 7, 2016 at 18:44
7

i have created a kernel module based on the ramfs example in the linux kernel, it is basically a blackhole filesystem called nullfsvfs. The FUSE system implementation needs to copy data from user to kernelspace and is quite slow, compared to a straight implementation as kernel module. See:

https://github.com/abbbi/nullfsvfs

0
1

You say that removing the files periodically with a script isn't fast enough. Could you live with a trigger that deletes a temporary file any time your application finishes writing and closes it? If so, you might make use of the "inotify" API.

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

2
  • 1
    On many systems, deleting a file that a process has open removes its directory entry, but the file itself stays on disk until it is closed by the last process using it. Processes might write files and then seek to the beginning and read them back, and so the OS can't just throw the data away.
    – interfect
    Commented Apr 18, 2017 at 21:58
  • 1
    In line with the previous comment, you're better off periodically truncating the logfile rather than deleting it. It might become sparse as a result, appearing to have lots of NUL bytes at the start, but those don't actually take any space in the filesystem, save for some indirection blocks. Commented Sep 21, 2020 at 6:59
0

If the program is so stupid to not let you switch those logs off, may be it also doesn't check for errors after opening a log file? I'd try mounting some dummy read-only file system (e.g. using mount -o loop.)

1
  • 1
    this approach doesn't work unfortunately. The application dies if it can't write to this file.
    – dogbane
    Commented Mar 16, 2011 at 12:22
-12

Just symlink that directory to /dev/null

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

/dev/null, doesn't have to be a directory. If the program tries writing to ~/.logs/log1.dump, it still goes right into /dev/null.
I do this for Google Chrome's cache because after a while it gets so big that Chrome will take minutes to start.

5
  • 3
    This wouldn't work because symlinks are files, not directories. Trying echo hello > ~/.logs/log1.dump gives ~/.logs/log1.dump: Not a directory. However, echo hello > ~/.logs works because .logs is a file.
    – dogbane
    Commented Mar 16, 2011 at 13:25
  • 2
    You must be kidding us. $ ln -s /dev/null dev-null; touch dev-null/zzz gives me touch: cannot touch 'dev-null/zzz': Not a directory
    – alex
    Commented Mar 16, 2011 at 13:28
  • 2
    Like I said, it works for Chrome. It prevents it from writing into the cache. If it causes the asker's program to crash, then obviously it doesn't check if file pointers are NULL.
    – jonescb
    Commented Mar 16, 2011 at 13:54
  • 9
    It probably means that Chrome skips writing if there is an error opening the file. You could achieve the same effect by removing write permission from the dump file or the directory its writing in.
    – KeithB
    Commented Mar 16, 2011 at 14:04
  • True, changing the permissions of the directory would probably make more sense.
    – jonescb
    Commented Mar 16, 2011 at 14:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .