青蛙小白
博客 / 2017/03

Linux systemd 无法关机问题总结与解决方案

2017/03/15 · — 字 · 阅读约 — 分钟 ·
目录

在使用 systemd 的 Linux 系统(如 Debian、Ubuntu、CentOS 7+、Fedora 等)中遇到无法正常关机的问题时,通常表现为 systemd 内部通信死锁,导致关机命令超时。本文总结了该问题的排查与修复过程,以及通过 Magic SysRq 实现安全关机的方法。

警告:Magic SysRq 是绕过用户态直接从内核层面操作系统的应急手段

Magic SysRq 是 Linux 内核提供的紧急系统请求功能,当系统无响应时可以直接与内核通信执行底层操作。与正常的关机流程不同,它会:

  • 绕过 systemd 和所有用户态进程管理
  • 直接从内核层面强制操作
  • 可能导致应用程序数据损坏或丢失

使用 Magic SysRq 前需要理解的风险:

  1. 数据库应用(如 MySQL、PostgreSQL)可能无法完成事务提交,导致数据不一致
  2. 正在写入的文件可能损坏或截断
  3. 应用程序缓存中未刷新到磁盘的数据会丢失
  4. 某些应用的锁文件可能残留,下次启动时需要手动清理

因此,Magic SysRq 仅应作为最后的救援手段使用,只有在以下情况下才考虑使用:

  • systemd 完全无响应,无法通过常规方式关机
  • 系统已经卡死,没有其他选择
  • 需要避免硬重启(直接断电)对文件系统造成更严重的损坏

问题现象

在 Linux 系统中执行以下命令均无法关机:

systemctl poweroff
shutdown -h now

系统报错:

Failed to call poweroff: Connection timed out

并伴随日志:

Failed to send WATCHDOG=1 notification message: Transport endpoint is not connected

问题分析

通过 ps -p 1 -o pid,cmd 检查系统初始化进程:

1 /sbin/init splash

输出表明 PID 1 是 systemd,但它的内部通信循环已崩溃。主要原因包括:

  • systemd 自身进程或 D-Bus 通信挂起
  • FUSE / NFS / SSHFS / rclone 等挂载未正确卸载
  • journald watchdog 超时
  • systemd 死锁(部分旧版本的 bug)

排查与修复过程

检查挂载和服务状态

首先检查是否存在卡住的挂载点:

mount | egrep 'fuse|sshfs|rclone|gvfs|nfs|cifs'
systemctl --failed
systemctl list-jobs

若发现挂载点卡住,尝试卸载:

sudo umount -l <挂载点>
sudo fusermount -uz <挂载点>

确认 systemd 状态

sudo systemctl status

若命令卡住或报错,说明 systemd 的 D-Bus 通道已断开。

无法使用 systemctl 时的安全关机方案

桌面环境下使用 Magic SysRq 组合键

首先启用 SysRq:

sudo sysctl kernel.sysrq=1

然后依次按下以下组合键(每次间隔 1 秒):

  • Alt + SysRq + R - UnRaw:从 X11 接管键盘控制权,使键盘脱离原始模式
  • Alt + SysRq + E - tErminate:向除 init 外的所有进程发送 SIGTERM 信号,让进程有机会优雅退出
  • Alt + SysRq + I - kIll:向除 init 外的所有进程发送 SIGKILL 信号,强制终止未响应的进程
  • Alt + SysRq + S - Sync:强制将所有文件系统缓冲区同步到磁盘(最关键的数据保护步骤)
  • Alt + SysRq + U - Unmount:将所有文件系统重新挂载为只读模式,防止后续数据写入
  • Alt + SysRq + O - pOwer off:立即关机(使用 B 则为重启)

关键说明:

  • R、E、I 三步是清理用户态进程,为后续操作做准备
  • S (Sync) 是最重要的步骤:它强制将内存中的缓冲区数据写入磁盘,最大程度减少数据丢失
  • U (Unmount) 将文件系统改为只读:防止在关机过程中有新的写操作,保证文件系统一致性
  • 每步之间至少间隔 1 秒:给内核足够时间完成操作,特别是 S 步骤可能需要更长时间(视磁盘缓冲区大小而定)
  • 如果磁盘 I/O 灯还在闪烁,S 步骤后可以多等几秒,确保所有数据都写入完成

这个顺序可以记忆为 “REISUO” 或助记句 “Raising Elephants Is So Utterly Obvious”。

远程或无键盘时的等价命令

在远程 SSH 连接或无法使用键盘的环境下,可以通过 /proc/sysrq-trigger 执行等价操作:

sudo su
echo 1 > /proc/sys/kernel/sysrq     # 启用 SysRq
echo s > /proc/sysrq-trigger         # 同步磁盘数据
sleep 3                               # 等待同步完成
echo u > /proc/sysrq-trigger         # 只读重新挂载所有分区
sleep 1
echo o > /proc/sysrq-trigger         # 立即关机(重启使用 b)

重要提示:

  • 在执行 echo s 之后,建议等待几秒钟,确保所有数据都同步到磁盘
  • 如果系统有大量缓冲数据,sync 操作可能需要较长时间
  • 可以先手动执行几次 sync 命令,观察是否还有磁盘 I/O 活动
  • 一旦执行 echo o,系统会立即关机,SSH 连接会断开

总结

Linux 系统无法关机的根本原因通常是 systemd 内部通信死锁,导致 D-Bus 无法正常工作。该问题在 Debian、Ubuntu、CentOS、Fedora 等使用 systemd 的发行版中都可能出现。在紧急情况下,可以通过 Magic SysRq 组合键(或其命令行等价方式)实现安全关机。

掌握 Magic SysRq 的使用方法对于 Linux 系统管理员来说是一项重要的技能,它可以在系统严重故障时提供最后的救援手段。

参考

TAGS # linux
评论