Contact us
Leave a message

Please use:

My public cryptographic key


Member of

Let your RasPi be kind to its SD card!

There are many reports on SD cards getting worn out by Raspberry Pis when running them 24/7. In particular, when extensive logging is turned on for some daemon(s), locations like /var/log are written to very frequently, and SD card wear leveling quickly seems to reach its limits. To this end, it is recommended to (re-)mount such write-intensive directories to RAM disks, thus relieving the card from a good portion of strain.

However, virtually all examples I found on the internet failed me in re-mounting /var/log (or some of its subdirectories) to RAM since they all kicked in only after the syslog daemon and/or other services had begun writing to /var/log. This resulted in either some service not continuing logging after their log file seemed to have gone, or the whole process of re-mounting failing with some "device busy" error.

No here's what worked for me:

Re-mount as early as possible

The trick is to re-mount the directories under question as early as possble, i.e. before a lot of writing takes place. The following systemd service file calls the re-mount scripts just before syslog starts:

[Unit]
Description=Convert heavily-used directories to RAM disks
Before=syslog.service

[Service]
Type=simple
ExecStart=/usr/local/sbin/mkramdisks

[Install]
WantedBy=default.target
/etc/systemd/system/ramdisks.service

The mkramdisks script called by the service unit defines all directories which are to be re-located to RAM:

#!/bin/sh

/usr/local/sbin/convert2ramdisk /tmp
/usr/local/sbin/convert2ramdisk /var/log
/usr/local/sbin/convert2ramdisk /var/spool
/usr/local/sbin/convert2ramdisk /var/tmp
/usr/local/sbin/mkramdisks

Don't lose what's already there

The actual workhorse of the mkramdisks script is the following bit of code which does not just re-mount a given location as RAM disk, but also copies all content from the original to the new location. An temporary RAM disk serves a, well, temporary storage for the content during the re-mounting procedure:

#!/bin/sh

SIZE=100m
TMPMP=/mnt/tmpramdisk
UMOUNT=

printUsage() {
    cat << EOT
convert2ramdisk - Move a directory to a RAM filesystem
-----------------------------------------------------------------------
Usage: convert2ramdisk [options] <dir>
with possible options:
m <path> : Temporary mountpoint. [$TMPMP]
s <size> : RAM disk size. [$SIZE]
u        : Unmount RAM disk.
EOT
}

while getopts "s: u ?" option; do
    case $option in
        s)  SIZE=${OPTARG};;
        u)  UMOUNT=1;;
        \?) printUsage
            exit 0;;
        * ) printUsage
            exit 1;;
    esac
done

shift $((OPTIND-1))
OPTIND=1

if [ $# -ne 1 ]; then printUsage; exit 1; fi

if [ ! -e "$TMPMP" ]; then
    mkdir -p "$TMPMP"
fi

DIR=$(readlink -f "$1")

if [ -z "$UMOUNT" ]; then

    mount -t tmpfs -o defaults,noatime,nosuid,mode=0755,size=$SIZE tmpfs "$TMPMP"
    cp -a "$DIR/." "$TMPMP"
    mount -t tmpfs -o defaults,noatime,nosuid,mode=0755,size=$SIZE tmpfs "$DIR"
    cp -a "$TMPMP/." "$DIR"
    umount "$TMPMP"

else

    mount -t tmpfs -o defaults,noatime,nosuid,mode=0755,size=$SIZE tmpfs "$TMPMP"
    cp -a "$DIR/." "$TMPMP"
    umount "$DIR"
    cp -a "$TMPMP/." "$DIR"
    umount "$TMPMP"

fi
/usr/local/sbin/mkramdisks