返回首页
杂谈
meli @meli

aTrust关不上?未必是开发者背锅

📝 修改于 2026年9月23日 12:42 ⏱️ 阅读时间 4 分钟 👁️ 浏览 2 🔑 UUID: 428b12e6-8162-4f90-a9...

今天发现电脑关机时间格外长,遂与AI联合排查日志,最后定位到aTrust退出超时。系统先是好心好意地向其进程发送SIGTERM信号,要求其尽快保存相关文件并结束进程,然而这家伙硬是赖着不走,生生拖延了90秒,系统忍无可忍丢过去一个SIGKILL强行结束了进程。然而事情还没完,SIGKILL竟然只结束了主进程,两个子进程还保持运行,导致系统卸载/home分区失败;于是系统只能硬着头皮往下走,把烂摊子丢给内核后由内核强行从内存抹除所有进程,最后导致一个重启花了将近3分钟。

7月 26 19:48:20 meli-HUAWEI systemd[1]: Stopping aTrustDaemon.service - Sangfor aTrustDaemon Service...
# 省略中间...
7月 26 19:49:50 meli-HUAWEI systemd[1]: aTrustDaemon.service: State 'stop-sigterm' timed out. Killing.
7月 26 19:49:50 meli-HUAWEI systemd[1]: aTrustDaemon.service: Killing process 2081 (aTrustAgent) with signal SIGKILL.
7月 26 19:49:50 meli-HUAWEI systemd[1]: aTrustDaemon.service: Main process exited, code=killed, status=9/KILL
7月 26 19:49:50 meli-HUAWEI systemd[1]: aTrustDaemon.service: Failed with result 'timeout'.
7月 26 19:49:50 meli-HUAWEI systemd[1]: aTrustDaemon.service: Unit process 2248 (aTrustXtunnel-6) remains running after unit stopped.
7月 26 19:49:50 meli-HUAWEI systemd[1]: aTrustDaemon.service: Unit process 2291 (aTrustXtunnel-6) remains running after unit stopped.
7月 26 19:49:50 meli-HUAWEI systemd[1]: aTrustDaemon.service: Unit process 11616 (aTrustAgent) remains running after unit stopped.
7月 26 19:49:50 meli-HUAWEI systemd[1]: Stopped aTrustDaemon.service - Sangfor aTrustDaemon Service.
7月 26 19:49:50 meli-HUAWEI systemd[1]: aTrustDaemon.service: Consumed 2h 33min 13.954s CPU time over 2d 14h 7min 3.630s wall clock time, 2.6G memory peak, 57.7M memory swap peak.

当我看到这段日志其实有点出乎意料,因为我这两天根本没用aTrust,没想到它不仅开着后台进程,最高还占了2.6G内存。考虑到我以后还是有可能会用到它,我还是没有当场删除💢

于是开始排查其systemd配置文件,试图将后台进程自启关闭,然而我万万没想到,事情从这里变得十分有意思了。

#/usr/lib/systemd/system/aTrustDaemon.service 注:原样内容

[Unit]
Description=Sangfor aTrustDaemon Service
After=network.target
#Requires=user@%i.service 

[Service]
Type=forking

ExecStart=/usr/share/sangfor/aTrust/resources/shell/aTrustDaemon.sh start
ExecReload=/usr/share/sangfor/aTrust/resources/shell/aTrustDaemon.sh restart
ExecStop=/usr/share/sangfor/aTrust/resources/shell/aTrustDaemon.sh stop
PIDFile=/run/aTrustDaemon.pid

#保活设置,挂掉后1s无条件重启
#KillSignal=SIGTERM
#PrivateTmp=false
Restart=always
#默认SIGHUP, SIGINT, SIGTERM or SIGPIPE四中信号不重启,其他信号全部重启
#但是中标上用kill -9/-11 杀死的都不会拉起,所以这里指定强制拉起的信号
RestartForceExitStatus=SIGKILL SIGSEGV SIGABRT SIGTERM SIGBUS SIGSTOP
RestartSec=5s
KillMode=process
#设置服务安装方式,支持多用户
[Install]
WantedBy=multi-user.target
#WantedBy=default.target

首先,在systemd配置里写一堆注释的软件我还是头一回见,暂且不论;关键是,你一个网络工具的后台进程,设置Restart=always,挂掉即静默重启?与此同时,你这一堆神奇的信号处理又是什么东西啊?KillMode=process只退出主进程?完了注释还有错别字?

遂更改:Restart=no KillMode=mixed。然而,运行systemctl stop aTrustDaemon,程序竟然毫无反应,连kill -9程序也爱搭不理,仍然会等到超时强行结束。AI的建议是对它不要太客气,把原来90秒的超时直接减到5秒。这样操作虽然可行,但是systemd的日志会显示退出状态为Failed,况且每次强制结束进程也不是一个优雅的关闭方式。于是我决定研究一下它的stop脚本。然后我就彻底震惊了。
aTrust 管理默认脚本展示
先不说你拿麒麟系统配置搬到Ubuntu安装包是什么行为,也不说你reload等于restart的强行兼容,合着你stop函数定义了个return 0?没了?全给注释了?

更神奇的是,经过我用各种信号对主进程"狂轰滥炸",发现:
1. 进程捕获SIGTERM(优雅结束)信号和SIGINT(手动中止)信号,但根本理都不理;
2. 进程未捕获SIGHUP(一般定义为平滑重载),也未忽略;
3. 其他信号处理也相当粗犷:
- SIGKILL(物理斩杀)→ 重启!
- SIGSEGV(段错误,崩溃)→ 重启!
- SIGABRT(断言失败)→ 重启!
- SIGTERM(标准停止信号)→ 重启!

最后没办法,只得硬着头皮帮作者重写了stop函数:

stop() {
        # 1. 尝试优雅退出(发送 SIGTERM,让进程自己清理现场)
        # 注意:使用 USER1 而不是 -9 (SIGKILL)
        echo "尝试优雅停止 aTrustAgent..."
        if killall -USER1 ${PROG} 2>/dev/null ; then
            # 2. 给它最多 3 秒时间做清理工作(断开VPN、保存日志、通知服务器)
            local WAIT_COUNT=0
            while [ $WAIT_COUNT -lt 2 ]; do
                if ! pgrep -f ${PROG} > /dev/null ; then
                    echo "aTrustAgent 已优雅退出。"
                    break
                fi
                sleep 1
                WAIT_COUNT=$((WAIT_COUNT + 1))
            done
        fi

        # 3. 如果 3 秒后它还在(被卡住了),才使用暴力手段清场
        if pgrep -f ${PROG} > /dev/null ; then
            echo "aTrustAgent 未响应 SIGTERM,强制结束..."
            killall -9 ${PROG} 2>/dev/null
        fi

        # 4. 清场隧道进程(这些子进程必须杀掉,防止挂载 /home)
        echo "清理残留隧道进程..."
        killall -9 aTrustXtunnel-64 2>/dev/null

        RETVAL=$?
        return $RETVAL
}

其实仍然是一个并不算优雅的退出方式,但是再进一步的话就要修改闭源二进制部分的文件了,难度大且有法律风险,遂作罢。

我并不是不支持国产操作系统,但是如果一个操作系统为了一时的上线速度,在合规化改造过程中bug不断,以至于只能靠软件开发者使用各种邪修方法解决问题,这个系统的生态要怎样才能繁荣呢?还是说,这只是一个用来应付合规要求来盈利的工具而已?

评论 (0)

还没有评论,来说点什么吧

登录

相关文章