init 6和reboot

如果直接搜索“init 6和reboot的区别”,会得到大量的以讹传讹的网页,它们纷纷表示init 6才是正确的重启命令。

而实际上,在现在的大多数发行版中,init和reboot来自于同一个软件包(sysvinit、upstart或者systemd等等)。reboot最终仍然是通过init进程完成的。reboot在正常情况下会做两件事——1.通知所有用户系统要重启 2.init 6。

在sysvinit的早期版本(2.74以前)中,reboot会不经过init而直接通知内核重启。upstart和systemd中的reboot一直是经过init的。在新的sysvinit中,reboot仍然保留的这种方式(-f参数)。

内核快捷键重启

无论reboot还是init 6都会等到所有进程被正确关闭之后才会通知内核重启。那么当你遇到一大堆因为等待IO而被挂起到D状态的进程怎么办?这种进程在回归正常之前是不能被kill的,所以reboot会被挂起。

一种方法是给reboot增加-f参数以强制重启,另一种方法是通过内核预留(内核编译时开启CONFIG_MAGIC_SYSRQ ,大多数发行版默认都开启)的内核快捷键接口,/proc/sys/kernel/sysrq置1时,可以通过向/proc/sysrq-trigger写入内核快捷键来强制重启。

一个典型的强制重启过程大致如下:

echo 1 > /proc/sys/kernel/sysrq
echo b > /proc/sysrq-trigger

如果服务器的ssh已经挂掉,而且没有serial console的情况下怎么办?如果提前安装过ipt_sysrq的话大概还有救,只要网络还通,那么可以通过发送特殊的数据包来触发内核快捷键。

如果是桌面系统,那么用Alt+SysRq触发内核快捷键更方便一些。比如显卡驱动挂掉之后可以尝试用Alt+SysRq+REISUB重启。

完整的内核快捷键列表可以看这里

高级的重启

传统的重启基本上相当于关机+开机的过程,特别是开机自检这一步实在太慢了,kexec提出了另外的重启方式——置换内核,重新init。

更多的情况下重启linux系统仅仅是为了更新内核,ksplice可以直接将更新patch到正在运行的内核上,于是干脆将重启这一步省了。