Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#

sudo: required
dist: trusty
dist: xenial

os:
- linux
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

Expand Down Expand Up @@ -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{
Expand Down
4 changes: 2 additions & 2 deletions channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

Expand Down Expand Up @@ -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
}
}
Expand Down
56 changes: 50 additions & 6 deletions grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package main

import (
"bufio"
"bytes"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -190,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
}
Expand Down Expand Up @@ -373,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")
}

Expand Down Expand Up @@ -793,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")
}

Expand Down Expand Up @@ -887,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")
}

Expand Down Expand Up @@ -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)
}

Expand All @@ -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 {
Expand Down Expand Up @@ -1343,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")
}

Expand Down Expand Up @@ -1392,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
}
Expand Down
95 changes: 58 additions & 37 deletions grpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"reflect"
"sort"
"strconv"
"syscall"
"testing"
"time"

Expand Down Expand Up @@ -741,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)
Expand Down Expand Up @@ -869,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)
Expand Down Expand Up @@ -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)
}
6 changes: 6 additions & 0 deletions kata-containers.target
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 2 additions & 2 deletions protocols/grpc/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down