Files
MeowOS-For-R3P2/patch_v2/ntpsync/50meow_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

34 lines
1.1 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
#
# 50meow_ntpsync — udhcpc 钩子(M22)
#
# /usr/share/udhcpc/default.script 结尾会执行 default.script.d/*,
# 参数是本轮 DHCP 事件(deconfig|bound|renew|leasefail|nak)。
# 本钩子只在拿到租约(bound/renew)时动作——这是设备上唯一可靠的
# 「网络真的就绪」事件(S40network 阶段 WiFi 还没起来)。
#
# 关键:**绝不能阻塞**。default.script 是 udhcpc 同步调用的,
# 这里把校时丢后台后立即 exit 0,否则会拖住 DHCP 脚本。
#
# $ntpsrv = DHCP option 42(NTP 服务器列表)。
# 实测 2026-11-06 热点不下发(租约环境变量里没有 ntpsrv),企业网可能有;
# 有就优先用,没有就走 /usr/bin/meow_ntpsync 里的内置 IP 兜底。
#
# 重复触发由 meow_ntpsync 自己的 1 h 短路 + 锁兜住:续租每 30 min 一次,
# 最多 1 h 真同步一次,开销可忽略。
#
case "$1" in
bound|renew) ;;
*) exit 0 ;;
esac
[ -x /usr/bin/meow_ntpsync ] || exit 0
if [ -n "$ntpsrv" ]; then
setsid /usr/bin/meow_ntpsync -s "$ntpsrv" >/dev/null 2>&1 &
else
setsid /usr/bin/meow_ntpsync >/dev/null 2>&1 &
fi
exit 0