Persistent storage with ramdisks

As written in the last post about ramdisks, it is good to reduce the number of write cycles to the sd card of the Raspberry Pi, to prevent damage to the filesystem and the sd card. But what to do with data that is regularly written and that you want to preserve over a reboot or a power loss. Here is a way to create a kind of persistent ramdisk storage.

The idea is to let your software work in a ramdisk as long as the raspberry is running. During startup, data is copied from the sd card to the ramdisk and during shutdown it is backed up to the sd card. Additionally there is a cron job that regulary creates a backup of the ramdisk data, so that in case of a power loss not too much data is lost. My Raspberry stores temperature data in a rrdtool database on a ramdisk and backs it up this way.

First, you create two directories somewhere on the sd card. One is the backup location for the data on the sd card (/home/andreas/persist). The other is the mount point of the ramdisk (/home/andreas/rrd). Set this up by editing /etc/fstab. How to create the ramdisk you can read here.

Then we need a script to backup and restore the ramdisk data. We use an init script called persist-ramdist, because we want to do this during startup and shutdown:

#!/bin/bash
#
### BEGIN INIT INFO
# Provides:          persist-ramdisk
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Required-Start:  
# Required-Stop:   
# Short-Description: Backup / restore ram disk contents during boot / shutdown.
# Description:       Backup / restore ram disk contents during boot / shutdown.
### END INIT INFO

PERSIST_STORE=/home/andreas/persist
RAMDISK=/home/andreas/rrd

case "$1" in
  start)
    echo "Restoring ramdisk contents"
    rsync --quiet --archive ${PERSIST_STORE}/ ${RAMDISK}
    ;;
  sync|stop)
    echo "Persisting ramdisk contents"
    rsync --quiet --archive --delete --recursive --force ${RAMDISK}/ ${PERSIST_STORE}
    ;;
  *)
    echo "Usage: /etc/init.d/ramdisk {start|stop|sync}"
    exit 1
    ;;
esac

exit 0

The script can be called with three different parameters: start, stop and sync. start copies the data from the sd card to the ramdisk (the ramdisk has to be mounted before the script is called). The parameters stop and sync copy the data from the ramdisk back to the sd card.

Both copy operations are done by rsync. Rsync does not copy all files but does a synchronization and skips files that are already present in the destination and not changed. So there are as few write operations to the sd card as possible.

The init script can be installed by copying (or linking) it to /etc/init.d and calling

update-rc.d prepare-dirs defaults 02 98

For more info on init scripts, see my post here.

Now the ramdisk is initialized with data during startup and the data is backed up during shutdown. But my Raspberry has uptimes of a few weeks, so the data would be only backed up every few weeks and huge parts would be lost if the power is switched off without shutting the Raspberry down correctly.

Therefor we need a mechanism to regulary back up the data with cron. Add a file (the filename does not matter) to /etc/cron.d with the following contents:

17 2 * * * root /usr/sbin/service persist-ramdisk sync > /dev/null

and run service cron reload to make cron reload its configuration.

The first 5 fields tell cron when to execute the command, at 2:17 am every day in this case. It is executed as the user root. Cron calls the init script with the service tool and discards all console output of the script by redirecting it to /dev/null. If the output is not discarded, cron will try to e-mail it to root, so if you have set up the Raspberry for sending mail, you would get a mail with the text " persisting ramdisk contents" every night at 2:17am.

LinkedIn logo mail logo