mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-04 12:53:56 +08:00
💐 Sync 2026-10-06 12:33:44
This commit is contained in:
1 parent
8be03ce939
commit
7fe69dbb3a
246 files changed
+50330
-3414
No files matched your search
@@ -601,6 +601,108 @@ hp_capture_candidate() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# hp_reload_is_noop <run-dir> <good-dir> <client-enabled> <server-enabled>
|
||||
# 0 when this reload would change nothing that is currently running, so the
|
||||
# caller can skip the stop;start entirely.
|
||||
#
|
||||
# Why this exists: reload_service used to stop and start unconditionally, and
|
||||
# hp_same_file was only ever used on the rollback path. Measured on the device,
|
||||
# one reload costs about eight seconds (09:17:40 -> 09:17:48 in the log) and
|
||||
# interrupts every connection, even when the generated configuration is
|
||||
# byte-identical to the one already running. That is the common case for
|
||||
# "Save & Apply" with nothing edited, for a node switch that lands on the same
|
||||
# node, and for the nightly resource refresh.
|
||||
#
|
||||
# THE COMPARISON IS AGAINST known-good, NOT AGAINST THE CANDIDATE, and getting
|
||||
# that wrong silently disables the whole mechanism. Measured on the device:
|
||||
# the generator writes straight to $RUN_DIR/sing-box-c.json and
|
||||
# hp_capture_candidate() copies that same file afterwards, so after a preflight
|
||||
# the candidate and the live file are the SAME BYTES BY CONSTRUCTION - comparing
|
||||
# them reports "unchanged" for every reload, including one that switched the main
|
||||
# node. The first version of this helper did exactly that, and the only reason
|
||||
# it was caught is an on-device test that switched nodes and watched the PID.
|
||||
#
|
||||
# known-good is the right counterpart for the same reason the rollback path uses
|
||||
# it: hp_promote_known_good writes it ONLY after the health gate has passed, so
|
||||
# it is by definition "the configuration that is currently running and working".
|
||||
# live vs known-good answers the question this helper is actually asking - "would
|
||||
# the running configuration change?" - and a missing known-good simply falls
|
||||
# through to a real reload.
|
||||
#
|
||||
# Every condition is a *precondition for the skip being safe*, and the default
|
||||
# on any doubt is to reload:
|
||||
#
|
||||
# [1] the service is actually running. A live file left over from a crashed
|
||||
# instance is not a running service, and skipping the restart would
|
||||
# report success over a dead proxy. Asked of ubus, the same source the
|
||||
# status page reads.
|
||||
# [2] the side has both a live file and a known-good copy to compare against.
|
||||
# A side the user just enabled has neither, and that is a change, not a
|
||||
# no-op.
|
||||
# [3] the intercept layer is installed. A released layer (the marker
|
||||
# hp_release_stale_intercept writes) means the firewall is NOT proxying
|
||||
# right now even though sing-box is up. Skipping the restart would leave
|
||||
# it that way and log "nothing to restart" - the exact silent state
|
||||
# hp_rearm_intercept exists to undo. Reloading is what re-arms it.
|
||||
hp_reload_is_noop() {
|
||||
local run_dir="$1"
|
||||
local good_dir="$2"
|
||||
local client_enabled="$3"
|
||||
local server_enabled="$4"
|
||||
local live good
|
||||
|
||||
# [3] first, because it is the cheapest and the most dangerous to skip.
|
||||
[ ! -f "$run_dir/intercept-released" ] || return 1
|
||||
|
||||
# [1] the instances. `command -v ubus` because this module is also sourced
|
||||
# by the off-target test driver, where ubus does not exist and the honest
|
||||
# answer there is "cannot prove it is a no-op".
|
||||
#
|
||||
# The check is on `"running": true`, NOT on the instance merely appearing
|
||||
# in the list: procd keeps a stopped instance in `service list` with
|
||||
# running=false, so matching the key alone reports a dead proxy as running
|
||||
# and the skip then claims success over it. That was not theoretical - the
|
||||
# first version of this grep did exactly that and its own test caught it.
|
||||
command -v ubus > "/dev/null" 2>&1 || return 1
|
||||
|
||||
local svc_list
|
||||
svc_list="$(ubus call service list "{\"name\":\"$CONF\"}" 2>/dev/null)"
|
||||
|
||||
if [ "$client_enabled" = "1" ]; then
|
||||
printf '%s' "$svc_list" \
|
||||
| grep -A 3 '"sing-box-c"' \
|
||||
| grep -q '"running"[[:space:]]*:[[:space:]]*true' || return 1
|
||||
fi
|
||||
|
||||
if [ "$server_enabled" = "1" ]; then
|
||||
printf '%s' "$svc_list" \
|
||||
| grep -A 3 '"sing-box-s"' \
|
||||
| grep -q '"running"[[:space:]]*:[[:space:]]*true' || return 1
|
||||
fi
|
||||
|
||||
# [2] and the byte comparison, per side.
|
||||
# [2] and the byte comparison, per side, against what is known to be running
|
||||
# rather than against the candidate (see the note at the top of this
|
||||
# function - the two are the same bytes by construction).
|
||||
if [ "$client_enabled" = "1" ]; then
|
||||
live="$run_dir/sing-box-c.json"
|
||||
good="$good_dir/sing-box-c.json"
|
||||
|
||||
[ -s "$live" ] && [ -s "$good" ] || return 1
|
||||
cmp -s "$live" "$good" 2>"/dev/null" || return 1
|
||||
fi
|
||||
|
||||
if [ "$server_enabled" = "1" ]; then
|
||||
live="$run_dir/sing-box-s.json"
|
||||
good="$good_dir/sing-box-s.json"
|
||||
|
||||
[ -s "$live" ] && [ -s "$good" ] || return 1
|
||||
cmp -s "$live" "$good" 2>"/dev/null" || return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# hp_start_generated_config <side> <hp-dir> <run-dir> <good-dir>
|
||||
# The start-path transaction for one side ("c" or "s"):
|
||||
#
|
||||
|
||||
Reference in new issue
Block a user