fix: GOMEMLIMIT for all devices, cascade delete orphans, logread cleanup

- GOMEMLIMIT: remove 256MB RAM threshold cap. Now applies to ALL
  devices. Formula: min(35% RAM, 512MB). mem_scale respected.
  Fixes sing-box eating 500MB+ on 2GB routers with no limit.

- Cascade delete: when a routing section is deleted, child UCI entries
  (subscription_url, urltest, priority_group, priority_level,
  section_interface) are now removed. Prevents orphaned entries that
  corrupt config generation.

- Migration cleanup: orphan_section_interfaces now cleans ALL child
  types, not just section_interface.

- Watchdog logread: kill orphans in stop_runtime(), add SIGTERM/SIGINT
  handlers in uloop mode (previously only in fallback mode).
This commit is contained in:
Dushnilin
2026-09-04 20:25:54 +03:00
parent 529db5fc6c
commit ae79195c17
7 changed files with 53 additions and 17 deletions
+17 -14
View File
@@ -1406,27 +1406,30 @@ function migrate_global_hosts_to_section(ctx) {
}
function migrate_orphan_section_interfaces(ctx) {
// Deleting a routing section used to leave its section_interface child
// records behind. A parent-less record never matches any section during
// Deleting a routing section used to leave its child records
// (subscription_url, section_interface, urltest, priority_group, priority_level)
// behind. A parent-less record never matches any section during
// config generation - dead weight that only confuses config readers.
let owners = {};
for (let section in ctx.model.sections)
owners[section_name(section)] = true;
let kept = [];
let changed = false;
for (let child in ctx.model.section_interface || []) {
let owner = option(child, "section", "");
if (owner != "" && !owners[owner]) {
record_operation(ctx, { op: "delete_section", section: section_name(child) });
changed = true;
continue;
let child_types = [ "subscription_url", "section_interface", "urltest", "priority_group", "priority_level" ];
for (let type_name in child_types) {
let kept = [];
let changed = false;
for (let child in ctx.model[type_name] || []) {
let owner = option(child, "section", "");
if (owner != "" && !owners[owner]) {
record_operation(ctx, { op: "delete_section", section: section_name(child) });
changed = true;
continue;
}
push(kept, child);
}
push(kept, child);
if (changed)
ctx.model[type_name] = kept;
}
if (changed)
ctx.model.section_interface = kept;
}
const MIGRATIONS = [
{ id: "interface_sections", run: migrate_interface_sections },