4

I have an embedded Linux system (currently running Angstrom) with supercapacitor hardware to provide time for writes to complete and avoid corrupted filesystems when external power is removed. Architecture is ARM, SOC is Freescale iMX6Q

There's a GPIO input that monitors the presence of external power.

What's the best way to hook this input to the existing logic for powerfail handling? Should I broadcast SIGPWR to all running processes myself? Raise it only to systemd? Write something to /dev/initctl? Do something else so that the kernel itself sends out SIGPWR?

Is there an existing mechanism for hardware powerfail inputs that I can configure in devicetree? Or is a user-mode daemon (with high priority) polling a sysfs gpio file the best approach?

This earlier question pointed out the advantages of battery backup, but stopped with "keep power on long enough" without getting into any details of how to trigger the powerfail path in write flushing code. (Since loss of power is imminent, the system should not waste any time in normal process shutdown, only perform operations that protect data integrity. Especially operations that log shutdown should be avoided, because they increase the chance of corruption by performing writes, including updates to wear-leveling data, at the worst possible time. Discussion.)

Ben Voigt
  • 289
  • 3
  • 14
  • This is a great question; I don't have an answer, except to point to legacy init using "shutdown -fh" when it learns of power failure. Might be tough to avoid shutting down every app, in order to sync & unmount filesystems, though. – Jeff Schaller Oct 13 '15 at 20:15
  • @JeffSchaller: At the moment, I'm willing to trust the programmed powerfail actions to do the right thing (`pf::powerfail:shutdown -fh` or `powerfail::powerfail:/etc/rc.powerfail` on sysvinit, `sigpwr.target` for systemd) and reconfigure those later if needed. Right now I'm focused on making "it learns of power failure" happen when the edge comes in on that GPIO. – Ben Voigt Oct 13 '15 at 20:19
  • 1
    Having never done this, `man init` indicates that sending SIGPWR to it will start the processing. Should be fun to test! :) – Jeff Schaller Oct 13 '15 at 20:37
  • I use sysV `init` and have a `/etc/init.d/powerfail` script which takes a single word argument which is called by the different `pf:`, `po:` and `pn:` entries in my inittab. To trigger that I send the correctly filed out `struct init_request` {detailed in `/usr/include/initreq.h`} which means it's `magic`, `sleeptime` (leave as default 5?) and `cmd` fields. I have a bigger reserve of power so do use the powerfailwait to start a 10 minute `shutdown -h -P +10` (and a powerok to cancel it with a "shutdown -c") as well as the powerfailnow `shutdown -h -P now` - if you are really limited you... – SlySven Apr 09 '16 at 19:37
  • ...could check what `shutdown -n` does in more detail - it is described as "[DEPRECATED] Don't call `init(8)` to do the shutdown but do it ourself. The use of this option is discouraged, and its results are not always what you expect." What all modern man pages I have seen for `shutdown` do **not** mention is that I am sure it *used to say* for the `-n` option: "go down really fast, the system unit is on Fire!` Of course you do seem to suggest you are using `systemd` and that does not handle those commands sent down the `initctl` pipe - the current github code says "update your ups daemon"! – SlySven Apr 09 '16 at 19:51
  • Tested in on a iMX6 with Debian, Indeed `kill -SIGPWR 1` results in system halt. What command exactly it calls - "shutdown" or equivalent "reboot" - is hard to tell. – ddbug Jul 17 '19 at 13:33

0 Answers0