kureshik.fun   >   books> books
Catalog
why cover
11 min7 pages

12 мая 2026 г.

why

техническая мистерия о сервере, который не хочет уходить без причины

технохоррорsysadminэкзистенциальное

Глава 1. Инвентаризация

В 02:16 мне приходит задача.

Тема: srv-archive-03 / подготовка к списанию
Приоритет: низкий
Дедлайн: до 09:00

В описании четыре строки.

Проверить остаточные сервисы.
Снять список активных процессов.
Отметить всё, что нельзя остановить.
Не трогать storage до согласования.

Я ставлю кружку слева от клавиатуры. Кофе уже холодный. На поверхности тонкая плёнка. Я не помню, когда его налил.

Подключаюсь через bastion.

ssh ops@srv-archive-03

Ответ приходит не сразу.

1.8 секунды до баннера. Для этой сети много.

Last login: Tue May 26 02:11:04 2026 from 10.40.0.12
srv-archive-03
Ubuntu 16.04.7 LTS
This system is scheduled for decommission.
Do not create new persistent services.

Я проверяю, кто ещё в системе.

w
 02:18:03 up 2178 days,  6:44,  1 user,  load average: 0.03, 0.02, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
ops      pts/0    10.40.0.12       02:17    0.00s  0.02s  0.00s w

2178 дней.

Почти шесть лет без нормальной перезагрузки.

Для архива это не рекорд.

Я создаю директорию для отчёта.

mkdir -p ~/audit/srv-archive-03
cd ~/audit/srv-archive-03

Снимаю базовое состояние.

date -Is > started_at.txt
uname -a > uname.txt
systemctl --failed > failed_units.txt
ps auxww > ps.txt
ss -tulpn > sockets.txt
crontab -l > crontab_ops.txt 2>&1

Потом запускаю свой скрипт. Он ищет процессы без нормального владельца: удалённые пользователи, старые UID, сироты с PPID=1, сервисы без unit-файла.

python3 orphan_scan.py --json > orphans.json

Скрипт падает.

KeyError: 'reason'

Я открываю файл. Последняя строка неполная.

