#!/usr/bin/env bash
# panic-on-lockup.sh —— 把「死机就永久死着」改成「锁死→panic→自动重启」，并让日志活到最后一刻
#
# 现状（2026-09-15 实测）：
#   kernel.panic=0  kernel.panic_on_oops=0  kernel.hung_task_panic=0
#   kernel.softlockup_panic=0  kernel.hardlockup_panic=0   （nmi_watchdog=1）
#   → 18:38 整机冻结后没有任何 panic/重启，一直死到 22 分 42 秒后人工按电源复位。
#
# 本脚本做两件事：
#   1) 打开锁死→panic（并设置 panic=10 → panic 后 10 秒自动重启）
#   2) journald 刷盘间隔 5m → 5s（默认值会让崩溃前最多 5 分钟日志留在页面缓存里丢掉）
#
# 用法（GPU 机上，需要 root）：
#     sudo bash panic-on-lockup.sh            # 立即生效（重启后失效）
#     sudo bash panic-on-lockup.sh --persist  # 同时写入 /etc/sysctl.d 与 journald.conf
#
# ⚠️ 行为变更：此脚本生效后，整机锁死会**自动重启**（约 2 分钟内），而不是无限期冻结。
#    你若不想自动重启，请只跑 --netconsole 那一套（见 enable-netconsole-gpu.sh），不要跑本脚本。

set -euo pipefail

[ "$(id -u)" = "0" ] || { echo "需要 root：sudo bash $0" >&2; exit 1; }

apply() {
  sysctl -w kernel.hardlockup_panic=1
  sysctl -w kernel.softlockup_panic=1
  sysctl -w kernel.hung_task_timeout_secs=300
  sysctl -w kernel.hung_task_panic=1
  sysctl -w kernel.panic=10
  echo "锁死→panic 已启用（hung_task 超时 300s；panic 后 10 秒重启）"
}

apply

if [ "${1:-}" = "--persist" ]; then
  cat >/etc/sysctl.d/99-panic-on-lockup.conf <<'EOF'
# 整机锁死时自动 panic + 重启（2026-09-15 硬挂事件后加入）
kernel.hardlockup_panic = 1
kernel.softlockup_panic = 1
kernel.hung_task_timeout_secs = 300
kernel.hung_task_panic = 1
kernel.panic = 10
EOF
  sysctl --system >/dev/null

  # journald：崩溃前最后几秒也要落盘
  if [ -f /etc/systemd/journald.conf ]; then
    sed -i 's/^#\?SyncIntervalSec=.*/SyncIntervalSec=5s/' /etc/systemd/journald.conf
    grep -q '^SyncIntervalSec=' /etc/systemd/journald.conf || echo 'SyncIntervalSec=5s' >>/etc/systemd/journald.conf
    systemctl restart systemd-journald
    echo "journald SyncIntervalSec=5s 已生效"
  fi

  echo "已持久化到 /etc/sysctl.d/99-panic-on-lockup.conf"
fi

echo
echo "当前状态："
for k in kernel.panic kernel.hardlockup_panic kernel.softlockup_panic kernel.hung_task_panic kernel.hung_task_timeout_secs; do
  printf '  %-32s = %s\n' "$k" "$(sysctl -n $k)"
done
