From d4605dafaa9c326a5cf24c28d0c1efe6c9997f49 Mon Sep 17 00:00:00 2001 From: holyfei Date: Sat, 21 Aug 2021 17:08:46 +0800 Subject: [PATCH] kata-containers: support with iSulad reason: support with iSulad Signed-off-by: holyfei --- src/agent/rustjail/src/cgroups/fs/mod.rs | 2 +- src/runtime/containerd-shim-v2/container.go | 9 +++ src/runtime/containerd-shim-v2/service.go | 55 +++++++++++++++++++ src/runtime/containerd-shim-v2/start.go | 10 ++++ .../containerd/runtime/v2/shim/shim.go | 8 ++- 5 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/agent/rustjail/src/cgroups/fs/mod.rs b/src/agent/rustjail/src/cgroups/fs/mod.rs index 7f41cb4..6c3bb32 100644 --- a/src/agent/rustjail/src/cgroups/fs/mod.rs +++ b/src/agent/rustjail/src/cgroups/fs/mod.rs @@ -369,7 +369,7 @@ fn set_memory_resources(cg: &cgroups::Cgroup, memory: &LinuxMemory, update: bool if let Some(swappiness) = memory.swappiness { if (0..=100).contains(&swappiness) { mem_controller.set_swappiness(swappiness as u64)?; - } else { + } else if swappiness != -1 { return Err(anyhow!( "invalid value:{}. valid memory swappiness range is 0-100", swappiness diff --git a/src/runtime/containerd-shim-v2/container.go b/src/runtime/containerd-shim-v2/container.go index faea0e2..d563888 100644 --- a/src/runtime/containerd-shim-v2/container.go +++ b/src/runtime/containerd-shim-v2/container.go @@ -7,10 +7,13 @@ package containerdshim import ( "io" + "os" + "path" "time" "github.com/containerd/containerd/api/types/task" "github.com/containerd/containerd/errdefs" + cdshim "github.com/containerd/containerd/runtime/v2/shim" taskAPI "github.com/containerd/containerd/runtime/v2/task" "github.com/opencontainers/runtime-spec/specs-go" @@ -37,6 +40,8 @@ type container struct { status task.Status terminal bool mounted bool + exitFifo string + exitFd *os.File } func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.ContainerType, spec *specs.Spec, mounted bool) (*container, error) { @@ -49,6 +54,9 @@ func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.Con spec = &specs.Spec{} } + dir := os.Getenv(cdshim.ExitFifoDir) + exitFifo := path.Join(dir, r.ID, exitFifoName) + c := &container{ s: s, spec: spec, @@ -65,6 +73,7 @@ func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.Con exitCh: make(chan uint32, 1), stdinCloser: make(chan struct{}), mounted: mounted, + exitFifo: exitFifo, } return c, nil } diff --git a/src/runtime/containerd-shim-v2/service.go b/src/runtime/containerd-shim-v2/service.go index 1003f8e..e13283c 100644 --- a/src/runtime/containerd-shim-v2/service.go +++ b/src/runtime/containerd-shim-v2/service.go @@ -6,13 +6,16 @@ package containerdshim import ( + "bytes" "context" + "encoding/binary" "io/ioutil" "os" sysexec "os/exec" "sync" "syscall" "time" + "unsafe" eventstypes "github.com/containerd/containerd/api/events" "github.com/containerd/containerd/api/types/task" @@ -51,6 +54,8 @@ const ( // A time span used to wait for publish a containerd event, // once it costs a longer time than timeOut, it will be canceld. timeOut = 5 * time.Second + + exitFifoName = "exit_fifo" ) var ( @@ -1019,6 +1024,10 @@ func (s *service) Wait(ctx context.Context, r *taskAPI.WaitRequest) (_ *taskAPI. func (s *service) processExits() { for e := range s.ec { s.checkProcesses(e) + + if os.Getenv(cdshim.ExitFifoDir) != "" { + s.closeExitFifo(e) + } } } @@ -1070,3 +1079,49 @@ func (s *service) getContainerStatus(containerID string) (task.Status, error) { return status, nil } + +func isBigEndian() (ret bool) { + i := int(0x1) + bs := (*[int(unsafe.Sizeof(i))]byte)(unsafe.Pointer(&i)) + return bs[0] == 0 +} + +func (s *service) closeExitFifo(e exit) { + if e.execid != "" { + // not a container, no need to close exit fifo + return + } + + var ret uint32 + var nativeEndian binary.ByteOrder + + s.mu.Lock() + c, err := s.getContainer(e.id) + s.mu.Unlock() + + if err != nil { + logrus.WithError(err).Errorf("Process container:%v exit fifo failed", e.id) + return + } + + ret = <-c.exitCh + // refill the exitCh with the container process's exit code in case + // there were other waits on this process. + c.exitCh <- ret + + if isBigEndian() { + nativeEndian = binary.BigEndian + } else { + nativeEndian = binary.LittleEndian + } + + bytesBuffer := bytes.NewBuffer([]byte{}) + binary.Write(bytesBuffer, nativeEndian, &ret) + + _, err = c.exitFd.Write(bytesBuffer.Bytes()) + if err != nil { + logrus.WithError(err).Error("write exit fifo failed") + } + + c.exitFd.Close() +} diff --git a/src/runtime/containerd-shim-v2/start.go b/src/runtime/containerd-shim-v2/start.go index 72420e4..e89dc48 100644 --- a/src/runtime/containerd-shim-v2/start.go +++ b/src/runtime/containerd-shim-v2/start.go @@ -8,8 +8,11 @@ package containerdshim import ( "context" "fmt" + "golang.org/x/sys/unix" + "os" "github.com/containerd/containerd/api/types/task" + cdshim "github.com/containerd/containerd/runtime/v2/shim" "github.com/kata-containers/kata-containers/src/runtime/pkg/katautils" ) @@ -59,6 +62,13 @@ func startContainer(ctx context.Context, s *service, c *container) error { c.status = task.StatusRunning + if os.Getenv(cdshim.ExitFifoDir) != "" { + c.exitFd, err = os.OpenFile(c.exitFifo, unix.O_WRONLY|unix.O_NONBLOCK|unix.O_CLOEXEC, 0) + if err != nil { + return err + } + } + stdin, stdout, stderr, err := s.sandbox.IOStream(c.id, c.id) if err != nil { return err diff --git a/src/runtime/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go b/src/runtime/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go index d60d496..946c386 100644 --- a/src/runtime/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go +++ b/src/runtime/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go @@ -84,6 +84,8 @@ var ( action string ) +var ExitFifoDir = "EXIT_FIFO_DIR" + func parseFlags() { flag.BoolVar(&debugFlag, "debug", false, "enable debug output in logs") flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim") @@ -198,8 +200,10 @@ func run(id string, initFunc Init, config Config) error { } return nil default: - if err := setLogger(ctx, idFlag); err != nil { - return err + if os.Getenv("EXIT_FIFO_DIR") == "" { + if err := setLogger(ctx, idFlag); err != nil { + return err + } } client := NewShimClient(ctx, service, signals) return client.Serve() -- 2.23.0