Fix process stability checks in containers

This commit is contained in:
ushan0v
2026-07-14 01:04:37 +03:00
parent 40848660fa
commit c60ce8179b
2 changed files with 42 additions and 14 deletions
+32 -14
View File
@@ -460,15 +460,8 @@ function hup_sing_box_runtime() {
exit(1);
}
function process_age_seconds(pid) {
pid = as_string(pid);
if (match(pid, /^[0-9]+$/) == null)
return null;
let stat = fs.readfile("/proc/" + pid + "/stat");
if (stat == null)
return null;
function process_start_ticks(stat) {
stat = as_string(stat);
let marker = index(stat, ") ");
if (marker < 0)
return null;
@@ -481,15 +474,34 @@ function process_age_seconds(pid) {
if (match(start_ticks, /^[0-9]+$/) == null)
return null;
let uptime = fs.readfile("/proc/uptime");
if (uptime == null)
return int(start_ticks);
}
function process_age_seconds_from_ticks(start_ticks, current_ticks) {
start_ticks = as_string(start_ticks);
current_ticks = as_string(current_ticks);
if (match(start_ticks, /^[0-9]+$/) == null || match(current_ticks, /^[0-9]+$/) == null)
return null;
let uptime_seconds = split(trim(as_string(uptime)), /[ \t\r\n.]+/)[0];
if (match(uptime_seconds, /^[0-9]+$/) == null)
start_ticks = int(start_ticks);
current_ticks = int(current_ticks);
if (current_ticks < start_ticks)
return null;
return int(uptime_seconds) - int(int(start_ticks) / 100);
return int((current_ticks - start_ticks) / 100);
}
function process_age_seconds(pid) {
pid = as_string(pid);
if (match(pid, /^[0-9]+$/) == null)
return null;
let start_ticks = process_start_ticks(fs.readfile("/proc/" + pid + "/stat"));
if (start_ticks == null)
return null;
let current_ticks = process_start_ticks(command_output_from_args([ "cat", "/proc/self/stat" ]));
return process_age_seconds_from_ticks(start_ticks, current_ticks);
}
function sing_box_pid_replaced(previous_pid, current_pid, current_is_sing_box) {
@@ -1821,6 +1833,12 @@ else if (mode == "sing-box-service-running")
exit(sing_box_service_running() ? 0 : 1);
else if (mode == "sing-box-service-stable")
exit(sing_box_service_stable(ARGV[1]) ? 0 : 1);
else if (mode == "process-age-seconds-fixture") {
let age = process_age_seconds_from_ticks(ARGV[1], ARGV[2]);
if (age == null)
exit(1);
print(age, "\n");
}
else if (mode == "sing-box-pid-replaced-fixture")
exit(sing_box_pid_replaced(ARGV[1], ARGV[2], ARGV[3]) ? 0 : 1);
else if (mode == "sing-box-reload-previous-pid-fixture")
+10
View File
@@ -126,6 +126,16 @@ assert_eq "0" \
"$(state_ucode sing-box-reload-previous-pid-fixture missing old new)" \
"missing sing-box PID replacement constraint"
assert_eq "8" \
"$(state_ucode process-age-seconds-fixture 786161359 786162159)" \
"process age on a shared kernel tick scale"
if state_ucode process-age-seconds-fixture 786162159 786161359 >/dev/null 2>&1; then
fail "process age must reject a current tick value older than the process"
fi
if sed -n '/^function process_age_seconds(pid) {$/,/^}$/p' "$STATE_UC" | grep -Fq '/proc/uptime'; then
fail "process age must not mix process start ticks with virtualized /proc/uptime"
fi
mkdir -p "$WORK_DIR/stable-start-bin"
cp "$(command -v sleep)" "$WORK_DIR/stable-start-bin/sing-box"
cat >"$WORK_DIR/stable-start-bin/ubus" <<'SH'