исправление: утечки ФД и временных файлов, переполнение ОЗУ

Проблема с FD-каскадом (зависание sing-box):
watchdog.uc открывал logread -f через popen() без O_CLOEXEC. Каждый
фоновый system('... &') порождал дочерний процесс, наследующий read-end
logread pipe. После kill watchdog — дочерний процесс держал pipe, logread
не получал SIGPIPE и оставался живым. За N перезапусков накапливалось
N orphan-процессов logread → исчерпание лимита 1024 FD → генератор
конфига sing-box не мог открыть .uc файлы → sing-box не стартовал.

Исправления FD-утечки:
- watchdog.uc: добавлена переменная logread_pipe_fd + помощник bg_system(),
  который закрывает FD logread перед запуском фоновых процессов
- watchdog.uc: killall logread перед открытием нового logread -f в
  setup_syslog_listener() для очистки orphan-процессов от предыдущих экземпляров
- watchdog.uc: все 7 вызовов system('... &') переведены на bg_system():
  restart, reload_firewall (x3), WAN ifdown/ifup, subscription_update_async (x3)
- initd.uc: killall logread в stop_service() после остановки tachyon
- nft/apply.uc: добавлены </dev/null >/dev/null 2>&1 к голому reload_firewall &
- updates.uc: добавлены редиректы к tachyon reload &
- telegram.uc: добавлен </dev/null к reload_firewall &

Проблема с утечкой временных файлов (500MB в /tmp):
При каждом tachyon restart (SIGKILL) процессы-генераторы умирали на
полуслове, оставляя /tmp/tmp.* файлы (sing-box config JSON ~3.4MB,
reload state). За 8 дней накопилось 227 файлов = 506MB в tmpfs,
что занимало 25% всего ОЗУ (519MB из 2007MB shared).

Исправления утечки временных файлов:
- temp_path() в runtime.uc и updates.uc теперь создаёт /tmp/tachyon-XXXXXX
  вместо /tmp/tmp.XXXXXX (безопасный для очистки префикс)
- nft/apply.uc и lifecycle.uc: аналогичное изменение mktemp
- lifecycle.uc start_impl(): автоматическая очистка /tmp/tachyon-* файлов
  старше 30 минут при каждом старте сервиса

Результат на роутере 192.168.2.1:
  logread после stop  = 0 (было 1+)
  logread после start = 1 (было 2+ в каскаде)
  sing-box = запущен
  /tmp shared         = 27MB (было 519MB, освобождено ~490MB)
  ОЗУ available       = 1691MB (было 1195MB)
This commit is contained in:
Dushnilin
2026-08-04 15:36:37 +03:00
parent a3de505a9a
commit b7d05034c8
7 changed files with 43 additions and 14 deletions
+6 -1
View File
@@ -794,6 +794,11 @@ function start_main() {
}
function start_impl() {
// Clean up orphaned /tmp/tachyon-* temp files from processes killed mid-operation
// (e.g. config generator killed during restart). 30-min threshold is safe since
// all tachyon temp files are created and deleted within seconds under normal operation.
command_status("find /tmp -maxdepth 1 -name 'tachyon-*' -mmin +30 -delete 2>/dev/null; true");
// Start Watchdog & Telegram Bot early so they remain active even if proxy configuration fails
let wd_status = module_status(WATCHDOG_UC, [ "start-runtime" ]);
if (wd_status != 0)
@@ -1180,7 +1185,7 @@ function reload(reason) {
if (status != 0)
return status;
let current_reload_state_file = trim(command_output_from_args([ "mktemp" ]));
let current_reload_state_file = trim(command_output_from_args([ "mktemp", "/tmp/tachyon-XXXXXX" ]));
if (current_reload_state_file == "")
return abort_reload(1, false);