Skip to content

Commit df859b0

Browse files
authored
Merge pull request #288 from wnlen/fix/issue-287-systemd-boot
Fix systemd boot runtime supervision
2 parents 6abf500 + 9ac17a5 commit df859b0

6 files changed

Lines changed: 99 additions & 20 deletions

File tree

scripts/core/clashctl.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7382,6 +7382,11 @@ cmd_start_direct() {
73827382
start_runtime
73837383
}
73847384

7385+
cmd_run_direct() {
7386+
prepare
7387+
run_runtime_foreground
7388+
}
7389+
73857390
cmd_stop_direct() {
73867391
prepare
73877392
stop_runtime
@@ -7801,6 +7806,7 @@ case "$cmd" in
78017806
upgrade) cmd_upgrade "$@" ;;
78027807
update) cmd_update "$@" ;;
78037808
completion) cmd_completion "$@" ;;
7809+
run-direct) cmd_run_direct "$@" ;;
78047810
start-direct) cmd_start_direct "$@" ;;
78057811
stop-direct) cmd_stop_direct "$@" ;;
78067812
restart-direct) cmd_restart_direct "$@" ;;

scripts/core/runtime.sh

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,16 +533,23 @@ wait_runtime_controller_ready() {
533533
return 1
534534
}
535535

