mirror of
https://github.com/ALLFATHER-BV/wadamesh.git
synced 2026-09-27 02:48:01 +00:00
touch: beta_26 — fix SPIFFS-GC watchdog reboot loop (contacts->SD + shared guard)
Decoded a T-Deck coredump (Task WDT, loopTask stuck in spiffs_gc_clean under DataStore::saveContacts): a contact save on a churned SPIFFS can trigger a multi-second garbage-collection pass that starves core 0 and trips the task watchdog, giving a reboot loop. - Route contacts/channels to SD when a card is present, even on upgraded devices whose data is still on SPIFFS (main.cpp mounts SD every boot; if not fully adopting SD, store.setSecondaryFS(&SD)). DataStore::begin() migrates the existing /contacts3 + /channels2 to the card once; identity/prefs stay put. - Move the ref-counted WdtHeavyGuard into a shared header so the core DataStore::saveContacts shares one count with the UI history/backup saves, and wrap saveContacts with it (guaranteed fix for card-less devices). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
ddc4a34d4d
commit
5f69a61c9c
@@ -3,6 +3,7 @@
|
||||
#include "DataStore.h"
|
||||
#if defined(ESP32)
|
||||
#include <SD.h>
|
||||
#include "helpers/esp32/WdtHeavyGuard.h" // suspend core-0 idle WDT during the (SPIFFS-GC-prone) contact write
|
||||
#endif
|
||||
|
||||
#if defined(EXTRAFS) || defined(QSPIFLASH)
|
||||
@@ -70,6 +71,38 @@ void DataStore::begin() {
|
||||
#else
|
||||
// init 'blob store' support
|
||||
_fs->mkdir("/bl");
|
||||
#if defined(ESP32)
|
||||
// One-time migration: when a secondary FS is active (an SD card is present)
|
||||
// but contacts/channels still live on the primary FS from an earlier build,
|
||||
// copy them onto the card ONCE and delete the primary copies. This preserves
|
||||
// the user's contact list while getting the frequently-rewritten files off a
|
||||
// small/near-full SPIFFS — whose garbage collection can otherwise stall the
|
||||
// loop task for seconds during saveContacts and trip the task watchdog
|
||||
// (the beta_25 reboot loop). Identity + prefs stay on _fs and never move.
|
||||
// No-op once the card already holds the files, and a safe no-op on boards
|
||||
// whose primary-FS metadata can't confirm the source exists (e.g. P4 FFat).
|
||||
if (_fsExtra) {
|
||||
static const char* const kMoveFiles[] = { "/contacts3", "/channels2" };
|
||||
for (const char* nm : kMoveFiles) {
|
||||
if (_fsExtra->exists(nm)) continue; // already on the card
|
||||
if (!_fs->exists(nm)) continue; // nothing to move
|
||||
File in = openRead(_fs, nm);
|
||||
File out = openWrite(_fsExtra, nm);
|
||||
bool ok = in && out;
|
||||
if (ok) {
|
||||
uint8_t buf[256];
|
||||
int n;
|
||||
while ((n = in.read(buf, sizeof(buf))) > 0) {
|
||||
if (out.write(buf, (size_t)n) != (size_t)n) { ok = false; break; }
|
||||
}
|
||||
}
|
||||
if (in) in.close();
|
||||
if (out) out.close();
|
||||
if (ok) _fs->remove(nm); // reclaim SPIFFS space
|
||||
else if (_fsExtra->exists(nm)) _fsExtra->remove(nm); // don't leave a partial copy
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -382,6 +415,17 @@ File file = openRead(_getContactsChannelsFS(), "/contacts3");
|
||||
}
|
||||
|
||||
void DataStore::saveContacts(DataStoreHost* host, bool (*filter)(const ContactInfo& c)) {
|
||||
#if defined(ESP32)
|
||||
// A full/fragmenting contacts write on SPIFFS can trigger a multi-second GC
|
||||
// pass that disables the flash cache and starves core 0's idle task, tripping
|
||||
// the task watchdog (the beta_25 reboot loop, confirmed by coredump: loopTask
|
||||
// stuck in spiffs_gc_clean under this exact call). Suspend that watchdog for
|
||||
// the write so a bounded-but-slow pass stalls the UI instead of rebooting. The
|
||||
// ref-count is shared with the UI history/backup guards, so a backup import
|
||||
// that calls saveContacts stays balanced. On SD-routed devices this is cheap
|
||||
// (FAT has no such GC); it matters most for card-less SPIFFS devices.
|
||||
WdtHeavyGuard _wdt;
|
||||
#endif
|
||||
File file = openWrite(_getContactsChannelsFS(), "/contacts3");
|
||||
if (file) {
|
||||
uint32_t idx = 0;
|
||||
|
||||
Reference in New Issue
Block a user