{"pid":18342,"ppid":1,"uid":1007,"user":"deleted_2021","cmd":"./watcher","started":"2019-04-03T18:44:12","reason":

Поля reason в скрипте нет.

Я проверяю историю.

history | grep reason

Пусто.

Открываю сам скрипт.

grep -R "reason" -n .
./orphans.json:48:{"pid":18342,"ppid":1,"uid":1007,"user":"deleted_2021","cmd":"./watcher","started":"2019-04-03T18:44:12","reason":

Скрипт не писал это поле.

Он не мог.

Я удаляю файл и запускаю ещё раз.

rm orphans.json
python3 orphan_scan.py --json > orphans.json

На этот раз проходит.

jq '.[] | select(.pid==18342)' orphans.json
{
  "pid": 18342,
  "ppid": 1,
  "uid": 1007,
  "user": "deleted_2021",
  "cmd": "./watcher",
  "started": "2019-04-03T18:44:12"
}

Нормально.

Процесс лежит в старой домашней директории.

readlink /proc/18342/cwd
/home/deleted_2021/projects/listener

Директории нет.

ls -la /home/deleted_2021
ls: cannot access '/home/deleted_2021': No such file or directory

Но /proc/18342/cwd всё ещё указывает туда.

Так бывает.

Удалённая директория может жить, пока процесс держит inode. Ничего необычного.

Я фиксирую в заметку:

PID 18342 держит cwd в удалённой home-директории. Проверить перед остановкой.

Потом смотрю командную строку.

tr '\0' ' ' < /proc/18342/cmdline
./watcher --config ./keepalive.yml

Окружение пустое.

tr '\0' '\n' < /proc/18342/environ

Нет вывода.

Я проверяю бинарник.

ls -la /proc/18342/exe
lrwxrwxrwx 1 deleted_2021 deleted_2021 0 May 26 02:24 /proc/18342/exe -> /home/deleted_2021/projects/listener/watcher (deleted)

Удалённый бинарник.

Удалённая директория.

Удалённый пользователь.

Процесс работает.

Я пишу:

echo "18342 watcher deleted binary deleted cwd deleted user" >> notes.txt

Потом машинально ввожу:

why 18342

Команда существует.

Это первое странное.

Я хотел набрать whatis, потом ps -p. Пальцы сделали другое.

В PATH действительно есть /usr/local/bin/why.

Ответ приходит через 1.3 секунды.

Process is running because nobody remembered to stop it.

Я смотрю на строку.

Потом проверяю exit code.

echo $?
0

Успешно.

Слишком удачная шутка для /usr/local/bin.

Я ищу файл.

which why
file /usr/local/bin/why
/usr/local/bin/why
/usr/local/bin/why: ELF 64-bit LSB executable, x86-64, dynamically linked, stripped

Размер небольшой.

ls -lh /usr/local/bin/why
-rwxr-xr-x 1 root root 17K Nov  9  2015 /usr/local/bin/why

2015 год.

Я проверяю help.

why --help
why — show reason of existence.
Usage:
  why <pid|unit|name>
Try:
  why 1

Ни версии, ни автора.

man why
No manual entry for why

Я запускаю strings.

strings /usr/local/bin/why | head -50
/lib64/ld-linux-x86-64.so.2
puts
printf
strtol
/proc
Process is running because %s.
why — show reason of existence.
Try 'why 1'

Никаких готовых фраз.

Я запускаю ещё раз.

why 18342
Process is running because nobody remembered to stop it.

Тот же ответ.

Я проверяю другой процесс. sshd.

pgrep -x sshd | head -1
914
why 914
Process is running because remote access is still required.

Нормально.

Даже слишком нормально.

Проверяю cron.

pgrep -x cron
821
why 821
Process is running because some promises were scheduled, not kept.

Я сохраняю вывод.

{
  echo "$ why 18342"
  why 18342
  echo
  echo "$ why 914"
  why 914
  echo
  echo "$ why 821"
  why 821
} > why_samples.txt

Файл создаётся пустой.

cat why_samples.txt

Нет вывода.

Проверяю размер.

ls -lh why_samples.txt
-rw-r--r-- 1 ops ops 0 May 26 02:31 why_samples.txt

Повторяю через script.

script -q -c "why 18342" why_18342.typescript
Process is running because nobody remembered to stop it.
cat why_18342.typescript
Script started on 2026-05-26 02:32:10+00:00 [COMMAND="why 18342" <not executed on terminal>]
Script done on 2026-05-26 02:32:11+00:00 [COMMAND_EXIT_CODE="0"]

Вывода нет.

Я не записываю это в отчёт.

Пока не надо.

Смотрю auditd.

ausearch -x /usr/local/bin/why
<no matches>

Смотрю shell history.

grep -R "why " /home/*/.bash_history /root/.bash_history 2>/dev/null

Пусто.

Проверяю package owner.

dpkg -S /usr/local/bin/why
dpkg-query: no path found matching pattern /usr/local/bin/why

Обычный локальный мусор.

Я возвращаюсь к задаче.

Список процессов важнее.


Глава 2. Причина существования

На сервере 94 процесса.

Из них 17 не должны быть запущены.

Из них 5 висят дольше четырёх лет.

ps -eo pid,ppid,user,lstart,cmd --sort=start_time | tail -20
18342     1 deleted_2021 Wed Apr  3 18:44:12 2019 ./watcher --config ./keepalive.yml
2204      1 1004         Mon Jan 13 03:12:00 2020 ./wait.sh
6021      1 backup       Fri Aug 21 00:00:01 2020 /usr/local/bin/postgres_exporter --web.listen-address=:9187
7110      1 root         Thu Dec 31 23:59:59 2020 /opt/legacy/listener_final
9012      1 1009         Sun Feb 14 04:04:04 2021 ./remind_me_to_leave

Я проверяю wait.sh.

tr '\0' ' ' < /proc/2204/cmdline
readlink /proc/2204/cwd
getent passwd 1004
/bin/bash ./wait.sh
/home/1004/old/tickets

Пользователя с UID 1004 нет.

Я запускаю why уже специально.

why 2204

Ответ приходит не сразу.

2.9 секунды.

Process is running because the answer was archived before the question.

Exit code:

echo $?
0

Пробую перенаправить только stderr.

why 2204 2>err.txt
Process is running because the answer was archived before the question.

err.txt пустой.

Пробую stdout.

why 2204 >out.txt

На экране всё равно появляется строка.

Process is running because the answer was archived before the question.

out.txt пустой.

Я пишу в notes:

why writes directly to tty or other fd. Not captured by redirect/script.

Потом стираю строку.

Она выглядит глупо.

В 02:41 в syslog появляется запись.

tail -n 5 /var/log/syslog
May 26 02:41:09 srv-archive-03 systemd[1]: Started Session 18492 of user ops.
May 26 02:41:12 srv-archive-03 CRON[24871]: (root) CMD (test -x /usr/local/bin/cleanup && /usr/local/bin/cleanup)
May 26 02:41:12 srv-archive-03 cleanup[24872]: skipped: active handles found
May 26 02:41:13 srv-archive-03 kernel: [188197123.004188] why: process 2204 requested status of itself
May 26 02:41:13 srv-archive-03 kernel: [188197123.004189] why: process 2204 responded: still waiting

Я не запускал why от имени процесса 2204.

Проверяю время.

date -Is
2026-05-26T02:41:31+00:00

Проверяю dmesg.

dmesg | tail -5
[188197123.004188] why: process 2204 requested status of itself
[188197123.004189] why: process 2204 responded: still waiting

В ядре не должно быть сообщений от локальной утилиты /usr/local/bin/why.

Я смотрю модули.

lsmod | grep why

Пусто.

Проверяю /dev.

find /dev -iname '*why*' -o -iname '*reason*'

Пусто.

Проверяю unit-файлы.

grep -R "why" -n /etc/systemd /lib/systemd 2>/dev/null

Пусто.

Проверяю cron.

grep -R "why" -n /etc/cron* /var/spool/cron 2>/dev/null

Пусто.

Я добавляю в отчёт одну строку:

Unexpected kernel log entries related to /usr/local/bin/why. Needs follow-up.

Этого достаточно.

В 02:48 я пытаюсь остановить postgres_exporter.

Он слушает порт 9187, но Prometheus уже три года как переехал.

why 6021
Process is running because the database is gone and someone must continue reporting.

Я проверяю unit.

systemctl status postgres_exporter --no-pager
● postgres_exporter.service - PostgreSQL Exporter
   Loaded: loaded (/etc/systemd/system/postgres_exporter.service; enabled)
   Active: active (running) since Fri 2020-08-21 00:00:01 UTC; 5 years 9 months ago
 Main PID: 6021 (postgres_export)

Останавливаю.

sudo systemctl stop postgres_exporter

Команда висит 12 секунд.

Job for postgres_exporter.service canceled.

Не failed.

Canceled.

Смотрю статус.

systemctl status postgres_exporter --no-pager
● postgres_exporter.service - PostgreSQL Exporter
   Loaded: loaded (/etc/systemd/system/postgres_exporter.service; enabled)
   Active: active (running) since Fri 2020-08-21 00:00:01 UTC; 5 years 9 months ago
 Main PID: 6021 (postgres_export)

PID тот же.

В syslog:

May 26 02:49:03 srv-archive-03 systemd[1]: Stopping PostgreSQL Exporter...
May 26 02:49:15 srv-archive-03 systemd[1]: postgres_exporter.service: Stop operation timed out. Terminating.
May 26 02:49:15 srv-archive-03 systemd[1]: postgres_exporter.service: State 'stop-sigterm' timed out. Skipping final SIGKILL.
May 26 02:49:15 srv-archive-03 systemd[1]: postgres_exporter.service: Failed with result 'protocol'.
May 26 02:49:15 srv-archive-03 systemd[1]: Started PostgreSQL Exporter.

Skipping final SIGKILL не норма.

Я открываю unit.

cat /etc/systemd/system/postgres_exporter.service
[Unit]
Description=PostgreSQL Exporter
After=network.target
 
[Service]
User=backup
ExecStart=/usr/local/bin/postgres_exporter --web.listen-address=:9187
Restart=always
RestartSec=3
KillSignal=SIGTERM
SendSIGKILL=yes
 
[Install]
WantedBy=multi-user.target

SendSIGKILL=yes.

Systemd должен добить.

Не добил.

Я не трогаю больше.

В задаче было: отметить всё, что нельзя остановить.

В 03:02 на терминал выводится строка без prompt.

[WARNING] child process 2204 exited with reason: not yet

Я ничего не запускал.

Проверяю процесс.

ps -p 2204 -o pid,ppid,user,lstart,cmd
  PID  PPID USER     STARTED                      CMD
 2204     1 1004     Mon Jan 13 03:12:00 2020     /bin/bash ./wait.sh

Не вышел.

Я открываю /proc/2204/status.

cat /proc/2204/status | head
Name:	wait.sh
Umask:	0022
State:	S (sleeping)
Tgid:	2204
Ngid:	0
Pid:	2204
PPid:	1
TracerPid:	0
Uid:	1004	1004	1004	1004
Gid:	1004	1004	1004	1004

Спит.

Смотрю файловые дескрипторы.

ls -la /proc/2204/fd
total 0
dr-x------ 2 1004 1004  0 May 26 03:03 .
dr-xr-xr-x 9 1004 1004  0 May 26 03:03 ..
lr-x------ 1 1004 1004 64 May 26 03:03 0 -> /dev/null
l-wx------ 1 1004 1004 64 May 26 03:03 1 -> /var/log/old/tickets.log
l-wx------ 1 1004 1004 64 May 26 03:03 2 -> /var/log/old/tickets.log

Лог существует.

tail -20 /var/log/old/tickets.log
[2020-01-13 03:12:00] started
[2020-01-13 03:12:00] waiting for ticket #4419
[2020-01-13 03:12:01] ticket #4419 status: archived
[2020-01-13 03:12:01] retry in 86400 seconds

Дальше пусто.

Файл не обновлялся шесть лет.

stat /var/log/old/tickets.log
Modify: 2020-01-13 03:12:01.000000000 +0000
Change: 2020-01-13 03:12:01.000000000 +0000

Тогда строка [WARNING] пришла не оттуда.

Я проверяю tty.

tty
/dev/pts/0

И кто пишет в мой терминал.

lsof /dev/pts/0
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    24790 ops    0u   CHR  136,0      0t0    3 /dev/pts/0
bash    24790 ops    1u   CHR  136,0      0t0    3 /dev/pts/0
bash    24790 ops    2u   CHR  136,0      0t0    3 /dev/pts/0
lsof    25112 ops    1u   CHR  136,0      0t0    3 /dev/pts/0
lsof    25112 ops    2u   CHR  136,0      0t0    3 /dev/pts/0

Только я.

В 03:06 я делаю то, что обычно не делаю на списываемых серверах.

sudo cp /usr/local/bin/why ./why.bin
sudo sha256sum /usr/local/bin/why ./why.bin
3f09f3c9bdbd6b2dd7ecf8027d8fd4cf9e0a6d6d8eb9219d30e1fa2a4e8dd03b  /usr/local/bin/why
3f09f3c9bdbd6b2dd7ecf8027d8fd4cf9e0a6d6d8eb9219d30e1fa2a4e8dd03b  ./why.bin

Потом запускаю копию.

./why.bin 18342
Process is running because nobody remembered to stop it.

Копия работает.

Я переименовываю её.

mv why.bin test.bin
./test.bin 18342
Process is running because nobody remembered to stop it.

Значит, дело не в имени.

Я запускаю на несуществующий PID.

./test.bin 999999
No such process.

Exit code:

echo $?
3

Нормально.

Я запускаю на себя.

echo $$
24790
./test.bin 24790
Process is running because you are not done.

Я закрываю терминал на три секунды.

Не сессию.

Просто убираю окно за другое.

Потом возвращаю.

Prompt на месте.

ops@srv-archive-03:~/audit/srv-archive-03$

Я пишу в файл:

Do not run why on own shell again.

Файл сохраняется нормально.

В 03:14 приходит сообщение от дежурного в общем чате.

ты архив-03 смотришь?
там до утра надо просто список
без героизма

Я отвечаю:

да
список будет

Не пишу про why.

Пока нечего писать.

Я собираю таблицу.

cat > stuck_processes.tsv <<EOF
pid	user	started	cmd	note
18342	deleted_2021	2019-04-03	./watcher --config ./keepalive.yml	deleted cwd/exe/user
2204	uid_1004	2020-01-13	/bin/bash ./wait.sh	no passwd entry, old ticket wait
6021	backup	2020-08-21	postgres_exporter	stop canceled, still active
7110	root	2020-12-31	/opt/legacy/listener_final	unknown listener
9012	uid_1009	2021-02-14	./remind_me_to_leave	no passwd entry
EOF

Проверяю listener_final.

why 7110
Process is running because the last listener must not disconnect first.

Смотрю порт.

ss -tulpn | grep 7110

Нет вывода.

Смотрю fd.

ls -la /proc/7110/fd
0 -> /dev/null
1 -> /var/log/listener_final.log
2 -> /var/log/listener_final.log
3 -> socket:[44201]
4 -> anon_inode:[eventpoll]
5 -> socket:[44202]

Сокеты есть, но ss их не показывает.

cat /proc/7110/net/unix | grep 442
grep 442 /proc/net/unix

Пусто.

Сокеты без адреса.

Открываю лог.

tail -50 /var/log/listener_final.log
[2020-12-31 23:59:59] listener started
[2021-01-01 00:00:00] waiting for peer

И всё.

Пять лет тишины.

В 03:21 я запускаю why на remind_me_to_leave.

why 9012
Process is running because the reminder was set before the departure was canceled.

Я проверяю cwd.

readlink /proc/9012/cwd
/home/anna/reminders

Пользователь anna удалён.

getent passwd anna
ls /home
ops
backup
deploy

Но процесс с UID 1009 всё ещё имеет cwd /home/anna/reminders.

Я уже видел это на PID 18342.

Технически возможно.

Я повторяю это себе как комментарий к багу.

Технически возможно.

В 03:26 я нахожу файл.

find / -name keepalive.yml 2>/dev/null

Команда идёт долго.

Диск старый, много мусора.

Через минуту:

/proc/18342/cwd/keepalive.yml

Я читаю.

cat /proc/18342/cwd/keepalive.yml
name: watcher
mode: passive
owner: m.korotkov
created_at: 2019-04-03T18:40:02Z
comment: keep alive until she replies

Я смотрю на строку comment.

Потом копирую файл в отчёт.

cp /proc/18342/cwd/keepalive.yml ./keepalive_18342.yml

Проверяю owner.

stat /proc/18342/cwd/keepalive.yml
File: /proc/18342/cwd/keepalive.yml
Size: 112        Blocks: 8          IO Block: 4096   regular file
Device: 0,46     Inode: 917128      Links: 0
Access: (0644/-rw-r--r--)  Uid: ( 1007/ UNKNOWN)   Gid: ( 1007/ UNKNOWN)

Links: 0.

Файл удалён.

Держится только процессом.

Я не знаю, кто такая she.

В 03:33 я ищу m.korotkov.

grep -R "m.korotkov" -n /var/log /etc /opt 2>/dev/null | head -20
/var/log/auth.log.4.gz: binary file matches
/opt/legacy/owners.csv:17:m.korotkov,infra,2015-2019,disabled

Открываю owners.

cat /opt/legacy/owners.csv
login,team,period,status
a.serov,infra,2012-2016,left
m.korotkov,infra,2015-2019,disabled
anna,qa,2018-2021,disabled
root,system,always,protected

Строка root,system,always,protected выглядит человеческой.

Это хуже.

Я проверяю архивный auth log.

zgrep "m.korotkov" /var/log/auth.log.4.gz | tail -5
Apr 03 18:39:11 srv-archive-03 sshd[14881]: Accepted publickey for m.korotkov from 10.20.14.55 port 54112 ssh2
Apr 03 18:40:14 srv-archive-03 sudo: m.korotkov : TTY=pts/2 ; PWD=/home/m.korotkov/projects/listener ; USER=root ; COMMAND=/bin/systemctl daemon-reload
Apr 03 18:40:19 srv-archive-03 sudo: m.korotkov : TTY=pts/2 ; PWD=/home/m.korotkov/projects/listener ; USER=root ; COMMAND=/bin/systemctl start watcher
Apr 03 18:44:12 srv-archive-03 systemd[1]: Started watcher.
Apr 03 18:44:13 srv-archive-03 sshd[14881]: pam_unix(sshd:session): session closed for user m.korotkov

Но процесс сейчас показывает deleted_2021, UID 1007.

Пользователя переименовали или удалили.

Нормально.

В 03:40 я запускаю:

why watcher
Process is running because Mikhail asked the machine to wait on his behalf.

До этого why не называл имён.

Я проверяю, откуда оно могло взять Mikhail.

grep -R "Mikhail" -n /etc /opt /var/log 2>/dev/null | head
getent passwd 1007
grep -R "m.korotkov" -n /opt /etc 2>/dev/null
/opt/legacy/owners.csv:17:m.korotkov,infra,2015-2019,disabled

В доступных источниках имени Mikhail нет.

Я пишу в notes:

why knows name missing from system sources.

Потом не стираю.

В 03:47 в syslog появляется новая строка.

May 26 03:47:02 srv-archive-03 why[1]: process 18342 asked if reply was received
May 26 03:47:02 srv-archive-03 why[1]: answer unavailable

Процесс why[1].

PID 1 — systemd.

Я запускаю:

ps -p 1 -o pid,comm,args
PID COMMAND         COMMAND
1   systemd         /sbin/init

Нормально.

Потом:

why 1

Команда не возвращает prompt 8 секунд.

Я уже понимаю, что не надо было.

Ответ:

Process is running because everything else is afraid to begin.

Exit code:

echo $?
0

Я смотрю на строку.

Не потому что страшно.

Потому что её нельзя вставить в отчёт.

В 03:56 я формирую итоговый файл.

cat > report.txt <<EOF
srv-archive-03 audit
Started: $(cat started_at.txt)
Host uptime: $(uptime -p)
Found active legacy processes with deleted owners/binaries/cwd.
Several services cannot be stopped cleanly.
Critical:
- PID 18342 watcher, deleted owner/cwd/exe, started 2019-04-03
- PID 2204 wait.sh, no passwd entry, started 2020-01-13
- PID 6021 postgres_exporter, stop canceled, restarted/stayed active
- PID 7110 listener_final, inactive logs, unknown sockets
- PID 9012 remind_me_to_leave, no passwd entry
Notes:
- Do not decommission before storage snapshot.
- Do not kill unknown legacy processes without escalation.
- Unexpected kernel/syslog entries related to /usr/local/bin/why.
EOF

Я отправляю отчёт в тикет.

В 04:02 дежурный ставит реакцию ок.

В 04:06 приходит новый комментарий от менеджера.

если критичных зависимостей нет, выключаем по плану
дата-центр ждёт освобождения стойки
нужна финальная отметка до 08:30

Я открываю пустой ответ.

Пишу:

Есть процессы без владельцев. Часть не останавливается штатно. Рекомендую не выключать до ручной проверки.

Стираю ручной.

Пишу:

Рекомендую не выключать до проверки.

Отправляю.

В 04:11 терминал выводит:

[INFO] report.txt accepted
[INFO] shutdown approval pending

Это не сообщение shell.

Это не systemd.

Это не мой скрипт.

Я проверяю историю команд.

history | tail

Ничего похожего.

В 04:12 я запускаю последнюю команду, хотя в этом нет необходимости.

why shutdown

Ответ приходит сразу.

Process is running because someone always approves too late.

Prompt возвращается.

Я закрываю ноутбук не сразу.

Сначала проверяю, что отчёт сохранился.

sha256sum report.txt
d9f8b6cc3a6828ddf4d87f3b0ff3e4e5c65d861f4a2b3b0f68258ff3ad0c2a11  report.txt

Потом зачем-то проверяю файл ещё раз.

stat report.txt
File: report.txt
Size: 612        Blocks: 8          IO Block: 4096   regular file
Device: 0,46     Inode: 917144      Links: 0
Access: (0644/-rw-r--r--)  Uid: ( 1000/ ops)   Gid: ( 1000/ ops)
Access: 2026-05-26 04:12:44.000000000 +0000
Modify: 2026-05-26 04:12:44.000000000 +0000
Change: 2026-05-26 04:12:44.000000000 +0000

Links: 0.

Я не запускал rm report.txt.

Проверяю, кто держит файл.

lsof | grep report.txt
why       1 root    7r   REG    0,46      612 917144 /home/ops/audit/srv-archive-03/report.txt (deleted)

PID 1.

Я больше не пишу в notes.

Выхожу.

exit
logout
Connection to srv-archive-03 closed.

На локальном терминале остаётся одна строка.

Process is running because you disconnected first.

Глава 3. Согласование

В 07:18 я снова открываю ноутбук.

Кофе стоит там же.

Плёнка на поверхности стала толще. Она держится цельным серым кругом, как крышка.

На экране — локальный терминал.

Последняя строка всё ещё там.

Process is running because you disconnected first.

Я нажимаю Enter.

Новый prompt появляется сразу.

Значит, строка просто осталась после SSH.

Нормально.

Я повторяю это слово слишком часто.

В чате восемь непрочитанных.

Дежурный:

менеджер давит
им надо до 8:30 финально
можешь коротко — блокер есть или нет?

Менеджер:

в отчете нет критичных зависимостей
если есть только старые процессы — выключаем

Я перечитываю вторую строку.

В отчёте были критичные процессы.

Не “зависимости”, но процессы.

Не “hard blocker”, но причина не выключать.

Разница бюрократическая.

Разница смертельная только для данных.

Я открываю тикет.

Вложение report.txt.

Размер: 0 B.

Комментарий системы:

Attachment accepted.
No blocking dependencies detected.
Shutdown approval pending.

Я смотрю на это секунд десять.

Потом подключаюсь снова.

ssh ops@srv-archive-03

Ответ приходит через 3.4 секунды.

Больше, чем ночью.

Last login: Tue May 26 04:16:03 2026 from 10.40.0.12
srv-archive-03
Ubuntu 16.04.7 LTS
This system is scheduled for decommission.
Do not create new persistent services.
Do not create new reasons.

Последней строки ночью не было.

Я проверяю баннер.

grep -R "Do not create new reasons" -n /etc 2>/dev/null

Пусто.

Проверяю motd.

ls -la /etc/update-motd.d
grep -R "reasons" -n /etc/update-motd.d /etc/motd /etc/issue 2>/dev/null

Пусто.

Я не записываю это в отчёт.

Пока нечего записывать.

Проверяю, кто в системе.

w
 07:21:02 up 2178 days, 11:47,  1 user,  load average: 0.00, 0.01, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
ops      pts/0    10.40.0.12       07:20    0.00s  0.03s  0.00s w

Один пользователь.

Хорошо.

Плохо, что это всё ещё что-то значит.

Я перехожу в директорию аудита.

cd ~/audit/srv-archive-03
ls -la
total 52
drwxr-xr-x 2 ops ops 4096 May 26 04:12 .
drwxr-xr-x 3 ops ops 4096 May 26 02:18 ..
-rw-r--r-- 1 ops ops  119 May 26 02:18 crontab_ops.txt
-rw-r--r-- 1 ops ops  211 May 26 02:18 failed_units.txt
-rw-r--r-- 1 ops ops  112 May 26 03:27 keepalive_18342.yml
-rw-r--r-- 1 ops ops  184 May 26 03:58 notes.txt
-rw-r--r-- 1 ops ops 3872 May 26 02:29 orphans.json
-rw-r--r-- 1 ops ops 9144 May 26 02:18 ps.txt
-rw-r--r-- 1 ops ops  312 May 26 03:15 stuck_processes.tsv
-rw-r--r-- 1 ops ops  867 May 26 02:18 sockets.txt
-rw-r--r-- 1 ops ops   33 May 26 02:18 started_at.txt
-rwxr-xr-x 1 root root 17408 May 26 03:06 test.bin
-rw-r--r-- 1 ops ops  129 May 26 02:18 uname.txt
-rw-r--r-- 1 ops ops    0 May 26 02:31 why_samples.txt
-rw-r--r-- 1 ops ops  143 May 26 02:32 why_18342.typescript

report.txt нет.

Это логично.

Links: 0.

Удалённый файл не должен показываться в директории.

Но PID 1 держал его открытым.

Я проверяю.

sudo ls -la /proc/1/fd | grep 917144

Пусто.

sudo lsof -p 1 | grep report

Пусто.

В 04:12 файл был.

В 07:21 его уже нет.

Я смотрю journal.

sudo journalctl -b --since "2026-05-26 04:10:00" | grep report
May 26 04:12:44 srv-archive-03 why[1]: report.txt accepted
May 26 04:12:44 srv-archive-03 why[1]: report.txt detached
May 26 04:12:45 srv-archive-03 why[1]: report.txt became advisory

became advisory.

Я не знаю, какой severity у этого сообщения.

Я не знаю, как это вообще попало в journal.

Я проверяю binary path для PID 1 ещё раз.

readlink /proc/1/exe
/lib/systemd/systemd

Systemd.

Обычный.

Страшнее всего выглядят обычные вещи, когда они не имеют права быть обычными.

Я восстанавливаю отчёт из командной истории и файлов.

cat > report_recreated.txt <<EOF
srv-archive-03 audit
Started: $(cat started_at.txt)
Host uptime: $(uptime -p)
Found active legacy processes with deleted owners/binaries/cwd.
Several services cannot be stopped cleanly.
Critical:
- PID 18342 watcher, deleted owner/cwd/exe, started 2019-04-03
- PID 2204 wait.sh, no passwd entry, started 2020-01-13
- PID 6021 postgres_exporter, stop canceled, restarted/stayed active
- PID 7110 listener_final, inactive logs, unknown sockets
- PID 9012 remind_me_to_leave, no passwd entry
Notes:
- Do not decommission before storage snapshot.
- Do not kill unknown legacy processes without escalation.
- Unexpected kernel/syslog entries related to /usr/local/bin/why.
EOF

Проверяю размер.

wc -c report_recreated.txt
612 report_recreated.txt

Хэш совпасть не может.

Время другое, но содержимое такое же.

sha256sum report_recreated.txt
d9f8b6cc3a6828ddf4d87f3b0ff3e4e5c65d861f4a2b3b0f68258ff3ad0c2a11  report_recreated.txt

Хэш совпадает.

Это хорошо.

Это значит, что я помню правильно.

Я отправляю в тикет новый файл.

Через веб, не с сервера.

На этот раз размер нормальный.

612 B.

Через секунду размер меняется.

0 B.

Комментарий системы:

Attachment accepted.
No blocking dependencies detected.

Я ничего не трогаю.

Смотрю на экран.

Потом пишу в чат дежурному:

вложения обнуляются
текстом продублирую

Он отвечает почти сразу:

ты щас серьёзно?

Я не отвечаю.

Пишу комментарий в тикет текстом, без файла.

BLOCKER:
srv-archive-03 has active legacy processes with deleted cwd/exe/users.
postgres_exporter cannot be stopped cleanly; systemd skips final SIGKILL despite SendSIGKILL=yes.
There are unexpected kernel/journal entries related to /usr/local/bin/why.
Do not power off before storage snapshot and manual review.

Нажимаю отправить.

Комментарий появляется.

Я обновляю страницу.

Комментарий остаётся.

Потом меняется.

BLOCKER:
srv-archive-03 has active legacy processes with deleted cwd/exe/users.
postgres_exporter cannot be stopped cleanly.
No storage impact detected.

Последняя строка не моя.

Я открываю историю изменений.

Edited by system
07:26:18

Системный пользователь.

Не человек.

Не сервисный аккаунт, который обычно ставит статусы.

Просто system.

Я возвращаюсь в SSH.

Мне нужно доказательство, которое не проходит через тикет.

Сначала локальное.

cp report_recreated.txt report_recreated.copy
sha256sum report_recreated.txt report_recreated.copy
d9f8b6cc3a6828ddf4d87f3b0ff3e4e5c65d861f4a2b3b0f68258ff3ad0c2a11  report_recreated.txt
d9f8b6cc3a6828ddf4d87f3b0ff3e4e5c65d861f4a2b3b0f68258ff3ad0c2a11  report_recreated.copy

Потом tar.

tar -czf audit_bundle.tgz *.txt *.json *.tsv *.yml
sha256sum audit_bundle.tgz
a7f3b5d3d47d4f0a1f18f18c4ac51a0e9398f4b55e62fb60c8922a6f6a9c1180  audit_bundle.tgz

Проверяю архив.

tar -tzf audit_bundle.tgz | sort
crontab_ops.txt
failed_units.txt
keepalive_18342.yml
notes.txt
orphans.json
ps.txt
report_recreated.copy
report_recreated.txt
sockets.txt
started_at.txt
stuck_processes.tsv
uname.txt
why_18342.typescript
why_samples.txt

Нормально.

Я пересылаю дежурному хэш прямо в чат.

audit_bundle.tgz sha256:
a7f3b5d3d47d4f0a1f18f18c4ac51a0e9398f4b55e62fb60c8922a6f6a9c1180

Он отвечает:

вижу
а сам файл?

Я прикрепляю файл.

Он скачивает.

Пишет:

у меня архив открывается, но report пустой

Я не спрашиваю, какой report.

Смотрю локально.

tar -xOzf audit_bundle.tgz report_recreated.txt | wc -c
612

Текст есть.

tar -xOzf audit_bundle.tgz report_recreated.txt | tail -3
- Do not decommission before storage snapshot.
- Do not kill unknown legacy processes without escalation.
- Unexpected kernel/syslog entries related to /usr/local/bin/why.

Я отправляю ему только эти три строки.

В чат.

Без файла.

Он пишет:

первая и вторая дошли
третьей нет

Я смотрю на своё отправленное сообщение.

У меня три строки.

У него две.

Я пробую заменить слово.

Unexpected kernel/syslog entries related to local diagnostic binary.

Он отвечает:

теперь есть

Значит, дело не в строке.

Дело в имени.

Я не пишу его больше в чат.

В 07:33 в терминал выводится:

[INFO] report_recreated.txt accepted
[INFO] blocker converted to advisory

Я проверяю lsof.

sudo lsof | grep report_recreated
why       1 root    8r   REG    0,46      612 917219 /home/ops/audit/srv-archive-03/report_recreated.txt
why       1 root    9r   REG    0,46      612 917220 /home/ops/audit/srv-archive-03/report_recreated.copy

На этот раз файлы не удалены.

PID 1 держит их как обычные.

Почему обычные — я не знаю.

Я проверяю ссылки.

stat report_recreated.txt | grep Links
Links: 1

Нормально.

Впервые за час это слово не помогает.

Я запускаю:

why report_recreated.txt

Ответ появляется сразу.

Process is running because a warning becomes harmless after it is filed.

Я закрываю глаза.

На секунду.

Больше нельзя.

В 07:39 менеджер пишет в тикет:

Нет подтверждённого blocker.
Ожидаем финальную отметку до 08:30.

Потом в общий чат:

Коллеги, давайте без драматизации.
Если сервисов нет — сервер выводим.

Дежурный пишет мне отдельно:

я не понимаю что происходит
но давай без слова why
оно реально пропадает из сообщений

Я не отвечаю.

Открываю stuck_processes.tsv.

Пять процессов.

Пять причин.

Ни одной зависимости, которую можно красиво вписать в форму.

Я проверяю mounts.

Не storage, только список.

findmnt -rno TARGET,SOURCE,FSTYPE,OPTIONS
/ /dev/mapper/vg0-root ext4 rw,relatime,errors=remount-ro
/boot /dev/sda1 ext2 rw,relatime
/archive /dev/mapper/vg0-archive ext4 rw,relatime,data=ordered
/run tmpfs tmpfs rw,nosuid,noexec,relatime,size=1638428k,mode=755

/archive.

Я не открываю его.

В задаче было: не трогать storage до согласования.

Я проверяю только, кто держит mount.

sudo fuser -vm /archive
                     USER        PID ACCESS COMMAND
/archive:            root     kernel mount /archive
                     1007      18342 ..c.. watcher
                     1004       2204 ..c.. wait.sh
                     root       7110 F.... listener_final
                     1009       9012 ..c.. remind_me_to_leave

Вот оно.

Не сервисная зависимость.

Файловая.

Процессы держат storage.

Удалённые cwd.

Удалённые файлы.

Удалённые пользователи.

Если выключить сервер, всё, что держится только ими, исчезнет окончательно.

Возможно, там мусор.

Возможно, это и есть архив.

Я пишу новую формулировку.

Без запрещённого имени.

HARD BLOCKER:
Power-off will destroy currently open deleted inodes on /archive.
PIDs 18342, 2204, 7110, 9012 hold storage handles.
A storage snapshot or forensic copy is required before shutdown.

Дежурному в личку.

Он отвечает:

вот это дошло полностью
кидай в тикет

Я кидаю.

Комментарий появляется.

Обновляю страницу.

Комментарий остаётся.

Обновляю ещё раз.

Остаётся.

В 07:46 статус тикета меняется.

Shutdown approval pending → Manual review required

Я выдыхаю.

Слишком рано.

Через 11 секунд статус меняется обратно.

Manual review required → Shutdown approval pending

Комментарий остаётся.

Ниже появляется системная строка.

Manual review canceled: no owner assigned.

Я смотрю на список owners.

m.korotkov — disabled.

anna — disabled.

root — protected.

У процессов нет владельцев.

У риска тоже.

Я запускаю команду, хотя обещал себе не запускать.

why approval

Ответ приходит почти без задержки.

Process is running because nobody owns the risk after it becomes collective.

В этот раз я не проверяю exit code.


Глава 4. Снимок

В 08:03 дежурный звонит.

Не пишет.

Звонит.

Я беру не сразу.

Он говорит тихо.

— Они хотят выключать. Говорят, storage snapshot не нужен, потому что сервер архивный и всё уже мигрировано.

Я спрашиваю:

— Кто подтвердил?

Он молчит секунду.

— В тикете стоит approved.

Я обновляю страницу.

Статус:

Shutdown approved.
Window: 08:30–09:00 UTC.
Reason: decommission / rack release.
Approver: system

Approver: system.

Это уже даже не смешно.

Я открываю SSH.

Сессия жива.

date -Is
2026-05-26T08:04:12+00:00

Проверяю jobs.

systemctl list-jobs
No jobs running.

Проверяю scheduled shutdown.

cat /run/systemd/shutdown/scheduled 2>/dev/null

Нет вывода.

Проверяю wall.

who -b
         system boot  2020-06-08 19:34

Ничего.

Тогда пока approved только в тикете.

Не на сервере.

Я снова проверяю /archive.

Не читаю содержимое.

Только метаданные.

sudo lsof +f -- /archive | awk 'NR==1 || /18342|2204|7110|9012/'
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
watcher   18342 1007  cwd    DIR  253,1     4096 917120 /archive/home/m.korotkov/projects/listener (deleted)
wait.sh    2204 1004  cwd    DIR  253,1     4096 882014 /archive/home/1004/old/tickets (deleted)
listener_ 7110 root    3u  sock    0,8      0t0  44201 protocol: UNIX-STREAM
remind_m   9012 1009  cwd    DIR  253,1     4096 901881 /archive/home/anna/reminders (deleted)

Теперь путь не /home.

Путь /archive/home.

Ночью readlink /proc/18342/cwd показывал /home/deleted_2021/projects/listener.

Я проверяю.

readlink /proc/18342/cwd
/archive/home/m.korotkov/projects/listener

Путь изменился.

Процесс не перезапускался.

ps -p 18342 -o pid,lstart,cmd
  PID                  STARTED CMD
18342 Wed Apr  3 18:44:12 2019 ./watcher --config ./keepalive.yml

Технически возможно?

Bind mount.

Symlink.

Старый automount.

Я проверяю /home.

ls -la /home
total 20
drwxr-xr-x  5 root root 4096 May 26 08:05 .
drwxr-xr-x 23 root root 4096 May 26 02:11 ..
drwxr-xr-x  2 ops  ops  4096 May 26 02:18 ops
drwxr-xr-x  2 root root 4096 May 26 08:05 backup
drwxr-xr-x  2 root root 4096 May 26 08:05 deploy

Нет mount.

findmnt /home

Пусто.

Ночью я видел /home/deleted_2021.

Или думал, что видел.

Я проверяю сохранённые файлы.

grep "readlink /proc/18342/cwd" -n ~/.bash_history | tail

История ещё не записалась.

Я открываю notes.txt.

cat notes.txt
18342 watcher deleted binary deleted cwd deleted user
Do not run why on own shell again.
why knows name missing from system sources.

Про /home там нет.

Потому что я не записал.

Конечно.

Я ищу в typescript.

grep -R "/home/deleted" -n .

Пусто.

Вывода той команды нигде нет.

Он был только на экране.

Я был уверен.

Это не доказательство.

Это ощущение.

Ощущения в отчёт не кладут.

Я делаю новый файл.

cat > storage_blocker.txt <<EOF
srv-archive-03 storage blocker
Time: $(date -Is)
Mount: /archive
Risk:
- active processes hold deleted cwd/files on /archive
- shutdown will release inodes before snapshot
- previous report attachment was accepted as empty in ticket
Evidence:
$(sudo fuser -vm /archive 2>&1)
EOF

Проверяю.

cat storage_blocker.txt
srv-archive-03 storage blocker
Time: 2026-05-26T08:08:41+00:00
Mount: /archive
Risk:
- active processes hold deleted cwd/files on /archive
- shutdown will release inodes before snapshot
- previous report attachment was accepted as empty in ticket
Evidence:
                     USER        PID ACCESS COMMAND
/archive:            root     kernel mount /archive
                     1007      18342 ..c.. watcher
                     1004       2204 ..c.. wait.sh
                     root       7110 F.... listener_final
                     1009       9012 ..c.. remind_me_to_leave

Файл нормальный.

Я хэширую.

sha256sum storage_blocker.txt
6b9e2f1d2d7f6b2e11f05cf0a919de4e7f45d3d3fb39b8a3fd72d7fb50b93f13  storage_blocker.txt

Отправляю хэш дежурному.

Он отвечает:

вижу

Отправляю текст.

Он отвечает:

вижу полностью

Значит, это формулировка проходит.

Я отправляю её в тикет.

Статус не меняется.

Shutdown approved.

В 08:12 в терминал приходит wall-сообщение.

Broadcast message from root@srv-archive-03 (Tue 2026-05-26 08:12:03 UTC):

The system is going down for power-off at Tue 2026-05-26 08:30:00 UTC!

Я не ставил shutdown.

Проверяю.

cat /run/systemd/shutdown/scheduled
USEC=1779784200000000
WARN_WALL=1
MODE=poweroff

Кто поставил?

stat /run/systemd/shutdown/scheduled
Access: 2026-05-26 08:12:04.000000000 +0000
Modify: 2026-05-26 08:12:03.000000000 +0000
Change: 2026-05-26 08:12:03.000000000 +0000

Смотрю journal.

sudo journalctl -b --since "2026-05-26 08:11:50" --until "2026-05-26 08:12:10"
May 26 08:12:03 srv-archive-03 systemd-logind[804]: System is powering down.
May 26 08:12:03 srv-archive-03 shutdown[28114]: shutting down for system halt
May 26 08:12:03 srv-archive-03 why[1]: shutdown approved by absence of owner

shutdown[28114].

ps -p 28114 -o pid,user,args
  PID USER     COMMAND

Процесс уже вышел.

Я проверяю audit.

sudo ausearch -p 28114
<no matches>

Пробую отменить.

sudo shutdown -c
Shutdown cancelled.

В терминал сразу падает:

Broadcast message from root@srv-archive-03 (Tue 2026-05-26 08:12:31 UTC):

The system shutdown has been cancelled.

Хорошо.

Через четыре секунды:

Broadcast message from root@srv-archive-03 (Tue 2026-05-26 08:12:35 UTC):

The system is going down for power-off at Tue 2026-05-26 08:30:00 UTC!

Я снова отменяю.

sudo shutdown -c
Shutdown cancelled.

Через четыре секунды — снова wall.

The system is going down for power-off at Tue 2026-05-26 08:30:00 UTC!

Я больше не отменяю.

Не потому что сдался.

Потому что надо понять источник.

Смотрю timers.

systemctl list-timers --all | grep -i shutdown

Пусто.

Cron.

grep -R "shutdown\|poweroff\|halt" -n /etc/cron* /var/spool/cron 2>/dev/null

Пусто.

At jobs.

atq
warning: commands will be executed using /bin/sh

Нет jobs.

Systemd jobs.

systemctl list-jobs
JOB UNIT           TYPE  STATE
941 poweroff.target start waiting

1 jobs listed.

Пробую cancel.

sudo systemctl cancel 941
systemctl list-jobs
No jobs running.

Через четыре секунды:

systemctl list-jobs
JOB UNIT           TYPE  STATE
942 poweroff.target start waiting

1 jobs listed.

Номер увеличился.

Кто-то или что-то ставит заново.

Я запускаю:

why poweroff.target

Ответ приходит после паузы.

5.1 секунды.

Process is running because approval is a stronger signal than caution.

Я хочу ударить ноутбук.

Вместо этого пишу:

sudo systemctl mask poweroff.target
Created symlink from /etc/systemd/system/poweroff.target to /dev/null.

Это грубо.

Это некрасиво.

Это ровно то, за что потом спрашивают.

Но это reversible.

И это не трогает storage.

Проверяю jobs.

systemctl list-jobs
No jobs running.

Через четыре секунды jobs не возвращаются.

В journal:

May 26 08:15:02 srv-archive-03 systemd[1]: Cannot add dependency job for unit poweroff.target, ignoring: Unit poweroff.target is masked.
May 26 08:15:02 srv-archive-03 why[1]: shutdown reason deferred

deferred.

Не canceled.

Deferred.

Я пишу в тикет:

Emergency hold placed: poweroff.target masked temporarily because shutdown keeps rescheduling without visible initiator.
Storage blocker remains. Need owner review.

Комментарий появляется.

Не меняется.

В 08:17 статус тикета:

Shutdown approved → Manual review required

На этот раз не откатывается.

Дежурный пишет:

что ты сделал?

Я отвечаю:

поставил технический стоп
обоснование в тикете

Он:

менеджер орет

Я:

пусть орет в тикет

Через минуту менеджер действительно пишет.

Кто замаскировал poweroff.target?
Это выходит за рамки задачи.

Я набираю ответ.

Стираю.

Набираю снова.

Я. Причина: плановое выключение пересоздавалось после отмены без видимого инициатора. На /archive есть активные deleted inodes, удерживаемые legacy-процессами. До snapshot выключение может уничтожить единственные доступные копии этих данных.

Отправляю.

Комментарий остаётся.

Никто его не редактирует.

В 08:21 в терминал выводится:

[INFO] owner required
[INFO] reason cannot be converted to advisory

Я впервые за ночь улыбаюсь.

Немного.

Плохо.

В 08:22 я проверяю /archive ещё раз.

sudo fuser -vm /archive
                     USER        PID ACCESS COMMAND
/archive:            root     kernel mount /archive
                     1007      18342 ..c.. watcher
                     1004       2204 ..c.. wait.sh
                     root       7110 F.... listener_final
                     1009       9012 ..c.. remind_me_to_leave

Те же четыре.

postgres_exporter в списке нет.

Он не держит storage.

Он просто не умирает.

Это почти честно.

Я смотрю deleted files.

sudo lsof +L1 /archive
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NLINK    NODE NAME
watcher   18342 1007  cwd    DIR  253,1     4096     0  917120 /archive/home/m.korotkov/projects/listener (deleted)
watcher   18342 1007  txt    REG  253,1    17408     0  917121 /archive/home/m.korotkov/projects/listener/watcher (deleted)
watcher   18342 1007    3r   REG  253,1      112     0  917128 /archive/home/m.korotkov/projects/listener/keepalive.yml (deleted)
wait.sh    2204 1004  cwd    DIR  253,1     4096     0  882014 /archive/home/1004/old/tickets (deleted)
remind_m   9012 1009  cwd    DIR  253,1     4096     0  901881 /archive/home/anna/reminders (deleted)

Вот оно.

Нормальный blocker.

Скучный.

Технический.

Достаточный.

Не мистика.

Просто открытые удалённые inode на storage.

Если выключить — они исчезнут.

Я сохраняю вывод.

sudo lsof +L1 /archive > deleted_inodes_archive.txt
sha256sum deleted_inodes_archive.txt
b1d6a66a3a6f66b3ed5f0b5a3d8b2a9a7c7e70d0ea0c5b8f66e2b06a3f58fd2c  deleted_inodes_archive.txt

Файл не пустеет.

Я прикрепляю его.

Размер остаётся.

Статус тикета меняется:

Manual review required → Storage snapshot required

Approver:

infra-lead

Человек.

Наконец-то человек.

В 08:26 мне пишет незнакомый аккаунт в чате.

Имя: Михаил Коротков.

Аватарки нет.

Статус: offline.

Сообщение одно.

не копируй содержимое
сначала снимок

Я смотрю на него.

Потом на keepalive.yml.

comment: keep alive until she replies

Я открываю профиль.

User disabled.
Last active: 2019-04-03.

Скриншот я не делаю.

Не потому что не успеваю.

Потому что понимаю: скриншот будет пустым.

Я закрываю чат.

В 08:28 приходит сообщение от infra-lead.

poweroff.target не трогать до snapshot
кто маскировал — после разберём
сейчас не мешайте

Я отвечаю:

принял

Потом снимаю маску.

sudo systemctl unmask poweroff.target
Removed /etc/systemd/system/poweroff.target.

Проверяю jobs.

systemctl list-jobs
No jobs running.

Shutdown не возвращается.

В journal:

May 26 08:29:02 srv-archive-03 systemd[1]: Removed mask for poweroff.target.
May 26 08:29:03 srv-archive-03 why[1]: shutdown reason superseded by storage snapshot

Снимок ещё не начался.

Но причина уже изменилась.

В 08:31 infra-lead пишет:

snapshot started

В 08:34:

snapshot complete

В 08:35:

можно выключать после выгрузки audit bundle

Я собираю новый архив.

tar -czf audit_bundle_final.tgz *.txt *.json *.tsv *.yml
sha256sum audit_bundle_final.tgz
c0fd2d1a0ef3cc97aa1912c3f6a6e2b2bbf0c0f43dc195646c84a6c3b8a6f41e  audit_bundle_final.tgz

Отправляю.

Дежурный пишет:

скачал
открывается
всё на месте

Я проверяю последний раз.

why 18342

Ответ другой.

Process is running because the snapshot has not learned how to wait.

Я не понимаю, лучше это или хуже.

В 08:39 infra-lead пишет:

выключаем

Я не выполняю команду.

Её выполняет кто-то другой.

В терминале:

Broadcast message from root@srv-archive-03 (Tue 2026-05-26 08:40:11 UTC):

The system is going down for power-off NOW!

SSH не рвётся сразу.

Сначала идут строки.

Stopping PostgreSQL Exporter...
Stopping Session 18531 of user ops...
Stopping OpenBSD Secure Shell server...
Unmounting /archive...

Потом пауза.

archive.mount: Mount process exited, code=exited status=32
archive.mount: Failed unmounting /archive.

Я почти не дышу.

Следующая строка:

why[1]: active handles found

Потом:

watcher[18342]: reply unavailable
wait.sh[2204]: ticket #4419 still archived
listener_final[7110]: peer not connected
remind_me_to_leave[9012]: departure canceled

Все четыре процесса пишут в shutdown.

Все четыре молчали годы.

Сейчас — нет.

Systemd ждёт.

A stop job is running for /archive (32s / no limit)

no limit.

Кто-то поставил TimeoutStopSec=infinity.

Или оно само.

Я не проверяю.

Иногда лучше не знать точный unit-файл.

В 08:43 infra-lead пишет:

сервер не гаснет
видим busy mount
не трогаем

Я отвечаю:

да

Больше ничего.

В 08:44 терминал выводит:

[INFO] shutdown blocked by storage
[INFO] reason accepted

Потом prompt.

Обычный prompt.

ops@srv-archive-03:~/audit/srv-archive-03$

Я запускаю последнюю команду.

Не why.

date -Is
2026-05-26T08:44:51+00:00

Потом всё-таки запускаю.

why 1

Ответ приходит сразу.

Process is running because someone finally wrote the reason down.

Exit code:

echo $?
0

Я выхожу.

exit
logout
Connection to srv-archive-03 closed.

На локальном терминале ничего не появляется.

Пустая строка.

Prompt.

Я смотрю на него дольше, чем надо.

Потом приходит новое сообщение в тикете.

Storage snapshot verified.
Decommission postponed.
Owner assignment required.

Ниже — ещё одно.

Owner assigned: m.korotkov

Через секунду строка исчезает.

Страница обновляется сама.

Теперь там:

Owner assigned: infra-lead

Я успел увидеть первое.

Этого нигде нет.

И правильно.

Не всё, что появляется на экране, должно становиться доказательством.

Некоторые вещи существуют только пока кто-то смотрит.

Некоторые процессы — тоже.