Temporarily Unavailable: /tmp: filesystem full

/tmp is a vital ingredient of any Unix-like OS. If your /tmp is too small, but you only discover that fact when you are in the middle of a crucial task, is all lost? Or is there a way to avoid the worst consequences of your earlier imprudence?

Youtube karaoke

Cautious Koala was enjoying his favourite indulgence, Youtube karaoke, when, Oliver Sudden, things started to go pear-shaped.

"Oh dear, what can the mather be?" he sang aloud. He had not quite shaken off the karaoke mood, even though it was the karaoke that was misbehaving. More precisely, it seemed that the Youtube was misbehaving.

CK started investigating. Largely his actions were random. Unbeknownst to him, had he applied the universal Microsoft solution - restart the machine - his problems would have vanished. (They may have returned later.) But CK was a reluctant restarter. He gained a smug satisfaction from running uptime and seeing responses like up 76 days.

Investigating the problem might uncover something useful

Further, he was reluctant to restart his machine because he lost context. Being an absent-minded Koala of very little brain (a little like Pooh - in the brain department, not the bear department (see Bio)), he found that, after a restart he could rarely remember what he had been doing. Secretly he believed that that was part of the universal Microsoft solution: tell the customer to restart her machine and, who knows? When the machine is back up, something might come along to distract the befuddled user.

But he also believed that there were times when investigating the problem might uncover something useful. Perhaps this was one of those times.

/tmp full

After rummaging around here, there and everywhere, CK discovered that /tmp was full:

Filesystem                      Size     Used    Avail Capacity Mounted

/dev/ad1s3e                     310M     285M       0B 100% /tmp

"Oh, no! How much can a koala bear? [See Bio.] Am I going to have to give up Youtube karaoke?"

After a little further analysis, he let out a sigh. "Well, I guess I only have myself to blame: there's crap here that goes back over two years. Which part of tmp did I have difficulty understanding?"

Being Cautious both in name and spirit, CK was a Reluctant Deleter. He had been known to delete files occasionally, but he would be hard put to recall the last time if pressed.

CK looked for recent files in /tmp:

What to do?

        ls -latr /tmp | tail

...

-rw-------   1 ckoala  wheel      36874038 Dec 22 09:55 FlashpokETZ



        file /tmp/FlashpokETZ

/tmp/FlashpokETZ: Macromedia Flash Video

He realised, his ls command was totally inadequate for the Youtube temp files.

        ls -latrh /tmp | tail

...

-rw-------   1 ckoala  wheel       35M Dec 22 09:55 FlashpokETZ

Later - much later - after he'd solved all his problems, he learnt a little more about Youtube. Obviously, shorter clips created shorter temp files. What was not quite so obvious was that, even if he paused a clip, the temp file kept growing. It probably didn't matter much on a 3-minute clip. But at about 4 MB per minute, his puny /tmp would fill up very quickly indeed.

Which made him think of something else. What was he thinking when he created /tmp way back when? He'd started off with an 80 GB drive, the larger of 2 in this machine. It had seemed so much space back then. Why, he had split the disk into 7 partitions! Was that possible? He looked at his portable 1 TB USB drive and scratched his head ruefully. A lot had changed in just under 3 years.

