Files
MeowOS-For-R3P2/patch_v2/ntpsync/S45meow_ntpsync
T
AskaEth c9f0cbaab6 feat(ntp): M22 网络校时 — 复用固件自带 ntpd + hwclock 回写 RTC
真机实测(0.8.47,2026-11-06)定位到的根因不是「没有 NTP 客户端」:
固件自带 ntp-4.2.8p14(/usr/sbin/ntpd)和 /etc/ntp.conf(4 个 pool.ntp.org),
但没有任何 init 脚本/进程启动它 —— 有客户端、没启动。

实测证据:
- RTC 存在且可读(/dev/rtc0,10003000.rtc),内核开机 hctosys=1,
  冷启动不回到 1970 → 掉电保持;RTC 存 UTC(since_epoch == date +%s)。
- 但 RTC 会走慢且无人纠正:实测系统时间比 NTP 慢 49 s;把系统时间人为
  拨错 4 h 后观察 65 s 无人纠正,RTC 也不跟随系统时间。
- UDP/123 出网正常(ntpd -q 一次成功 time set +48.877s);DNS/HTTP 正常。
- udhcpc 的 default.script 不处理 option 42,实测热点也不下发。
- ntpd -q 不会回写 RTC(步进后 sys-rtc 仍差 49 s)→ 必须 hwclock -w -u。
- ntpd 没有超时参数,无服务器时永久存活 → 必须自带看门狗。
- -p 形式的 server 首个 poll 要 ~64 s;配置里加 iburst 后 8 s 内返回。

实现(新增,不改任何基线文件):
- /usr/bin/meow_ntpsync:一次性校时器。复用 ntpd -q -g + 运行时生成的
  iburst 配置;内置 IP 兜底(阿里/腾讯/Cloudflare)→ DNS 名兜底;
  单次 15 s 看门狗、默认路由轮询、1 h 短路、进程锁、失败静默。
  成功严格校时后 hwclock -w -u 回写 RTC(RTC 存 UTC,必须 -u)。
- /etc/init.d/S45meow_ntpsync:开机只 setsid 后台拉起并立即返回
  (关键路径 +0 秒;后台最长约 150 s 自行退出),失败不阻断 init。
- /usr/share/udhcpc/default.script.d/50meow_ntpsync:只在 bound/renew
  触发(设备上唯一可靠的「网络就绪」事件),后台拉起后立即 exit 0;
  有 $ntpsrv(option 42)就优先用。基线 default.script 本就有 HOOK_DIR
  循环,目录原本为空。
- tests/run_tests.sh:宿主沙箱单测(假 ntpd/hwclock/网络探测)。

验证:dash 与 busybox sh 各 sh -n 通过;单测两套 shell 各 23/23 通过;
真机(/tmp 下运行,未装系统目录)首跑 8 s rc=0、ntpd slew 成功、
RTC 由 1793940395 写成 1793940452(49 s 偏差被纠正)、hwclock -u -r 吻合;
二次运行 0 s 短路;-b -t 3 无网络 5 s 退出 rc=1;
DHCP 灌入不可达服务器 192.0.2.x 仍靠 IP 兜底在 ~10 s 内成功。
2026-11-06 12:49:13 +08:00

41 lines
1.2 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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: "
if [ -f /tmp/meow_ntpsync.lock/pid ]; then
kill "$(cat /tmp/meow_ntpsync.lock/pid 2>/dev/null)" 2>/dev/null
fi
rm -rf /tmp/meow_ntpsync.lock 2>/dev/null
echo "OK"
;;
restart|reload)
"$0" stop
"$0" start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0