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

Commit 0461ce2

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 0461ce2

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

grpc.go

Lines changed: 43 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,38 @@ 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 = 1 << (uint(syscall.SIGTERM) - 1)
952+
procFile := fmt.Sprintf("/proc/%d/status", pid)
953+
file, err := os.Open(procFile)
954+
if err != nil {
955+
agentLog.Warnf("Open proc file %s failed", procFile)
956+
}
957+
defer file.Close()
958+
959+
scanner := bufio.NewScanner(file)
960+
for scanner.Scan() {
961+
line := scanner.Text()
962+
if strings.HasPrefix(line, "SigCgt:") {
963+
maskSlice := strings.Split(line, ":")
964+
if len(maskSlice) != 2 {
965+
agentLog.Warnf("Parse the SigCgt field in proc file %s failed", procFile)
966+
return true
967+
}
968+
sigCgtStr := strings.TrimSpace(maskSlice[1])
969+
sigCgtMask, err := strconv.ParseUint(sigCgtStr, 16, 64)
970+
if err != nil {
971+
agentLog.Warnf("parse sigCgtStr %s to hex failed", sigCgtStr)
972+
return true
973+
}
974+
return (sigCgtMask & termMask) == termMask
975+
}
976+
}
977+
return true
978+
}
979+
937980
func (a *agentGRPC) WaitProcess(ctx context.Context, req *pb.WaitProcessRequest) (*pb.WaitProcessResponse, error) {
938981
proc, ctr, err := a.sandbox.getProcess(req.ContainerId, req.ExecId)
939982
if err != nil {

0 commit comments

Comments
 (0)