/*
* The last thread in the cgroup-init thread group is terminating.
* Find remaining pid_ts in the namespace, signal and wait for them
* to exit.
*
* Note: This signals each threads in the namespace - even those that
* belong to the same thread group, To avoid this, we would have
* to walk the entire tasklist looking a processes in this
* namespace, but that could be unnecessarily expensive if the
* pid namespace has just a few processes. Or we need to
* maintain a tasklist for each pid namespace.
*
*/rcu_read_lock();read_lock(&tasklist_lock);nr=2;idr_for_each_entry_continue(&pid_ns->idr,pid,nr){task=pid_task(pid,PIDTYPE_PID);if(task&&!__fatal_signal_pending(task))group_send_sig_info(SIGKILL,SEND_SIG_PRIV,task,PIDTYPE_MAX);}
tini 是怎么做到向其他进程转发 SIGTERM 信号的
如果容器中使用 tini 作为 init 进程,tini 的 sigtimedwait() 函数来检查自己收到的信号,然后调用 kill() 把信号传递给子进程。
intwait_and_forward_signal(sigset_tconst*constparent_sigset_ptr,pid_tconstchild_pid){siginfo_tsig;if(sigtimedwait(parent_sigset_ptr,&sig,&ts)==-1){switch(errno){…}}else{/* There is a signal to handle here */switch(sig.si_signo){caseSIGCHLD:/* Special-cased, as we don't forward SIGCHLD. Instead, we'll
* fallthrough to reaping processes.
*/PRINT_DEBUG("Received SIGCHLD");break;default:PRINT_DEBUG("Passing signal: '%s'",strsignal(sig.si_signo));/* Forward anything else */if(kill(kill_process_group?-child_pid:child_pid,sig.si_signo)){if(errno==ESRCH){PRINT_WARNING("Child was dead when forwarding signal");}else{PRINT_FATAL("Unexpected error when forwarding signal: '%s'",strerror(errno));return1;}}break;}}return0;}