Manuals, Timing, Ham Radio, Test Equipment

Help keep this site free:
(More Info)
        

Mount Linux Read-Only on Raspbian

adapted from: http://blog.pi3g.com/2014/04/make-raspbian-system-read-only/

Why mounting the Linux filesystem Read-Only?

The filesystem on the Raspberry Pi’s SD card, as every filesystem on every computer, can be corrupted if you disconnect the power suply before properly instructing the operating system to shut down.

This is true even if critical system files are marked Read-Only, as the flash memory manager can only modify large blocks of memory at once, therefore even a small edit may result in several files being rewritten, even Read-Only files. If power is removed while this happen, the operating system may not be able to boot the next time it is powered.

Since Linux regularly writes data to log files and also updates the access time of every file it touches, as long as the main filesystem is mounted Read-Write, you cannot be sure that critical files will not be affected during power outage.

A better solution is to make the entire filesystem Read-Only and write only to a RAM disk.

Once you make the filesystem read-only (and limit all changes to files on a RAM-Disk), you will be able to disconnect the power supply whenever you want.

An additional bonus is less wear on the SD card – sometimes you do NOT want the logfiles which a standard Linux / Raspbian will write to anyway. Our solution will write those to a RAM-Disk and discard them on reboot / power cycling.

Last but not least, you can set up a known state to boot into, experiment, and if things go wrong, simply reboot.

How-To make Raspbian read-only

All commands to be run as root (sudo su) if not specified otherwise.

This how-to is based on another how-to I found on the Internet, in German. Thanks guys!

Italics font indicate commands you have to enter at the prompt.

Courrier New Normal font is used to show the content of files or responses from commands.

Disable swap

dphys-swapfile swapoff
dphys-swapfile uninstall
update-rc.d dphys-swapfile disable

Install UnionFS

UnionFS is an overlaying filesystem (you can mount from several different locations into the same folder). In case of collisions, UnionFS uses priorities for the filesystems. It is frequently used to create RAM-Disk Overlays for read-only systems, for instance also with Live CDs.

apt-get install unionfs-fuse

Create mount script

nano /usr/local/bin/mount_unionfs

Add the following content to this file:

#!/bin/sh
DIR=$1
ROOT_MOUNT=$(awk '$2=="/" {print substr($4,1,2)}' < /etc/fstab)
if [ $ROOT_MOUNT = "rw" ]
then
   /bin/mount --bind ${DIR}_org ${DIR}
else
   /bin/mount -t tmpfs ramdisk ${DIR}_rw
   /usr/bin/unionfs-fuse -o cow,allow_other,suid,dev,nonempty ${DIR}_rw=RW:${DIR}_org=RO ${DIR}
fi

make it executable:

chmod +x /usr/local/bin/mount_unionfs

Update /etc/fstab:

nano /etc/fstab

Modify the file to read (adjust partitions for NOOBS!) as follows:

proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    ro                0       2
/dev/mmcblk0p2  /               ext4    ro,noatime        0       1
mount_unionfs   /etc            fuse    defaults          0       0
mount_unionfs   /var            fuse    defaults          0       0
none            /tmp            tmpfs   defaults          0       0

Prepare the directories:

cp -al /etc /etc_org
mv /var /var_org
mkdir /etc_rw
mkdir /var /var_rw
reboot

Verify:

At this point your Raspberry Pi should be read-only already. You can verify this with

mount

This command should show something like the following:

/dev/root on / type ext4 (ro,noatime,data=ordered)
devtmpfs on /dev type devtmpfs (rw,relatime,size=215824k,nr_inodes=53956,mode=755)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=44820k,mode=755)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /run/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=89620k)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620)
/dev/mmcblk0p1 on /boot type vfat (ro,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
ramdisk on /etc_rw type tmpfs (rw,relatime)
unionfs-fuse on /etc type fuse.unionfs-fuse (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other)
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)
ramdisk on /var_rw type tmpfs (rw,relatime)
unionfs-fuse on /var type fuse.unionfs-fuse (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other)
none on /tmp type tmpfs (rw,relatime)

This indicates to you that the filesystems are mounted read-only and unionfs is active.

Clean up the Log directory

mount -o remount,rw /
for f in $(find . -name \*log); do > $f; done
cd /var_org/log
rm -f *.gz

Reboot

Another reboot and you’re done!

reboot

How-To Install additional Packages after “read-only-modding”

You’ve got to remount the root filesystem as readable. For instance, as root, you can do:

mount -o remount,rw /
aptitude update
aptitude install stress