我们有一个 ansible playbook 来管理我们的服务器。服务器使用 Oracle Linux 9 运行。然后它会dnf upgrade
检查是否有任何服务需要重新启动。如果需要,它会启动机器。
为了查看是否需要,它会运行dnf needs-restarting
。首先它会运行,dnf needs-restarting -r
然后在没有 的情况下再次运行-r
。
在这种情况下,-r
运行(在 ansible 中运行ignore_errors: true
)指示我们需要重新启动,因此它确实重新启动了。但是,当它运行时dnf needs-restarting
(没有-r
),重新启动后它直接失败并显示No such file or directory: '/proc/771/stat'
。
谁能解释一下这种情况是如何发生的以及我该如何避免它?
完整输出为
TASK [dnf_upgrade_all : Check if any services need restarting] *****************
Thursday 13 February 2025 05:25:49 +0200 (0:00:00.111) 0:45:46.296 *****
fatal: [app-dev-carc.internal.carus.com]: FAILED! => {
"changed": false,
"cmd": [
"dnf",
"needs-restarting"
],
"delta": "0:00:15.312549",
"end": "2025-02-13 05:26:08.254522",
"rc": 1,
"start": "2025-02-13 05:25:52.941973"
}
STDERR:
[Errno 2] No such file or directory: '/proc/771/stat'
MSG:
non-zero return code
失败的任务定义为
- name: Check if any services need restarting
command: dnf needs-restarting
args:
warn: false #Avoid warning about direct use of dnf - dnf module doesn't support needs-restarting
register: dnf_upgrade_all_services_restart
changed_when: false
而且,正如我所说,这是(在这种情况下)在重启后直接发生的。
当 dnf 即将读取其状态时,进程退出时就会发生这种情况。
该函数被赋予一个 PID,然后检查该 PID 是否存在,并从 /proc 读取 3 个文件来收集有关该 PID 的信息,其中 /proc/##/stat 是最后一个。有时第二个文件不是特定于 PID 的。
因此,很有可能进程会在代码的第 2 步和第 4 步之间退出 - 在“PID 存在”检查已经通过之后,但在 dnf 继续读取最终
/proc/##/stat
文件之前 - 并且直到4.16.2版本,dnf 都没有针对这种情况的异常处理,因此任何故障都会导致整个程序退出。