mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-09-14 12:24:20 +08:00
132 lines
3.5 KiB
Bash
132 lines
3.5 KiB
Bash
#!/bin/sh
|
|
# Keep daed as a child so signals can be forwarded and stale netns/veth
|
|
# state can be cleaned before start and after exit. daed owns TC detach;
|
|
# /sys/fs/bpf/daed is normal persistent state and is never removed here.
|
|
|
|
. /usr/share/daed/cleanup.sh
|
|
|
|
# Pre-start cleanup refuses to remove runtime state while another
|
|
# daed instance is active, and fails closed if that probe is broken.
|
|
DAED_GUARD_CLEANUP=start
|
|
if ! daed_cleanup_runtime; then
|
|
echo "daed: stale /usr/bin/daed or netns state could not be verified or removed; refusing to start. Check process and netns state." >&2
|
|
logger -t daed-init "pre-start cleanup failed: refusing to start daed"
|
|
exit 1
|
|
fi
|
|
|
|
# Keep daed as a child so post-exit cleanup runs before procd can
|
|
# respawn it.
|
|
child_pid=
|
|
pending_signal=
|
|
shutdown_signal=
|
|
shutdown_elapsed=0
|
|
forced_kill=0
|
|
child_term_timeout=20
|
|
|
|
forward_signal() {
|
|
local sig="$1"
|
|
if [ -z "$child_pid" ]; then
|
|
pending_signal="$sig"
|
|
logger -t daed-init "signal $sig received before daed child started; launch cancelled"
|
|
return 0
|
|
fi
|
|
case "$sig" in
|
|
TERM|INT|QUIT)
|
|
if [ -z "$shutdown_signal" ]; then
|
|
shutdown_signal="$sig"
|
|
shutdown_elapsed=0
|
|
fi
|
|
;;
|
|
esac
|
|
kill -"$sig" "$child_pid" 2>/dev/null
|
|
}
|
|
|
|
exit_with_signal() {
|
|
local sig="$1"
|
|
trap - TERM INT HUP QUIT
|
|
kill -"$sig" "$$" 2>/dev/null
|
|
exit 1
|
|
}
|
|
|
|
child_is_running() {
|
|
local state
|
|
kill -0 "$child_pid" 2>/dev/null || return 1
|
|
state=$(awk '{ print $3 }' "/proc/$child_pid/stat" 2>/dev/null)
|
|
[ "$state" != "Z" ]
|
|
}
|
|
trap 'forward_signal TERM' TERM
|
|
trap 'forward_signal INT' INT
|
|
trap 'forward_signal HUP' HUP
|
|
trap 'forward_signal QUIT' QUIT
|
|
|
|
start_child() {
|
|
local sig
|
|
# Keep this check inside the function as well as at the call site:
|
|
# it closes the ordinary pre-start window, while the pending-signal
|
|
# path below handles a signal arriving during the background fork.
|
|
[ -z "$pending_signal" ] || return 125
|
|
/usr/bin/daed "$@" &
|
|
child_pid=$!
|
|
if [ -n "$pending_signal" ]; then
|
|
sig="$pending_signal"
|
|
pending_signal=
|
|
forward_signal "$sig"
|
|
fi
|
|
}
|
|
|
|
if [ -n "$pending_signal" ]; then
|
|
logger -t daed-init "refusing to start daed after pending signal $pending_signal"
|
|
exit_with_signal "$pending_signal"
|
|
fi
|
|
|
|
# Best-effort OOM preference; failure must not block startup.
|
|
if ! echo -16 > /proc/self/oom_score_adj 2>/dev/null; then
|
|
logger -t daed-init "warn: failed to set /proc/self/oom_score_adj; continuing without OOM preference"
|
|
fi
|
|
if ! start_child "$@"; then
|
|
logger -t daed-init "refusing to start daed after pending signal $pending_signal"
|
|
if [ -n "$pending_signal" ]; then
|
|
exit_with_signal "$pending_signal"
|
|
fi
|
|
exit 1
|
|
fi
|
|
status=0
|
|
reaped=0
|
|
while [ "$reaped" -eq 0 ]; do
|
|
if [ -n "$shutdown_signal" ] && child_is_running; then
|
|
if [ "$shutdown_elapsed" -ge "$child_term_timeout" ]; then
|
|
if [ "$forced_kill" -eq 0 ]; then
|
|
logger -t daed-init "daed did not exit within ${child_term_timeout}s after $shutdown_signal; sending KILL"
|
|
kill -KILL "$child_pid" 2>/dev/null
|
|
forced_kill=1
|
|
fi
|
|
else
|
|
sleep 1
|
|
shutdown_elapsed=$((shutdown_elapsed + 1))
|
|
continue
|
|
fi
|
|
sleep 1
|
|
continue
|
|
fi
|
|
wait "$child_pid" 2>/dev/null
|
|
status=$?
|
|
if ! child_is_running; then
|
|
reaped=1
|
|
fi
|
|
done
|
|
child_pid=
|
|
trap - TERM INT HUP QUIT
|
|
|
|
# Post-exit cleanup runs after the child is reaped.
|
|
DAED_GUARD_CLEANUP=post-exit
|
|
cleanup_status=0
|
|
daed_cleanup_runtime || cleanup_status=$?
|
|
if [ "$cleanup_status" -ne 0 ]; then
|
|
echo "daed: runtime cleanup after exit failed" >&2
|
|
logger -t daed-init "post-exit cleanup failed; check ip netns / ip link show"
|
|
fi
|
|
if [ "$status" -ne 0 ]; then
|
|
exit "$status"
|
|
fi
|
|
exit "$cleanup_status"
|