天天看点

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 UNIT                           TYPE  STATE
4044 session-295.scope              start waiting
3924 session-275.scope              start waiting
3702 session-238.scope              start waiting
6779 session-750.scope              start waiting
4020 session-291.scope              start waiting
6917 session-773.scope              start waiting
6347 session-678.scope              start waiting
7199 session-820.scope              start waiting
5795 session-586.scope              start 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指令,所有进程将没有任何保存数据的机会,内存中的数据将立即全部丢失)

最后,耐心等待系统的重新启动即可。

继续阅读