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.