Fix bootloop if config is reset (#4852)

* Fix bootloop if config missing/reset

Can't reset the config if there's nothing to reset!

* ESP8266: Commit ACTIONT_TRACKER

* Use consistent naming for backups and reset cfgs

Use 'rst.cfg.json' instead of 'cfg.json.rst.json' for configs that were
reset.

* Add a little more PSTR to bootloop handling
This commit is contained in:
Will Miles
2025-08-20 01:37:14 -04:00
committed by GitHub
parent dcc1fbc96e
commit 3b5c6ca284
3 changed files with 18 additions and 13 deletions

View File

@@ -787,13 +787,15 @@ bool verifyConfig() {
} }
// rename config file and reboot // rename config file and reboot
// if the cfg file doesn't exist, such as after a reset, do nothing
void resetConfig() { void resetConfig() {
DEBUG_PRINTLN(F("Reset config")); if (WLED_FS.exists(s_cfg_json)) {
char backupname[32]; DEBUG_PRINTLN(F("Reset config"));
strcpy(backupname, s_cfg_json); char backupname[32];
strcat(backupname, ".rst.json"); snprintf_P(backupname, sizeof(backupname), PSTR("/rst.%s"), &s_cfg_json[1]);
WLED_FS.rename(s_cfg_json, backupname); WLED_FS.rename(s_cfg_json, backupname);
doReboot = true; doReboot = true;
}
} }
bool deserializeConfigFromFS() { bool deserializeConfigFromFS() {

View File

@@ -515,7 +515,7 @@ bool compareFiles(const char* path1, const char* path2) {
return identical; return identical;
} }
static const char s_backup_json[] PROGMEM = "/bkp."; static const char s_backup_fmt[] PROGMEM = "/bkp.%s";
bool backupFile(const char* filename) { bool backupFile(const char* filename) {
DEBUG_PRINTF("backup %s \n", filename); DEBUG_PRINTF("backup %s \n", filename);
@@ -524,7 +524,7 @@ bool backupFile(const char* filename) {
return false; return false;
} }
char backupname[32]; char backupname[32];
snprintf(backupname, sizeof(backupname), "%s%s", s_backup_json, filename + 1); // skip leading '/' in filename snprintf_P(backupname, sizeof(backupname), s_backup_fmt, filename + 1); // skip leading '/' in filename
if (copyFile(filename, backupname)) { if (copyFile(filename, backupname)) {
DEBUG_PRINTLN(F("backup ok")); DEBUG_PRINTLN(F("backup ok"));
@@ -537,7 +537,7 @@ bool backupFile(const char* filename) {
bool restoreFile(const char* filename) { bool restoreFile(const char* filename) {
DEBUG_PRINTF("restore %s \n", filename); DEBUG_PRINTF("restore %s \n", filename);
char backupname[32]; char backupname[32];
snprintf(backupname, sizeof(backupname), "%s%s", s_backup_json, filename + 1); // skip leading '/' in filename snprintf_P(backupname, sizeof(backupname), s_backup_fmt, filename + 1); // skip leading '/' in filename
if (!WLED_FS.exists(backupname)) { if (!WLED_FS.exists(backupname)) {
DEBUG_PRINTLN(F("no backup found")); DEBUG_PRINTLN(F("no backup found"));
@@ -565,9 +565,9 @@ bool validateJsonFile(const char* filename) {
bool result = deserializeJson(doc, file, DeserializationOption::Filter(filter)) == DeserializationError::Ok; bool result = deserializeJson(doc, file, DeserializationOption::Filter(filter)) == DeserializationError::Ok;
file.close(); file.close();
if (!result) { if (!result) {
DEBUG_PRINTF("Invalid JSON file %s\n", filename); DEBUG_PRINTF_P(PSTR("Invalid JSON file %s\n"), filename);
} else { } else {
DEBUG_PRINTF("Valid JSON file %s\n", filename); DEBUG_PRINTF_P(PSTR("Valid JSON file %s\n"), filename);
} }
return result; return result;
} }

View File

@@ -721,8 +721,8 @@ void *realloc_malloc(void *ptr, size_t size) {
// if a bootloop is detected: restore settings from backup, then reset settings, then switch boot image (and repeat) // if a bootloop is detected: restore settings from backup, then reset settings, then switch boot image (and repeat)
#define BOOTLOOP_THRESHOLD 5 // number of consecutive crashes to trigger bootloop detection #define BOOTLOOP_THRESHOLD 5 // number of consecutive crashes to trigger bootloop detection
#define BOOTLOOP_ACTION_RESTORE 0 // default action: restore config from /cfg.bak #define BOOTLOOP_ACTION_RESTORE 0 // default action: restore config from /bak.cfg.json
#define BOOTLOOP_ACTION_RESET 1 // if restore does not work, reset config (rename /cfg.json to /cfg.fault) #define BOOTLOOP_ACTION_RESET 1 // if restore does not work, reset config (rename /cfg.json to /rst.cfg.json)
#define BOOTLOOP_ACTION_OTA 2 // swap the boot partition #define BOOTLOOP_ACTION_OTA 2 // swap the boot partition
#define BOOTLOOP_ACTION_DUMP 3 // nothing seems to help, dump files to serial and reboot (until hardware reset) #define BOOTLOOP_ACTION_DUMP 3 // nothing seems to help, dump files to serial and reboot (until hardware reset)
#ifdef ESP8266 #ifdef ESP8266
@@ -836,6 +836,9 @@ void handleBootLoop() {
#endif #endif
else else
dumpFilesToSerial(); dumpFilesToSerial();
#ifdef ESP8266
ESP.rtcUserMemoryWrite(ACTIONT_TRACKER_IDX, &bl_actiontracker, sizeof(uint32_t));
#endif
ESP.restart(); // restart cleanly and don't wait for another crash ESP.restart(); // restart cleanly and don't wait for another crash
} }