From 0dbf85de306ce2a0a7a7e32055b9e9b4e3f1b7d9 Mon Sep 17 00:00:00 2001 From: Hui Zhu Date: Thu, 11 Apr 2019 16:01:45 +0800 Subject: [PATCH 1/4] agent: Merge pull request #526 from lifupan/stopfix agent: send SIGKILL instead of SIGTERM to container init process (cherry picked from commit c624f6344587c6fa37a24f8507d27323b3188a36) Fixes:#525 Signed-off-by: Ganesh Maharaj Mahalingam --- grpc.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ grpc_test.go | 21 +++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/grpc.go b/grpc.go index 93eac49202..e4fa9db15e 100644 --- a/grpc.go +++ b/grpc.go @@ -7,6 +7,7 @@ package main import ( + "bufio" "bytes" "encoding/json" "fmt" @@ -919,6 +920,16 @@ func (a *agentGRPC) SignalProcess(ctx context.Context, req *pb.SignalProcessRequ if req.ExecId == "" || status == libcontainer.Paused { return emptyResp, ctr.container.Signal(signal, true) } else if ctr.initProcess.id == req.ExecId { + pid, err := ctr.initProcess.process.Pid() + if err != nil { + return emptyResp, err + } + // For container initProcess, if it hasn't installed handler for "SIGTERM" signal, + // it will ignore the "SIGTERM" signal sent to it, thus send it "SIGKILL" signal + // instead of "SIGTERM" to terminate it. + if signal == syscall.SIGTERM && !isSignalHandled(pid, syscall.SIGTERM) { + signal = syscall.SIGKILL + } return emptyResp, ctr.container.Signal(signal, false) } @@ -934,6 +945,39 @@ func (a *agentGRPC) SignalProcess(ctx context.Context, req *pb.SignalProcessRequ return emptyResp, nil } +// Check is the container process installed the +// handler for specific signal. +func isSignalHandled(pid int, signum syscall.Signal) bool { + var sigMask uint64 = 1 << (uint(signum) - 1) + procFile := fmt.Sprintf("/proc/%d/status", pid) + file, err := os.Open(procFile) + if err != nil { + agentLog.WithField("procFile", procFile).Warn("Open proc file failed") + return false + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "SigCgt:") { + maskSlice := strings.Split(line, ":") + if len(maskSlice) != 2 { + agentLog.WithField("procFile", procFile).Warn("Parse the SigCgt field failed") + return false + } + sigCgtStr := strings.TrimSpace(maskSlice[1]) + sigCgtMask, err := strconv.ParseUint(sigCgtStr, 16, 64) + if err != nil { + agentLog.WithField("sigCgt", sigCgtStr).Warn("parse the SigCgt to hex failed") + return false + } + return (sigCgtMask & sigMask) == sigMask + } + } + return false +} + func (a *agentGRPC) WaitProcess(ctx context.Context, req *pb.WaitProcessRequest) (*pb.WaitProcessResponse, error) { proc, ctr, err := a.sandbox.getProcess(req.ContainerId, req.ExecId) if err != nil { diff --git a/grpc_test.go b/grpc_test.go index de68d21926..d4772a0eb4 100644 --- a/grpc_test.go +++ b/grpc_test.go @@ -15,6 +15,7 @@ import ( "reflect" "sort" "strconv" + "syscall" "testing" "time" @@ -961,3 +962,23 @@ func TestCopyFile(t *testing.T) { // check file's content assert.Equal(content, append(part1, part2...)) } + +func TestIsSignalHandled(t *testing.T) { + assert := assert.New(t) + pid := 1 + + // process will not handle SIGKILL signal + signum := syscall.SIGKILL + handled := isSignalHandled(pid, signum) + assert.False(handled) + + // init process will not handle SIGTERM signal + signum = syscall.SIGTERM + handled = isSignalHandled(pid, signum) + assert.False(handled) + + // init process will handle the SIGQUIT signal + signum = syscall.SIGQUIT + handled = isSignalHandled(pid, signum) + assert.True(handled) +} From d1ace1bf8a62045a0a3578086637d12c228921fd Mon Sep 17 00:00:00 2001 From: Salvador Fuentes Date: Tue, 16 Apr 2019 15:54:28 -0500 Subject: [PATCH 2/4] license: Merge pull request #532 from jcvenegas/stable-1.5-fix-travis license: add license header (cherry picked from commit 741fdb943e5abaa34a5912036870fecb346e2ff5) Fixes: #531 Signed-off-by: Ganesh Maharaj Mahalingam --- kata-containers.target | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kata-containers.target b/kata-containers.target index bf78f01cd1..7eddea9517 100644 --- a/kata-containers.target +++ b/kata-containers.target @@ -1,3 +1,9 @@ +# +# Copyright (c) 2018-2019 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + [Unit] Description=Kata Containers Agent Target Requires=basic.target From 200d8e49856b545156e9fbdbde0f43b483365407 Mon Sep 17 00:00:00 2001 From: Salvador Fuentes Date: Tue, 9 Apr 2019 09:08:18 -0500 Subject: [PATCH 3/4] golang: Merge pull request #528 from teawater/lint Update code to handle lint issues after golangci-lint update to v1.6.0 (cherry picked from commit 801d79214f0fc508286eb46efec6ac8e669c5e89) Fixes: #527 Signed-off-by: Ganesh Maharaj Mahalingam --- .travis.yml | 4 ++-- grpc_test.go | 66 ++++++++++++++++++++++++++-------------------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.travis.yml b/.travis.yml index da13f7998b..8d124a99e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ # sudo: required -dist: trusty +dist: xenial os: - linux @@ -15,7 +15,7 @@ language: go go_import_path: github.com/kata-containers/agent go: - - "1.10.x" + - "1.11.x" env: - target_branch=$TRAVIS_BRANCH diff --git a/grpc_test.go b/grpc_test.go index d4772a0eb4..27c8c57a74 100644 --- a/grpc_test.go +++ b/grpc_test.go @@ -870,42 +870,42 @@ func TestPosixRlimitsToRlimits(t *testing.T) { assert := assert.New(t) expectedRlimits := []configs.Rlimit{ - {unix.RLIMIT_CPU, 100, 120}, - {unix.RLIMIT_FSIZE, 100, 120}, - {unix.RLIMIT_DATA, 100, 120}, - {unix.RLIMIT_STACK, 100, 120}, - {unix.RLIMIT_CORE, 100, 120}, - {unix.RLIMIT_RSS, 100, 120}, - {unix.RLIMIT_NPROC, 100, 120}, - {unix.RLIMIT_NOFILE, 100, 120}, - {unix.RLIMIT_MEMLOCK, 100, 120}, - {unix.RLIMIT_AS, 100, 120}, - {unix.RLIMIT_LOCKS, 100, 120}, - {unix.RLIMIT_SIGPENDING, 100, 120}, - {unix.RLIMIT_MSGQUEUE, 100, 120}, - {unix.RLIMIT_NICE, 100, 120}, - {unix.RLIMIT_RTPRIO, 100, 120}, - {unix.RLIMIT_RTTIME, 100, 120}, + {Type: unix.RLIMIT_CPU, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_FSIZE, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_DATA, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_STACK, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_CORE, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_RSS, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_NPROC, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_NOFILE, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_MEMLOCK, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_AS, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_LOCKS, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_SIGPENDING, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_MSGQUEUE, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_NICE, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_RTPRIO, Hard: 100, Soft: 120}, + {Type: unix.RLIMIT_RTTIME, Hard: 100, Soft: 120}, } posixRlimits := []specs.POSIXRlimit{ - {"RLIMIT_CPU", 100, 120}, - {"RLIMIT_FSIZE", 100, 120}, - {"RLIMIT_DATA", 100, 120}, - {"RLIMIT_STACK", 100, 120}, - {"RLIMIT_CORE", 100, 120}, - {"RLIMIT_RSS", 100, 120}, - {"RLIMIT_NPROC", 100, 120}, - {"RLIMIT_NOFILE", 100, 120}, - {"RLIMIT_MEMLOCK", 100, 120}, - {"RLIMIT_AS", 100, 120}, - {"RLIMIT_LOCKS", 100, 120}, - {"RLIMIT_SIGPENDING", 100, 120}, - {"RLIMIT_MSGQUEUE", 100, 120}, - {"RLIMIT_NICE", 100, 120}, - {"RLIMIT_RTPRIO", 100, 120}, - {"RLIMIT_RTTIME", 100, 120}, - {"RLIMIT_UNSUPPORTED", 0, 0}, + {Type: "RLIMIT_CPU", Hard: 100, Soft: 120}, + {Type: "RLIMIT_FSIZE", Hard: 100, Soft: 120}, + {Type: "RLIMIT_DATA", Hard: 100, Soft: 120}, + {Type: "RLIMIT_STACK", Hard: 100, Soft: 120}, + {Type: "RLIMIT_CORE", Hard: 100, Soft: 120}, + {Type: "RLIMIT_RSS", Hard: 100, Soft: 120}, + {Type: "RLIMIT_NPROC", Hard: 100, Soft: 120}, + {Type: "RLIMIT_NOFILE", Hard: 100, Soft: 120}, + {Type: "RLIMIT_MEMLOCK", Hard: 100, Soft: 120}, + {Type: "RLIMIT_AS", Hard: 100, Soft: 120}, + {Type: "RLIMIT_LOCKS", Hard: 100, Soft: 120}, + {Type: "RLIMIT_SIGPENDING", Hard: 100, Soft: 120}, + {Type: "RLIMIT_MSGQUEUE", Hard: 100, Soft: 120}, + {Type: "RLIMIT_NICE", Hard: 100, Soft: 120}, + {Type: "RLIMIT_RTPRIO", Hard: 100, Soft: 120}, + {Type: "RLIMIT_RTTIME", Hard: 100, Soft: 120}, + {Type: "RLIMIT_UNSUPPORTED", Hard: 0, Soft: 0}, } rlimits := posixRlimitsToRlimits(posixRlimits) From ccc8b26c3537363f82f1ef4099df54350e0c54f7 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Thu, 21 Mar 2019 14:10:02 -0700 Subject: [PATCH 4/4] lint: Merge pull request #491 from ganeshmaharaj/go-linter-change lint: Switch golang linter to golangci-lint (cherry picked from commit 02cacdea6ce0ff815856e2404c3905154dee09db) Fixes #494 Signed-off-by: Ganesh Maharaj Mahalingam --- agent.go | 4 ++-- channel.go | 4 ++-- grpc.go | 12 ++++++------ grpc_test.go | 8 ++++---- protocols/grpc/utils_test.go | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/agent.go b/agent.go index c834c0a636..9e609946eb 100644 --- a/agent.go +++ b/agent.go @@ -475,7 +475,7 @@ func (s *sandbox) deleteContainer(id string) { } func (s *sandbox) getProcess(cid, execID string) (*process, *container, error) { - if s.running == false { + if !s.running { return nil, nil, grpcStatus.Error(codes.FailedPrecondition, "Sandbox not started") } @@ -967,7 +967,7 @@ func makeUnaryInterceptor() grpc.UnaryServerInterceptor { if !tracing { // Just log call details - elapsed = time.Now().Sub(start) + elapsed = time.Since(start) message = resp.(proto.Message) logger := agentLog.WithFields(logrus.Fields{ diff --git a/channel.go b/channel.go index f9df04456a..47d107c6e1 100644 --- a/channel.go +++ b/channel.go @@ -171,7 +171,7 @@ func (c *serialChannel) wait() error { var events [1]unix.EpollEvent fd := c.serialConn.Fd() - if fd <= 0 { + if fd == 0 { return fmt.Errorf("serial port IO closed") } @@ -339,7 +339,7 @@ func findVirtualSerialPath(serialName string) (string, error) { return "", err } - if strings.Contains(string(content), serialName) == true { + if strings.Contains(string(content), serialName) { return filepath.Join(devRootPath, port), nil } } diff --git a/grpc.go b/grpc.go index e4fa9db15e..f6af4a64e9 100644 --- a/grpc.go +++ b/grpc.go @@ -191,7 +191,7 @@ func updateCpusetPath(cgroupPath string, newCpuset string, cookies cookie) error cgroupParentPath = filepath.Join(cgroupParentPath, path) // check if the cgroup was already updated. - if cookies[cgroupParentPath] == true { + if cookies[cgroupParentPath] { agentLog.WithField("path", cgroupParentPath).Debug("cpuset cgroup already updated") continue } @@ -374,7 +374,7 @@ func (a *agentGRPC) Version(ctx context.Context, req *pb.CheckRequest) (*pb.Vers } func (a *agentGRPC) getContainer(cid string) (*container, error) { - if a.sandbox.running == false { + if !a.sandbox.running { return nil, grpcStatus.Error(codes.FailedPrecondition, "Sandbox not started") } @@ -794,7 +794,7 @@ func posixRlimitsToRlimits(posixRlimits []specs.POSIXRlimit) []configs.Rlimit { } func (a *agentGRPC) createContainerChecks(req *pb.CreateContainerRequest) (err error) { - if a.sandbox.running == false { + if !a.sandbox.running { return grpcStatus.Error(codes.FailedPrecondition, "Sandbox not started, impossible to run a new container") } @@ -888,7 +888,7 @@ func (a *agentGRPC) ExecProcess(ctx context.Context, req *pb.ExecProcessRequest) } func (a *agentGRPC) SignalProcess(ctx context.Context, req *pb.SignalProcessRequest) (*gpb.Empty, error) { - if a.sandbox.running == false { + if !a.sandbox.running { return emptyResp, grpcStatus.Error(codes.FailedPrecondition, "Sandbox not started, impossible to signal the container") } @@ -1387,7 +1387,7 @@ func (a *agentGRPC) TtyWinResize(ctx context.Context, req *pb.TtyWinResizeReques } func (a *agentGRPC) CreateSandbox(ctx context.Context, req *pb.CreateSandboxRequest) (*gpb.Empty, error) { - if a.sandbox.running == true { + if a.sandbox.running { return emptyResp, grpcStatus.Error(codes.AlreadyExists, "Sandbox already started, impossible to start again") } @@ -1436,7 +1436,7 @@ func (a *agentGRPC) CreateSandbox(ctx context.Context, req *pb.CreateSandboxRequ } func (a *agentGRPC) DestroySandbox(ctx context.Context, req *pb.DestroySandboxRequest) (*gpb.Empty, error) { - if a.sandbox.running == false { + if !a.sandbox.running { agentLog.Info("Sandbox not started, this is a no-op") return emptyResp, nil } diff --git a/grpc_test.go b/grpc_test.go index 27c8c57a74..22b9029a39 100644 --- a/grpc_test.go +++ b/grpc_test.go @@ -742,11 +742,11 @@ func testAgentDetails(assert *assert.Assertions, details *pb.AgentDetails, haveS storages = append(storages, handler) } - sort.Sort(sort.StringSlice(details.DeviceHandlers)) - sort.Sort(sort.StringSlice(details.StorageHandlers)) + sort.Strings(details.DeviceHandlers) + sort.Strings(details.StorageHandlers) - sort.Sort(sort.StringSlice(devices)) - sort.Sort(sort.StringSlice(storages)) + sort.Strings(devices) + sort.Strings(storages) assert.Equal(details.DeviceHandlers, devices) assert.Equal(details.StorageHandlers, storages) diff --git a/protocols/grpc/utils_test.go b/protocols/grpc/utils_test.go index 0184551142..3fe3e51cdb 100644 --- a/protocols/grpc/utils_test.go +++ b/protocols/grpc/utils_test.go @@ -73,8 +73,8 @@ func assertIsEqual(t *testing.T, ociSpec *specs.Spec, grpcSpec *Spec) { assert.Equal(len(grpcSpec.Linux.Namespaces), 5) for i := range grpcSpec.Linux.Namespaces { - assert.Equal(grpcSpec.Linux.Namespaces[i].Type, (string)(ociSpec.Linux.Namespaces[i].Type)) - assert.Equal(grpcSpec.Linux.Namespaces[i].Path, (string)(ociSpec.Linux.Namespaces[i].Path)) + assert.Equal(grpcSpec.Linux.Namespaces[i].Type, (string)(ociSpec.Linux.Namespaces[i].Type)) //nolint:unconvert + assert.Equal(grpcSpec.Linux.Namespaces[i].Path, (string)(ociSpec.Linux.Namespaces[i].Path)) //nolint:unconvert } }