* containerd build clean on Solaris Signed-off-by: Amit Krishnan <krish.amit@gmail.com> * Vendor golang.org/x/sys Signed-off-by: Amit Krishnan <krish.amit@gmail.com>
		
			
				
	
	
		
			135 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package runtime
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"encoding/json"
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"os/exec"
 | 
						|
	"path/filepath"
 | 
						|
	"strings"
 | 
						|
	"syscall"
 | 
						|
 | 
						|
	"github.com/docker/containerd/specs"
 | 
						|
	"github.com/opencontainers/runc/libcontainer"
 | 
						|
	ocs "github.com/opencontainers/runtime-spec/specs-go"
 | 
						|
)
 | 
						|
 | 
						|
func (c *container) getLibctContainer() (libcontainer.Container, error) {
 | 
						|
	runtimeRoot := "/run/runc"
 | 
						|
 | 
						|
	// Check that the root wasn't changed
 | 
						|
	for _, opt := range c.runtimeArgs {
 | 
						|
		if strings.HasPrefix(opt, "--root=") {
 | 
						|
			runtimeRoot = strings.TrimPrefix(opt, "--root=")
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	f, err := libcontainer.New(runtimeRoot, libcontainer.Cgroupfs)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	return f.Load(c.id)
 | 
						|
}
 | 
						|
 | 
						|
func (c *container) OOM() (OOM, error) {
 | 
						|
	container, err := c.getLibctContainer()
 | 
						|
	if err != nil {
 | 
						|
		if lerr, ok := err.(libcontainer.Error); ok {
 | 
						|
			// with oom registration sometimes the container can run, exit, and be destroyed
 | 
						|
			// faster than we can get the state back so we can just ignore this
 | 
						|
			if lerr.Code() == libcontainer.ContainerNotExists {
 | 
						|
				return nil, ErrContainerExited
 | 
						|
			}
 | 
						|
		}
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	state, err := container.State()
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	memoryPath := state.CgroupPaths["memory"]
 | 
						|
	return c.getMemeoryEventFD(memoryPath)
 | 
						|
}
 | 
						|
 | 
						|
func u64Ptr(i uint64) *uint64 { return &i }
 | 
						|
 | 
						|
func (c *container) UpdateResources(r *Resource) error {
 | 
						|
	sr := ocs.Resources{
 | 
						|
		Memory: &ocs.Memory{
 | 
						|
			Limit:       u64Ptr(uint64(r.Memory)),
 | 
						|
			Reservation: u64Ptr(uint64(r.MemoryReservation)),
 | 
						|
			Swap:        u64Ptr(uint64(r.MemorySwap)),
 | 
						|
			Kernel:      u64Ptr(uint64(r.KernelMemory)),
 | 
						|
		},
 | 
						|
		CPU: &ocs.CPU{
 | 
						|
			Shares: u64Ptr(uint64(r.CPUShares)),
 | 
						|
			Quota:  u64Ptr(uint64(r.CPUQuota)),
 | 
						|
			Period: u64Ptr(uint64(r.CPUPeriod)),
 | 
						|
			Cpus:   &r.CpusetCpus,
 | 
						|
			Mems:   &r.CpusetMems,
 | 
						|
		},
 | 
						|
		BlockIO: &ocs.BlockIO{
 | 
						|
			Weight: &r.BlkioWeight,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	srStr := bytes.NewBuffer(nil)
 | 
						|
	if err := json.NewEncoder(srStr).Encode(&sr); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	args := c.runtimeArgs
 | 
						|
	args = append(args, "update", "-r", "-", c.id)
 | 
						|
	cmd := exec.Command(c.runtime, args...)
 | 
						|
	cmd.Stdin = srStr
 | 
						|
	b, err := cmd.CombinedOutput()
 | 
						|
	if err != nil {
 | 
						|
		return fmt.Errorf(string(b))
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func getRootIDs(s *specs.Spec) (int, int, error) {
 | 
						|
	if s == nil {
 | 
						|
		return 0, 0, nil
 | 
						|
	}
 | 
						|
	var hasUserns bool
 | 
						|
	for _, ns := range s.Linux.Namespaces {
 | 
						|
		if ns.Type == ocs.UserNamespace {
 | 
						|
			hasUserns = true
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if !hasUserns {
 | 
						|
		return 0, 0, nil
 | 
						|
	}
 | 
						|
	uid := hostIDFromMap(0, s.Linux.UIDMappings)
 | 
						|
	gid := hostIDFromMap(0, s.Linux.GIDMappings)
 | 
						|
	return uid, gid, nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *container) getMemeoryEventFD(root string) (*oom, error) {
 | 
						|
	f, err := os.Open(filepath.Join(root, "memory.oom_control"))
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	fd, _, serr := syscall.RawSyscall(syscall.SYS_EVENTFD2, 0, syscall.FD_CLOEXEC, 0)
 | 
						|
	if serr != 0 {
 | 
						|
		f.Close()
 | 
						|
		return nil, serr
 | 
						|
	}
 | 
						|
	if err := c.writeEventFD(root, int(f.Fd()), int(fd)); err != nil {
 | 
						|
		syscall.Close(int(fd))
 | 
						|
		f.Close()
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	return &oom{
 | 
						|
		root:    root,
 | 
						|
		id:      c.id,
 | 
						|
		eventfd: int(fd),
 | 
						|
		control: f,
 | 
						|
	}, nil
 | 
						|
}
 |