Stopping SD Card Corruption on Raspberry Pi’s Raspbian
The following are instructions for minimizing SD card writes for Raspberry Pi’s “Raspbian” Distribution.
If you’re like me, you’ve run into a corrupted SD card too many times to not become hell-bent on making it never happen again. I have the following setup, and it seems to be working well for me.
The biggest offender for Filesystem writes on any linux system is logging. If you are like me, you don’t really look at /var/log after a recycle anyways. This area, and /var/run, a location where lock files, pid files and other “stuff” shows up, are the most common areas for mess-ups. Take a look at your blinking FS light on the board. Our goal is to make that light stay off as long as possible.
Set up tmpfs mounts for worst offenders. Do other tweaks.
Linux has with it the concept of an in-memory filesystem. If you write files to an in-memory filesystem, they will only exist in memory, and never be written to disk. There are two common mount types you can use here: ramfs, which will continue to eat memory until your system locks up (bad), and tmpfs, which sets a hard upper limit on mount size, but will swap things out if memory gets low (bad for raspberry pi, you will probably be hard stopping your device if it is low on memory).
We will first solve the usual corruption culprit and then move on to making sure we are covered when our programs decide to blow up.
The following two lines should be added to /etc/fstab:
none /var/run tmpfs size=1M,noatime 00 none /var/log tmpfs size=1M,noatime 00 |
UPDATE (unverified): I have been told that /var/run is now a symlink to a tmpfs filesystem, anyways, so you may not need to add /var/run anymore, and adding it may cause issues.
There’s more, however. By default, linux also records when a file was last accessed. That means that every time you read a file, the SD card is written to. That is no good! Luckily, you can specify the “noatime” option to disable this filesystem feature. I use this flag generously.
Also, for good measure, i set /boot to read-only. There’s really no need to regularly update this, and you can come back here and change it to “defaults” and reboot when you need to do something.
After this, /etc/fstab should look as follows:
proc /proc proc defaults 0 0 /dev/mmcblk0p1 /boot vfat ro,noatime 0 2 /dev/mmcblk0p2 / ext4 defaults,noatime 0 1 none /var/run tmpfs size=1M,noatime 0 0 none /var/log tmpfs size=1M,noatime 0 0 |
UPDATE (unverified): I have been told that /var/run is now a symlink to a tmpfs filesystem, anyways, so you may not need to add /var/run anymore, and adding it may cause issues.
Go ahead and reboot now to see things come up. Check the Filesystem light on your raspberry pi after it’s fully booted. You should see no blinking at all.
Disable swapping
As a note, since i have done the changes above, i have not corrupted an SD card. I’m not saying I’ve tried very hard, but it is much better, even with power plug pulls, which i tried a few of after doing these changes.
One protection against SD card corruption is an optional, but potentially “I’m glad i did that” change to disable swapping.
The raspberry pi uses dphys-swapfile to control swapping. It dynamically creates a swap partition based on the available RAM. This tool needs to be used to turn off swap, and then needs to be removed from startup.
Run the following commands to disable swapping forever on your system:
sudo dphys-swapfile swapoff sudo dphys-swapfile uninstall sudo update-rc.d dphys-swapfile remove |
After doing this, call free -m in order to see your memory usage:
pi@raspberrypi ~ $ free -m total used free shared buffers cached Mem: 438 59 378 0 9 27 -/+ buffers/cache: 22 416 Swap: 0 0 0 |
If you reboot, and run a free -m again, you should still see swap at 0. Now we don’t have to worry about tmpfs filesystems swapping out to hard disk!
Housekeeping!
As you go on and install other tools and frameworks on your raspberry pi (like ROS), you need to be aware of where caches and logfiles are written to. If, for example, you use ROS, the nodes will, by default, log to ~/.ros/log/. For these sorts of things, and for ROS in particular, point these logs to a folder on /dev/shm. This mount is created by default on linux boxes, and is a tmpfs filesystem that is globally writable by default. Mine has 88 MB.
For example, pointing ROS logs to this file could be done by adding the following to your .bashrc:
export ROS_LOG_DIR=/dev/shm/rosLogs |
If you feel like creating more mounts, feel free, but I have run into ownership issues that required having another script on startup that had to be run as root to chown directories to their proper owners.
Getting to 100%
The only way to fully protect against SD card corruption is to mount your root filesystem as readonly. For me, this was too much of a usability issue. I am editing files and installing new packages too often for this to be feasible. The steps listed above should, however, cover you 98% of the time. Try not to pull power while you’re editing files or installing new packages on your device, and you should be fine. Still make backup images of your SD card every once in a while! This is a best practice no matter what!
Happy Hacking!