77package main
88
99import (
10+ "bufio"
1011 "bytes"
1112 "encoding/json"
1213 "fmt"
@@ -919,6 +920,16 @@ func (a *agentGRPC) SignalProcess(ctx context.Context, req *pb.SignalProcessRequ
919920 if req .ExecId == "" || status == libcontainer .Paused {
920921 return emptyResp , ctr .container .Signal (signal , true )
921922 } else if ctr .initProcess .id == req .ExecId {
923+ pid , err := ctr .initProcess .process .Pid ()
924+ if err != nil {
925+ return emptyResp , err
926+ }
927+ // For container initProcess, if it hasn't installed handler for "SIGTERM" signal,
928+ // it will ignore the "SIGTERM" signal sent to it, thus send it "SIGKILL" signal
929+ // instead of "SIGTERM" to terminate it.
930+ if signal == syscall .SIGTERM && ! isSignalHandled (pid , syscall .SIGTERM ) {
931+ signal = syscall .SIGKILL
932+ }
922933 return emptyResp , ctr .container .Signal (signal , false )
923934 }
924935
@@ -934,6 +945,39 @@ func (a *agentGRPC) SignalProcess(ctx context.Context, req *pb.SignalProcessRequ
934945 return emptyResp , nil
935946}
936947
948+ // Check is the container process installed the
949+ // handler for specific signal.
950+ func isSignalHandled (pid int , signum syscall.Signal ) bool {
951+ var sigMask uint64 = 1 << (uint (signum ) - 1 )
952+ procFile := fmt .Sprintf ("/proc/%d/status" , pid )
953+ file , err := os .Open (procFile )
954+ if err != nil {
955+ agentLog .WithField ("procFile" , procFile ).Warn ("Open proc file failed" )
956+ return false
957+ }
958+ defer file .Close ()
959+
960+ scanner := bufio .NewScanner (file )
961+ for scanner .Scan () {
962+ line := scanner .Text ()
963+ if strings .HasPrefix (line , "SigCgt:" ) {
964+ maskSlice := strings .Split (line , ":" )
965+ if len (maskSlice ) != 2 {
966+ agentLog .WithField ("procFile" , procFile ).Warn ("Parse the SigCgt field failed" )
967+ return false
968+ }
969+ sigCgtStr := strings .TrimSpace (maskSlice [1 ])
970+ sigCgtMask , err := strconv .ParseUint (sigCgtStr , 16 , 64 )
971+ if err != nil {
972+ agentLog .WithField ("sigCgt" , sigCgtStr ).Warn ("parse the SigCgt to hex failed" )
973+ return false
974+ }
975+ return (sigCgtMask & sigMask ) == sigMask
976+ }
977+ }
978+ return false
979+ }
980+
937981func (a * agentGRPC ) WaitProcess (ctx context.Context , req * pb.WaitProcessRequest ) (* pb.WaitProcessResponse , error ) {
938982 proc , ctr , err := a .sandbox .getProcess (req .ContainerId , req .ExecId )
939983 if err != nil {
0 commit comments