FS#24279 - [initscripts] 2011.05.2 fails to remove temporary files
Attached to Project:
Arch Linux
Opened by orbisvicis (orbisvicis) - Saturday, 14 May 2011, 21:28 GMT
Last edited by Tom Gundersen (tomegun) - Thursday, 19 May 2011, 13:03 GMT
Opened by orbisvicis (orbisvicis) - Saturday, 14 May 2011, 21:28 GMT
Last edited by Tom Gundersen (tomegun) - Thursday, 19 May 2011, 13:03 GMT
|
Details
Description:
The rc.sysinit script from initscripts 2011.05.2 will only clear the contents of the /tmp directory if it is not a mountpoint. This is not very useful behavior for users with a separate /tmp partition: . if /tmp is not mounted, then the /tmp folder from / will be empty, so removing contents doesn't affect anything . if /tmp is mounted, then nothing will be deleted. The offending line in rc.sysinit 2011.05.2: /bin/mountpoint -q /tmp || /bin/rm -rf /tmp/* /tmp/.* &>/dev/null rc.sysinit 2011.04.1 /bin/rm -rf /tmp/* /tmp/.* &>/dev/null * I think rc.sysinit should revert to the 2011.04.1 behavior Additional info: * package version(s) initscripts 2011.05.2-1 * config and/or log files etc. Boot Log (paraphrased): Removing Leftover files mkdir: could not create /tmp/.X11 - already exists mkdir: could not create /tmp/.ICE - already exists |
This task depends upon
Closed by Tom Gundersen (tomegun)
Thursday, 19 May 2011, 13:03 GMT
Reason for closing: Fixed
Additional comments about closing: Fix in git.
Thursday, 19 May 2011, 13:03 GMT
Reason for closing: Fixed
Additional comments about closing: Fix in git.
findmnt -k -t notmpfs,noramfs /tmp
That said, I would like to add that the proper fix is to mount tmp as tmpfs (and convert whatever partition you used to have it on into swap space). Is there a use case where this is not the best solution (I would be very interested to know)?
I agree that a check is the best idea, especially since many older systems probably mount /tmp on a storage device.
Computationally intensive applications, especially graphic design and photography software often store several gigabytes of information on the /tmp partition. Gimp stores a scratch disk in /tmp, and I recently finished a hugin panorama requiring approximately 12GB of /tmp scratch space.
I did some brief research and the default tmpfs partition can grow to half the available memory after which data will be swapped out.
However, these same applications often use considerable memory, and their /tmp scratch spaces are specifically designed to accommodate any data that will not fit into memory. I suspect that reducing the amount of memory - which is already at a premium on 32-bit systems, at a max of 3GB - will reduce performance and might even hasten thrashing.
On the other hand, the maximum size of the tmpfs partitions could be set to a small value such as 128MB, after which writing to /tmp becomes synonymous to writing to swap space. Which makes it necessary to compare features, performance and efficency of using tmpfs to write to a swap partition versus writing to a storage device using standard file-systems (ext/xfs/jfs/btfs...). In both cases the kernel is responsible for managing the disk, so tmpfs presents no benefits to databases. Aside from the spurious performance benefits gained by assuming (possibly incorrectly) the often-accessed and small locks and pipes residing in /tmp will remain in memory and not be swapped out, I see no reason to prefer one approach over the other.
Off the top of my head I can think of a spurious security issue. Does swap storage (hence tmpfs) properly implement delete, or will the data simply reside in swap space till overwritten?
As a partition, /tmp space can be limited to the maximum size of the partition
As tmpfs, /tmp space becomes tmpfs size + swap size. There is no way of preventing /tmp from accessing swap space reserved for memory.
Granted, I don't think this last point is of any importance.
We do not assume that tmp is tmpfs. It was just a mistake I made when adding the check to think that there were no other options than "no mountpoint" and "mounted as tmpfs". I'm not sure what other distro's do, but I believe it is common to mount /tmp as tmpfs.
A few clarifications about tmpfs:
* size= denotes the total size of the partition, and the partition will not grow beyond this. E.g.:
# mount -t tmpfs none -o size=1m /mnt/test
# cp /boot/kernel26.img /mnt/test
cp: writing `test/kernel26.img': No space left on device
cp: failed to extend `test/kernel26.img': No space left on device
* creating a tmpfs partition will not mean that you reserve memory for it. Only the data you write to it will take up space in mem/swap. I.e., if you were to convert your partition to swap space, you will have gained some swap space (whatever is not actually being used by /tmp) and not have lost any memory.
* swap does not "delete" your data, but then I don't think any of the common file systems do either. What you can do is to use an encrypted swap partition (with a randomly created key at each boot). This will make the swap meaningless once the power is switched off (without the need to clear the data).
* the big benefit of using tmpfs compared to a regular file system is that the kernel knows that you don't care if it saves the data to disk. A normal file system will write data to disk both in case it needs some more memory (in this case the tmpfs will write the data to swap), but also a normal file system will write data to disk at regular intervals to make sure it is not lost in case of a crash. As an example, imagine you have some gigs of data in memory that reside on /tmp when you shutdown your machine. In case of /tmp being on tmpfs all this data is simply ignored. In case /tmp is on a regular file system all the data has to be written to disk before the computer will shut down (and on boot it is all deleted again).
There are cases in which using tmpfs is not ideal (e.g., it does not yet support user quotas), but I do not think this is relevant in your case.
I will in any case add a fix to this issue for the next release.
By doing so if it's set to "yes" in init script you perform rm's stuff else you left /tmp as it is (if the user stores data for temporary usage, which doesn't mean with a lifetime of a single reboot, he could clean it by himself or in /etc/rc.local or with cron or whatever he wants).
I've got another one: supposing that a user is working with his temporary data in /tmp (yes, a traditional filesystem ;-)) and the o.s. crashes, then come a reboot and the (unstoppable?) deletion of /tmp content that leads the user to loose all of he was working on; should be better considering to clean up /tmp during the shutdown (/etc/rc.shutdown)?
If we start supporting other usages than what it is designed for we will have a maintenance nightmare.
By putting something in /tmp or /var/tmp you say that as soon as the program that created the files close, you no longer need them, and the system is allowed to delete them.
The difference between /tmp and /var/tmp is that stuff in /tmp will never be used twice whereas stuff in /var/tmp could be used twice, but if it is lost it is not important (e.g. a cache that could be regenerated).
Other directories like /run, /var/run and /var/lock have similar semantics, and if you put stuff in them it can and will get deleted behind your back.
If you use /tmp in such a way that having it on tmpfs is not the best solution, then you probably should not be using /tmp. However, I could be wrong, so if you have a specific use-case I'd be interested to know.
I don't use /tmp in any specific case, mine was just an hypothesis and now that i red fhs it's gone forever ;-)
For instance, rdiff-backup will use /tmp at times, and when you're backing up, say, VirtualBox images, /tmp can fill up right quickly. It's one thing to have a dedicated filesystem fill up, but it's quite another to have tmpfs start filling RAM and swap, especially when you may have one or more preexisting memory-hungry processes.
The difference is that in the first instance, rdiff-backup dies with an out-of-space error (easy to diagnose), while in the second either rdiff-backup dies with either an out-of-space or an out-of-memory error (potentially difficult to diagnose) -or- some other, unrelated, and otherwise harmless process dies with an out-of-memory error (unacceptable behavior).
I'm not sure I understand your scenario though. Imagine you have a 2G (just a random number) disk where /tmp is mounted, you also have a 2G swap disk and 2G ram (so you will get ENOMEM if you use more than 4G of virtual memory).
Now mount /tmp as tmpfs with size=2G instead, and use the underlying disk as swap (giving you a total of 4G of swap, and ENOMEM if you use more than 6G of virtual memory).
If your process fills more than 2G into /tmp it will get ENOSP. The only thing that will be different is that the stuff you put on /tmp could use up your swap space, but it could at most use 2G more swap than before, and that's what you added, so you are no more likely to get ENOMEM (for any process) than before.
After looking around a bit it looks like the only problem you might hit is if you have any particular file being larger than 256GB (on 64bit, 2TB on 32bit), the tmpfs mount itself can be as big as 16EB (on 64 bit, 16TB on 32bit), so that should hopefully not be a problem.
If you are in a situation where you need larger than 256GB files, transparent hugepages might help, but I'm not up to speed THP development and how far they have come. Is this your case?
There is no real advantage, in terms of performance, of having /tmp in RAM on a desktop system. On a build server, it is true that compiling can benefit from the speedup provided by tmpfs, but one could just remount /tmp by hand in such cases...
1) tmpfs provide the semantics that /tmp guarantee (look at the above link to FHS, not that we are following it religiously, but in this case it makes a lot of sense). If your program crashes it should assume that whatever was in /tmp is lost forever (even if the OS itself does not crash). Any important data (such as backups/snapshots) should be stored elsewhere.
2) using tmpfs is particularly useful on laptops where you want to conserve power. Since there are no requirements to preserve data in case of a crash, data will be written to disk much less frequently (only when low on RAM), so the disk will spin up less often, and it will free up io bandwidth for other processes.
In general, using a backing fs that provide stricter guarantees (like persistence) than what your directory requires, will obviously come at a cost.
You make a very good and valid point.
I would only say in response that it may be desired that your swap partition(s) not be large enough to accommodate large files on /tmp, but rather that the user may desire a large ext4/reiserfs/jfs/other_general-purpose_filesystem partition for usage on /tmp, if nothing else for the ability to remount it and use it as something other than /tmp. You can't do that with swap without reformatting.
Really, all of this is academic at best, as you've already said that you'll update rc.sysinit to wipe /tmp in any event. Essentially, it boils down to user preference. I think I might try out your tmpfs solution with the size= option. I'll report back if I notice any difference in operation.
Thanks for the enlightening discussion.
I thought that these considerations motivated erasing /tmp/* in rc.sysinit, as opposed to rc.shutdown. I don't know about other modern systems, but at least RHELs 5.x (client and server alike) do not clean /tmp at all.
I'm not sure about RHEL, but fedora 15 (so I guess also eventually RHEL) deletes files from /tmp both at boot and when they have not been touched for 10 days.
@dhaines: I don't thinke there is such a big difference between doing "rm -rf * .*" or "mkfs.XXX" on a device, especially as I assume it is a rare occurrence.
Thanks to everyone who took part in the discussion, it has been very useful. I think the best solution which should accommodate everyone (but which will be most convenient for what should be the standard setup) is the following (I'll propose this to arch-projects and see if they agree before implementing it):
1) recommend everyone to put /tmp on tmpfs (and tell them to possibly add a swap partition and set a size= accordingly)
2) never touch /tmp at all in rc.sysinit, which is the right thing to do for tmpfs (the fewer "rm -rf *" I see in code that I maintain and that is ran on lots of machines, the happier I am)
3) advice people who choose to use something different than tmpfs to add "rm -rf /tmp/* /tmp/.*" to their rc.local, or in some other way maintain the contents of /tmp as they wish (I believe there was a tmpwatch package in AUR, maybe it is still there...).
@lisaev: this was the misconception I was trying to correct. By having /tmp on tmpfs you are not using any more memory. Not a single byte.
@ALL: however, this give and take has been useful, thanks! :-)