To make matters worse, his current OS, FreeBSD, resided on one of the partitions (8 GB); and FreeBSD in turn sliced (FreeBSD's term for partitioning) the 8 GB even further. He supposed he would have taken FreeBSD's defaults. It all boiled down to a /tmp which had been allocated 310 MB, and which was now full when it showed 285 MB used.

What to do?

There was space in other places on the hard disks. There was also heaps of space on the portable drive, but he shuddered as he imagined wanting to unmount it for some reason. He was not called Cautious for nothing.

He formed a plan. He understood that /tmp was a vital ingredient of any Unix-like OS. So he needed to do things cautiously. He thought he could rename /tmp and create a symlink to replace it. If he did it all as a single command, it might work.

His first foray went something like this:

        mv /tmp /tmp_orig; ln -s /DISKA/TMP /tmp

mv: cannot rename a mount point

"Hmm, not so easy. Back to the drawing board," he said to himself.

After a while, he had another idea. "If you can't lick 'em, join 'em. If it won't let me rename a mount point, I'll unmount /tmp."

        umount /tmp; ln -s /DISKA/TMP /tmp

umount: unmount of /tmp failed: Device busy

ln: /tmp/TMP: File exists

"Damn and double damn! The first damn for not working; the second because I could have done bether." CK realised that he had let himself down in the caution department. Fortunately there had been no bad consequence, but he should have used a slightly different command:

        umount /tmp && ln -s /DISKA/TMP /tmp

The way he had entered the command, the umount had failed, but the ln command had been attempted (and failed). The semicolon (;) between the two commands usually means do command 1 and then do command 2, no matter what. (In a shell script, it's possible to use set -e to exit if a command returns a non-zero status. Use with care.)

Damn and double damn!

The second form (using &&) means do command 1 and, only if the first command succeeds, do command 2. Which is what CK really wanted, even if he hadn't realised at the time.

The following example says it all:

        aaa; bbb

bash: aaa: command not found

bash: bbb: command not found



        aaa && bbb

bash: aaa: command not found

Consider the consequences of this contrived example:

        cp file1 file2; rm file1

        cp file1 file2 && rm file1

In the first case, if the copy fails, you end up with no files. That might be a little disappointing if file1 is valuable. A Cautious Koala would always prefer the second command: if the copy fails, the remove is not invoked.

CK went to the internet. At the time, he may have had a plan, but, as has already been noted, he is a Koala of very little brain. He found a solution, but he can no longer remember what led him to it. However, he is a very cautious koala, well aware of his limitations, so he dutifully recorded all the details. Omitting distracting output, here it is:

        mkdir /DISKA/TMP

        mount_unionfs /DISKA/TMP /tmp



        mount -t unionfs

<above>:/DISKA/TMP on /tmp (unionfs, local)



        df -h 

Filesystem                      Size     Used    Avail Capacity Mounted

/dev/ad1s3e                     310M     285M       0B 100% /tmp

/dev/ad0                         36G      29G     4.1G  88% /DISKA

<above>:/DISKA/TMP               36G      29G     4.1G  88% /tmp

CK noted that this was not what the creators of unionfs had in mind (see here).

Conclusion

The effect of his solution was very pleasing to CK, who was starting to get peckish. Should he return to his Youtube karaoke, or should he get something to eat? "It might be difficult to do both at the same time," he observed, his mouth not yet full.

He decided to review his accomplishment first.

"I now have an enlarged /tmp. In effect, /DISKA/TMP has been mounted on /tmp. But, whereas in the case of a normal mount, the previous contents of /tmp would be inaccessible for the duration of the mount, with a union mount, the mount is sort of transparent. It's possible to see files underneath the directory that is mounted above. In fact, for reads on /tmp, I see the union of what was in /tmp and what was in /DISKA/TMP. Of course, since I only just created /DISKA/TMP, that's a little like the union of a set with an empty set, so it's not all that interesting.

The effect of his solution was very pleasing

"But, what really mathers to me at the moment is that I can now write to /tmp - even though a minute ago /tmp was full! That's magic. (Why do they say I have a liddle brain?) Attempts to write to /tmp will actually populate /DISKA/TMP, which can be easily confirmed by examining /DISKA/TMP.

"It is also possible to write to /DISKA/TMP directly (rather than to /tmp). It really doesn't mather. Files so created will also be visible when /tmp is examined.

"If I edit a file which is physically in the real /tmp, the behaviour I get is copy on write. Although the original file in /tmp is still there, it is now inaccessible. Instead I am presented with the edited file which resides in /DISKA/TMP.

"I can get some confirmation by looking at inodes and examining /DISKA/TMP directly. But by and large, what's actually in the underlying /tmp is unavailable to me until I unmount /DISKA/TMP.

"Again, what really mathers is that I can go back to Youtube karaoke. I have no control over where Youtube writes. (I suppose it might be possible to configure, but I doubt I could change that in the middle of a clip.) But it doesn't mather. Youtube still "thinks" it's writing to /tmp - the same /tmp as before. It doesn't "know" that it is a somewhat different /tmp."

And so, feeling very pleased with himself, CK went off to find some eucalypt leaves, whose effect on koalas is not unlike that of certain recreational psychoactive drugs on humans. "For medicinal purposes only. All the bether to appreciate the music," he muttered to himself.

Footnotes

CK would like to point out that his exercise was performed on a FreeBSD machine. Linux has a similar capability - sort of.

The FreeBSD man page for mountunionfs claims that the _utility first appeared in 4.4BSD, which is to say June 1994. CK believes that it has been available as a standard part of FreeBSD since then.

The Wikipedia page for UnionFS lists several Linux implementations. CK was a bit perplexed. "How do I choose?"

In the end, just for the exercise, he did the following on a Fedora 16 system:

        yum info funionfs

        yum install funionfs

CK was pleased to see that the whole shooting match only took 30 k.

He thought a little test was called for:

        mkdir /UX

        mkdir /UX/tmp

        touch /UX/tmp/file1

        touch /UX/tmp/file2

        touch /UX/tmp/file3

        mkdir /UX/user

        touch /UX/user/fileu1

        touch /UX/user/fileu2

        touch /UX/user/fileu3

        chown -R ckoala /UX/user

The next bit had him stumped. "How do I mount things?"

Looking back at the output of yum info funionfs he saw a reference to a URL.

There he found something that worked:

        mkdir /mnt/union

        funionfs -o dirs=/UX/tmp=RO:/UX/user NONE /mnt/union



        mount

funionfs on /mnt/union type fuse.funionfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0)



        df -h

funionfs           18G  4.4G   13G  26% /mnt/union

"That seems to be a near equivalent to my FreeBSD setup. /UX/tmp is mounted read-only. /UX/user is mounted read-write. There doesn't seem to be a notion of above and below. Maybe I'm missing something."

He tried creating files. It seemed satisfactory.

There is another use of UnionFS described here.

Bio

Cautious Koala enjoys writing about himself in the third person. Details about his family can be found here. In particular, he wants it known that he is not a bear.

License

Verbatim copying and distribution of this entire article are permitted worldwide, without royalty, in any medium, provided this notice is preserved.