26

For non-critical Linux systems, I often move things like /tmp and /var/log to tmpfs to save on some disk writing. I've been doing this for a year or so and if I ever need the logs across reboots, I just comment out a line in /etc/fstab and then start debugging.

In any case, I would like to do the same thing on OS X. I've seen posts on creating a ramdisk for OS X, but I'm looking for a more permanent solution that works on every boot. I always want /tmp and /var/log mounted in a ramdisk, with the ability to turn that off with a bit of command-line editing in vi if I have to.

kbyrd
  • 2,207
  • 1
  • 22
  • 34
  • This sounds like premature optimization to me. Are you really running into a lot of situations where you're disk I/O-bound so you need to save disk writes whenever you can? – Spiff Mar 20 '10 at 07:46
  • I will openly admit this isn't likely a huge optimization. I originally did it on a Linux systems where I was booting from a cheap USB stick and was trying to avoid writing to it as much as possible while still providing the log and tmp space many process want. The idea stuck and I felt what I was giving up (can't view the logs to trace a problem that I noticed AFTER it happened unless I can reproduce) was worth this tinkering. For a "non-tinker" system, I wouldn't do this. My OS X laptop falls into the tinker category. – kbyrd Mar 20 '10 at 14:26
  • 8
    Another justific^D^D^D...err...rationalization: My macbook has an SSD and if I can prevent random writes for things that I don't care about much, the whole system is better off. How about that? – kbyrd Mar 20 '10 at 14:28

2 Answers2

9

Here is a script to create ramdisks on OS X. Sorry, it doesn't answer your question. You could use this to build up something that runs on boot and then mounts /tmp and /var/log.

#!/bin/bash  
ramfs_size_mb=1024  
mount_point=~/volatile  

ramfs_size_sectors=$((${ramfs_size_mb}*1024*1024/512))  
ramdisk_dev=`hdid -nomount ram://${ramfs_size_sectors}`  
newfs_hfs -v 'Volatile' ${ramdisk_dev}  
mkdir -p ${mount_point}  
mount -o noatime -t hfs ${ramdisk_dev} ${mount_point}  

echo "remove with:"  
echo "umount ${mount_point}"  
echo "diskutil eject ${ramdisk_dev}"  

From @salvatore http://pastie.textmate.org/pastes/1417478/text?key=igcxuzqqvlmlbavxooj2uw

xer0x
  • 341
  • 3
  • 6
6

EDIT: I'm just going to accept my own answer, as it did solve one part of the problem for me. If someone posts something more like --bind in Linux, I'll accept that answer.

In an effort to spur more answers, I'll begin answering my own question with what I have found out.

Step 1 is to get a ramdisk mounted at boot every time. To do this, I create a bash script and then a launchd entry to call the bash script on boot.

Write a bash script like this:

RD=ramdisk
if [ ! -e "/Volumes/$RD" ];  then
    diskutil erasevolume HFS+ "$RD" `hdiutil attach -nomount`
fi

mkdir -p /Volumes/$RD/private/tmp
mkdir -p /Volumes/$RD/private/var/log
mkdir -p /Volumes/$RD/private/var/tmp

Then get it called on boot by adding it to launchd by creating a file called /Library/LaunchDaemons/com.my.ramdisk.plist with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.my.ramdisk</string>
    <key>ProgramArguments</key>
    <array>
            <string>/usr/local/sbin/ramdisk.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

Where I am stuck is a way to symlink or mount directories inside the ramdisk at /tmp, /var/log, and /var/tmp. These three directories are all symlinked on my system to /private/tmp, /private/var/log and /private/var/tmp. When I changed the symlinks to point into /Volumes/ramdisk/..., the system won't boot. I expect this is because at boot time, something wants /tmp and /var/log BEFORE the my com.my.ramdisk script mounts the ramdisk. I need a way to mount the ramdisk right after root is mounted, before anything else runs.

Note If you mount /var/log (kernel, daemon, and other critical user-space logs) in temporary space, you will lose its contents in the next reboot. This might inhibit your ability to diagnose.

Raystafarian
  • 21,583
  • 11
  • 60
  • 89
kbyrd
  • 2,207
  • 1
  • 22
  • 34
  • Odds are good that you're not going to be able to do this, and even if you can, it will absolutely not be worth the time spent. All the public documentation on the boot cycle is available here if you're really bent on trying: http://bit.ly/d1kAPd – Hasaan Chop Mar 24 '10 at 06:16
  • @NSD: Thanks for the link. Man, I really want --bind mounting. – kbyrd Mar 25 '10 at 03:03
  • You could *probably* redirect the logger's output without writing a kernel extension, but I've never actually tried. – Hasaan Chop Mar 25 '10 at 05:31
  • A few editors have said that you must have /var/log on permanent storage. This isn't true. Not having it persist across reboots makes some things hard to debug. This is a tradeoff. If you read my original question, I mentioned this. For a critical server, I would never do this. For a personal machine I tinker with, I would. – kbyrd May 02 '14 at 21:06
  • 3
    I realise this is an old issue, and I can't seem to post a proper answer, but it comes up prominently in searches. To answer the question, you want to use `hdik -drivekey system-image=yes -nomount ram://262144` to create a 128mb ram-disk, then `newfs_hfs` to format it, then use `mount -o union,nobrowse,noatime` to mount the volume over `/tmp`. This way, existing files in `/tmp` are untouched, but new files go to your ram disk. – Haravikk Oct 11 '14 at 11:33
  • 2
    My only other comment is that you should be wary of doing this; whereas `tmpfs` will use swap if necessary, a RAM disk won't, so you'll lose a chunk of active RAM, this means you'll want to keep it small, however some tasks in `/tmp` may require more memory and will fail, so be careful what you run in case it needs more space than you allocate. – Haravikk Oct 11 '14 at 11:39
  • 1
    Does this even work? `hdiutil attach -nomount` is lacking an argument, so that whole `diskutil` business will fail. That `hdik` trick above is neat though, I didn't know about `ram://` - thanks, @Haravikk! – ckujau Jul 13 '19 at 22:07
  • Seeing "diskutil erasevolume" I have goose bumps. – mauron85 Oct 01 '19 at 16:24