On Wed, Sep 26, 2012 at 02:59:12PM +0100, Simon Slavin scratched on the wall:
> Allow me to present an alternative point of view. > > If filling up your filespace is causing you to crash, it's easier to > understand what's going on if you can see the files which are filling > it up. Running out of disk space when you can't see huge files makes > it difficult to debug. With an unlinked file I would find it hard to > figure out what was filling my hard disk causing me to crash. That's a valid point, and is one of the reasons why /tmp is traditionally its own file system... if you accidentally fill it, you might lock an application or two, but you shouldn't cause issues with the whole OS. Of course if the application dies because it ran out of space, that's its own fault for making assumptions about storage. Having the file unlinked (or not) doesn't change those issues, other than leaving behind evidence of the cause. An application properly checking and reporting error codes doesn't need evidence. Regardless, you're saying it is easier and more logical to hunt through a whole file tree looking for a large file, rather than just checking to see how full the disks are. While I get where you're coming from, I think it is a pretty weak point next to the general advantages open-and-unlink offers. There also seems to be a running assumption that disk space should, in some direct way, relate to the sum total of all the file sizes on a volume. That's not a very safe assumption with Unix file systems. While the use non-symbolic links is somewhat rare these days, they do exist. You can have the same file show up multiple places in the file system as a full-on native file (not a link or alias), but it only shows up on the disk once (that's why the call is unlink() and not delete()). Similarly, the "size" of a file and how much disk space it takes up are not always the same. Most Unix file systems support sparse files, so you can have a files that report a "size" significantly larger than their actual disk usage. In fact, we used to test backup and archive software that way. Open a file, write a byte, advanced the file counter several hundred gigabytes, write another byte. The file shows up as huge, but it is only taking up a few kilobytes on disk. The smart backup systems understand this, the dumb ones burn through a lot of tape recording zeros. Same with tar and similar utilities, and don't get me started with crappy home-grown quota systems. You can cause a lot of headaches for your sysadmin that way. It's also fun to freak out the newbies by putting a 2 TB file onto their 500 GB disk. > Avoiding filename clashes can be done by creating files with random > or time-related elements to their names. It's less of a problem. As I already pointed out, there are many, many reasons for the "open-and-unlink" pattern that go beyond file name collision. In fact, that's a very minor reason, since an application should be using one of the C standard calls like tmpnam() to generate unique file names in a known, accepted way. > > How would a file that clogs up /tmp be preferrable to some unnamed data > > that will be automatically removed from the file system by the fsck > > after the crash? > > Unix deletes the contents of /tmp at boot time. Some, but not all. I've run across systems that don't bother to delete /tmp. Not that it matters... many Unix systems have a high enough uptime that anything done on reboot happens pretty rare, and really shouldn't be considered standard maintenance. > That's why it's special. That, and it has specific permissions that allow anyone to create files. Traditionally, it is also its own file system, although that's somewhat rare these days. > In contrast, using unlink() can cause some > chaos including filespace hogs turning up in lost+found -- the sort > of thing that might cause problems that a mundane user might never > understand. No, it can't. In fact, if "problems for the mundane user" is your primary concern, open-and-unlink is a much better pattern in almost every way. Understand that if a process does an open-and-unlink and the process terminates FOR ANY REASON, including a crash, then the OS will close all the file descriptors, which will trigger an automatic deletion of the file. The process cannot exit without cleaning up. Compare this to a traditional file in temp, which is just going to get left there, taking up space until the next reboot. Most users-- even savvy users-- don't manually clean up their /tmp directory between reboots. If this is a desktop with a multi-month uptime, and more and more cruft is getting left behind, it is conceivable that /tmp may fill up. If an application manages to fill up /tmp, the correct thing to do is notice that the write operations aren't working, report the error and exit. The open-and-unlink file will always be cleaned up. The normal file will hopefully be cleaned up by the application, assuming it remembers to do so correctly, even when exiting under and error condition. If the application is not so careful and crashes due to filling up /tmp, the open-and-unlink file will just be deleted by the OS and /tmp will have plenty of free space. The normal file will remain, keeping /tmp full, and likely confusing the heck out of the user. The savvy user/admin may be smart enough to look in /tmp, the mundane user will just see their machine get slow, many applications not work, and will likely reboot the machine because something is clearly borked. Clearly Linux/MacOS/Sun sucks. If the OS itself crashes, locks, panics, or loses power while an application is putting things into /tmp, then things get a bit more interesting. In the case of the open-and-unlink file, the file and its contents will be cleaned up when the disks are fsck'ed on reboot. The file will NOT be put into lost+found, since the reference count in the i-node is zero. It will simply be deleted and the space recovered. This is true of files created in /tmp, as well as files created on any other file system. While this is a process that only happens on reboot, it is recovering for a situation that can only happen due to unintentional shut-down. Normal files in /tmp will, in most cases, simply be deleted on reboot. That works for files in /tmp, but not in other places. It should also be noted that since cleaning up unlinked files is part of the mount process, the open-and-unlink files will be removed, and the space recovered, long before any /tmp cleanup script is run. So in every way, the open-and-unlink approach is better for the mundane user, as it always has an equal or better chance of returning the system to a usable state, even for poorly written applications, and even if there is a very long duration between reboots. The only situation when a normal file makes more sense is if something goes wrong, and a developer or administrator trying to debug the issue is trying to figure out why it went wrong. In short, situations when you need evidence left behind in the form of a big temp file that wasn't cleaned up after a crash. If that crash was caused by filling up /tmp or some similar issue, the application should have reported the error. If the crash was caused by some other problem, then the file is just going to be wasted space and may cause issues until it is cleaned up. In all those situations, it makes more sense to blame the application for playing fast and loose with error codes. > >> Is there any chance that the use of this trick can be discontinued ? > > > > This is not a trick, it's a widely used Unix idiom. > > It's widely used outside /tmp. It's widely used inside /tmp for anything that only needs to be seen by the process that created the file. When this technique is used correctly for files of small or moderate size, you (the admin or user) never see it. That's half the point. Just because you've never noticed it doesn't mean it isn't happening. Just because you don't know about it doesn't mean it hasn't been there all along. The standard C I/O library includes the tmpfile() call, which performs the whole process of generating a random temporary file name, opening the file, and then unlinking the file. It returns an anonymous file pointer with no associated file name that does not appear in the file system, and is deleted as soon as the file pointer is closed OR if the application terminates for any reason. It will create the file in the system's default temp space, which is /tmp in the case of UNIX systems. This call is part of the POSIX platform standard, as well as the ISO C-90 standard. I'm sure one could trace its roots back pretty far into the history of C and UNIX. There is a strong history of open-and-unlink being the standard practice for this kind of thing. It is exactly what I would expect SQLite to be doing with it's temp files. -j -- Jay A. Kreibich < J A Y @ K R E I B I.C H > "Intelligence is like underwear: it is important that you have it, but showing it to the wrong people has the tendency to make them feel uncomfortable." -- Angela Johnson _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users