536-
start_runtime() {
536+
prepare_runtime_start() {
537537
local config_file="$RUNTIME_DIR/config.yaml"
538538

539+
mkdir -p "$RUNTIME_DIR" "$LOG_DIR"
539540
resolve_runtime_kernel
540541
if [ -s "$config_file" ]; then
541542
ensure_mihomo_geodata_ready "$config_file" || die "因 GEOIP 依赖未就绪,当前配置无法启动:$config_file"
542543
fi
543544

544545
ensure_runtime_config_ready
545546
ensure_mihomo_geodata_ready "$config_file" || die "因 GEOIP 依赖未就绪,当前配置无法启动:$config_file"
547+
}
548+
549+
start_runtime() {
550+
local config_file="$RUNTIME_DIR/config.yaml"
551+
552+
prepare_runtime_start
546553

547554
if [ -f "$RUNTIME_DIR/mihomo.pid" ]; then
548555
local old_pid
@@ -575,6 +582,18 @@ start_runtime() {
575582
success "$(runtime_kernel_name) 已启动:pid=$(cat "$RUNTIME_DIR/mihomo.pid")"
576583
}
577584

585+
run_runtime_foreground() {
586+
local config_file="$RUNTIME_DIR/config.yaml"
587+
588+
prepare_runtime_start
589+
590+
rm -f "$RUNTIME_DIR/mihomo.pid" 2>/dev/null || true
591+
echo "$$" > "$RUNTIME_DIR/mihomo.pid"
592+
593+
exec "$(runtime_kernel_bin)" -f "$config_file" -d "$RUNTIME_DIR" \
594+
>> "$LOG_DIR/mihomo.out.log" 2>&1
595+
}
596+
578597
stop_runtime() {
579598
local pid_file="$RUNTIME_DIR/mihomo.pid"
580599

scripts/core/update.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,10 @@ refresh_installed_entry_files() {
8383
# shellcheck source=scripts/core/common.sh
8484
source "$PROJECT_DIR/scripts/core/common.sh"
8585

86-
info "正在刷新命令入口与 shell profile"
86+
info "正在刷新命令入口、shell profile 与运行后端入口"
8787
install_clashctl_entry
8888
install_shell_alias_entry
89+
install_runtime_entry
8990
}
9091

9192
remove_mihomo_binary() {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5+
PROJECT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
6+
7+
assert_contains() {
8+
local name="$1"
9+
local file="$2"
10+
local pattern="$3"
11+
12+
if ! grep -Fq "$pattern" "$file"; then
13+
echo "not ok - $name: missing '$pattern' in $file" >&2
14+
return 1
15+
fi
16+
17+
echo "ok - $name"
18+
}
19+
20+
assert_not_contains() {
21+
local name="$1"
22+
local file="$2"
23+
local pattern="$3"
24+
25+
if grep -Fq "$pattern" "$file"; then
26+
echo "not ok - $name: unexpected '$pattern' in $file" >&2
27+
return 1
28+
fi
29+
30+
echo "ok - $name"
31+
}
32+
33+
assert_contains "system service uses simple foreground process" "$PROJECT_DIR/scripts/init/systemd.sh" "Type=simple"
34+
assert_contains "system service starts run-direct" "$PROJECT_DIR/scripts/init/systemd.sh" "ExecStart=/usr/local/bin/clashctl run-direct"
35+
assert_not_contains "system service no longer uses forking" "$PROJECT_DIR/scripts/init/systemd.sh" "Type=forking"
36+
assert_not_contains "system service no longer relies on PIDFile" "$PROJECT_DIR/scripts/init/systemd.sh" "PIDFile="
37+
38+
assert_contains "user service uses simple foreground process" "$PROJECT_DIR/scripts/init/systemd-user.sh" "Type=simple"
39+
assert_contains "user service starts run-direct" "$PROJECT_DIR/scripts/init/systemd-user.sh" "clashctl run-direct"
40+
assert_not_contains "user service no longer uses forking" "$PROJECT_DIR/scripts/init/systemd-user.sh" "Type=forking"
41+
assert_not_contains "user service no longer relies on PIDFile" "$PROJECT_DIR/scripts/init/systemd-user.sh" "PIDFile="

scripts/init/systemd-user.sh

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@ Description=clash-for-linux (user)
1414
After=default.target
1515
1616
[Service]
17-
Type=forking
18-
ExecStart=$home_dir/.local/bin/clashctl start-direct
19-
ExecStop=$home_dir/.local/bin/clashctl stop-direct
20-
ExecReload=$home_dir/.local/bin/clashctl restart-direct
21-
PIDFile=$RUNTIME_DIR/mihomo.pid
17+
Type=simple
18+
ExecStart=$home_dir/.local/bin/clashctl run-direct
19+
ExecStopPost=/bin/rm -f $RUNTIME_DIR/mihomo.pid
2220
WorkingDirectory=$PROJECT_DIR
2321
Restart=on-failure
2422
RestartSec=3
@@ -107,8 +105,16 @@ systemd_user_service_status_text() {
107105
}
108106

109107
systemd_user_service_logs() {
110-
journalctl --user -u "$(service_unit_name)" -n 200 --no-pager 2>/dev/null || {
111-
echo "未获取到用户级 systemd 服务日志"
112-
return 0
113-
}
108+
echo "== systemctl --user status =="
109+
systemctl --user status "$(service_unit_name)" --no-pager -l 2>/dev/null || echo "未获取到用户级 systemd 服务状态"
110+
echo
111+
echo "== journalctl --user =="
112+
journalctl --user -u "$(service_unit_name)" -n 200 --no-pager 2>/dev/null || echo "未获取到用户级 systemd journal 日志"
113+
echo
114+
echo "== mihomo log =="
115+
if [ -f "$LOG_DIR/mihomo.out.log" ]; then
116+
tail -n 200 "$LOG_DIR/mihomo.out.log"
117+
else
118+
echo "mihomo 日志文件不存在:$LOG_DIR/mihomo.out.log"
119+
fi
114120
}

scripts/init/systemd.sh

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@ After=network-online.target
1111
Wants=network-online.target
1212
1313
[Service]
14-
Type=forking
15-
ExecStart=/usr/local/bin/clashctl start-direct
16-
ExecStop=/usr/local/bin/clashctl stop-direct
17-
ExecReload=/usr/local/bin/clashctl restart-direct
18-
PIDFile=$RUNTIME_DIR/mihomo.pid
14+
Type=simple
15+
ExecStart=/usr/local/bin/clashctl run-direct
16+
ExecStopPost=/bin/rm -f $RUNTIME_DIR/mihomo.pid
1917
WorkingDirectory=$PROJECT_DIR
2018
Restart=on-failure
2119
RestartSec=3
@@ -103,8 +101,16 @@ systemd_service_status_text() {
103101
}
104102

105103
systemd_service_logs() {
106-
journalctl -u "$(service_unit_name)" -n 200 --no-pager 2>/dev/null || {
107-
echo "未获取到 systemd 服务日志"
108-
return 0
109-
}
104+
echo "== systemctl status =="
105+
systemctl status "$(service_unit_name)" --no-pager -l 2>/dev/null || echo "未获取到 systemd 服务状态"
106+
echo
107+
echo "== journalctl =="
108+
journalctl -u "$(service_unit_name)" -n 200 --no-pager 2>/dev/null || echo "未获取到 systemd journal 日志"
109+
echo
110+
echo "== mihomo log =="
111+
if [ -f "$LOG_DIR/mihomo.out.log" ]; then
112+
tail -n 200 "$LOG_DIR/mihomo.out.log"
113+
else
114+
echo "mihomo 日志文件不存在:$LOG_DIR/mihomo.out.log"
115+
fi
110116
}

0 commit comments

Comments
 (0)