In my previous posts about ramdisks and persistent storage on my Raspberry Pi, I explained my goal to reduce write access to the sd card as far as possible.
The last step is to mount the sd card read-only, so its filesystems can almost never get damaged. This is the expected behaviour of most embedded devices. You can power-cycle them and do no damage to their internal storage.
First, you need to edit your /etc/fstab
file to configure the root and boot
filesystems to be mounted read-only. To do this, you change the option field
(the 4th field) of the lines starting with /dev/mmcblk0p0
and /dev/mmcblk0p1
from defaults
to ro
:
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat ro 0 2
/dev/mmcblk0p2 / ext4 ro 0 1
tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0
tmpfs /var/log tmpfs defaults,noatime,mode=0755 0 0
tmpfs /var/lock tmpfs defaults,noatime,mode=0755 0 0
tmpfs /home/andreas/rrd tmpfs defaults,noatime,mode=0777 0 0
With the next reboot, both your root and boot filesystems are write-protected and cannot be modified by the system. In my case, I needed to do some more changes, so that all system services run without errors.
If you log in to your system and want to change something, e.g. change a configuration file, then you can re-enable the write access with the following command:
mount / -o remount,rw
and disable write access again with
mount / -o remount,ro
nginx
My raspberry is executing the nginx webserver to process and deliver some PHP
files. The PHP scripts are processed by the FastCGI
module of nginx. This
module sometimes tries to create temporary files in /var/lib/nginx/fastcgi
. To
disable this, edit the /etc/nginx/nginx.conf
file and add this line to the
http-section:
fastcgi_temp_path /tmp/fastcgi_temp 1 2;
Then all temporary files get stored in the /tmp
directory mounted as a
ramdisk.
fake-hwclock
The raspberry does not have a realtime clock. During startup it gets the current
time and date by querying a NTP server. To prevent the time jumping back to
start of 1970 if the ntp server does not answer (e.g. due to network problems),
the file /etc/fake-hwclock.data
is written once per hour with the current
time. During startup this time is restored to the system.
My raspberry is always connected to the network, so I can disable the
fake-hwclock mechanism. Simply comment out all lines in
/etc/cron.hourly/fake-hwclock
by prepending a #
character. Then reload the
cron configuration with
service cron reload
Persistent Ramdisk Storage
As described here, I use a ramdisk for working data which is regularly (once per night) and during shutdown backed up to the sd card. For this to work, I added two lines to the init script managing the backup which enables write access to the sd card, then does the backup and then disables write access again:
mount / -o remount,rw
rsync --quiet --archive --delete --recursive --force ${RAMDISK}/ ${PERSIST_STORE}
mount / -o remount,ro
This is a bit dangerous, because for a short time, the write access to the sd card is enabled and data is written. Only once per day and during shutdown. But it might happen that the power is switched off too early during shutdown and the filesystem could be damaged. Because of that I currently think about sending the ramdisk contents to another system over the network, so I never need to enable write access to the sd card.
sudo
Sudo tries to write a timestamp to the directory /var/lib/sudo
everytime you
use it. I have not yet found a solution to disable this, so sudo will print out
an error message, but anyhow lets you execute your command under the root
account.
logrotate
Logrotate is a tool to prevent logfiles from growing indefinitely. By default,
every week it compresses the logfiles to gziped files and discards compressed
files older than 4 weeks. Logrotate writes internal info to a state file which
is stored under /var/lib/logrotate
. To move this file to a writeable location,
edit the cron script /etc/cron.daily/logrotate
and add the option --state
/var/log/logrotate.state
:
#!/bin/sh
test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate --state /var/log/logrotate.state /etc/logrotate.conf
man-db
Every week an index of the man pages installed on the raspberry is built. This
does not work on a read-only filesystem, so I disabled it by adding the line
exit 0
to the beginning of the scripts /etc/cron.weekly/man.db
and
/etc/cron.daily/man.db
. This is no important change, but my raspberry keeps
sending me mails as long as the man-db
scripts fails to update the index.
Package Update Check
Here I described how the raspberry could automatically
check for Raspbian updates. This also does not work on a read-only
filesystem. As an intermediaty solution I added the mount / -o remount,rw
and
mount / -o remount,ro
commands before and after the apt-get update
call and
run the script only once per week (sundays at 3am) to reduce the risk of
damaging the filesystem. This is no optimal solution, but I have no better one
yet.