r1 评审 verdict=p2-3items,三条均已按评审给的修法修掉,且都补了可证伪的回归断言。 P2-1 SIGTERM 后遗留孤儿 ntpd,之后每次静默 skip 且 rc=0 - attempt() 把子进程记进全局 NTPD_CHILD 并落盘 <锁目录>/ntpd.pid; 新增 cleanup()(EXIT trap)先收尸子进程再释放锁;新增 on_signal() (INT/TERM/HUP)清理后 exit 143——旧代码的 TERM trap 只清锁、不 exit, 被杀后还会继续跑完看门狗。 - 取代原来的 "pidof ntpd 就 skip":新增 reap_or_skip_ntpd(),用 /proc/<pid>/cmdline 是否含本锁目录来区分「我们自己遗留的孤儿」(收尸) 与「别人的常驻 ntpd」(让路)。崩溃后留下的 ntpd.pid 也据此校验, pid 被复用时不会误判成外部 daemon(不会永久 skip)。 - S45 stop 不再按陈旧 pid 文件盲杀:只从 <锁目录>/<pid> 取持有者, 再核对 /proc/<pid>/cmdline 含 meow_ntpsync 才 kill。 P2-2 日志重定向失败导致 hwclock 根本不执行 - persist_rtc 改 ">/dev/null 2>>$LOG_FILE":hwclock 的 rc 与日志写入解耦。 - 新增 prepare_log():启动时在子 shell 里试写日志,不可写就整体退化 /dev/null。 必须用子 shell——`:` 是 POSIX 特殊内建,它的重定向失败会让 dash 直接 退出整个脚本(本单自测先踩到了,rc=2)。 P2-3 锁 mkdir→写 pid 有窗口,并发抑制非原子 - 锁的持有者改由 <锁目录>/<pid> 子目录自证(mkdir 原子),不再写 pid 文件; 读到空锁时给 3s 宽限而不是立刻判死。 - 清失效锁改用 mv 到 <锁目录>.stale.$$(rename 原子),并发清锁时只有 一个能成功,避免「抢锁失败方删掉胜方的锁」。 - 退出只删自己的锁:没有自己的 <pid> 子目录就不动锁目录。 验证 - 新增回归断言 11-16(run_tests.sh):SIGTERM 收尸/锁释放、遗留孤儿收尸、 日志不可写仍写 RTC、锁被占用不抢、死锁可接管、pid 复用不阻断。 - 可证伪性:新套件跑旧代码(c9f0cba 的 meow_ntpsync)→ 6 条 FAIL (孤儿 alive、日志不可写 rc=1 且 hwclock 未执行、抢锁并发调 ntpd×3)。 再跑「仅回退 STALE_NTPD 硬化」的变体 → pid 复用那条 FAIL (rc=0 但 RTC 未写,正是评审指出的静默失效)。 - dash 与 busybox ash 各 41/41 PASS,rc=0;dash -n / busybox sh -n 均 0 错。 - 时间断言放宽为负载容忍(宿主是多 agent 共享机,实测 sleep 5 能跑成 85s), 假 ntpd 改为挂 3600s,保证上界仍能证明是看门狗掐断而非自然退出。 fw_content.conf: meow_ntpsync md5 ad324e3f→f3c3abe4, S45meow_ntpsync md5 25454a3f→115e7592(50meow_ntpsync 未改,md5 不变)。
50 lines
1.5 KiB
Bash
Executable File
50 lines
1.5 KiB
Bash
Executable File
#!/bin/sh
|
||
#
|
||
# S45meow_ntpsync — 开机网络校时(M22)
|
||
#
|
||
# 只负责把同步器丢到后台并**立即返回**,开机关键路径增加 0 秒。
|
||
# 真正的「等网络就绪 + 有限重试 + 总超时」全在 /usr/bin/meow_ntpsync 里。
|
||
#
|
||
# 为什么排 S45:S40network 只 ifup 了 lo,WiFi 由 S43 之后才起来,租约更晚,
|
||
# 所以本脚本启动时大概率还没有网络——同步器自己轮询默认路由(最多 -t 秒)。
|
||
# WiFi 在更晚(用户手动连)才就绪的情况,由 udhcpc 钩子
|
||
# /usr/share/udhcpc/default.script.d/50meow_ntpsync 在拿到租约时再触发一次。
|
||
#
|
||
# 失败不阻断 init:所有分支都 exit 0(除非参数错误)。
|
||
#
|
||
case "$1" in
|
||
start)
|
||
printf "Starting meow_ntpsync: "
|
||
[ -x /usr/bin/meow_ntpsync ] || { echo "SKIP (not installed)"; exit 0; }
|
||
setsid /usr/bin/meow_ntpsync -b -t 120 >/dev/null 2>&1 &
|
||
echo "OK"
|
||
;;
|
||
stop)
|
||
printf "Stopping meow_ntpsync: "
|
||
# 持锁者自证在 <锁目录>/<pid> 子目录里;kill 前再核对 cmdline,
|
||
# 防止 pid 复用误杀无关进程(P2-1 顺带项)
|
||
for d in /tmp/meow_ntpsync.lock/*; do
|
||
[ -d "$d" ] || continue
|
||
pid=${d##*/}
|
||
case "$pid" in
|
||
''|*[!0-9]*) continue ;;
|
||
esac
|
||
cmd=$(tr '\0' ' ' <"/proc/$pid/cmdline" 2>/dev/null)
|
||
case "$cmd" in
|
||
*meow_ntpsync*) kill "$pid" 2>/dev/null ;;
|
||
esac
|
||
done
|
||
echo "OK"
|
||
;;
|
||
restart|reload)
|
||
"$0" stop
|
||
"$0" start
|
||
;;
|
||
*)
|
||
echo "Usage: $0 {start|stop|restart}"
|
||
exit 1
|
||
;;
|
||
esac
|
||
|
||
exit 0
|