容器的优雅退出(2):为什么是 SIGKILL?
既然不能从其他进程想办法,那我们就转变一下思路,从 init 进程入手。SIGKILL 信号我们不能捕获,但是 SIGTERM 信号是可以捕获的。那我们就捕获 init 进程接收到的 SIGTERM 信号就好了。但是,我们直接捕获会不会出错呢?原来 init 进程收到 SIGTERM 信号又做了些什么呢?
我们就必须看一下内核的代码了 ,我看的是 linux6.0 版本的内核源码。这次重要的代码文件主要是 linux-6.0/kernel/exit.c 和 linux-6.0/kernel/pid_namespace.c 这两个:
进程收到 SIGTERM 信号并使进程退出时,Linux 内核处理进程退出的入口点就是 do_exit()
函数。
linux-6.0/kernel/exit.c
void __noreturn do_exit(long code)
{
......
exit_notify(tsk, group_dead);
......
}
do_exit()
函数会释放进程的相关的资源,比如内存、文件句柄、信号量等等;会设置当前进程的状态;然后会通知其他进程本进程要退出了,也就是会调用 exit_notify()
函数。
linux-6.0/kernel/exit.c
static void exit_notify(struct task_struct *tsk, int group_dead)