Таймаут вернул 124, а следующий запуск пропущен: какие фоновые утилиты держат flock

opium 37 минут назад Краткое содержание статьи Таймаут вернул 124, а следующий запуск пропущен: какие фоновые утилиты держат flock 5 мин 1.3K Серверное администрирование * Системное программирование * Linux * Аналитика...
Will Anthropic have the best AI model at the end of October 2026?
Вот важная новость с фронта ИИ: opium 37 минут назад Краткое содержание статьи Таймаут вернул 124, а следующий запуск пропущен: какие фоновые утилиты держат flock 5 мин 1. 3K Серверное администрирование * Системное программирование * Linux * Аналитика Задача из cron превысила лимит timeout 600, в логе код 124. Через минуту cron запускает её снова, и обёртка flock -n молча выходит: lock занят, «предыдущий запуск ещё идёт».
Но timeout уже вернул 124: главный процесс задачи завершился, а её фоновые потомки могли остаться. Я проверил в контейнере семь обычных способов, которыми задача оставляет что-то работать в фоне: setsid -f, nohup … &, start-stop-daemon --background, двойной fork на Python с закрытием дескрипторов и без, ssh-agent, gpg-agent. Каждый запускался из задачи, которая держит flock, и обрывался через timeout 2 и subprocess.
Технические детали
Демона не убила ни одна обёртка. Будет ли пропущен следующий запуск, решает сама фоновая утилита: закрывает ли она унаследованные дескрипторы. gpg-agent и наивный двойной fork держат lock, ssh-agent и start-stop-daemon отпускают.
Зато у тех, что отпускают, процессы копятся: пять запусков подряд дали пять живых ssh-agent. А оборванный запуск в обоих случаях заканчивается одинаково: 124 от timeout, TimeoutExpired от subprocess. СтендЗадача берёт lock на дескрипторе 9, уходит в фон одним из семи способов и ждёт 30 секунд.
Сама она ждёт с закрытым дескриптором, так что после её смерти lock может держать только фоновый потомок:exec 9>"$D/lock"; flock -n 9 { echo "job: lock busy"; exit 1; } case $M in setsid_f) setsid -f sleep 30 /dev/null 2>&1 ;; nohup_bg) nohup sleep 30 /dev/null 2>&1 & ;; ssd_bg) start-stop-daemon --start --background --make-pidfile \ --pidfile "$D/ssd. pid" --exec /usr/bin/sleep -- 30 ;; py_dfork) python3 dfork. py keep ;; # двойной fork + setsid py_dfork_close) python3 dfork.
Отраслевые последствия
py close ;; # то же + os. closerange(3, 1024) ssh_agent) eval "$(ssh-agent -s)" >/dev/null ;; gpg_agent) export GNUPGHOME="$D/gh. $$"; mkdir -m 700 "$GNUPGHOME" gpg-agent --daemon >/dev/null 2>&1 ;; esac sleep 30 9>&- Через две секунды после возврата обёртки скрипт находит в /proc новые процессы, смотрит, у кого среди открытых файлов есть lock, и пробует flock -n тем же файлом, как следующий запуск.
У ssh-agent и gpg-agent каталог /proc/PID/fd закрыт для чтения: оба помечают себя как non-dumpable. Держателя я находил иначе: убивал выживших по одному и смотрел, после кого lock освободился. Каждая ячейка прогнана три раза, повторы совпали.
15 (Debian 13), coreutils 9. Почему вообще важен дескриптор. По man flock(2) блокировка принадлежит открытому описанию файла, копии после fork её разделяют, и снимается она, когда закроется последняя копия.
Событие, по словам экспертов, усилит конкуренцию в сфере ИИ.





