服务器|Linux强制重新启动系统——重启服务器的最终救济途径

最近,有一台Linux服务器出现了不可控的局面,由于umount磁盘操作的失效,导致相关进程都陷入了D状态里,一般情况下最好的解决办法就是重启大法了。

  • 进程陷入D状态无外乎就是因为外部原因造成的,例如等待磁盘的IO、网络的IO……
  • 即便你使用kill -9也是无济于事的……因为进程已经陷进去了,无法响应你的SIGKILL。
理所当然的,我果断采取了reboot -f的操作,让人意想不到的是,连reboot自身也陷进去了,失去响应。
  • reboot -f的区别在于直接通知init重启信号,而跳过一系列的killall、umount操作
下面这是当时保存的现场画面。
服务器|Linux强制重新启动系统——重启服务器的最终救济途径
文章图片

当时的情景如下:
  1. 使用systemctl关闭docker服务(docker是在vdb上的)
  2. systemd(init)连带卡死
  3. 尝试remount vdb卡死
  4. reboot -f因systemd连带卡死
通过systemctl查看joblist,基本都因为systemd的原因全部处于waiting状态,导致systemd一直处于cpu的消耗状态。
JOB UNITTYPESTATE 4044 session-295.scopestart waiting 3924 session-275.scopestart waiting 3702 session-238.scopestart waiting 6779 session-750.scopestart waiting 4020 session-291.scopestart waiting 6917 session-773.scopestart waiting 6347 session-678.scopestart waiting 7199 session-820.scopestart waiting 5795 session-586.scopestart waiting ......

如果人在现场,很简单,按下reset按钮就好。可人不在现场,那还怎么强制重启这台服务器呢?
  • systemd(init)虽然是1号进程,但是在它之上还有操作系统的最底层界面——内核。
  • 就好比中控台坏掉了,但是我们还可以直接接线至主机,直接进行操控。
那么我的目的是重启,想办法通知内核就是最直接的办法。
linux内核有一个功能,叫System request或者称之为SysRq,它的功能就如主机箱上的按钮面板一样,是内核层面的最终操控办法。
首先,SysRq的开关在/proc/sys/kernel/sysrq中,默认情况下是限制功能的16,要使用所有功能需要置为1。
0 - disable sysrq completely 1 - enable all functions of sysrq >bitmask of allowed sysrq functions (see below for detailed function description): 2 - enable control of console logging level 4 - enable control of keyboard (SAK, unraw) 8 - enable debugging dumps of processes etc. 16 - enable sync command 32 - enable remount read-only 64 - enable signalling of processes (term, kill, oom-kill) 128 - allow reboot/poweroff 256 - allow nicing of all RT tasks

  • 需要临时开启,置为1即可:echo 1 > /proc/sys/kernel/sysrq
  • 需要长期开启则写入配置文件:sysctl -w kernel.sysrq=1
然后,发送重启指令b到SysRq触发器上,将直接触发内核的重启。
echo b > /proc/sysrq-trigger

(这个重启将直接调用核心的reboot指令,所有进程将没有任何保存数据的机会,内存中的数据将立即全部丢失)
【服务器|Linux强制重新启动系统——重启服务器的最终救济途径】最后,耐心等待系统的重新启动即可。

    推荐阅读