Prevent (or repair) read-only on powerloss?

I have a small, lightweight networking rack in my RV that runs on a 12v system. It's just the nature of things that more than I would prefer I suffer a momentary power loss. When the system reboots the /boot/ partition is mounted as read-only. I'm using an EXT4 image. Is there a way I can harden the system to prevent this behavior -- or schedule disk checks on reboot to repair/remount the device?

Add a 12V SLA battery back up.

Or a lifepo4 50-200Watt hour back up battery?

Or a brand new golabs lifepo4 modified sine 200wh power bank? It's nice. Runs an EA8300 no prob. Pass through charging capable.

1 Like

When you find yourself in this RO situation, what is your typical (manual) fix? Does this work reliably or does it fail from time to time?

Are you doing regular/custom writes to /boot?

I ended up adding a custom preinit script for the rpi4... (as I couldn't figure out the other available options block-mount based and regular linux methods) Going this route would likely mean you have to build/generate your own images with the required tools...

Turned out most of my issues were created by my own scripts... ( but /boot being RO is not an issue on this device at all afaik )

Good point. In fact, unless the OP is changing the contents of /boot, this might actually be a good thing. If the partition mounts as RO, it would be really difficult for it to become corrupted upon future power-loss events.

1 Like

afaik you can enable disk checking on boot from Luci page about "mount points"

When you find yourself in this RO situation, what is your typical (manual) fix? Does this work reliably or does it fail from time to time?

Usually I can run fsck.fat and repair the drive (which usually involves resetting the dirty-shutdown flag) and then reboot and it will be mounted correctly.

I'm not savvy enough to know why the ext4 base image mounts a fat32 /boot/ overlay.

Are you doing regular/custom writes to /boot?

I actually don't know for sure. It is nice to be able to update packages and install new ones -- which I can't do while it's RO. I also cant change firewall rules or startup options. It's a bit annoying.

I'm running https://www.openmptcprouter.com/ version of OpenWRT and although I'm not sure it actually needs write-access to the /boot/ in order to function correctly, it does complain and show an error message when the fs is ro.

afaik you can enable disk checking on boot from Luci page about "mount points"

This doesn't seem to be the case on the /boot/ overlay. I can toggle disk checking and it seems to do it for my other mounts but not that one?

The FAT32 boot partition is necessary because the bootloader ROM in the Pi only understands FAT32. Certain device configurations and the Linux kernel are read from the partition, then the kernel takes over. Since kmod-ext4 is built into the kernel blob, the running kernel can mount and use the ext4 rootfs.

Vanilla OpenWrt doesn't automatically mount the FAT partition on /boot (or anywhere) since it is not needed in a normal operation runtime. Having it mounted is only an opportunity for it to be corrupted.

The squashfs build would be more robust against power cuts. Make sure your power supply cuts off the power to the Pi cleanly before the battery source completely runs down. Running the Pi on less than the proper voltage is likely to cause a lot of file corruption.

can you check if dosfstools package is installed? It provides the tool required by that function to work with FAT32 partitions.
This is the source of that "run fs check before mount" function
https://git.openwrt.org/?p=project/fstools.git;a=blob;f=block.c;hb=d4f01298105bb8c97e7ac0cad0e78f0ffe261354#l709

 709 static void check_filesystem(struct probe_info *pr)
 710 {
 711         pid_t pid;
 712         struct stat statbuf;
 713         const char *e2fsck = "/usr/sbin/e2fsck";
 714         const char *f2fsck = "/usr/sbin/fsck.f2fs";
 715         const char *fatfsck = "/usr/sbin/fsck.fat";
 716         const char *btrfsck = "/usr/bin/btrfsck";
 717         const char *ntfsck = "/usr/bin/ntfsfix";
 718         const char *ckfs;

and here the makefile of the dosfstools package

1 Like

I'm very confused. It seems like some things work while it is RO (I've been able to update and install packages) but other things don't. For instance, I can't save custom firewall rules or edit my startup script?

I do have dosfstools as well as the fsck packages.

Here's some info that may be helpful?

root@OpenMPTCProuter:/# mount
/dev/root on /rom type ext4 (ro,noatime)
devtmpfs on /rom/dev type devtmpfs (rw,relatime,size=1914328k,nr_inodes=478582,mode=755)
proc on /proc type proc (rw,nosuid,nodev,noexec,noatime)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,noatime)
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime)
/dev/mmcblk0p2 on / type ext4 (ro,relatime)
/dev/mmcblk0p1 on /boot type vfat (rw,noatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
tmpfs on /dev type tmpfs (rw,nosuid,relatime,size=512k,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,mode=600,ptmxmode=000)
debugfs on /sys/kernel/debug type debugfs (rw,noatime)
none on /sys/fs/bpf type bpf (rw,nosuid,nodev,noexec,noatime,mode=700)
/dev/sda1 on /mnt/sda1 type ext4 (rw,relatime)
mountd(pid5832) on /tmp/run/blockd type autofs (rw,relatime,fd=7,pgrp=1,timeout=21474836510,minproto=5,maxproto=5,indirect)
root@OpenMPTCProuter:/# cat /etc/config/fstab

config global
        option anon_swap '0'
        option anon_mount '0'
        option auto_swap '1'
        option auto_mount '1'
        option delay_root '5'
        option check_fs '1'

config mount
        option target '/boot'
        option uuid 'BF78-31F1'
        option enabled '1'
        option enabled_fsck '1'

config mount
        option target '/'
        option uuid 'ff313567-e9f1-5a5d-9895-3ba130b4a864'
        option enabled '1'
        option enabled_fsck '1'

config mount
        option target '/mnt/sda1'
        option uuid '40240dd3-ed8e-46f4-acef-884260788a5e'
        option enabled '1'