Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.

Commit a8df202

Browse files
committed
agent: send SIGKILL instead of SIGTERM to container init process
If container initProcess doesn't install any handler for SIGTERM, it will ignore this signal, thus send it SIGKILL instead of SIGTERM to terminate it. Fixes:#525 Signed-off-by: lifupan <lifupan@gmail.com>
1 parent 74639b7 commit a8df202

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

grpc.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package main
88

99
import (
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 && !isSigTermCatched(pid) {
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 "term" signal.
950+
func isSigTermCatched(pid int) bool {
951+
var termMask uint64
952+
termMask = 1 << (uint(syscall.SIGTERM) - 1)
953+
procFile := fmt.Sprintf("/proc/%d/status", pid)
954+
file, err := os.Open(procFile)
955+
if err != nil {
956+
agentLog.Warnf("Open proc file %s failed", procFile)
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.Warnf("Parse the SigCgt field in proc file %s failed", procFile)
967+
return true
968+
}
969+
sigCgtStr := strings.TrimSpace(maskSlice[1])
970+
sigCgtMask, err := strconv.ParseUint(sigCgtStr, 16, 64)
971+
if err != nil {
972+
agentLog.Warnf("parse sigCgtStr %s to hex failed", sigCgtStr)
973+
return true
974+
}
975+
return (sigCgtMask & termMask) == termMask
976+
}
977+
}
978+
return true
979+
}
980+
937981
func (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

Comments
 (0)