summaryrefslogtreecommitdiff
path: root/vendor/github.com/opencontainers/runc/libcontainer
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2018-02-28 16:55:00 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-03-01 13:20:16 +0000
commit72b975ee3bc53b3b657c50a867ce73251a15d16a (patch)
treec5f61b8eca8106f9b9a49c1cfed02f8198539ad5 /vendor/github.com/opencontainers/runc/libcontainer
parentb1ae92fa6711de378d3bf0c6553f633f070d68c3 (diff)
downloadpodman-72b975ee3bc53b3b657c50a867ce73251a15d16a.tar.gz
podman-72b975ee3bc53b3b657c50a867ce73251a15d16a.tar.bz2
podman-72b975ee3bc53b3b657c50a867ce73251a15d16a.zip
Remove unused runc files
We no longer use runc code to read network I/O usage. This lets us remove a lot of vendored code. Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #425 Approved by: rhatdan
Diffstat (limited to 'vendor/github.com/opencontainers/runc/libcontainer')
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go54
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go20
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/capabilities_linux.go114
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go373
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go237
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go125
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go121
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go163
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go80
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go66
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs_unsupported.go3
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go71
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go313
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go40
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go43
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio.go41
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/perf_event.go35
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids.go73
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils.go78
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_nosystemd.go55
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go563
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/configs/validate/rootless.go117
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go212
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/console_linux.go41
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/container.go166
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/container_linux.go1849
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go40
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/criurpc/criurpc.pb.go1178
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/criurpc/criurpc.proto209
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/error.go70
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/factory.go44
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go364
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/generic_error.go92
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/init_linux.go534
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/intelrdt/intelrdt.go553
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/intelrdt/stats.go24
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go50
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/message_linux.go89
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/mount/mount.go23
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/mount/mount_linux.go82
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/mount/mountinfo.go40
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/network_linux.go259
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/notify_linux.go90
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/process.go110
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/process_linux.go547
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/restored_process.go122
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go838
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go76
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go258
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go24
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go76
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture.go27
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/stacktrace/frame.go38
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/stacktrace/stacktrace.go5
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go193
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/state_linux.go255
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/stats.go15
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/stats_linux.go10
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/sync.go107
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go93
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go127
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go44
62 files changed, 0 insertions, 11759 deletions
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go
deleted file mode 100644
index 7fff0627f..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// +build apparmor,linux
-
-package apparmor
-
-import (
- "fmt"
- "io/ioutil"
- "os"
-)
-
-// IsEnabled returns true if apparmor is enabled for the host.
-func IsEnabled() bool {
- if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil && os.Getenv("container") == "" {
- if _, err = os.Stat("/sbin/apparmor_parser"); err == nil {
- buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled")
- return err == nil && len(buf) > 1 && buf[0] == 'Y'
- }
- }
- return false
-}
-
-func setprocattr(attr, value string) error {
- // Under AppArmor you can only change your own attr, so use /proc/self/
- // instead of /proc/<tid>/ like libapparmor does
- path := fmt.Sprintf("/proc/self/attr/%s", attr)
-
- f, err := os.OpenFile(path, os.O_WRONLY, 0)
- if err != nil {
- return err
- }
- defer f.Close()
-
- _, err = fmt.Fprintf(f, "%s", value)
- return err
-}
-
-// changeOnExec reimplements aa_change_onexec from libapparmor in Go
-func changeOnExec(name string) error {
- value := "exec " + name
- if err := setprocattr("exec", value); err != nil {
- return fmt.Errorf("apparmor failed to apply profile: %s", err)
- }
- return nil
-}
-
-// ApplyProfile will apply the profile with the specified name to the process after
-// the next exec.
-func ApplyProfile(name string) error {
- if name == "" {
- return nil
- }
-
- return changeOnExec(name)
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go
deleted file mode 100644
index d4110cf0b..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// +build !apparmor !linux
-
-package apparmor
-
-import (
- "errors"
-)
-
-var ErrApparmorNotEnabled = errors.New("apparmor: config provided but apparmor not supported")
-
-func IsEnabled() bool {
- return false
-}
-
-func ApplyProfile(name string) error {
- if name != "" {
- return ErrApparmorNotEnabled
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/capabilities_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/capabilities_linux.go
deleted file mode 100644
index 8981b2a2f..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/capabilities_linux.go
+++ /dev/null
@@ -1,114 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "fmt"
- "os"
- "strings"
-
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/syndtr/gocapability/capability"
-)
-
-const allCapabilityTypes = capability.CAPS | capability.BOUNDS | capability.AMBS
-
-var capabilityMap map[string]capability.Cap
-
-func init() {
- capabilityMap = make(map[string]capability.Cap)
- last := capability.CAP_LAST_CAP
- // workaround for RHEL6 which has no /proc/sys/kernel/cap_last_cap
- if last == capability.Cap(63) {
- last = capability.CAP_BLOCK_SUSPEND
- }
- for _, cap := range capability.List() {
- if cap > last {
- continue
- }
- capKey := fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String()))
- capabilityMap[capKey] = cap
- }
-}
-
-func newContainerCapList(capConfig *configs.Capabilities) (*containerCapabilities, error) {
- bounding := []capability.Cap{}
- for _, c := range capConfig.Bounding {
- v, ok := capabilityMap[c]
- if !ok {
- return nil, fmt.Errorf("unknown capability %q", c)
- }
- bounding = append(bounding, v)
- }
- effective := []capability.Cap{}
- for _, c := range capConfig.Effective {
- v, ok := capabilityMap[c]
- if !ok {
- return nil, fmt.Errorf("unknown capability %q", c)
- }
- effective = append(effective, v)
- }
- inheritable := []capability.Cap{}
- for _, c := range capConfig.Inheritable {
- v, ok := capabilityMap[c]
- if !ok {
- return nil, fmt.Errorf("unknown capability %q", c)
- }
- inheritable = append(inheritable, v)
- }
- permitted := []capability.Cap{}
- for _, c := range capConfig.Permitted {
- v, ok := capabilityMap[c]
- if !ok {
- return nil, fmt.Errorf("unknown capability %q", c)
- }
- permitted = append(permitted, v)
- }
- ambient := []capability.Cap{}
- for _, c := range capConfig.Ambient {
- v, ok := capabilityMap[c]
- if !ok {
- return nil, fmt.Errorf("unknown capability %q", c)
- }
- ambient = append(ambient, v)
- }
- pid, err := capability.NewPid(os.Getpid())
- if err != nil {
- return nil, err
- }
- return &containerCapabilities{
- bounding: bounding,
- effective: effective,
- inheritable: inheritable,
- permitted: permitted,
- ambient: ambient,
- pid: pid,
- }, nil
-}
-
-type containerCapabilities struct {
- pid capability.Capabilities
- bounding []capability.Cap
- effective []capability.Cap
- inheritable []capability.Cap
- permitted []capability.Cap
- ambient []capability.Cap
-}
-
-// ApplyBoundingSet sets the capability bounding set to those specified in the whitelist.
-func (c *containerCapabilities) ApplyBoundingSet() error {
- c.pid.Clear(capability.BOUNDS)
- c.pid.Set(capability.BOUNDS, c.bounding...)
- return c.pid.Apply(capability.BOUNDS)
-}
-
-// Apply sets all the capabilities for the current process in the config.
-func (c *containerCapabilities) ApplyCaps() error {
- c.pid.Clear(allCapabilityTypes)
- c.pid.Set(capability.BOUNDS, c.bounding...)
- c.pid.Set(capability.PERMITTED, c.permitted...)
- c.pid.Set(capability.INHERITABLE, c.inheritable...)
- c.pid.Set(capability.EFFECTIVE, c.effective...)
- c.pid.Set(capability.AMBIENT, c.ambient...)
- return c.pid.Apply(allCapabilityTypes)
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go
deleted file mode 100644
index 43bdccf3e..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go
+++ /dev/null
@@ -1,373 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "sync"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
- libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
-)
-
-var (
- subsystems = subsystemSet{
- &CpusetGroup{},
- &DevicesGroup{},
- &MemoryGroup{},
- &CpuGroup{},
- &CpuacctGroup{},
- &PidsGroup{},
- &BlkioGroup{},
- &HugetlbGroup{},
- &NetClsGroup{},
- &NetPrioGroup{},
- &PerfEventGroup{},
- &FreezerGroup{},
- &NameGroup{GroupName: "name=systemd", Join: true},
- }
- HugePageSizes, _ = cgroups.GetHugePageSize()
-)
-
-var errSubsystemDoesNotExist = errors.New("cgroup: subsystem does not exist")
-
-type subsystemSet []subsystem
-
-func (s subsystemSet) Get(name string) (subsystem, error) {
- for _, ss := range s {
- if ss.Name() == name {
- return ss, nil
- }
- }
- return nil, errSubsystemDoesNotExist
-}
-
-type subsystem interface {
- // Name returns the name of the subsystem.
- Name() string
- // Returns the stats, as 'stats', corresponding to the cgroup under 'path'.
- GetStats(path string, stats *cgroups.Stats) error
- // Removes the cgroup represented by 'cgroupData'.
- Remove(*cgroupData) error
- // Creates and joins the cgroup represented by 'cgroupData'.
- Apply(*cgroupData) error
- // Set the cgroup represented by cgroup.
- Set(path string, cgroup *configs.Cgroup) error
-}
-
-type Manager struct {
- mu sync.Mutex
- Cgroups *configs.Cgroup
- Paths map[string]string
-}
-
-// The absolute path to the root of the cgroup hierarchies.
-var cgroupRootLock sync.Mutex
-var cgroupRoot string
-
-// Gets the cgroupRoot.
-func getCgroupRoot() (string, error) {
- cgroupRootLock.Lock()
- defer cgroupRootLock.Unlock()
-
- if cgroupRoot != "" {
- return cgroupRoot, nil
- }
-
- root, err := cgroups.FindCgroupMountpointDir()
- if err != nil {
- return "", err
- }
-
- if _, err := os.Stat(root); err != nil {
- return "", err
- }
-
- cgroupRoot = root
- return cgroupRoot, nil
-}
-
-type cgroupData struct {
- root string
- innerPath string
- config *configs.Cgroup
- pid int
-}
-
-func (m *Manager) Apply(pid int) (err error) {
- if m.Cgroups == nil {
- return nil
- }
- m.mu.Lock()
- defer m.mu.Unlock()
-
- var c = m.Cgroups
-
- d, err := getCgroupData(m.Cgroups, pid)
- if err != nil {
- return err
- }
-
- m.Paths = make(map[string]string)
- if c.Paths != nil {
- for name, path := range c.Paths {
- _, err := d.path(name)
- if err != nil {
- if cgroups.IsNotFound(err) {
- continue
- }
- return err
- }
- m.Paths[name] = path
- }
- return cgroups.EnterPid(m.Paths, pid)
- }
-
- for _, sys := range subsystems {
- // TODO: Apply should, ideally, be reentrant or be broken up into a separate
- // create and join phase so that the cgroup hierarchy for a container can be
- // created then join consists of writing the process pids to cgroup.procs
- p, err := d.path(sys.Name())
- if err != nil {
- // The non-presence of the devices subsystem is
- // considered fatal for security reasons.
- if cgroups.IsNotFound(err) && sys.Name() != "devices" {
- continue
- }
- return err
- }
- m.Paths[sys.Name()] = p
-
- if err := sys.Apply(d); err != nil {
- if os.IsPermission(err) && m.Cgroups.Path == "" {
- // If we didn't set a cgroup path, then let's defer the error here
- // until we know whether we have set limits or not.
- // If we hadn't set limits, then it's ok that we couldn't join this cgroup, because
- // it will have the same limits as its parent.
- delete(m.Paths, sys.Name())
- continue
- }
- return err
- }
-
- }
- return nil
-}
-
-func (m *Manager) Destroy() error {
- if m.Cgroups.Paths != nil {
- return nil
- }
- m.mu.Lock()
- defer m.mu.Unlock()
- if err := cgroups.RemovePaths(m.Paths); err != nil {
- return err
- }
- m.Paths = make(map[string]string)
- return nil
-}
-
-func (m *Manager) GetPaths() map[string]string {
- m.mu.Lock()
- paths := m.Paths
- m.mu.Unlock()
- return paths
-}
-
-func (m *Manager) GetStats() (*cgroups.Stats, error) {
- m.mu.Lock()
- defer m.mu.Unlock()
- stats := cgroups.NewStats()
- for name, path := range m.Paths {
- sys, err := subsystems.Get(name)
- if err == errSubsystemDoesNotExist || !cgroups.PathExists(path) {
- continue
- }
- if err := sys.GetStats(path, stats); err != nil {
- return nil, err
- }
- }
- return stats, nil
-}
-
-func (m *Manager) Set(container *configs.Config) error {
- // If Paths are set, then we are just joining cgroups paths
- // and there is no need to set any values.
- if m.Cgroups.Paths != nil {
- return nil
- }
-
- paths := m.GetPaths()
- for _, sys := range subsystems {
- path := paths[sys.Name()]
- if err := sys.Set(path, container.Cgroups); err != nil {
- if path == "" {
- // cgroup never applied
- return fmt.Errorf("cannot set limits on the %s cgroup, as the container has not joined it", sys.Name())
- }
- return err
- }
- }
-
- if m.Paths["cpu"] != "" {
- if err := CheckCpushares(m.Paths["cpu"], container.Cgroups.Resources.CpuShares); err != nil {
- return err
- }
- }
- return nil
-}
-
-// Freeze toggles the container's freezer cgroup depending on the state
-// provided
-func (m *Manager) Freeze(state configs.FreezerState) error {
- paths := m.GetPaths()
- dir := paths["freezer"]
- prevState := m.Cgroups.Resources.Freezer
- m.Cgroups.Resources.Freezer = state
- freezer, err := subsystems.Get("freezer")
- if err != nil {
- return err
- }
- err = freezer.Set(dir, m.Cgroups)
- if err != nil {
- m.Cgroups.Resources.Freezer = prevState
- return err
- }
- return nil
-}
-
-func (m *Manager) GetPids() ([]int, error) {
- paths := m.GetPaths()
- return cgroups.GetPids(paths["devices"])
-}
-
-func (m *Manager) GetAllPids() ([]int, error) {
- paths := m.GetPaths()
- return cgroups.GetAllPids(paths["devices"])
-}
-
-func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) {
- root, err := getCgroupRoot()
- if err != nil {
- return nil, err
- }
-
- if (c.Name != "" || c.Parent != "") && c.Path != "" {
- return nil, fmt.Errorf("cgroup: either Path or Name and Parent should be used")
- }
-
- // XXX: Do not remove this code. Path safety is important! -- cyphar
- cgPath := libcontainerUtils.CleanPath(c.Path)
- cgParent := libcontainerUtils.CleanPath(c.Parent)
- cgName := libcontainerUtils.CleanPath(c.Name)
-
- innerPath := cgPath
- if innerPath == "" {
- innerPath = filepath.Join(cgParent, cgName)
- }
-
- return &cgroupData{
- root: root,
- innerPath: innerPath,
- config: c,
- pid: pid,
- }, nil
-}
-
-func (raw *cgroupData) path(subsystem string) (string, error) {
- mnt, err := cgroups.FindCgroupMountpoint(subsystem)
- // If we didn't mount the subsystem, there is no point we make the path.
- if err != nil {
- return "", err
- }
-
- // If the cgroup name/path is absolute do not look relative to the cgroup of the init process.
- if filepath.IsAbs(raw.innerPath) {
- // Sometimes subsystems can be mounted together as 'cpu,cpuacct'.
- return filepath.Join(raw.root, filepath.Base(mnt), raw.innerPath), nil
- }
-
- // Use GetOwnCgroupPath instead of GetInitCgroupPath, because the creating
- // process could in container and shared pid namespace with host, and
- // /proc/1/cgroup could point to whole other world of cgroups.
- parentPath, err := cgroups.GetOwnCgroupPath(subsystem)
- if err != nil {
- return "", err
- }
-
- return filepath.Join(parentPath, raw.innerPath), nil
-}
-
-func (raw *cgroupData) join(subsystem string) (string, error) {
- path, err := raw.path(subsystem)
- if err != nil {
- return "", err
- }
- if err := os.MkdirAll(path, 0755); err != nil {
- return "", err
- }
- if err := cgroups.WriteCgroupProc(path, raw.pid); err != nil {
- return "", err
- }
- return path, nil
-}
-
-func writeFile(dir, file, data string) error {
- // Normally dir should not be empty, one case is that cgroup subsystem
- // is not mounted, we will get empty dir, and we want it fail here.
- if dir == "" {
- return fmt.Errorf("no such directory for %s", file)
- }
- if err := ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700); err != nil {
- return fmt.Errorf("failed to write %v to %v: %v", data, file, err)
- }
- return nil
-}
-
-func readFile(dir, file string) (string, error) {
- data, err := ioutil.ReadFile(filepath.Join(dir, file))
- return string(data), err
-}
-
-func removePath(p string, err error) error {
- if err != nil {
- return err
- }
- if p != "" {
- return os.RemoveAll(p)
- }
- return nil
-}
-
-func CheckCpushares(path string, c uint64) error {
- var cpuShares uint64
-
- if c == 0 {
- return nil
- }
-
- fd, err := os.Open(filepath.Join(path, "cpu.shares"))
- if err != nil {
- return err
- }
- defer fd.Close()
-
- _, err = fmt.Fscanf(fd, "%d", &cpuShares)
- if err != nil && err != io.EOF {
- return err
- }
-
- if c > cpuShares {
- return fmt.Errorf("The maximum allowed cpu-shares is %d", cpuShares)
- } else if c < cpuShares {
- return fmt.Errorf("The minimum allowed cpu-shares is %d", cpuShares)
- }
-
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go
deleted file mode 100644
index a142cb991..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go
+++ /dev/null
@@ -1,237 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "bufio"
- "fmt"
- "os"
- "path/filepath"
- "strconv"
- "strings"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type BlkioGroup struct {
-}
-
-func (s *BlkioGroup) Name() string {
- return "blkio"
-}
-
-func (s *BlkioGroup) Apply(d *cgroupData) error {
- _, err := d.join("blkio")
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
- return nil
-}
-
-func (s *BlkioGroup) Set(path string, cgroup *configs.Cgroup) error {
- if cgroup.Resources.BlkioWeight != 0 {
- if err := writeFile(path, "blkio.weight", strconv.FormatUint(uint64(cgroup.Resources.BlkioWeight), 10)); err != nil {
- return err
- }
- }
-
- if cgroup.Resources.BlkioLeafWeight != 0 {
- if err := writeFile(path, "blkio.leaf_weight", strconv.FormatUint(uint64(cgroup.Resources.BlkioLeafWeight), 10)); err != nil {
- return err
- }
- }
- for _, wd := range cgroup.Resources.BlkioWeightDevice {
- if err := writeFile(path, "blkio.weight_device", wd.WeightString()); err != nil {
- return err
- }
- if err := writeFile(path, "blkio.leaf_weight_device", wd.LeafWeightString()); err != nil {
- return err
- }
- }
- for _, td := range cgroup.Resources.BlkioThrottleReadBpsDevice {
- if err := writeFile(path, "blkio.throttle.read_bps_device", td.String()); err != nil {
- return err
- }
- }
- for _, td := range cgroup.Resources.BlkioThrottleWriteBpsDevice {
- if err := writeFile(path, "blkio.throttle.write_bps_device", td.String()); err != nil {
- return err
- }
- }
- for _, td := range cgroup.Resources.BlkioThrottleReadIOPSDevice {
- if err := writeFile(path, "blkio.throttle.read_iops_device", td.String()); err != nil {
- return err
- }
- }
- for _, td := range cgroup.Resources.BlkioThrottleWriteIOPSDevice {
- if err := writeFile(path, "blkio.throttle.write_iops_device", td.String()); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (s *BlkioGroup) Remove(d *cgroupData) error {
- return removePath(d.path("blkio"))
-}
-
-/*
-examples:
-
- blkio.sectors
- 8:0 6792
-
- blkio.io_service_bytes
- 8:0 Read 1282048
- 8:0 Write 2195456
- 8:0 Sync 2195456
- 8:0 Async 1282048
- 8:0 Total 3477504
- Total 3477504
-
- blkio.io_serviced
- 8:0 Read 124
- 8:0 Write 104
- 8:0 Sync 104
- 8:0 Async 124
- 8:0 Total 228
- Total 228
-
- blkio.io_queued
- 8:0 Read 0
- 8:0 Write 0
- 8:0 Sync 0
- 8:0 Async 0
- 8:0 Total 0
- Total 0
-*/
-
-func splitBlkioStatLine(r rune) bool {
- return r == ' ' || r == ':'
-}
-
-func getBlkioStat(path string) ([]cgroups.BlkioStatEntry, error) {
- var blkioStats []cgroups.BlkioStatEntry
- f, err := os.Open(path)
- if err != nil {
- if os.IsNotExist(err) {
- return blkioStats, nil
- }
- return nil, err
- }
- defer f.Close()
-
- sc := bufio.NewScanner(f)
- for sc.Scan() {
- // format: dev type amount
- fields := strings.FieldsFunc(sc.Text(), splitBlkioStatLine)
- if len(fields) < 3 {
- if len(fields) == 2 && fields[0] == "Total" {
- // skip total line
- continue
- } else {
- return nil, fmt.Errorf("Invalid line found while parsing %s: %s", path, sc.Text())
- }
- }
-
- v, err := strconv.ParseUint(fields[0], 10, 64)
- if err != nil {
- return nil, err
- }
- major := v
-
- v, err = strconv.ParseUint(fields[1], 10, 64)
- if err != nil {
- return nil, err
- }
- minor := v
-
- op := ""
- valueField := 2
- if len(fields) == 4 {
- op = fields[2]
- valueField = 3
- }
- v, err = strconv.ParseUint(fields[valueField], 10, 64)
- if err != nil {
- return nil, err
- }
- blkioStats = append(blkioStats, cgroups.BlkioStatEntry{Major: major, Minor: minor, Op: op, Value: v})
- }
-
- return blkioStats, nil
-}
-
-func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error {
- // Try to read CFQ stats available on all CFQ enabled kernels first
- if blkioStats, err := getBlkioStat(filepath.Join(path, "blkio.io_serviced_recursive")); err == nil && blkioStats != nil {
- return getCFQStats(path, stats)
- }
- return getStats(path, stats) // Use generic stats as fallback
-}
-
-func getCFQStats(path string, stats *cgroups.Stats) error {
- var blkioStats []cgroups.BlkioStatEntry
- var err error
-
- if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.sectors_recursive")); err != nil {
- return err
- }
- stats.BlkioStats.SectorsRecursive = blkioStats
-
- if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_service_bytes_recursive")); err != nil {
- return err
- }
- stats.BlkioStats.IoServiceBytesRecursive = blkioStats
-
- if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_serviced_recursive")); err != nil {
- return err
- }
- stats.BlkioStats.IoServicedRecursive = blkioStats
-
- if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_queued_recursive")); err != nil {
- return err
- }
- stats.BlkioStats.IoQueuedRecursive = blkioStats
-
- if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_service_time_recursive")); err != nil {
- return err
- }
- stats.BlkioStats.IoServiceTimeRecursive = blkioStats
-
- if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_wait_time_recursive")); err != nil {
- return err
- }
- stats.BlkioStats.IoWaitTimeRecursive = blkioStats
-
- if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_merged_recursive")); err != nil {
- return err
- }
- stats.BlkioStats.IoMergedRecursive = blkioStats
-
- if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.time_recursive")); err != nil {
- return err
- }
- stats.BlkioStats.IoTimeRecursive = blkioStats
-
- return nil
-}
-
-func getStats(path string, stats *cgroups.Stats) error {
- var blkioStats []cgroups.BlkioStatEntry
- var err error
-
- if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.throttle.io_service_bytes")); err != nil {
- return err
- }
- stats.BlkioStats.IoServiceBytesRecursive = blkioStats
-
- if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.throttle.io_serviced")); err != nil {
- return err
- }
- stats.BlkioStats.IoServicedRecursive = blkioStats
-
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go
deleted file mode 100644
index b712bd0b1..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go
+++ /dev/null
@@ -1,125 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "bufio"
- "os"
- "path/filepath"
- "strconv"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type CpuGroup struct {
-}
-
-func (s *CpuGroup) Name() string {
- return "cpu"
-}
-
-func (s *CpuGroup) Apply(d *cgroupData) error {
- // We always want to join the cpu group, to allow fair cpu scheduling
- // on a container basis
- path, err := d.path("cpu")
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
- return s.ApplyDir(path, d.config, d.pid)
-}
-
-func (s *CpuGroup) ApplyDir(path string, cgroup *configs.Cgroup, pid int) error {
- // This might happen if we have no cpu cgroup mounted.
- // Just do nothing and don't fail.
- if path == "" {
- return nil
- }
- if err := os.MkdirAll(path, 0755); err != nil {
- return err
- }
- // We should set the real-Time group scheduling settings before moving
- // in the process because if the process is already in SCHED_RR mode
- // and no RT bandwidth is set, adding it will fail.
- if err := s.SetRtSched(path, cgroup); err != nil {
- return err
- }
- // because we are not using d.join we need to place the pid into the procs file
- // unlike the other subsystems
- if err := cgroups.WriteCgroupProc(path, pid); err != nil {
- return err
- }
-
- return nil
-}
-
-func (s *CpuGroup) SetRtSched(path string, cgroup *configs.Cgroup) error {
- if cgroup.Resources.CpuRtPeriod != 0 {
- if err := writeFile(path, "cpu.rt_period_us", strconv.FormatUint(cgroup.Resources.CpuRtPeriod, 10)); err != nil {
- return err
- }
- }
- if cgroup.Resources.CpuRtRuntime != 0 {
- if err := writeFile(path, "cpu.rt_runtime_us", strconv.FormatInt(cgroup.Resources.CpuRtRuntime, 10)); err != nil {
- return err
- }
- }
- return nil
-}
-
-func (s *CpuGroup) Set(path string, cgroup *configs.Cgroup) error {
- if cgroup.Resources.CpuShares != 0 {
- if err := writeFile(path, "cpu.shares", strconv.FormatUint(cgroup.Resources.CpuShares, 10)); err != nil {
- return err
- }
- }
- if cgroup.Resources.CpuPeriod != 0 {
- if err := writeFile(path, "cpu.cfs_period_us", strconv.FormatUint(cgroup.Resources.CpuPeriod, 10)); err != nil {
- return err
- }
- }
- if cgroup.Resources.CpuQuota != 0 {
- if err := writeFile(path, "cpu.cfs_quota_us", strconv.FormatInt(cgroup.Resources.CpuQuota, 10)); err != nil {
- return err
- }
- }
- if err := s.SetRtSched(path, cgroup); err != nil {
- return err
- }
-
- return nil
-}
-
-func (s *CpuGroup) Remove(d *cgroupData) error {
- return removePath(d.path("cpu"))
-}
-
-func (s *CpuGroup) GetStats(path string, stats *cgroups.Stats) error {
- f, err := os.Open(filepath.Join(path, "cpu.stat"))
- if err != nil {
- if os.IsNotExist(err) {
- return nil
- }
- return err
- }
- defer f.Close()
-
- sc := bufio.NewScanner(f)
- for sc.Scan() {
- t, v, err := getCgroupParamKeyValue(sc.Text())
- if err != nil {
- return err
- }
- switch t {
- case "nr_periods":
- stats.CpuStats.ThrottlingData.Periods = v
-
- case "nr_throttled":
- stats.CpuStats.ThrottlingData.ThrottledPeriods = v
-
- case "throttled_time":
- stats.CpuStats.ThrottlingData.ThrottledTime = v
- }
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go
deleted file mode 100644
index 53afbaddf..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "fmt"
- "io/ioutil"
- "path/filepath"
- "strconv"
- "strings"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/system"
-)
-
-const (
- cgroupCpuacctStat = "cpuacct.stat"
- nanosecondsInSecond = 1000000000
-)
-
-var clockTicks = uint64(system.GetClockTicks())
-
-type CpuacctGroup struct {
-}
-
-func (s *CpuacctGroup) Name() string {
- return "cpuacct"
-}
-
-func (s *CpuacctGroup) Apply(d *cgroupData) error {
- // we just want to join this group even though we don't set anything
- if _, err := d.join("cpuacct"); err != nil && !cgroups.IsNotFound(err) {
- return err
- }
-
- return nil
-}
-
-func (s *CpuacctGroup) Set(path string, cgroup *configs.Cgroup) error {
- return nil
-}
-
-func (s *CpuacctGroup) Remove(d *cgroupData) error {
- return removePath(d.path("cpuacct"))
-}
-
-func (s *CpuacctGroup) GetStats(path string, stats *cgroups.Stats) error {
- userModeUsage, kernelModeUsage, err := getCpuUsageBreakdown(path)
- if err != nil {
- return err
- }
-
- totalUsage, err := getCgroupParamUint(path, "cpuacct.usage")
- if err != nil {
- return err
- }
-
- percpuUsage, err := getPercpuUsage(path)
- if err != nil {
- return err
- }
-
- stats.CpuStats.CpuUsage.TotalUsage = totalUsage
- stats.CpuStats.CpuUsage.PercpuUsage = percpuUsage
- stats.CpuStats.CpuUsage.UsageInUsermode = userModeUsage
- stats.CpuStats.CpuUsage.UsageInKernelmode = kernelModeUsage
- return nil
-}
-
-// Returns user and kernel usage breakdown in nanoseconds.
-func getCpuUsageBreakdown(path string) (uint64, uint64, error) {
- userModeUsage := uint64(0)
- kernelModeUsage := uint64(0)
- const (
- userField = "user"
- systemField = "system"
- )
-
- // Expected format:
- // user <usage in ticks>
- // system <usage in ticks>
- data, err := ioutil.ReadFile(filepath.Join(path, cgroupCpuacctStat))
- if err != nil {
- return 0, 0, err
- }
- fields := strings.Fields(string(data))
- if len(fields) != 4 {
- return 0, 0, fmt.Errorf("failure - %s is expected to have 4 fields", filepath.Join(path, cgroupCpuacctStat))
- }
- if fields[0] != userField {
- return 0, 0, fmt.Errorf("unexpected field %q in %q, expected %q", fields[0], cgroupCpuacctStat, userField)
- }
- if fields[2] != systemField {
- return 0, 0, fmt.Errorf("unexpected field %q in %q, expected %q", fields[2], cgroupCpuacctStat, systemField)
- }
- if userModeUsage, err = strconv.ParseUint(fields[1], 10, 64); err != nil {
- return 0, 0, err
- }
- if kernelModeUsage, err = strconv.ParseUint(fields[3], 10, 64); err != nil {
- return 0, 0, err
- }
-
- return (userModeUsage * nanosecondsInSecond) / clockTicks, (kernelModeUsage * nanosecondsInSecond) / clockTicks, nil
-}
-
-func getPercpuUsage(path string) ([]uint64, error) {
- percpuUsage := []uint64{}
- data, err := ioutil.ReadFile(filepath.Join(path, "cpuacct.usage_percpu"))
- if err != nil {
- return percpuUsage, err
- }
- for _, value := range strings.Fields(string(data)) {
- value, err := strconv.ParseUint(value, 10, 64)
- if err != nil {
- return percpuUsage, fmt.Errorf("Unable to convert param value to uint64: %s", err)
- }
- percpuUsage = append(percpuUsage, value)
- }
- return percpuUsage, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go
deleted file mode 100644
index 20c9eafac..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "bytes"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
- libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
-)
-
-type CpusetGroup struct {
-}
-
-func (s *CpusetGroup) Name() string {
- return "cpuset"
-}
-
-func (s *CpusetGroup) Apply(d *cgroupData) error {
- dir, err := d.path("cpuset")
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
- return s.ApplyDir(dir, d.config, d.pid)
-}
-
-func (s *CpusetGroup) Set(path string, cgroup *configs.Cgroup) error {
- if cgroup.Resources.CpusetCpus != "" {
- if err := writeFile(path, "cpuset.cpus", cgroup.Resources.CpusetCpus); err != nil {
- return err
- }
- }
- if cgroup.Resources.CpusetMems != "" {
- if err := writeFile(path, "cpuset.mems", cgroup.Resources.CpusetMems); err != nil {
- return err
- }
- }
- return nil
-}
-
-func (s *CpusetGroup) Remove(d *cgroupData) error {
- return removePath(d.path("cpuset"))
-}
-
-func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error {
- return nil
-}
-
-func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) error {
- // This might happen if we have no cpuset cgroup mounted.
- // Just do nothing and don't fail.
- if dir == "" {
- return nil
- }
- mountInfo, err := ioutil.ReadFile("/proc/self/mountinfo")
- if err != nil {
- return err
- }
- root := filepath.Dir(cgroups.GetClosestMountpointAncestor(dir, string(mountInfo)))
- // 'ensureParent' start with parent because we don't want to
- // explicitly inherit from parent, it could conflict with
- // 'cpuset.cpu_exclusive'.
- if err := s.ensureParent(filepath.Dir(dir), root); err != nil {
- return err
- }
- if err := os.MkdirAll(dir, 0755); err != nil {
- return err
- }
- // We didn't inherit cpuset configs from parent, but we have
- // to ensure cpuset configs are set before moving task into the
- // cgroup.
- // The logic is, if user specified cpuset configs, use these
- // specified configs, otherwise, inherit from parent. This makes
- // cpuset configs work correctly with 'cpuset.cpu_exclusive', and
- // keep backward compatbility.
- if err := s.ensureCpusAndMems(dir, cgroup); err != nil {
- return err
- }
-
- // because we are not using d.join we need to place the pid into the procs file
- // unlike the other subsystems
- if err := cgroups.WriteCgroupProc(dir, pid); err != nil {
- return err
- }
-
- return nil
-}
-
-func (s *CpusetGroup) getSubsystemSettings(parent string) (cpus []byte, mems []byte, err error) {
- if cpus, err = ioutil.ReadFile(filepath.Join(parent, "cpuset.cpus")); err != nil {
- return
- }
- if mems, err = ioutil.ReadFile(filepath.Join(parent, "cpuset.mems")); err != nil {
- return
- }
- return cpus, mems, nil
-}
-
-// ensureParent makes sure that the parent directory of current is created
-// and populated with the proper cpus and mems files copied from
-// it's parent.
-func (s *CpusetGroup) ensureParent(current, root string) error {
- parent := filepath.Dir(current)
- if libcontainerUtils.CleanPath(parent) == root {
- return nil
- }
- // Avoid infinite recursion.
- if parent == current {
- return fmt.Errorf("cpuset: cgroup parent path outside cgroup root")
- }
- if err := s.ensureParent(parent, root); err != nil {
- return err
- }
- if err := os.MkdirAll(current, 0755); err != nil {
- return err
- }
- return s.copyIfNeeded(current, parent)
-}
-
-// copyIfNeeded copies the cpuset.cpus and cpuset.mems from the parent
-// directory to the current directory if the file's contents are 0
-func (s *CpusetGroup) copyIfNeeded(current, parent string) error {
- var (
- err error
- currentCpus, currentMems []byte
- parentCpus, parentMems []byte
- )
-
- if currentCpus, currentMems, err = s.getSubsystemSettings(current); err != nil {
- return err
- }
- if parentCpus, parentMems, err = s.getSubsystemSettings(parent); err != nil {
- return err
- }
-
- if s.isEmpty(currentCpus) {
- if err := writeFile(current, "cpuset.cpus", string(parentCpus)); err != nil {
- return err
- }
- }
- if s.isEmpty(currentMems) {
- if err := writeFile(current, "cpuset.mems", string(parentMems)); err != nil {
- return err
- }
- }
- return nil
-}
-
-func (s *CpusetGroup) isEmpty(b []byte) bool {
- return len(bytes.Trim(b, "\n")) == 0
-}
-
-func (s *CpusetGroup) ensureCpusAndMems(path string, cgroup *configs.Cgroup) error {
- if err := s.Set(path, cgroup); err != nil {
- return err
- }
- return s.copyIfNeeded(path, filepath.Dir(path))
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go
deleted file mode 100644
index 0ac5b4ed7..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/system"
-)
-
-type DevicesGroup struct {
-}
-
-func (s *DevicesGroup) Name() string {
- return "devices"
-}
-
-func (s *DevicesGroup) Apply(d *cgroupData) error {
- _, err := d.join("devices")
- if err != nil {
- // We will return error even it's `not found` error, devices
- // cgroup is hard requirement for container's security.
- return err
- }
- return nil
-}
-
-func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) error {
- if system.RunningInUserNS() {
- return nil
- }
-
- devices := cgroup.Resources.Devices
- if len(devices) > 0 {
- for _, dev := range devices {
- file := "devices.deny"
- if dev.Allow {
- file = "devices.allow"
- }
- if err := writeFile(path, file, dev.CgroupString()); err != nil {
- return err
- }
- }
- return nil
- }
- if cgroup.Resources.AllowAllDevices != nil {
- if *cgroup.Resources.AllowAllDevices == false {
- if err := writeFile(path, "devices.deny", "a"); err != nil {
- return err
- }
-
- for _, dev := range cgroup.Resources.AllowedDevices {
- if err := writeFile(path, "devices.allow", dev.CgroupString()); err != nil {
- return err
- }
- }
- return nil
- }
-
- if err := writeFile(path, "devices.allow", "a"); err != nil {
- return err
- }
- }
-
- for _, dev := range cgroup.Resources.DeniedDevices {
- if err := writeFile(path, "devices.deny", dev.CgroupString()); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (s *DevicesGroup) Remove(d *cgroupData) error {
- return removePath(d.path("devices"))
-}
-
-func (s *DevicesGroup) GetStats(path string, stats *cgroups.Stats) error {
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go
deleted file mode 100644
index 4b19f8a97..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "fmt"
- "strings"
- "time"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type FreezerGroup struct {
-}
-
-func (s *FreezerGroup) Name() string {
- return "freezer"
-}
-
-func (s *FreezerGroup) Apply(d *cgroupData) error {
- _, err := d.join("freezer")
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
- return nil
-}
-
-func (s *FreezerGroup) Set(path string, cgroup *configs.Cgroup) error {
- switch cgroup.Resources.Freezer {
- case configs.Frozen, configs.Thawed:
- for {
- // In case this loop does not exit because it doesn't get the expected
- // state, let's write again this state, hoping it's going to be properly
- // set this time. Otherwise, this loop could run infinitely, waiting for
- // a state change that would never happen.
- if err := writeFile(path, "freezer.state", string(cgroup.Resources.Freezer)); err != nil {
- return err
- }
-
- state, err := readFile(path, "freezer.state")
- if err != nil {
- return err
- }
- if strings.TrimSpace(state) == string(cgroup.Resources.Freezer) {
- break
- }
-
- time.Sleep(1 * time.Millisecond)
- }
- case configs.Undefined:
- return nil
- default:
- return fmt.Errorf("Invalid argument '%s' to freezer.state", string(cgroup.Resources.Freezer))
- }
-
- return nil
-}
-
-func (s *FreezerGroup) Remove(d *cgroupData) error {
- return removePath(d.path("freezer"))
-}
-
-func (s *FreezerGroup) GetStats(path string, stats *cgroups.Stats) error {
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs_unsupported.go
deleted file mode 100644
index 3ef9e0315..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs_unsupported.go
+++ /dev/null
@@ -1,3 +0,0 @@
-// +build !linux
-
-package fs
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go
deleted file mode 100644
index 2f9727719..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "fmt"
- "strconv"
- "strings"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type HugetlbGroup struct {
-}
-
-func (s *HugetlbGroup) Name() string {
- return "hugetlb"
-}
-
-func (s *HugetlbGroup) Apply(d *cgroupData) error {
- _, err := d.join("hugetlb")
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
- return nil
-}
-
-func (s *HugetlbGroup) Set(path string, cgroup *configs.Cgroup) error {
- for _, hugetlb := range cgroup.Resources.HugetlbLimit {
- if err := writeFile(path, strings.Join([]string{"hugetlb", hugetlb.Pagesize, "limit_in_bytes"}, "."), strconv.FormatUint(hugetlb.Limit, 10)); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (s *HugetlbGroup) Remove(d *cgroupData) error {
- return removePath(d.path("hugetlb"))
-}
-
-func (s *HugetlbGroup) GetStats(path string, stats *cgroups.Stats) error {
- hugetlbStats := cgroups.HugetlbStats{}
- for _, pageSize := range HugePageSizes {
- usage := strings.Join([]string{"hugetlb", pageSize, "usage_in_bytes"}, ".")
- value, err := getCgroupParamUint(path, usage)
- if err != nil {
- return fmt.Errorf("failed to parse %s - %v", usage, err)
- }
- hugetlbStats.Usage = value
-
- maxUsage := strings.Join([]string{"hugetlb", pageSize, "max_usage_in_bytes"}, ".")
- value, err = getCgroupParamUint(path, maxUsage)
- if err != nil {
- return fmt.Errorf("failed to parse %s - %v", maxUsage, err)
- }
- hugetlbStats.MaxUsage = value
-
- failcnt := strings.Join([]string{"hugetlb", pageSize, "failcnt"}, ".")
- value, err = getCgroupParamUint(path, failcnt)
- if err != nil {
- return fmt.Errorf("failed to parse %s - %v", failcnt, err)
- }
- hugetlbStats.Failcnt = value
-
- stats.HugetlbStats[pageSize] = hugetlbStats
- }
-
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
deleted file mode 100644
index ad395a5d6..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
+++ /dev/null
@@ -1,313 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "bufio"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "strconv"
- "strings"
- "syscall" // only for Errno
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- cgroupKernelMemoryLimit = "memory.kmem.limit_in_bytes"
- cgroupMemorySwapLimit = "memory.memsw.limit_in_bytes"
- cgroupMemoryLimit = "memory.limit_in_bytes"
-)
-
-type MemoryGroup struct {
-}
-
-func (s *MemoryGroup) Name() string {
- return "memory"
-}
-
-func (s *MemoryGroup) Apply(d *cgroupData) (err error) {
- path, err := d.path("memory")
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- } else if path == "" {
- return nil
- }
- if memoryAssigned(d.config) {
- if _, err := os.Stat(path); os.IsNotExist(err) {
- if err := os.MkdirAll(path, 0755); err != nil {
- return err
- }
- // Only enable kernel memory accouting when this cgroup
- // is created by libcontainer, otherwise we might get
- // error when people use `cgroupsPath` to join an existed
- // cgroup whose kernel memory is not initialized.
- if err := EnableKernelMemoryAccounting(path); err != nil {
- return err
- }
- }
- }
- defer func() {
- if err != nil {
- os.RemoveAll(path)
- }
- }()
-
- // We need to join memory cgroup after set memory limits, because
- // kmem.limit_in_bytes can only be set when the cgroup is empty.
- _, err = d.join("memory")
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
- return nil
-}
-
-func EnableKernelMemoryAccounting(path string) error {
- // Check if kernel memory is enabled
- // We have to limit the kernel memory here as it won't be accounted at all
- // until a limit is set on the cgroup and limit cannot be set once the
- // cgroup has children, or if there are already tasks in the cgroup.
- for _, i := range []int64{1, -1} {
- if err := setKernelMemory(path, i); err != nil {
- return err
- }
- }
- return nil
-}
-
-func setKernelMemory(path string, kernelMemoryLimit int64) error {
- if path == "" {
- return fmt.Errorf("no such directory for %s", cgroupKernelMemoryLimit)
- }
- if !cgroups.PathExists(filepath.Join(path, cgroupKernelMemoryLimit)) {
- // kernel memory is not enabled on the system so we should do nothing
- return nil
- }
- if err := ioutil.WriteFile(filepath.Join(path, cgroupKernelMemoryLimit), []byte(strconv.FormatInt(kernelMemoryLimit, 10)), 0700); err != nil {
- // Check if the error number returned by the syscall is "EBUSY"
- // The EBUSY signal is returned on attempts to write to the
- // memory.kmem.limit_in_bytes file if the cgroup has children or
- // once tasks have been attached to the cgroup
- if pathErr, ok := err.(*os.PathError); ok {
- if errNo, ok := pathErr.Err.(syscall.Errno); ok {
- if errNo == unix.EBUSY {
- return fmt.Errorf("failed to set %s, because either tasks have already joined this cgroup or it has children", cgroupKernelMemoryLimit)
- }
- }
- }
- return fmt.Errorf("failed to write %v to %v: %v", kernelMemoryLimit, cgroupKernelMemoryLimit, err)
- }
- return nil
-}
-
-func setMemoryAndSwap(path string, cgroup *configs.Cgroup) error {
- // If the memory update is set to -1 we should also
- // set swap to -1, it means unlimited memory.
- if cgroup.Resources.Memory == -1 {
- // Only set swap if it's enabled in kernel
- if cgroups.PathExists(filepath.Join(path, cgroupMemorySwapLimit)) {
- cgroup.Resources.MemorySwap = -1
- }
- }
-
- // When memory and swap memory are both set, we need to handle the cases
- // for updating container.
- if cgroup.Resources.Memory != 0 && cgroup.Resources.MemorySwap != 0 {
- memoryUsage, err := getMemoryData(path, "")
- if err != nil {
- return err
- }
-
- // When update memory limit, we should adapt the write sequence
- // for memory and swap memory, so it won't fail because the new
- // value and the old value don't fit kernel's validation.
- if cgroup.Resources.MemorySwap == -1 || memoryUsage.Limit < uint64(cgroup.Resources.MemorySwap) {
- if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatInt(cgroup.Resources.MemorySwap, 10)); err != nil {
- return err
- }
- if err := writeFile(path, cgroupMemoryLimit, strconv.FormatInt(cgroup.Resources.Memory, 10)); err != nil {
- return err
- }
- } else {
- if err := writeFile(path, cgroupMemoryLimit, strconv.FormatInt(cgroup.Resources.Memory, 10)); err != nil {
- return err
- }
- if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatInt(cgroup.Resources.MemorySwap, 10)); err != nil {
- return err
- }
- }
- } else {
- if cgroup.Resources.Memory != 0 {
- if err := writeFile(path, cgroupMemoryLimit, strconv.FormatInt(cgroup.Resources.Memory, 10)); err != nil {
- return err
- }
- }
- if cgroup.Resources.MemorySwap != 0 {
- if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatInt(cgroup.Resources.MemorySwap, 10)); err != nil {
- return err
- }
- }
- }
-
- return nil
-}
-
-func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error {
- if err := setMemoryAndSwap(path, cgroup); err != nil {
- return err
- }
-
- if cgroup.Resources.KernelMemory != 0 {
- if err := setKernelMemory(path, cgroup.Resources.KernelMemory); err != nil {
- return err
- }
- }
-
- if cgroup.Resources.MemoryReservation != 0 {
- if err := writeFile(path, "memory.soft_limit_in_bytes", strconv.FormatInt(cgroup.Resources.MemoryReservation, 10)); err != nil {
- return err
- }
- }
-
- if cgroup.Resources.KernelMemoryTCP != 0 {
- if err := writeFile(path, "memory.kmem.tcp.limit_in_bytes", strconv.FormatInt(cgroup.Resources.KernelMemoryTCP, 10)); err != nil {
- return err
- }
- }
- if cgroup.Resources.OomKillDisable {
- if err := writeFile(path, "memory.oom_control", "1"); err != nil {
- return err
- }
- }
- if cgroup.Resources.MemorySwappiness == nil || int64(*cgroup.Resources.MemorySwappiness) == -1 {
- return nil
- } else if *cgroup.Resources.MemorySwappiness <= 100 {
- if err := writeFile(path, "memory.swappiness", strconv.FormatUint(*cgroup.Resources.MemorySwappiness, 10)); err != nil {
- return err
- }
- } else {
- return fmt.Errorf("invalid value:%d. valid memory swappiness range is 0-100", *cgroup.Resources.MemorySwappiness)
- }
-
- return nil
-}
-
-func (s *MemoryGroup) Remove(d *cgroupData) error {
- return removePath(d.path("memory"))
-}
-
-func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error {
- // Set stats from memory.stat.
- statsFile, err := os.Open(filepath.Join(path, "memory.stat"))
- if err != nil {
- if os.IsNotExist(err) {
- return nil
- }
- return err
- }
- defer statsFile.Close()
-
- sc := bufio.NewScanner(statsFile)
- for sc.Scan() {
- t, v, err := getCgroupParamKeyValue(sc.Text())
- if err != nil {
- return fmt.Errorf("failed to parse memory.stat (%q) - %v", sc.Text(), err)
- }
- stats.MemoryStats.Stats[t] = v
- }
- stats.MemoryStats.Cache = stats.MemoryStats.Stats["cache"]
-
- memoryUsage, err := getMemoryData(path, "")
- if err != nil {
- return err
- }
- stats.MemoryStats.Usage = memoryUsage
- swapUsage, err := getMemoryData(path, "memsw")
- if err != nil {
- return err
- }
- stats.MemoryStats.SwapUsage = swapUsage
- kernelUsage, err := getMemoryData(path, "kmem")
- if err != nil {
- return err
- }
- stats.MemoryStats.KernelUsage = kernelUsage
- kernelTCPUsage, err := getMemoryData(path, "kmem.tcp")
- if err != nil {
- return err
- }
- stats.MemoryStats.KernelTCPUsage = kernelTCPUsage
-
- useHierarchy := strings.Join([]string{"memory", "use_hierarchy"}, ".")
- value, err := getCgroupParamUint(path, useHierarchy)
- if err != nil {
- return err
- }
- if value == 1 {
- stats.MemoryStats.UseHierarchy = true
- }
- return nil
-}
-
-func memoryAssigned(cgroup *configs.Cgroup) bool {
- return cgroup.Resources.Memory != 0 ||
- cgroup.Resources.MemoryReservation != 0 ||
- cgroup.Resources.MemorySwap > 0 ||
- cgroup.Resources.KernelMemory > 0 ||
- cgroup.Resources.KernelMemoryTCP > 0 ||
- cgroup.Resources.OomKillDisable ||
- (cgroup.Resources.MemorySwappiness != nil && int64(*cgroup.Resources.MemorySwappiness) != -1)
-}
-
-func getMemoryData(path, name string) (cgroups.MemoryData, error) {
- memoryData := cgroups.MemoryData{}
-
- moduleName := "memory"
- if name != "" {
- moduleName = strings.Join([]string{"memory", name}, ".")
- }
- usage := strings.Join([]string{moduleName, "usage_in_bytes"}, ".")
- maxUsage := strings.Join([]string{moduleName, "max_usage_in_bytes"}, ".")
- failcnt := strings.Join([]string{moduleName, "failcnt"}, ".")
- limit := strings.Join([]string{moduleName, "limit_in_bytes"}, ".")
-
- value, err := getCgroupParamUint(path, usage)
- if err != nil {
- if moduleName != "memory" && os.IsNotExist(err) {
- return cgroups.MemoryData{}, nil
- }
- return cgroups.MemoryData{}, fmt.Errorf("failed to parse %s - %v", usage, err)
- }
- memoryData.Usage = value
- value, err = getCgroupParamUint(path, maxUsage)
- if err != nil {
- if moduleName != "memory" && os.IsNotExist(err) {
- return cgroups.MemoryData{}, nil
- }
- return cgroups.MemoryData{}, fmt.Errorf("failed to parse %s - %v", maxUsage, err)
- }
- memoryData.MaxUsage = value
- value, err = getCgroupParamUint(path, failcnt)
- if err != nil {
- if moduleName != "memory" && os.IsNotExist(err) {
- return cgroups.MemoryData{}, nil
- }
- return cgroups.MemoryData{}, fmt.Errorf("failed to parse %s - %v", failcnt, err)
- }
- memoryData.Failcnt = value
- value, err = getCgroupParamUint(path, limit)
- if err != nil {
- if moduleName != "memory" && os.IsNotExist(err) {
- return cgroups.MemoryData{}, nil
- }
- return cgroups.MemoryData{}, fmt.Errorf("failed to parse %s - %v", limit, err)
- }
- memoryData.Limit = value
-
- return memoryData, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go
deleted file mode 100644
index d8cf1d87c..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type NameGroup struct {
- GroupName string
- Join bool
-}
-
-func (s *NameGroup) Name() string {
- return s.GroupName
-}
-
-func (s *NameGroup) Apply(d *cgroupData) error {
- if s.Join {
- // ignore errors if the named cgroup does not exist
- d.join(s.GroupName)
- }
- return nil
-}
-
-func (s *NameGroup) Set(path string, cgroup *configs.Cgroup) error {
- return nil
-}
-
-func (s *NameGroup) Remove(d *cgroupData) error {
- if s.Join {
- removePath(d.path(s.GroupName))
- }
- return nil
-}
-
-func (s *NameGroup) GetStats(path string, stats *cgroups.Stats) error {
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go
deleted file mode 100644
index 8e74b645e..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "strconv"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type NetClsGroup struct {
-}
-
-func (s *NetClsGroup) Name() string {
- return "net_cls"
-}
-
-func (s *NetClsGroup) Apply(d *cgroupData) error {
- _, err := d.join("net_cls")
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
- return nil
-}
-
-func (s *NetClsGroup) Set(path string, cgroup *configs.Cgroup) error {
- if cgroup.Resources.NetClsClassid != 0 {
- if err := writeFile(path, "net_cls.classid", strconv.FormatUint(uint64(cgroup.Resources.NetClsClassid), 10)); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (s *NetClsGroup) Remove(d *cgroupData) error {
- return removePath(d.path("net_cls"))
-}
-
-func (s *NetClsGroup) GetStats(path string, stats *cgroups.Stats) error {
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio.go
deleted file mode 100644
index d0ab2af89..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type NetPrioGroup struct {
-}
-
-func (s *NetPrioGroup) Name() string {
- return "net_prio"
-}
-
-func (s *NetPrioGroup) Apply(d *cgroupData) error {
- _, err := d.join("net_prio")
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
- return nil
-}
-
-func (s *NetPrioGroup) Set(path string, cgroup *configs.Cgroup) error {
- for _, prioMap := range cgroup.Resources.NetPrioIfpriomap {
- if err := writeFile(path, "net_prio.ifpriomap", prioMap.CgroupString()); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (s *NetPrioGroup) Remove(d *cgroupData) error {
- return removePath(d.path("net_prio"))
-}
-
-func (s *NetPrioGroup) GetStats(path string, stats *cgroups.Stats) error {
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/perf_event.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/perf_event.go
deleted file mode 100644
index 5693676d3..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/perf_event.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type PerfEventGroup struct {
-}
-
-func (s *PerfEventGroup) Name() string {
- return "perf_event"
-}
-
-func (s *PerfEventGroup) Apply(d *cgroupData) error {
- // we just want to join this group even though we don't set anything
- if _, err := d.join("perf_event"); err != nil && !cgroups.IsNotFound(err) {
- return err
- }
- return nil
-}
-
-func (s *PerfEventGroup) Set(path string, cgroup *configs.Cgroup) error {
- return nil
-}
-
-func (s *PerfEventGroup) Remove(d *cgroupData) error {
- return removePath(d.path("perf_event"))
-}
-
-func (s *PerfEventGroup) GetStats(path string, stats *cgroups.Stats) error {
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids.go
deleted file mode 100644
index f1e372055..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "fmt"
- "path/filepath"
- "strconv"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type PidsGroup struct {
-}
-
-func (s *PidsGroup) Name() string {
- return "pids"
-}
-
-func (s *PidsGroup) Apply(d *cgroupData) error {
- _, err := d.join("pids")
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
- return nil
-}
-
-func (s *PidsGroup) Set(path string, cgroup *configs.Cgroup) error {
- if cgroup.Resources.PidsLimit != 0 {
- // "max" is the fallback value.
- limit := "max"
-
- if cgroup.Resources.PidsLimit > 0 {
- limit = strconv.FormatInt(cgroup.Resources.PidsLimit, 10)
- }
-
- if err := writeFile(path, "pids.max", limit); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (s *PidsGroup) Remove(d *cgroupData) error {
- return removePath(d.path("pids"))
-}
-
-func (s *PidsGroup) GetStats(path string, stats *cgroups.Stats) error {
- current, err := getCgroupParamUint(path, "pids.current")
- if err != nil {
- return fmt.Errorf("failed to parse pids.current - %s", err)
- }
-
- maxString, err := getCgroupParamString(path, "pids.max")
- if err != nil {
- return fmt.Errorf("failed to parse pids.max - %s", err)
- }
-
- // Default if pids.max == "max" is 0 -- which represents "no limit".
- var max uint64
- if maxString != "max" {
- max, err = parseUint(maxString, 10, 64)
- if err != nil {
- return fmt.Errorf("failed to parse pids.max - unable to parse %q as a uint from Cgroup file %q", maxString, filepath.Join(path, "pids.max"))
- }
- }
-
- stats.PidsStats.Current = current
- stats.PidsStats.Limit = max
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils.go
deleted file mode 100644
index 5ff0a1615..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// +build linux
-
-package fs
-
-import (
- "errors"
- "fmt"
- "io/ioutil"
- "path/filepath"
- "strconv"
- "strings"
-)
-
-var (
- ErrNotValidFormat = errors.New("line is not a valid key value format")
-)
-
-// Saturates negative values at zero and returns a uint64.
-// Due to kernel bugs, some of the memory cgroup stats can be negative.
-func parseUint(s string, base, bitSize int) (uint64, error) {
- value, err := strconv.ParseUint(s, base, bitSize)
- if err != nil {
- intValue, intErr := strconv.ParseInt(s, base, bitSize)
- // 1. Handle negative values greater than MinInt64 (and)
- // 2. Handle negative values lesser than MinInt64
- if intErr == nil && intValue < 0 {
- return 0, nil
- } else if intErr != nil && intErr.(*strconv.NumError).Err == strconv.ErrRange && intValue < 0 {
- return 0, nil
- }
-
- return value, err
- }
-
- return value, nil
-}
-
-// Parses a cgroup param and returns as name, value
-// i.e. "io_service_bytes 1234" will return as io_service_bytes, 1234
-func getCgroupParamKeyValue(t string) (string, uint64, error) {
- parts := strings.Fields(t)
- switch len(parts) {
- case 2:
- value, err := parseUint(parts[1], 10, 64)
- if err != nil {
- return "", 0, fmt.Errorf("unable to convert param value (%q) to uint64: %v", parts[1], err)
- }
-
- return parts[0], value, nil
- default:
- return "", 0, ErrNotValidFormat
- }
-}
-
-// Gets a single uint64 value from the specified cgroup file.
-func getCgroupParamUint(cgroupPath, cgroupFile string) (uint64, error) {
- fileName := filepath.Join(cgroupPath, cgroupFile)
- contents, err := ioutil.ReadFile(fileName)
- if err != nil {
- return 0, err
- }
-
- res, err := parseUint(strings.TrimSpace(string(contents)), 10, 64)
- if err != nil {
- return res, fmt.Errorf("unable to parse %q as a uint from Cgroup file %q", string(contents), fileName)
- }
- return res, nil
-}
-
-// Gets a string value from the specified cgroup file
-func getCgroupParamString(cgroupPath, cgroupFile string) (string, error) {
- contents, err := ioutil.ReadFile(filepath.Join(cgroupPath, cgroupFile))
- if err != nil {
- return "", err
- }
-
- return strings.TrimSpace(string(contents)), nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_nosystemd.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_nosystemd.go
deleted file mode 100644
index a65d8e443..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_nosystemd.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// +build !linux static_build
-
-package systemd
-
-import (
- "fmt"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type Manager struct {
- Cgroups *configs.Cgroup
- Paths map[string]string
-}
-
-func UseSystemd() bool {
- return false
-}
-
-func (m *Manager) Apply(pid int) error {
- return fmt.Errorf("Systemd not supported")
-}
-
-func (m *Manager) GetPids() ([]int, error) {
- return nil, fmt.Errorf("Systemd not supported")
-}
-
-func (m *Manager) GetAllPids() ([]int, error) {
- return nil, fmt.Errorf("Systemd not supported")
-}
-
-func (m *Manager) Destroy() error {
- return fmt.Errorf("Systemd not supported")
-}
-
-func (m *Manager) GetPaths() map[string]string {
- return nil
-}
-
-func (m *Manager) GetStats() (*cgroups.Stats, error) {
- return nil, fmt.Errorf("Systemd not supported")
-}
-
-func (m *Manager) Set(container *configs.Config) error {
- return fmt.Errorf("Systemd not supported")
-}
-
-func (m *Manager) Freeze(state configs.FreezerState) error {
- return fmt.Errorf("Systemd not supported")
-}
-
-func Freeze(c *configs.Cgroup, state configs.FreezerState) error {
- return fmt.Errorf("Systemd not supported")
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
deleted file mode 100644
index 45bd3acce..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
+++ /dev/null
@@ -1,563 +0,0 @@
-// +build linux,!static_build
-
-package systemd
-
-import (
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "strings"
- "sync"
- "time"
-
- systemdDbus "github.com/coreos/go-systemd/dbus"
- systemdUtil "github.com/coreos/go-systemd/util"
- "github.com/godbus/dbus"
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/cgroups/fs"
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type Manager struct {
- mu sync.Mutex
- Cgroups *configs.Cgroup
- Paths map[string]string
-}
-
-type subsystem interface {
- // Name returns the name of the subsystem.
- Name() string
- // Returns the stats, as 'stats', corresponding to the cgroup under 'path'.
- GetStats(path string, stats *cgroups.Stats) error
- // Set the cgroup represented by cgroup.
- Set(path string, cgroup *configs.Cgroup) error
-}
-
-var errSubsystemDoesNotExist = errors.New("cgroup: subsystem does not exist")
-
-type subsystemSet []subsystem
-
-func (s subsystemSet) Get(name string) (subsystem, error) {
- for _, ss := range s {
- if ss.Name() == name {
- return ss, nil
- }
- }
- return nil, errSubsystemDoesNotExist
-}
-
-var subsystems = subsystemSet{
- &fs.CpusetGroup{},
- &fs.DevicesGroup{},
- &fs.MemoryGroup{},
- &fs.CpuGroup{},
- &fs.CpuacctGroup{},
- &fs.PidsGroup{},
- &fs.BlkioGroup{},
- &fs.HugetlbGroup{},
- &fs.PerfEventGroup{},
- &fs.FreezerGroup{},
- &fs.NetPrioGroup{},
- &fs.NetClsGroup{},
- &fs.NameGroup{GroupName: "name=systemd"},
-}
-
-const (
- testScopeWait = 4
- testSliceWait = 4
-)
-
-var (
- connLock sync.Mutex
- theConn *systemdDbus.Conn
- hasStartTransientUnit bool
- hasStartTransientSliceUnit bool
- hasTransientDefaultDependencies bool
- hasDelegate bool
-)
-
-func newProp(name string, units interface{}) systemdDbus.Property {
- return systemdDbus.Property{
- Name: name,
- Value: dbus.MakeVariant(units),
- }
-}
-
-func UseSystemd() bool {
- if !systemdUtil.IsRunningSystemd() {
- return false
- }
-
- connLock.Lock()
- defer connLock.Unlock()
-
- if theConn == nil {
- var err error
- theConn, err = systemdDbus.New()
- if err != nil {
- return false
- }
-
- // Assume we have StartTransientUnit
- hasStartTransientUnit = true
-
- // But if we get UnknownMethod error we don't
- if _, err := theConn.StartTransientUnit("test.scope", "invalid", nil, nil); err != nil {
- if dbusError, ok := err.(dbus.Error); ok {
- if dbusError.Name == "org.freedesktop.DBus.Error.UnknownMethod" {
- hasStartTransientUnit = false
- return hasStartTransientUnit
- }
- }
- }
-
- // Ensure the scope name we use doesn't exist. Use the Pid to
- // avoid collisions between multiple libcontainer users on a
- // single host.
- scope := fmt.Sprintf("libcontainer-%d-systemd-test-default-dependencies.scope", os.Getpid())
- testScopeExists := true
- for i := 0; i <= testScopeWait; i++ {
- if _, err := theConn.StopUnit(scope, "replace", nil); err != nil {
- if dbusError, ok := err.(dbus.Error); ok {
- if strings.Contains(dbusError.Name, "org.freedesktop.systemd1.NoSuchUnit") {
- testScopeExists = false
- break
- }
- }
- }
- time.Sleep(time.Millisecond)
- }
-
- // Bail out if we can't kill this scope without testing for DefaultDependencies
- if testScopeExists {
- return hasStartTransientUnit
- }
-
- // Assume StartTransientUnit on a scope allows DefaultDependencies
- hasTransientDefaultDependencies = true
- ddf := newProp("DefaultDependencies", false)
- if _, err := theConn.StartTransientUnit(scope, "replace", []systemdDbus.Property{ddf}, nil); err != nil {
- if dbusError, ok := err.(dbus.Error); ok {
- if strings.Contains(dbusError.Name, "org.freedesktop.DBus.Error.PropertyReadOnly") {
- hasTransientDefaultDependencies = false
- }
- }
- }
-
- // Not critical because of the stop unit logic above.
- theConn.StopUnit(scope, "replace", nil)
-
- // Assume StartTransientUnit on a scope allows Delegate
- hasDelegate = true
- dl := newProp("Delegate", true)
- if _, err := theConn.StartTransientUnit(scope, "replace", []systemdDbus.Property{dl}, nil); err != nil {
- if dbusError, ok := err.(dbus.Error); ok {
- if strings.Contains(dbusError.Name, "org.freedesktop.DBus.Error.PropertyReadOnly") {
- hasDelegate = false
- }
- }
- }
-
- // Assume we have the ability to start a transient unit as a slice
- // This was broken until systemd v229, but has been back-ported on RHEL environments >= 219
- // For details, see: https://bugzilla.redhat.com/show_bug.cgi?id=1370299
- hasStartTransientSliceUnit = true
-
- // To ensure simple clean-up, we create a slice off the root with no hierarchy
- slice := fmt.Sprintf("libcontainer_%d_systemd_test_default.slice", os.Getpid())
- if _, err := theConn.StartTransientUnit(slice, "replace", nil, nil); err != nil {
- if _, ok := err.(dbus.Error); ok {
- hasStartTransientSliceUnit = false
- }
- }
-
- for i := 0; i <= testSliceWait; i++ {
- if _, err := theConn.StopUnit(slice, "replace", nil); err != nil {
- if dbusError, ok := err.(dbus.Error); ok {
- if strings.Contains(dbusError.Name, "org.freedesktop.systemd1.NoSuchUnit") {
- hasStartTransientSliceUnit = false
- break
- }
- }
- } else {
- break
- }
- time.Sleep(time.Millisecond)
- }
-
- // Not critical because of the stop unit logic above.
- theConn.StopUnit(scope, "replace", nil)
- theConn.StopUnit(slice, "replace", nil)
- }
- return hasStartTransientUnit
-}
-
-func (m *Manager) Apply(pid int) error {
- var (
- c = m.Cgroups
- unitName = getUnitName(c)
- slice = "system.slice"
- properties []systemdDbus.Property
- )
-
- if c.Paths != nil {
- paths := make(map[string]string)
- for name, path := range c.Paths {
- _, err := getSubsystemPath(m.Cgroups, name)
- if err != nil {
- // Don't fail if a cgroup hierarchy was not found, just skip this subsystem
- if cgroups.IsNotFound(err) {
- continue
- }
- return err
- }
- paths[name] = path
- }
- m.Paths = paths
- return cgroups.EnterPid(m.Paths, pid)
- }
-
- if c.Parent != "" {
- slice = c.Parent
- }
-
- properties = append(properties, systemdDbus.PropDescription("libcontainer container "+c.Name))
-
- // if we create a slice, the parent is defined via a Wants=
- if strings.HasSuffix(unitName, ".slice") {
- // This was broken until systemd v229, but has been back-ported on RHEL environments >= 219
- if !hasStartTransientSliceUnit {
- return fmt.Errorf("systemd version does not support ability to start a slice as transient unit")
- }
- properties = append(properties, systemdDbus.PropWants(slice))
- } else {
- // otherwise, we use Slice=
- properties = append(properties, systemdDbus.PropSlice(slice))
- }
-
- // only add pid if its valid, -1 is used w/ general slice creation.
- if pid != -1 {
- properties = append(properties, newProp("PIDs", []uint32{uint32(pid)}))
- }
-
- if hasDelegate {
- // This is only supported on systemd versions 218 and above.
- properties = append(properties, newProp("Delegate", true))
- }
-
- // Always enable accounting, this gets us the same behaviour as the fs implementation,
- // plus the kernel has some problems with joining the memory cgroup at a later time.
- properties = append(properties,
- newProp("MemoryAccounting", true),
- newProp("CPUAccounting", true),
- newProp("BlockIOAccounting", true))
-
- if hasTransientDefaultDependencies {
- properties = append(properties,
- newProp("DefaultDependencies", false))
- }
-
- if c.Resources.Memory != 0 {
- properties = append(properties,
- newProp("MemoryLimit", uint64(c.Resources.Memory)))
- }
-
- if c.Resources.CpuShares != 0 {
- properties = append(properties,
- newProp("CPUShares", c.Resources.CpuShares))
- }
-
- // cpu.cfs_quota_us and cpu.cfs_period_us are controlled by systemd.
- if c.Resources.CpuQuota != 0 && c.Resources.CpuPeriod != 0 {
- cpuQuotaPerSecUSec := uint64(c.Resources.CpuQuota*1000000) / c.Resources.CpuPeriod
- // systemd converts CPUQuotaPerSecUSec (microseconds per CPU second) to CPUQuota
- // (integer percentage of CPU) internally. This means that if a fractional percent of
- // CPU is indicated by Resources.CpuQuota, we need to round up to the nearest
- // 10ms (1% of a second) such that child cgroups can set the cpu.cfs_quota_us they expect.
- if cpuQuotaPerSecUSec%10000 != 0 {
- cpuQuotaPerSecUSec = ((cpuQuotaPerSecUSec / 10000) + 1) * 10000
- }
- properties = append(properties,
- newProp("CPUQuotaPerSecUSec", cpuQuotaPerSecUSec))
- }
-
- if c.Resources.BlkioWeight != 0 {
- properties = append(properties,
- newProp("BlockIOWeight", uint64(c.Resources.BlkioWeight)))
- }
-
- // We have to set kernel memory here, as we can't change it once
- // processes have been attached to the cgroup.
- if c.Resources.KernelMemory != 0 {
- if err := setKernelMemory(c); err != nil {
- return err
- }
- }
-
- statusChan := make(chan string)
- if _, err := theConn.StartTransientUnit(unitName, "replace", properties, statusChan); err != nil && !isUnitExists(err) {
- return err
- }
-
- <-statusChan
-
- if err := joinCgroups(c, pid); err != nil {
- return err
- }
-
- paths := make(map[string]string)
- for _, s := range subsystems {
- subsystemPath, err := getSubsystemPath(m.Cgroups, s.Name())
- if err != nil {
- // Don't fail if a cgroup hierarchy was not found, just skip this subsystem
- if cgroups.IsNotFound(err) {
- continue
- }
- return err
- }
- paths[s.Name()] = subsystemPath
- }
- m.Paths = paths
- return nil
-}
-
-func (m *Manager) Destroy() error {
- if m.Cgroups.Paths != nil {
- return nil
- }
- m.mu.Lock()
- defer m.mu.Unlock()
- theConn.StopUnit(getUnitName(m.Cgroups), "replace", nil)
- if err := cgroups.RemovePaths(m.Paths); err != nil {
- return err
- }
- m.Paths = make(map[string]string)
- return nil
-}
-
-func (m *Manager) GetPaths() map[string]string {
- m.mu.Lock()
- paths := m.Paths
- m.mu.Unlock()
- return paths
-}
-
-func join(c *configs.Cgroup, subsystem string, pid int) (string, error) {
- path, err := getSubsystemPath(c, subsystem)
- if err != nil {
- return "", err
- }
- if err := os.MkdirAll(path, 0755); err != nil {
- return "", err
- }
- if err := cgroups.WriteCgroupProc(path, pid); err != nil {
- return "", err
- }
- return path, nil
-}
-
-func joinCgroups(c *configs.Cgroup, pid int) error {
- for _, sys := range subsystems {
- name := sys.Name()
- switch name {
- case "name=systemd":
- // let systemd handle this
- case "cpuset":
- path, err := getSubsystemPath(c, name)
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
- s := &fs.CpusetGroup{}
- if err := s.ApplyDir(path, c, pid); err != nil {
- return err
- }
- default:
- _, err := join(c, name, pid)
- if err != nil {
- // Even if it's `not found` error, we'll return err
- // because devices cgroup is hard requirement for
- // container security.
- if name == "devices" {
- return err
- }
- // For other subsystems, omit the `not found` error
- // because they are optional.
- if !cgroups.IsNotFound(err) {
- return err
- }
- }
- }
- }
-
- return nil
-}
-
-// systemd represents slice hierarchy using `-`, so we need to follow suit when
-// generating the path of slice. Essentially, test-a-b.slice becomes
-// test.slice/test-a.slice/test-a-b.slice.
-func ExpandSlice(slice string) (string, error) {
- suffix := ".slice"
- // Name has to end with ".slice", but can't be just ".slice".
- if len(slice) < len(suffix) || !strings.HasSuffix(slice, suffix) {
- return "", fmt.Errorf("invalid slice name: %s", slice)
- }
-
- // Path-separators are not allowed.
- if strings.Contains(slice, "/") {
- return "", fmt.Errorf("invalid slice name: %s", slice)
- }
-
- var path, prefix string
- sliceName := strings.TrimSuffix(slice, suffix)
- // if input was -.slice, we should just return root now
- if sliceName == "-" {
- return "/", nil
- }
- for _, component := range strings.Split(sliceName, "-") {
- // test--a.slice isn't permitted, nor is -test.slice.
- if component == "" {
- return "", fmt.Errorf("invalid slice name: %s", slice)
- }
-
- // Append the component to the path and to the prefix.
- path += prefix + component + suffix + "/"
- prefix += component + "-"
- }
-
- return path, nil
-}
-
-func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
- mountpoint, err := cgroups.FindCgroupMountpoint(subsystem)
- if err != nil {
- return "", err
- }
-
- initPath, err := cgroups.GetInitCgroup(subsystem)
- if err != nil {
- return "", err
- }
- // if pid 1 is systemd 226 or later, it will be in init.scope, not the root
- initPath = strings.TrimSuffix(filepath.Clean(initPath), "init.scope")
-
- slice := "system.slice"
- if c.Parent != "" {
- slice = c.Parent
- }
-
- slice, err = ExpandSlice(slice)
- if err != nil {
- return "", err
- }
-
- return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil
-}
-
-func (m *Manager) Freeze(state configs.FreezerState) error {
- path, err := getSubsystemPath(m.Cgroups, "freezer")
- if err != nil {
- return err
- }
- prevState := m.Cgroups.Resources.Freezer
- m.Cgroups.Resources.Freezer = state
- freezer, err := subsystems.Get("freezer")
- if err != nil {
- return err
- }
- err = freezer.Set(path, m.Cgroups)
- if err != nil {
- m.Cgroups.Resources.Freezer = prevState
- return err
- }
- return nil
-}
-
-func (m *Manager) GetPids() ([]int, error) {
- path, err := getSubsystemPath(m.Cgroups, "devices")
- if err != nil {
- return nil, err
- }
- return cgroups.GetPids(path)
-}
-
-func (m *Manager) GetAllPids() ([]int, error) {
- path, err := getSubsystemPath(m.Cgroups, "devices")
- if err != nil {
- return nil, err
- }
- return cgroups.GetAllPids(path)
-}
-
-func (m *Manager) GetStats() (*cgroups.Stats, error) {
- m.mu.Lock()
- defer m.mu.Unlock()
- stats := cgroups.NewStats()
- for name, path := range m.Paths {
- sys, err := subsystems.Get(name)
- if err == errSubsystemDoesNotExist || !cgroups.PathExists(path) {
- continue
- }
- if err := sys.GetStats(path, stats); err != nil {
- return nil, err
- }
- }
-
- return stats, nil
-}
-
-func (m *Manager) Set(container *configs.Config) error {
- // If Paths are set, then we are just joining cgroups paths
- // and there is no need to set any values.
- if m.Cgroups.Paths != nil {
- return nil
- }
- for _, sys := range subsystems {
- // Get the subsystem path, but don't error out for not found cgroups.
- path, err := getSubsystemPath(container.Cgroups, sys.Name())
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
-
- if err := sys.Set(path, container.Cgroups); err != nil {
- return err
- }
- }
-
- if m.Paths["cpu"] != "" {
- if err := fs.CheckCpushares(m.Paths["cpu"], container.Cgroups.Resources.CpuShares); err != nil {
- return err
- }
- }
- return nil
-}
-
-func getUnitName(c *configs.Cgroup) string {
- // by default, we create a scope unless the user explicitly asks for a slice.
- if !strings.HasSuffix(c.Name, ".slice") {
- return fmt.Sprintf("%s-%s.scope", c.ScopePrefix, c.Name)
- }
- return c.Name
-}
-
-func setKernelMemory(c *configs.Cgroup) error {
- path, err := getSubsystemPath(c, "memory")
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
-
- if err := os.MkdirAll(path, 0755); err != nil {
- return err
- }
- return fs.EnableKernelMemoryAccounting(path)
-}
-
-// isUnitExists returns true if the error is that a systemd unit already exists.
-func isUnitExists(err error) bool {
- if err != nil {
- if dbusError, ok := err.(dbus.Error); ok {
- return strings.Contains(dbusError.Name, "org.freedesktop.systemd1.UnitExists")
- }
- }
- return false
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/rootless.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/rootless.go
deleted file mode 100644
index 7a9f33b71..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/rootless.go
+++ /dev/null
@@ -1,117 +0,0 @@
-package validate
-
-import (
- "fmt"
- "os"
- "reflect"
- "strings"
-
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-var (
- geteuid = os.Geteuid
- getegid = os.Getegid
-)
-
-func (v *ConfigValidator) rootless(config *configs.Config) error {
- if err := rootlessMappings(config); err != nil {
- return err
- }
- if err := rootlessMount(config); err != nil {
- return err
- }
-
- // XXX: We currently can't verify the user config at all, because
- // configs.Config doesn't store the user-related configs. So this
- // has to be verified by setupUser() in init_linux.go.
-
- return nil
-}
-
-func hasIDMapping(id int, mappings []configs.IDMap) bool {
- for _, m := range mappings {
- if id >= m.ContainerID && id < m.ContainerID+m.Size {
- return true
- }
- }
- return false
-}
-
-func rootlessMappings(config *configs.Config) error {
- if euid := geteuid(); euid != 0 {
- if !config.Namespaces.Contains(configs.NEWUSER) {
- return fmt.Errorf("rootless containers require user namespaces")
- }
- }
-
- if len(config.UidMappings) == 0 {
- return fmt.Errorf("rootless containers requires at least one UID mapping")
- }
- if len(config.GidMappings) == 0 {
- return fmt.Errorf("rootless containers requires at least one UID mapping")
- }
-
- return nil
-}
-
-// cgroup verifies that the user isn't trying to set any cgroup limits or paths.
-func rootlessCgroup(config *configs.Config) error {
- // Nothing set at all.
- if config.Cgroups == nil || config.Cgroups.Resources == nil {
- return nil
- }
-
- // Used for comparing to the zero value.
- left := reflect.ValueOf(*config.Cgroups.Resources)
- right := reflect.Zero(left.Type())
-
- // This is all we need to do, since specconv won't add cgroup options in
- // rootless mode.
- if !reflect.DeepEqual(left.Interface(), right.Interface()) {
- return fmt.Errorf("cannot specify resource limits in rootless container")
- }
-
- return nil
-}
-
-// mount verifies that the user isn't trying to set up any mounts they don't have
-// the rights to do. In addition, it makes sure that no mount has a `uid=` or
-// `gid=` option that doesn't resolve to root.
-func rootlessMount(config *configs.Config) error {
- // XXX: We could whitelist allowed devices at this point, but I'm not
- // convinced that's a good idea. The kernel is the best arbiter of
- // access control.
-
- for _, mount := range config.Mounts {
- // Check that the options list doesn't contain any uid= or gid= entries
- // that don't resolve to root.
- for _, opt := range strings.Split(mount.Data, ",") {
- if strings.HasPrefix(opt, "uid=") {
- var uid int
- n, err := fmt.Sscanf(opt, "uid=%d", &uid)
- if n != 1 || err != nil {
- // Ignore unknown mount options.
- continue
- }
- if !hasIDMapping(uid, config.UidMappings) {
- return fmt.Errorf("cannot specify uid= mount options for unmapped uid in rootless containers")
- }
- }
-
- if strings.HasPrefix(opt, "gid=") {
- var gid int
- n, err := fmt.Sscanf(opt, "gid=%d", &gid)
- if n != 1 || err != nil {
- // Ignore unknown mount options.
- continue
- }
- if !hasIDMapping(gid, config.GidMappings) {
- return fmt.Errorf("cannot specify gid= mount options for unmapped gid in rootless containers")
- }
- }
- }
- }
-
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go
deleted file mode 100644
index cbbba9a03..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go
+++ /dev/null
@@ -1,212 +0,0 @@
-package validate
-
-import (
- "fmt"
- "os"
- "path/filepath"
- "strings"
-
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/intelrdt"
- selinux "github.com/opencontainers/selinux/go-selinux"
-)
-
-type Validator interface {
- Validate(*configs.Config) error
-}
-
-func New() Validator {
- return &ConfigValidator{}
-}
-
-type ConfigValidator struct {
-}
-
-func (v *ConfigValidator) Validate(config *configs.Config) error {
- if err := v.rootfs(config); err != nil {
- return err
- }
- if err := v.network(config); err != nil {
- return err
- }
- if err := v.hostname(config); err != nil {
- return err
- }
- if err := v.security(config); err != nil {
- return err
- }
- if err := v.usernamespace(config); err != nil {
- return err
- }
- if err := v.sysctl(config); err != nil {
- return err
- }
- if err := v.intelrdt(config); err != nil {
- return err
- }
- if config.Rootless {
- if err := v.rootless(config); err != nil {
- return err
- }
- }
- return nil
-}
-
-// rootfs validates if the rootfs is an absolute path and is not a symlink
-// to the container's root filesystem.
-func (v *ConfigValidator) rootfs(config *configs.Config) error {
- if _, err := os.Stat(config.Rootfs); err != nil {
- if os.IsNotExist(err) {
- return fmt.Errorf("rootfs (%s) does not exist", config.Rootfs)
- }
- return err
- }
- cleaned, err := filepath.Abs(config.Rootfs)
- if err != nil {
- return err
- }
- if cleaned, err = filepath.EvalSymlinks(cleaned); err != nil {
- return err
- }
- if filepath.Clean(config.Rootfs) != cleaned {
- return fmt.Errorf("%s is not an absolute path or is a symlink", config.Rootfs)
- }
- return nil
-}
-
-func (v *ConfigValidator) network(config *configs.Config) error {
- if !config.Namespaces.Contains(configs.NEWNET) {
- if len(config.Networks) > 0 || len(config.Routes) > 0 {
- return fmt.Errorf("unable to apply network settings without a private NET namespace")
- }
- }
- return nil
-}
-
-func (v *ConfigValidator) hostname(config *configs.Config) error {
- if config.Hostname != "" && !config.Namespaces.Contains(configs.NEWUTS) {
- return fmt.Errorf("unable to set hostname without a private UTS namespace")
- }
- return nil
-}
-
-func (v *ConfigValidator) security(config *configs.Config) error {
- // restrict sys without mount namespace
- if (len(config.MaskPaths) > 0 || len(config.ReadonlyPaths) > 0) &&
- !config.Namespaces.Contains(configs.NEWNS) {
- return fmt.Errorf("unable to restrict sys entries without a private MNT namespace")
- }
- if config.ProcessLabel != "" && !selinux.GetEnabled() {
- return fmt.Errorf("selinux label is specified in config, but selinux is disabled or not supported")
- }
-
- return nil
-}
-
-func (v *ConfigValidator) usernamespace(config *configs.Config) error {
- if config.Namespaces.Contains(configs.NEWUSER) {
- if _, err := os.Stat("/proc/self/ns/user"); os.IsNotExist(err) {
- return fmt.Errorf("USER namespaces aren't enabled in the kernel")
- }
- } else {
- if config.UidMappings != nil || config.GidMappings != nil {
- return fmt.Errorf("User namespace mappings specified, but USER namespace isn't enabled in the config")
- }
- }
- return nil
-}
-
-// sysctl validates that the specified sysctl keys are valid or not.
-// /proc/sys isn't completely namespaced and depending on which namespaces
-// are specified, a subset of sysctls are permitted.
-func (v *ConfigValidator) sysctl(config *configs.Config) error {
- validSysctlMap := map[string]bool{
- "kernel.msgmax": true,
- "kernel.msgmnb": true,
- "kernel.msgmni": true,
- "kernel.sem": true,
- "kernel.shmall": true,
- "kernel.shmmax": true,
- "kernel.shmmni": true,
- "kernel.shm_rmid_forced": true,
- }
-
- for s := range config.Sysctl {
- if validSysctlMap[s] || strings.HasPrefix(s, "fs.mqueue.") {
- if config.Namespaces.Contains(configs.NEWIPC) {
- continue
- } else {
- return fmt.Errorf("sysctl %q is not allowed in the hosts ipc namespace", s)
- }
- }
- if strings.HasPrefix(s, "net.") {
- if config.Namespaces.Contains(configs.NEWNET) {
- if path := config.Namespaces.PathOf(configs.NEWNET); path != "" {
- if err := checkHostNs(s, path); err != nil {
- return err
- }
- }
- continue
- } else {
- return fmt.Errorf("sysctl %q is not allowed in the hosts network namespace", s)
- }
- }
- return fmt.Errorf("sysctl %q is not in a separate kernel namespace", s)
- }
-
- return nil
-}
-
-func (v *ConfigValidator) intelrdt(config *configs.Config) error {
- if config.IntelRdt != nil {
- if !intelrdt.IsEnabled() {
- return fmt.Errorf("intelRdt is specified in config, but Intel RDT feature is not supported or enabled")
- }
- if config.IntelRdt.L3CacheSchema == "" {
- return fmt.Errorf("intelRdt is specified in config, but intelRdt.l3CacheSchema is empty")
- }
- }
-
- return nil
-}
-
-func isSymbolicLink(path string) (bool, error) {
- fi, err := os.Lstat(path)
- if err != nil {
- return false, err
- }
-
- return fi.Mode()&os.ModeSymlink == os.ModeSymlink, nil
-}
-
-// checkHostNs checks whether network sysctl is used in host namespace.
-func checkHostNs(sysctlConfig string, path string) error {
- var currentProcessNetns = "/proc/self/ns/net"
- // readlink on the current processes network namespace
- destOfCurrentProcess, err := os.Readlink(currentProcessNetns)
- if err != nil {
- return fmt.Errorf("read soft link %q error", currentProcessNetns)
- }
-
- // First check if the provided path is a symbolic link
- symLink, err := isSymbolicLink(path)
- if err != nil {
- return fmt.Errorf("could not check that %q is a symlink: %v", path, err)
- }
-
- if symLink == false {
- // The provided namespace is not a symbolic link,
- // it is not the host namespace.
- return nil
- }
-
- // readlink on the path provided in the struct
- destOfContainer, err := os.Readlink(path)
- if err != nil {
- return fmt.Errorf("read soft link %q error", path)
- }
- if destOfContainer == destOfCurrentProcess {
- return fmt.Errorf("sysctl %q is not allowed in the hosts network namespace", sysctlConfig)
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/console_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/console_linux.go
deleted file mode 100644
index 9997e93ed..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/console_linux.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package libcontainer
-
-import (
- "os"
-
- "golang.org/x/sys/unix"
-)
-
-// mount initializes the console inside the rootfs mounting with the specified mount label
-// and applying the correct ownership of the console.
-func mountConsole(slavePath string) error {
- oldMask := unix.Umask(0000)
- defer unix.Umask(oldMask)
- f, err := os.Create("/dev/console")
- if err != nil && !os.IsExist(err) {
- return err
- }
- if f != nil {
- f.Close()
- }
- return unix.Mount(slavePath, "/dev/console", "bind", unix.MS_BIND, "")
-}
-
-// dupStdio opens the slavePath for the console and dups the fds to the current
-// processes stdio, fd 0,1,2.
-func dupStdio(slavePath string) error {
- fd, err := unix.Open(slavePath, unix.O_RDWR, 0)
- if err != nil {
- return &os.PathError{
- Op: "open",
- Path: slavePath,
- Err: err,
- }
- }
- for _, i := range []int{0, 1, 2} {
- if err := unix.Dup3(fd, i, 0); err != nil {
- return err
- }
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/container.go b/vendor/github.com/opencontainers/runc/libcontainer/container.go
deleted file mode 100644
index 2e31b4d4f..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/container.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Package libcontainer provides a native Go implementation for creating containers
-// with namespaces, cgroups, capabilities, and filesystem access controls.
-// It allows you to manage the lifecycle of the container performing additional operations
-// after the container is created.
-package libcontainer
-
-import (
- "os"
- "time"
-
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-// Status is the status of a container.
-type Status int
-
-const (
- // Created is the status that denotes the container exists but has not been run yet.
- Created Status = iota
- // Running is the status that denotes the container exists and is running.
- Running
- // Pausing is the status that denotes the container exists, it is in the process of being paused.
- Pausing
- // Paused is the status that denotes the container exists, but all its processes are paused.
- Paused
- // Stopped is the status that denotes the container does not have a created or running process.
- Stopped
-)
-
-func (s Status) String() string {
- switch s {
- case Created:
- return "created"
- case Running:
- return "running"
- case Pausing:
- return "pausing"
- case Paused:
- return "paused"
- case Stopped:
- return "stopped"
- default:
- return "unknown"
- }
-}
-
-// BaseState represents the platform agnostic pieces relating to a
-// running container's state
-type BaseState struct {
- // ID is the container ID.
- ID string `json:"id"`
-
- // InitProcessPid is the init process id in the parent namespace.
- InitProcessPid int `json:"init_process_pid"`
-
- // InitProcessStartTime is the init process start time in clock cycles since boot time.
- InitProcessStartTime uint64 `json:"init_process_start"`
-
- // Created is the unix timestamp for the creation time of the container in UTC
- Created time.Time `json:"created"`
-
- // Config is the container's configuration.
- Config configs.Config `json:"config"`
-}
-
-// BaseContainer is a libcontainer container object.
-//
-// Each container is thread-safe within the same process. Since a container can
-// be destroyed by a separate process, any function may return that the container
-// was not found. BaseContainer includes methods that are platform agnostic.
-type BaseContainer interface {
- // Returns the ID of the container
- ID() string
-
- // Returns the current status of the container.
- //
- // errors:
- // ContainerNotExists - Container no longer exists,
- // Systemerror - System error.
- Status() (Status, error)
-
- // State returns the current container's state information.
- //
- // errors:
- // SystemError - System error.
- State() (*State, error)
-
- // Returns the current config of the container.
- Config() configs.Config
-
- // Returns the PIDs inside this container. The PIDs are in the namespace of the calling process.
- //
- // errors:
- // ContainerNotExists - Container no longer exists,
- // Systemerror - System error.
- //
- // Some of the returned PIDs may no longer refer to processes in the Container, unless
- // the Container state is PAUSED in which case every PID in the slice is valid.
- Processes() ([]int, error)
-
- // Returns statistics for the container.
- //
- // errors:
- // ContainerNotExists - Container no longer exists,
- // Systemerror - System error.
- Stats() (*Stats, error)
-
- // Set resources of container as configured
- //
- // We can use this to change resources when containers are running.
- //
- // errors:
- // SystemError - System error.
- Set(config configs.Config) error
-
- // Start a process inside the container. Returns error if process fails to
- // start. You can track process lifecycle with passed Process structure.
- //
- // errors:
- // ContainerNotExists - Container no longer exists,
- // ConfigInvalid - config is invalid,
- // ContainerPaused - Container is paused,
- // SystemError - System error.
- Start(process *Process) (err error)
-
- // Run immediately starts the process inside the container. Returns error if process
- // fails to start. It does not block waiting for the exec fifo after start returns but
- // opens the fifo after start returns.
- //
- // errors:
- // ContainerNotExists - Container no longer exists,
- // ConfigInvalid - config is invalid,
- // ContainerPaused - Container is paused,
- // SystemError - System error.
- Run(process *Process) (err error)
-
- // Destroys the container, if its in a valid state, after killing any
- // remaining running processes.
- //
- // Any event registrations are removed before the container is destroyed.
- // No error is returned if the container is already destroyed.
- //
- // Running containers must first be stopped using Signal(..).
- // Paused containers must first be resumed using Resume(..).
- //
- // errors:
- // ContainerNotStopped - Container is still running,
- // ContainerPaused - Container is paused,
- // SystemError - System error.
- Destroy() error
-
- // Signal sends the provided signal code to the container's initial process.
- //
- // If all is specified the signal is sent to all processes in the container
- // including the initial process.
- //
- // errors:
- // SystemError - System error.
- Signal(s os.Signal, all bool) error
-
- // Exec signals the container to exec the users process at the end of the init.
- //
- // errors:
- // SystemError - System error.
- Exec() error
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
deleted file mode 100644
index cfb05b43a..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
+++ /dev/null
@@ -1,1849 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "net"
- "os"
- "os/exec"
- "path/filepath"
- "reflect"
- "strings"
- "sync"
- "syscall" // only for SysProcAttr and Signal
- "time"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/criurpc"
- "github.com/opencontainers/runc/libcontainer/intelrdt"
- "github.com/opencontainers/runc/libcontainer/system"
- "github.com/opencontainers/runc/libcontainer/utils"
-
- "github.com/golang/protobuf/proto"
- "github.com/sirupsen/logrus"
- "github.com/syndtr/gocapability/capability"
- "github.com/vishvananda/netlink/nl"
- "golang.org/x/sys/unix"
-)
-
-const stdioFdCount = 3
-
-type linuxContainer struct {
- id string
- root string
- config *configs.Config
- cgroupManager cgroups.Manager
- intelRdtManager intelrdt.Manager
- initPath string
- initArgs []string
- initProcess parentProcess
- initProcessStartTime uint64
- criuPath string
- newuidmapPath string
- newgidmapPath string
- m sync.Mutex
- criuVersion int
- state containerState
- created time.Time
-}
-
-// State represents a running container's state
-type State struct {
- BaseState
-
- // Platform specific fields below here
-
- // Specifies if the container was started under the rootless mode.
- Rootless bool `json:"rootless"`
-
- // Path to all the cgroups setup for a container. Key is cgroup subsystem name
- // with the value as the path.
- CgroupPaths map[string]string `json:"cgroup_paths"`
-
- // NamespacePaths are filepaths to the container's namespaces. Key is the namespace type
- // with the value as the path.
- NamespacePaths map[configs.NamespaceType]string `json:"namespace_paths"`
-
- // Container's standard descriptors (std{in,out,err}), needed for checkpoint and restore
- ExternalDescriptors []string `json:"external_descriptors,omitempty"`
-
- // Intel RDT "resource control" filesystem path
- IntelRdtPath string `json:"intel_rdt_path"`
-}
-
-// Container is a libcontainer container object.
-//
-// Each container is thread-safe within the same process. Since a container can
-// be destroyed by a separate process, any function may return that the container
-// was not found.
-type Container interface {
- BaseContainer
-
- // Methods below here are platform specific
-
- // Checkpoint checkpoints the running container's state to disk using the criu(8) utility.
- //
- // errors:
- // Systemerror - System error.
- Checkpoint(criuOpts *CriuOpts) error
-
- // Restore restores the checkpointed container to a running state using the criu(8) utility.
- //
- // errors:
- // Systemerror - System error.
- Restore(process *Process, criuOpts *CriuOpts) error
-
- // If the Container state is RUNNING or CREATED, sets the Container state to PAUSING and pauses
- // the execution of any user processes. Asynchronously, when the container finished being paused the
- // state is changed to PAUSED.
- // If the Container state is PAUSED, do nothing.
- //
- // errors:
- // ContainerNotExists - Container no longer exists,
- // ContainerNotRunning - Container not running or created,
- // Systemerror - System error.
- Pause() error
-
- // If the Container state is PAUSED, resumes the execution of any user processes in the
- // Container before setting the Container state to RUNNING.
- // If the Container state is RUNNING, do nothing.
- //
- // errors:
- // ContainerNotExists - Container no longer exists,
- // ContainerNotPaused - Container is not paused,
- // Systemerror - System error.
- Resume() error
-
- // NotifyOOM returns a read-only channel signaling when the container receives an OOM notification.
- //
- // errors:
- // Systemerror - System error.
- NotifyOOM() (<-chan struct{}, error)
-
- // NotifyMemoryPressure returns a read-only channel signaling when the container reaches a given pressure level
- //
- // errors:
- // Systemerror - System error.
- NotifyMemoryPressure(level PressureLevel) (<-chan struct{}, error)
-}
-
-// ID returns the container's unique ID
-func (c *linuxContainer) ID() string {
- return c.id
-}
-
-// Config returns the container's configuration
-func (c *linuxContainer) Config() configs.Config {
- return *c.config
-}
-
-func (c *linuxContainer) Status() (Status, error) {
- c.m.Lock()
- defer c.m.Unlock()
- return c.currentStatus()
-}
-
-func (c *linuxContainer) State() (*State, error) {
- c.m.Lock()
- defer c.m.Unlock()
- return c.currentState()
-}
-
-func (c *linuxContainer) Processes() ([]int, error) {
- pids, err := c.cgroupManager.GetAllPids()
- if err != nil {
- return nil, newSystemErrorWithCause(err, "getting all container pids from cgroups")
- }
- return pids, nil
-}
-
-func (c *linuxContainer) Stats() (*Stats, error) {
- var (
- err error
- stats = &Stats{}
- )
- if stats.CgroupStats, err = c.cgroupManager.GetStats(); err != nil {
- return stats, newSystemErrorWithCause(err, "getting container stats from cgroups")
- }
- if c.intelRdtManager != nil {
- if stats.IntelRdtStats, err = c.intelRdtManager.GetStats(); err != nil {
- return stats, newSystemErrorWithCause(err, "getting container's Intel RDT stats")
- }
- }
- for _, iface := range c.config.Networks {
- switch iface.Type {
- case "veth":
- istats, err := getNetworkInterfaceStats(iface.HostInterfaceName)
- if err != nil {
- return stats, newSystemErrorWithCausef(err, "getting network stats for interface %q", iface.HostInterfaceName)
- }
- stats.Interfaces = append(stats.Interfaces, istats)
- }
- }
- return stats, nil
-}
-
-func (c *linuxContainer) Set(config configs.Config) error {
- c.m.Lock()
- defer c.m.Unlock()
- status, err := c.currentStatus()
- if err != nil {
- return err
- }
- if status == Stopped {
- return newGenericError(fmt.Errorf("container not running"), ContainerNotRunning)
- }
- if err := c.cgroupManager.Set(&config); err != nil {
- // Set configs back
- if err2 := c.cgroupManager.Set(c.config); err2 != nil {
- logrus.Warnf("Setting back cgroup configs failed due to error: %v, your state.json and actual configs might be inconsistent.", err2)
- }
- return err
- }
- if c.intelRdtManager != nil {
- if err := c.intelRdtManager.Set(&config); err != nil {
- // Set configs back
- if err2 := c.intelRdtManager.Set(c.config); err2 != nil {
- logrus.Warnf("Setting back intelrdt configs failed due to error: %v, your state.json and actual configs might be inconsistent.", err2)
- }
- return err
- }
- }
- // After config setting succeed, update config and states
- c.config = &config
- _, err = c.updateState(nil)
- return err
-}
-
-func (c *linuxContainer) Start(process *Process) error {
- c.m.Lock()
- defer c.m.Unlock()
- status, err := c.currentStatus()
- if err != nil {
- return err
- }
- if status == Stopped {
- if err := c.createExecFifo(); err != nil {
- return err
- }
- }
- if err := c.start(process, status == Stopped); err != nil {
- if status == Stopped {
- c.deleteExecFifo()
- }
- return err
- }
- return nil
-}
-
-func (c *linuxContainer) Run(process *Process) error {
- c.m.Lock()
- status, err := c.currentStatus()
- if err != nil {
- c.m.Unlock()
- return err
- }
- c.m.Unlock()
- if err := c.Start(process); err != nil {
- return err
- }
- if status == Stopped {
- return c.exec()
- }
- return nil
-}
-
-func (c *linuxContainer) Exec() error {
- c.m.Lock()
- defer c.m.Unlock()
- return c.exec()
-}
-
-func (c *linuxContainer) exec() error {
- path := filepath.Join(c.root, execFifoFilename)
-
- fifoOpen := make(chan struct{})
- select {
- case <-awaitProcessExit(c.initProcess.pid(), fifoOpen):
- return errors.New("container process is already dead")
- case result := <-awaitFifoOpen(path):
- close(fifoOpen)
- if result.err != nil {
- return result.err
- }
- f := result.file
- defer f.Close()
- if err := readFromExecFifo(f); err != nil {
- return err
- }
- return os.Remove(path)
- }
-}
-
-func readFromExecFifo(execFifo io.Reader) error {
- data, err := ioutil.ReadAll(execFifo)
- if err != nil {
- return err
- }
- if len(data) <= 0 {
- return fmt.Errorf("cannot start an already running container")
- }
- return nil
-}
-
-func awaitProcessExit(pid int, exit <-chan struct{}) <-chan struct{} {
- isDead := make(chan struct{})
- go func() {
- for {
- select {
- case <-exit:
- return
- case <-time.After(time.Millisecond * 100):
- stat, err := system.Stat(pid)
- if err != nil || stat.State == system.Zombie {
- close(isDead)
- return
- }
- }
- }
- }()
- return isDead
-}
-
-func awaitFifoOpen(path string) <-chan openResult {
- fifoOpened := make(chan openResult)
- go func() {
- f, err := os.OpenFile(path, os.O_RDONLY, 0)
- if err != nil {
- fifoOpened <- openResult{err: newSystemErrorWithCause(err, "open exec fifo for reading")}
- return
- }
- fifoOpened <- openResult{file: f}
- }()
- return fifoOpened
-}
-
-type openResult struct {
- file *os.File
- err error
-}
-
-func (c *linuxContainer) start(process *Process, isInit bool) error {
- parent, err := c.newParentProcess(process, isInit)
- if err != nil {
- return newSystemErrorWithCause(err, "creating new parent process")
- }
- if err := parent.start(); err != nil {
- // terminate the process to ensure that it properly is reaped.
- if err := ignoreTerminateErrors(parent.terminate()); err != nil {
- logrus.Warn(err)
- }
- return newSystemErrorWithCause(err, "starting container process")
- }
- // generate a timestamp indicating when the container was started
- c.created = time.Now().UTC()
- if isInit {
- c.state = &createdState{
- c: c,
- }
- state, err := c.updateState(parent)
- if err != nil {
- return err
- }
- c.initProcessStartTime = state.InitProcessStartTime
-
- if c.config.Hooks != nil {
- bundle, annotations := utils.Annotations(c.config.Labels)
- s := configs.HookState{
- Version: c.config.Version,
- ID: c.id,
- Pid: parent.pid(),
- Bundle: bundle,
- Annotations: annotations,
- }
- for i, hook := range c.config.Hooks.Poststart {
- if err := hook.Run(s); err != nil {
- if err := ignoreTerminateErrors(parent.terminate()); err != nil {
- logrus.Warn(err)
- }
- return newSystemErrorWithCausef(err, "running poststart hook %d", i)
- }
- }
- }
- } else {
- c.state = &runningState{
- c: c,
- }
- }
- return nil
-}
-
-func (c *linuxContainer) Signal(s os.Signal, all bool) error {
- if all {
- return signalAllProcesses(c.cgroupManager, s)
- }
- if err := c.initProcess.signal(s); err != nil {
- return newSystemErrorWithCause(err, "signaling init process")
- }
- return nil
-}
-
-func (c *linuxContainer) createExecFifo() error {
- rootuid, err := c.Config().HostRootUID()
- if err != nil {
- return err
- }
- rootgid, err := c.Config().HostRootGID()
- if err != nil {
- return err
- }
-
- fifoName := filepath.Join(c.root, execFifoFilename)
- if _, err := os.Stat(fifoName); err == nil {
- return fmt.Errorf("exec fifo %s already exists", fifoName)
- }
- oldMask := unix.Umask(0000)
- if err := unix.Mkfifo(fifoName, 0622); err != nil {
- unix.Umask(oldMask)
- return err
- }
- unix.Umask(oldMask)
- if err := os.Chown(fifoName, rootuid, rootgid); err != nil {
- return err
- }
- return nil
-}
-
-func (c *linuxContainer) deleteExecFifo() {
- fifoName := filepath.Join(c.root, execFifoFilename)
- os.Remove(fifoName)
-}
-
-// includeExecFifo opens the container's execfifo as a pathfd, so that the
-// container cannot access the statedir (and the FIFO itself remains
-// un-opened). It then adds the FifoFd to the given exec.Cmd as an inherited
-// fd, with _LIBCONTAINER_FIFOFD set to its fd number.
-func (c *linuxContainer) includeExecFifo(cmd *exec.Cmd) error {
- fifoName := filepath.Join(c.root, execFifoFilename)
- fifoFd, err := unix.Open(fifoName, unix.O_PATH|unix.O_CLOEXEC, 0)
- if err != nil {
- return err
- }
-
- cmd.ExtraFiles = append(cmd.ExtraFiles, os.NewFile(uintptr(fifoFd), fifoName))
- cmd.Env = append(cmd.Env,
- fmt.Sprintf("_LIBCONTAINER_FIFOFD=%d", stdioFdCount+len(cmd.ExtraFiles)-1))
- return nil
-}
-
-func (c *linuxContainer) newParentProcess(p *Process, doInit bool) (parentProcess, error) {
- parentPipe, childPipe, err := utils.NewSockPair("init")
- if err != nil {
- return nil, newSystemErrorWithCause(err, "creating new init pipe")
- }
- cmd, err := c.commandTemplate(p, childPipe)
- if err != nil {
- return nil, newSystemErrorWithCause(err, "creating new command template")
- }
- if !doInit {
- return c.newSetnsProcess(p, cmd, parentPipe, childPipe)
- }
-
- // We only set up fifoFd if we're not doing a `runc exec`. The historic
- // reason for this is that previously we would pass a dirfd that allowed
- // for container rootfs escape (and not doing it in `runc exec` avoided
- // that problem), but we no longer do that. However, there's no need to do
- // this for `runc exec` so we just keep it this way to be safe.
- if err := c.includeExecFifo(cmd); err != nil {
- return nil, newSystemErrorWithCause(err, "including execfifo in cmd.Exec setup")
- }
- return c.newInitProcess(p, cmd, parentPipe, childPipe)
-}
-
-func (c *linuxContainer) commandTemplate(p *Process, childPipe *os.File) (*exec.Cmd, error) {
- cmd := exec.Command(c.initPath, c.initArgs[1:]...)
- cmd.Args[0] = c.initArgs[0]
- cmd.Stdin = p.Stdin
- cmd.Stdout = p.Stdout
- cmd.Stderr = p.Stderr
- cmd.Dir = c.config.Rootfs
- if cmd.SysProcAttr == nil {
- cmd.SysProcAttr = &syscall.SysProcAttr{}
- }
- cmd.ExtraFiles = append(cmd.ExtraFiles, p.ExtraFiles...)
- if p.ConsoleSocket != nil {
- cmd.ExtraFiles = append(cmd.ExtraFiles, p.ConsoleSocket)
- cmd.Env = append(cmd.Env,
- fmt.Sprintf("_LIBCONTAINER_CONSOLE=%d", stdioFdCount+len(cmd.ExtraFiles)-1),
- )
- }
- cmd.ExtraFiles = append(cmd.ExtraFiles, childPipe)
- cmd.Env = append(cmd.Env,
- fmt.Sprintf("_LIBCONTAINER_INITPIPE=%d", stdioFdCount+len(cmd.ExtraFiles)-1),
- )
- // NOTE: when running a container with no PID namespace and the parent process spawning the container is
- // PID1 the pdeathsig is being delivered to the container's init process by the kernel for some reason
- // even with the parent still running.
- if c.config.ParentDeathSignal > 0 {
- cmd.SysProcAttr.Pdeathsig = syscall.Signal(c.config.ParentDeathSignal)
- }
- return cmd, nil
-}
-
-func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, parentPipe, childPipe *os.File) (*initProcess, error) {
- cmd.Env = append(cmd.Env, "_LIBCONTAINER_INITTYPE="+string(initStandard))
- nsMaps := make(map[configs.NamespaceType]string)
- for _, ns := range c.config.Namespaces {
- if ns.Path != "" {
- nsMaps[ns.Type] = ns.Path
- }
- }
- _, sharePidns := nsMaps[configs.NEWPID]
- data, err := c.bootstrapData(c.config.Namespaces.CloneFlags(), nsMaps)
- if err != nil {
- return nil, err
- }
- return &initProcess{
- cmd: cmd,
- childPipe: childPipe,
- parentPipe: parentPipe,
- manager: c.cgroupManager,
- intelRdtManager: c.intelRdtManager,
- config: c.newInitConfig(p),
- container: c,
- process: p,
- bootstrapData: data,
- sharePidns: sharePidns,
- }, nil
-}
-
-func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, parentPipe, childPipe *os.File) (*setnsProcess, error) {
- cmd.Env = append(cmd.Env, "_LIBCONTAINER_INITTYPE="+string(initSetns))
- state, err := c.currentState()
- if err != nil {
- return nil, newSystemErrorWithCause(err, "getting container's current state")
- }
- // for setns process, we don't have to set cloneflags as the process namespaces
- // will only be set via setns syscall
- data, err := c.bootstrapData(0, state.NamespacePaths)
- if err != nil {
- return nil, err
- }
- return &setnsProcess{
- cmd: cmd,
- cgroupPaths: c.cgroupManager.GetPaths(),
- intelRdtPath: state.IntelRdtPath,
- childPipe: childPipe,
- parentPipe: parentPipe,
- config: c.newInitConfig(p),
- process: p,
- bootstrapData: data,
- }, nil
-}
-
-func (c *linuxContainer) newInitConfig(process *Process) *initConfig {
- cfg := &initConfig{
- Config: c.config,
- Args: process.Args,
- Env: process.Env,
- User: process.User,
- AdditionalGroups: process.AdditionalGroups,
- Cwd: process.Cwd,
- Capabilities: process.Capabilities,
- PassedFilesCount: len(process.ExtraFiles),
- ContainerId: c.ID(),
- NoNewPrivileges: c.config.NoNewPrivileges,
- Rootless: c.config.Rootless,
- AppArmorProfile: c.config.AppArmorProfile,
- ProcessLabel: c.config.ProcessLabel,
- Rlimits: c.config.Rlimits,
- }
- if process.NoNewPrivileges != nil {
- cfg.NoNewPrivileges = *process.NoNewPrivileges
- }
- if process.AppArmorProfile != "" {
- cfg.AppArmorProfile = process.AppArmorProfile
- }
- if process.Label != "" {
- cfg.ProcessLabel = process.Label
- }
- if len(process.Rlimits) > 0 {
- cfg.Rlimits = process.Rlimits
- }
- cfg.CreateConsole = process.ConsoleSocket != nil
- cfg.ConsoleWidth = process.ConsoleWidth
- cfg.ConsoleHeight = process.ConsoleHeight
- return cfg
-}
-
-func (c *linuxContainer) Destroy() error {
- c.m.Lock()
- defer c.m.Unlock()
- return c.state.destroy()
-}
-
-func (c *linuxContainer) Pause() error {
- c.m.Lock()
- defer c.m.Unlock()
- status, err := c.currentStatus()
- if err != nil {
- return err
- }
- switch status {
- case Running, Created:
- if err := c.cgroupManager.Freeze(configs.Frozen); err != nil {
- return err
- }
- return c.state.transition(&pausedState{
- c: c,
- })
- }
- return newGenericError(fmt.Errorf("container not running or created: %s", status), ContainerNotRunning)
-}
-
-func (c *linuxContainer) Resume() error {
- c.m.Lock()
- defer c.m.Unlock()
- status, err := c.currentStatus()
- if err != nil {
- return err
- }
- if status != Paused {
- return newGenericError(fmt.Errorf("container not paused"), ContainerNotPaused)
- }
- if err := c.cgroupManager.Freeze(configs.Thawed); err != nil {
- return err
- }
- return c.state.transition(&runningState{
- c: c,
- })
-}
-
-func (c *linuxContainer) NotifyOOM() (<-chan struct{}, error) {
- // XXX(cyphar): This requires cgroups.
- if c.config.Rootless {
- return nil, fmt.Errorf("cannot get OOM notifications from rootless container")
- }
- return notifyOnOOM(c.cgroupManager.GetPaths())
-}
-
-func (c *linuxContainer) NotifyMemoryPressure(level PressureLevel) (<-chan struct{}, error) {
- // XXX(cyphar): This requires cgroups.
- if c.config.Rootless {
- return nil, fmt.Errorf("cannot get memory pressure notifications from rootless container")
- }
- return notifyMemoryPressure(c.cgroupManager.GetPaths(), level)
-}
-
-var criuFeatures *criurpc.CriuFeatures
-
-func (c *linuxContainer) checkCriuFeatures(criuOpts *CriuOpts, rpcOpts *criurpc.CriuOpts, criuFeat *criurpc.CriuFeatures) error {
-
- var t criurpc.CriuReqType
- t = criurpc.CriuReqType_FEATURE_CHECK
-
- // criu 1.8 => 10800
- if err := c.checkCriuVersion(10800); err != nil {
- // Feature checking was introduced with CRIU 1.8.
- // Ignore the feature check if an older CRIU version is used
- // and just act as before.
- // As all automated PR testing is done using CRIU 1.7 this
- // code will not be tested by automated PR testing.
- return nil
- }
-
- // make sure the features we are looking for are really not from
- // some previous check
- criuFeatures = nil
-
- req := &criurpc.CriuReq{
- Type: &t,
- // Theoretically this should not be necessary but CRIU
- // segfaults if Opts is empty.
- // Fixed in CRIU 2.12
- Opts: rpcOpts,
- Features: criuFeat,
- }
-
- err := c.criuSwrk(nil, req, criuOpts, false)
- if err != nil {
- logrus.Debugf("%s", err)
- return fmt.Errorf("CRIU feature check failed")
- }
-
- logrus.Debugf("Feature check says: %s", criuFeatures)
- missingFeatures := false
-
- // The outer if checks if the fields actually exist
- if (criuFeat.MemTrack != nil) &&
- (criuFeatures.MemTrack != nil) {
- // The inner if checks if they are set to true
- if *criuFeat.MemTrack && !*criuFeatures.MemTrack {
- missingFeatures = true
- logrus.Debugf("CRIU does not support MemTrack")
- }
- }
-
- // This needs to be repeated for every new feature check.
- // Is there a way to put this in a function. Reflection?
- if (criuFeat.LazyPages != nil) &&
- (criuFeatures.LazyPages != nil) {
- if *criuFeat.LazyPages && !*criuFeatures.LazyPages {
- missingFeatures = true
- logrus.Debugf("CRIU does not support LazyPages")
- }
- }
-
- if missingFeatures {
- return fmt.Errorf("CRIU is missing features")
- }
-
- return nil
-}
-
-func parseCriuVersion(path string) (int, error) {
- var x, y, z int
-
- out, err := exec.Command(path, "-V").Output()
- if err != nil {
- return 0, fmt.Errorf("Unable to execute CRIU command: %s", path)
- }
-
- x = 0
- y = 0
- z = 0
- if ep := strings.Index(string(out), "-"); ep >= 0 {
- // criu Git version format
- var version string
- if sp := strings.Index(string(out), "GitID"); sp > 0 {
- version = string(out)[sp:ep]
- } else {
- return 0, fmt.Errorf("Unable to parse the CRIU version: %s", path)
- }
-
- n, err := fmt.Sscanf(version, "GitID: v%d.%d.%d", &x, &y, &z) // 1.5.2
- if err != nil {
- n, err = fmt.Sscanf(version, "GitID: v%d.%d", &x, &y) // 1.6
- y++
- } else {
- z++
- }
- if n < 2 || err != nil {
- return 0, fmt.Errorf("Unable to parse the CRIU version: %s %d %s", version, n, err)
- }
- } else {
- // criu release version format
- n, err := fmt.Sscanf(string(out), "Version: %d.%d.%d\n", &x, &y, &z) // 1.5.2
- if err != nil {
- n, err = fmt.Sscanf(string(out), "Version: %d.%d\n", &x, &y) // 1.6
- }
- if n < 2 || err != nil {
- return 0, fmt.Errorf("Unable to parse the CRIU version: %s %d %s", out, n, err)
- }
- }
-
- return x*10000 + y*100 + z, nil
-}
-
-func compareCriuVersion(criuVersion int, minVersion int) error {
- // simple function to perform the actual version compare
- if criuVersion < minVersion {
- return fmt.Errorf("CRIU version %d must be %d or higher", criuVersion, minVersion)
- }
-
- return nil
-}
-
-// This is used to store the result of criu version RPC
-var criuVersionRPC *criurpc.CriuVersion
-
-// checkCriuVersion checks Criu version greater than or equal to minVersion
-func (c *linuxContainer) checkCriuVersion(minVersion int) error {
-
- // If the version of criu has already been determined there is no need
- // to ask criu for the version again. Use the value from c.criuVersion.
- if c.criuVersion != 0 {
- return compareCriuVersion(c.criuVersion, minVersion)
- }
-
- // First try if this version of CRIU support the version RPC.
- // The CRIU version RPC was introduced with CRIU 3.0.
-
- // First, reset the variable for the RPC answer to nil
- criuVersionRPC = nil
-
- var t criurpc.CriuReqType
- t = criurpc.CriuReqType_VERSION
- req := &criurpc.CriuReq{
- Type: &t,
- }
-
- err := c.criuSwrk(nil, req, nil, false)
- if err != nil {
- return fmt.Errorf("CRIU version check failed: %s", err)
- }
-
- if criuVersionRPC != nil {
- logrus.Debugf("CRIU version: %s", criuVersionRPC)
- // major and minor are always set
- c.criuVersion = int(*criuVersionRPC.Major) * 10000
- c.criuVersion += int(*criuVersionRPC.Minor) * 100
- if criuVersionRPC.Sublevel != nil {
- c.criuVersion += int(*criuVersionRPC.Sublevel)
- }
- if criuVersionRPC.Gitid != nil {
- // runc's convention is that a CRIU git release is
- // always the same as increasing the minor by 1
- c.criuVersion -= (c.criuVersion % 100)
- c.criuVersion += 100
- }
- return compareCriuVersion(c.criuVersion, minVersion)
- }
-
- // This is CRIU without the version RPC and therefore
- // older than 3.0. Parsing the output is required.
-
- // This can be remove once runc does not work with criu older than 3.0
-
- c.criuVersion, err = parseCriuVersion(c.criuPath)
- if err != nil {
- return err
- }
-
- return compareCriuVersion(c.criuVersion, minVersion)
-}
-
-const descriptorsFilename = "descriptors.json"
-
-func (c *linuxContainer) addCriuDumpMount(req *criurpc.CriuReq, m *configs.Mount) {
- mountDest := m.Destination
- if strings.HasPrefix(mountDest, c.config.Rootfs) {
- mountDest = mountDest[len(c.config.Rootfs):]
- }
-
- extMnt := &criurpc.ExtMountMap{
- Key: proto.String(mountDest),
- Val: proto.String(mountDest),
- }
- req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
-}
-
-func (c *linuxContainer) addMaskPaths(req *criurpc.CriuReq) error {
- for _, path := range c.config.MaskPaths {
- fi, err := os.Stat(fmt.Sprintf("/proc/%d/root/%s", c.initProcess.pid(), path))
- if err != nil {
- if os.IsNotExist(err) {
- continue
- }
- return err
- }
- if fi.IsDir() {
- continue
- }
-
- extMnt := &criurpc.ExtMountMap{
- Key: proto.String(path),
- Val: proto.String("/dev/null"),
- }
- req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
- }
- return nil
-}
-
-func waitForCriuLazyServer(r *os.File, status string) error {
-
- data := make([]byte, 1)
- _, err := r.Read(data)
- if err != nil {
- return err
- }
- fd, err := os.OpenFile(status, os.O_TRUNC|os.O_WRONLY, os.ModeAppend)
- if err != nil {
- return err
- }
- _, err = fd.Write(data)
- if err != nil {
- return err
- }
- fd.Close()
-
- return nil
-}
-
-func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
- c.m.Lock()
- defer c.m.Unlock()
-
- // TODO(avagin): Figure out how to make this work nicely. CRIU 2.0 has
- // support for doing unprivileged dumps, but the setup of
- // rootless containers might make this complicated.
- if c.config.Rootless {
- return fmt.Errorf("cannot checkpoint a rootless container")
- }
-
- // criu 1.5.2 => 10502
- if err := c.checkCriuVersion(10502); err != nil {
- return err
- }
-
- if criuOpts.ImagesDirectory == "" {
- return fmt.Errorf("invalid directory to save checkpoint")
- }
-
- // Since a container can be C/R'ed multiple times,
- // the checkpoint directory may already exist.
- if err := os.Mkdir(criuOpts.ImagesDirectory, 0755); err != nil && !os.IsExist(err) {
- return err
- }
-
- if criuOpts.WorkDirectory == "" {
- criuOpts.WorkDirectory = filepath.Join(c.root, "criu.work")
- }
-
- if err := os.Mkdir(criuOpts.WorkDirectory, 0755); err != nil && !os.IsExist(err) {
- return err
- }
-
- workDir, err := os.Open(criuOpts.WorkDirectory)
- if err != nil {
- return err
- }
- defer workDir.Close()
-
- imageDir, err := os.Open(criuOpts.ImagesDirectory)
- if err != nil {
- return err
- }
- defer imageDir.Close()
-
- rpcOpts := criurpc.CriuOpts{
- ImagesDirFd: proto.Int32(int32(imageDir.Fd())),
- WorkDirFd: proto.Int32(int32(workDir.Fd())),
- LogLevel: proto.Int32(4),
- LogFile: proto.String("dump.log"),
- Root: proto.String(c.config.Rootfs),
- ManageCgroups: proto.Bool(true),
- NotifyScripts: proto.Bool(true),
- Pid: proto.Int32(int32(c.initProcess.pid())),
- ShellJob: proto.Bool(criuOpts.ShellJob),
- LeaveRunning: proto.Bool(criuOpts.LeaveRunning),
- TcpEstablished: proto.Bool(criuOpts.TcpEstablished),
- ExtUnixSk: proto.Bool(criuOpts.ExternalUnixConnections),
- FileLocks: proto.Bool(criuOpts.FileLocks),
- EmptyNs: proto.Uint32(criuOpts.EmptyNs),
- OrphanPtsMaster: proto.Bool(true),
- AutoDedup: proto.Bool(criuOpts.AutoDedup),
- LazyPages: proto.Bool(criuOpts.LazyPages),
- }
-
- fcg := c.cgroupManager.GetPaths()["freezer"]
- if fcg != "" {
- rpcOpts.FreezeCgroup = proto.String(fcg)
- }
-
- // append optional criu opts, e.g., page-server and port
- if criuOpts.PageServer.Address != "" && criuOpts.PageServer.Port != 0 {
- rpcOpts.Ps = &criurpc.CriuPageServerInfo{
- Address: proto.String(criuOpts.PageServer.Address),
- Port: proto.Int32(criuOpts.PageServer.Port),
- }
- }
-
- //pre-dump may need parentImage param to complete iterative migration
- if criuOpts.ParentImage != "" {
- rpcOpts.ParentImg = proto.String(criuOpts.ParentImage)
- rpcOpts.TrackMem = proto.Bool(true)
- }
-
- // append optional manage cgroups mode
- if criuOpts.ManageCgroupsMode != 0 {
- // criu 1.7 => 10700
- if err := c.checkCriuVersion(10700); err != nil {
- return err
- }
- mode := criurpc.CriuCgMode(criuOpts.ManageCgroupsMode)
- rpcOpts.ManageCgroupsMode = &mode
- }
-
- var t criurpc.CriuReqType
- if criuOpts.PreDump {
- feat := criurpc.CriuFeatures{
- MemTrack: proto.Bool(true),
- }
-
- if err := c.checkCriuFeatures(criuOpts, &rpcOpts, &feat); err != nil {
- return err
- }
-
- t = criurpc.CriuReqType_PRE_DUMP
- } else {
- t = criurpc.CriuReqType_DUMP
- }
- req := &criurpc.CriuReq{
- Type: &t,
- Opts: &rpcOpts,
- }
-
- if criuOpts.LazyPages {
- // lazy migration requested; check if criu supports it
- feat := criurpc.CriuFeatures{
- LazyPages: proto.Bool(true),
- }
-
- if err := c.checkCriuFeatures(criuOpts, &rpcOpts, &feat); err != nil {
- return err
- }
-
- statusRead, statusWrite, err := os.Pipe()
- if err != nil {
- return err
- }
- rpcOpts.StatusFd = proto.Int32(int32(statusWrite.Fd()))
- go waitForCriuLazyServer(statusRead, criuOpts.StatusFd)
- }
-
- //no need to dump these information in pre-dump
- if !criuOpts.PreDump {
- for _, m := range c.config.Mounts {
- switch m.Device {
- case "bind":
- c.addCriuDumpMount(req, m)
- case "cgroup":
- binds, err := getCgroupMounts(m)
- if err != nil {
- return err
- }
- for _, b := range binds {
- c.addCriuDumpMount(req, b)
- }
- }
- }
-
- if err := c.addMaskPaths(req); err != nil {
- return err
- }
-
- for _, node := range c.config.Devices {
- m := &configs.Mount{Destination: node.Path, Source: node.Path}
- c.addCriuDumpMount(req, m)
- }
-
- // Write the FD info to a file in the image directory
- fdsJSON, err := json.Marshal(c.initProcess.externalDescriptors())
- if err != nil {
- return err
- }
-
- err = ioutil.WriteFile(filepath.Join(criuOpts.ImagesDirectory, descriptorsFilename), fdsJSON, 0655)
- if err != nil {
- return err
- }
- }
-
- err = c.criuSwrk(nil, req, criuOpts, false)
- if err != nil {
- return err
- }
- return nil
-}
-
-func (c *linuxContainer) addCriuRestoreMount(req *criurpc.CriuReq, m *configs.Mount) {
- mountDest := m.Destination
- if strings.HasPrefix(mountDest, c.config.Rootfs) {
- mountDest = mountDest[len(c.config.Rootfs):]
- }
-
- extMnt := &criurpc.ExtMountMap{
- Key: proto.String(mountDest),
- Val: proto.String(m.Source),
- }
- req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
-}
-
-func (c *linuxContainer) restoreNetwork(req *criurpc.CriuReq, criuOpts *CriuOpts) {
- for _, iface := range c.config.Networks {
- switch iface.Type {
- case "veth":
- veth := new(criurpc.CriuVethPair)
- veth.IfOut = proto.String(iface.HostInterfaceName)
- veth.IfIn = proto.String(iface.Name)
- req.Opts.Veths = append(req.Opts.Veths, veth)
- case "loopback":
- // Do nothing
- }
- }
- for _, i := range criuOpts.VethPairs {
- veth := new(criurpc.CriuVethPair)
- veth.IfOut = proto.String(i.HostInterfaceName)
- veth.IfIn = proto.String(i.ContainerInterfaceName)
- req.Opts.Veths = append(req.Opts.Veths, veth)
- }
-}
-
-func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
- c.m.Lock()
- defer c.m.Unlock()
-
- // TODO(avagin): Figure out how to make this work nicely. CRIU doesn't have
- // support for unprivileged restore at the moment.
- if c.config.Rootless {
- return fmt.Errorf("cannot restore a rootless container")
- }
-
- // criu 1.5.2 => 10502
- if err := c.checkCriuVersion(10502); err != nil {
- return err
- }
- if criuOpts.WorkDirectory == "" {
- criuOpts.WorkDirectory = filepath.Join(c.root, "criu.work")
- }
- // Since a container can be C/R'ed multiple times,
- // the work directory may already exist.
- if err := os.Mkdir(criuOpts.WorkDirectory, 0655); err != nil && !os.IsExist(err) {
- return err
- }
- workDir, err := os.Open(criuOpts.WorkDirectory)
- if err != nil {
- return err
- }
- defer workDir.Close()
- if criuOpts.ImagesDirectory == "" {
- return fmt.Errorf("invalid directory to restore checkpoint")
- }
- imageDir, err := os.Open(criuOpts.ImagesDirectory)
- if err != nil {
- return err
- }
- defer imageDir.Close()
- // CRIU has a few requirements for a root directory:
- // * it must be a mount point
- // * its parent must not be overmounted
- // c.config.Rootfs is bind-mounted to a temporary directory
- // to satisfy these requirements.
- root := filepath.Join(c.root, "criu-root")
- if err := os.Mkdir(root, 0755); err != nil {
- return err
- }
- defer os.Remove(root)
- root, err = filepath.EvalSymlinks(root)
- if err != nil {
- return err
- }
- err = unix.Mount(c.config.Rootfs, root, "", unix.MS_BIND|unix.MS_REC, "")
- if err != nil {
- return err
- }
- defer unix.Unmount(root, unix.MNT_DETACH)
- t := criurpc.CriuReqType_RESTORE
- req := &criurpc.CriuReq{
- Type: &t,
- Opts: &criurpc.CriuOpts{
- ImagesDirFd: proto.Int32(int32(imageDir.Fd())),
- WorkDirFd: proto.Int32(int32(workDir.Fd())),
- EvasiveDevices: proto.Bool(true),
- LogLevel: proto.Int32(4),
- LogFile: proto.String("restore.log"),
- RstSibling: proto.Bool(true),
- Root: proto.String(root),
- ManageCgroups: proto.Bool(true),
- NotifyScripts: proto.Bool(true),
- ShellJob: proto.Bool(criuOpts.ShellJob),
- ExtUnixSk: proto.Bool(criuOpts.ExternalUnixConnections),
- TcpEstablished: proto.Bool(criuOpts.TcpEstablished),
- FileLocks: proto.Bool(criuOpts.FileLocks),
- EmptyNs: proto.Uint32(criuOpts.EmptyNs),
- OrphanPtsMaster: proto.Bool(true),
- AutoDedup: proto.Bool(criuOpts.AutoDedup),
- LazyPages: proto.Bool(criuOpts.LazyPages),
- },
- }
-
- for _, m := range c.config.Mounts {
- switch m.Device {
- case "bind":
- c.addCriuRestoreMount(req, m)
- case "cgroup":
- binds, err := getCgroupMounts(m)
- if err != nil {
- return err
- }
- for _, b := range binds {
- c.addCriuRestoreMount(req, b)
- }
- }
- }
-
- if len(c.config.MaskPaths) > 0 {
- m := &configs.Mount{Destination: "/dev/null", Source: "/dev/null"}
- c.addCriuRestoreMount(req, m)
- }
-
- for _, node := range c.config.Devices {
- m := &configs.Mount{Destination: node.Path, Source: node.Path}
- c.addCriuRestoreMount(req, m)
- }
-
- if criuOpts.EmptyNs&unix.CLONE_NEWNET == 0 {
- c.restoreNetwork(req, criuOpts)
- }
-
- // append optional manage cgroups mode
- if criuOpts.ManageCgroupsMode != 0 {
- // criu 1.7 => 10700
- if err := c.checkCriuVersion(10700); err != nil {
- return err
- }
- mode := criurpc.CriuCgMode(criuOpts.ManageCgroupsMode)
- req.Opts.ManageCgroupsMode = &mode
- }
-
- var (
- fds []string
- fdJSON []byte
- )
- if fdJSON, err = ioutil.ReadFile(filepath.Join(criuOpts.ImagesDirectory, descriptorsFilename)); err != nil {
- return err
- }
-
- if err := json.Unmarshal(fdJSON, &fds); err != nil {
- return err
- }
- for i := range fds {
- if s := fds[i]; strings.Contains(s, "pipe:") {
- inheritFd := new(criurpc.InheritFd)
- inheritFd.Key = proto.String(s)
- inheritFd.Fd = proto.Int32(int32(i))
- req.Opts.InheritFd = append(req.Opts.InheritFd, inheritFd)
- }
- }
- return c.criuSwrk(process, req, criuOpts, true)
-}
-
-func (c *linuxContainer) criuApplyCgroups(pid int, req *criurpc.CriuReq) error {
- // XXX: Do we need to deal with this case? AFAIK criu still requires root.
- if err := c.cgroupManager.Apply(pid); err != nil {
- return err
- }
-
- if err := c.cgroupManager.Set(c.config); err != nil {
- return newSystemError(err)
- }
-
- path := fmt.Sprintf("/proc/%d/cgroup", pid)
- cgroupsPaths, err := cgroups.ParseCgroupFile(path)
- if err != nil {
- return err
- }
-
- for c, p := range cgroupsPaths {
- cgroupRoot := &criurpc.CgroupRoot{
- Ctrl: proto.String(c),
- Path: proto.String(p),
- }
- req.Opts.CgRoot = append(req.Opts.CgRoot, cgroupRoot)
- }
-
- return nil
-}
-
-func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *CriuOpts, applyCgroups bool) error {
- fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_SEQPACKET|unix.SOCK_CLOEXEC, 0)
- if err != nil {
- return err
- }
-
- var logPath string
- if opts != nil {
- logPath = filepath.Join(opts.WorkDirectory, req.GetOpts().GetLogFile())
- } else {
- // For the VERSION RPC 'opts' is set to 'nil' and therefore
- // opts.WorkDirectory does not exist. Set logPath to "".
- logPath = ""
- }
- criuClient := os.NewFile(uintptr(fds[0]), "criu-transport-client")
- criuClientFileCon, err := net.FileConn(criuClient)
- criuClient.Close()
- if err != nil {
- return err
- }
-
- criuClientCon := criuClientFileCon.(*net.UnixConn)
- defer criuClientCon.Close()
-
- criuServer := os.NewFile(uintptr(fds[1]), "criu-transport-server")
- defer criuServer.Close()
-
- args := []string{"swrk", "3"}
- if c.criuVersion != 0 {
- // If the CRIU Version is still '0' then this is probably
- // the initial CRIU run to detect the version. Skip it.
- logrus.Debugf("Using CRIU %d at: %s", c.criuVersion, c.criuPath)
- }
- logrus.Debugf("Using CRIU with following args: %s", args)
- cmd := exec.Command(c.criuPath, args...)
- if process != nil {
- cmd.Stdin = process.Stdin
- cmd.Stdout = process.Stdout
- cmd.Stderr = process.Stderr
- }
- cmd.ExtraFiles = append(cmd.ExtraFiles, criuServer)
-
- if err := cmd.Start(); err != nil {
- return err
- }
- criuServer.Close()
-
- defer func() {
- criuClientCon.Close()
- _, err := cmd.Process.Wait()
- if err != nil {
- return
- }
- }()
-
- if applyCgroups {
- err := c.criuApplyCgroups(cmd.Process.Pid, req)
- if err != nil {
- return err
- }
- }
-
- var extFds []string
- if process != nil {
- extFds, err = getPipeFds(cmd.Process.Pid)
- if err != nil {
- return err
- }
- }
-
- logrus.Debugf("Using CRIU in %s mode", req.GetType().String())
- // In the case of criurpc.CriuReqType_FEATURE_CHECK req.GetOpts()
- // should be empty. For older CRIU versions it still will be
- // available but empty. criurpc.CriuReqType_VERSION actually
- // has no req.GetOpts().
- if !(req.GetType() == criurpc.CriuReqType_FEATURE_CHECK ||
- req.GetType() == criurpc.CriuReqType_VERSION) {
-
- val := reflect.ValueOf(req.GetOpts())
- v := reflect.Indirect(val)
- for i := 0; i < v.NumField(); i++ {
- st := v.Type()
- name := st.Field(i).Name
- if strings.HasPrefix(name, "XXX_") {
- continue
- }
- value := val.MethodByName("Get" + name).Call([]reflect.Value{})
- logrus.Debugf("CRIU option %s with value %v", name, value[0])
- }
- }
- data, err := proto.Marshal(req)
- if err != nil {
- return err
- }
- _, err = criuClientCon.Write(data)
- if err != nil {
- return err
- }
-
- buf := make([]byte, 10*4096)
- oob := make([]byte, 4096)
- for true {
- n, oobn, _, _, err := criuClientCon.ReadMsgUnix(buf, oob)
- if err != nil {
- return err
- }
- if n == 0 {
- return fmt.Errorf("unexpected EOF")
- }
- if n == len(buf) {
- return fmt.Errorf("buffer is too small")
- }
-
- resp := new(criurpc.CriuResp)
- err = proto.Unmarshal(buf[:n], resp)
- if err != nil {
- return err
- }
- if !resp.GetSuccess() {
- typeString := req.GetType().String()
- if typeString == "VERSION" {
- // If the VERSION RPC fails this probably means that the CRIU
- // version is too old for this RPC. Just return 'nil'.
- return nil
- }
- return fmt.Errorf("criu failed: type %s errno %d\nlog file: %s", typeString, resp.GetCrErrno(), logPath)
- }
-
- t := resp.GetType()
- switch {
- case t == criurpc.CriuReqType_VERSION:
- logrus.Debugf("CRIU version: %s", resp)
- criuVersionRPC = resp.GetVersion()
- break
- case t == criurpc.CriuReqType_FEATURE_CHECK:
- logrus.Debugf("Feature check says: %s", resp)
- criuFeatures = resp.GetFeatures()
- case t == criurpc.CriuReqType_NOTIFY:
- if err := c.criuNotifications(resp, process, opts, extFds, oob[:oobn]); err != nil {
- return err
- }
- t = criurpc.CriuReqType_NOTIFY
- req = &criurpc.CriuReq{
- Type: &t,
- NotifySuccess: proto.Bool(true),
- }
- data, err = proto.Marshal(req)
- if err != nil {
- return err
- }
- _, err = criuClientCon.Write(data)
- if err != nil {
- return err
- }
- continue
- case t == criurpc.CriuReqType_RESTORE:
- case t == criurpc.CriuReqType_DUMP:
- case t == criurpc.CriuReqType_PRE_DUMP:
- default:
- return fmt.Errorf("unable to parse the response %s", resp.String())
- }
-
- break
- }
-
- criuClientCon.CloseWrite()
- // cmd.Wait() waits cmd.goroutines which are used for proxying file descriptors.
- // Here we want to wait only the CRIU process.
- st, err := cmd.Process.Wait()
- if err != nil {
- return err
- }
-
- // In pre-dump mode CRIU is in a loop and waits for
- // the final DUMP command.
- // The current runc pre-dump approach, however, is
- // start criu in PRE_DUMP once for a single pre-dump
- // and not the whole series of pre-dump, pre-dump, ...m, dump
- // If we got the message CriuReqType_PRE_DUMP it means
- // CRIU was successful and we need to forcefully stop CRIU
- if !st.Success() && *req.Type != criurpc.CriuReqType_PRE_DUMP {
- return fmt.Errorf("criu failed: %s\nlog file: %s", st.String(), logPath)
- }
- return nil
-}
-
-// block any external network activity
-func lockNetwork(config *configs.Config) error {
- for _, config := range config.Networks {
- strategy, err := getStrategy(config.Type)
- if err != nil {
- return err
- }
-
- if err := strategy.detach(config); err != nil {
- return err
- }
- }
- return nil
-}
-
-func unlockNetwork(config *configs.Config) error {
- for _, config := range config.Networks {
- strategy, err := getStrategy(config.Type)
- if err != nil {
- return err
- }
- if err = strategy.attach(config); err != nil {
- return err
- }
- }
- return nil
-}
-
-func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Process, opts *CriuOpts, fds []string, oob []byte) error {
- notify := resp.GetNotify()
- if notify == nil {
- return fmt.Errorf("invalid response: %s", resp.String())
- }
- logrus.Debugf("notify: %s\n", notify.GetScript())
- switch {
- case notify.GetScript() == "post-dump":
- f, err := os.Create(filepath.Join(c.root, "checkpoint"))
- if err != nil {
- return err
- }
- f.Close()
- case notify.GetScript() == "network-unlock":
- if err := unlockNetwork(c.config); err != nil {
- return err
- }
- case notify.GetScript() == "network-lock":
- if err := lockNetwork(c.config); err != nil {
- return err
- }
- case notify.GetScript() == "setup-namespaces":
- if c.config.Hooks != nil {
- bundle, annotations := utils.Annotations(c.config.Labels)
- s := configs.HookState{
- Version: c.config.Version,
- ID: c.id,
- Pid: int(notify.GetPid()),
- Bundle: bundle,
- Annotations: annotations,
- }
- for i, hook := range c.config.Hooks.Prestart {
- if err := hook.Run(s); err != nil {
- return newSystemErrorWithCausef(err, "running prestart hook %d", i)
- }
- }
- }
- case notify.GetScript() == "post-restore":
- pid := notify.GetPid()
- r, err := newRestoredProcess(int(pid), fds)
- if err != nil {
- return err
- }
- process.ops = r
- if err := c.state.transition(&restoredState{
- imageDir: opts.ImagesDirectory,
- c: c,
- }); err != nil {
- return err
- }
- // create a timestamp indicating when the restored checkpoint was started
- c.created = time.Now().UTC()
- if _, err := c.updateState(r); err != nil {
- return err
- }
- if err := os.Remove(filepath.Join(c.root, "checkpoint")); err != nil {
- if !os.IsNotExist(err) {
- logrus.Error(err)
- }
- }
- case notify.GetScript() == "orphan-pts-master":
- scm, err := unix.ParseSocketControlMessage(oob)
- if err != nil {
- return err
- }
- fds, err := unix.ParseUnixRights(&scm[0])
- if err != nil {
- return err
- }
-
- master := os.NewFile(uintptr(fds[0]), "orphan-pts-master")
- defer master.Close()
-
- // While we can access console.master, using the API is a good idea.
- if err := utils.SendFd(process.ConsoleSocket, master.Name(), master.Fd()); err != nil {
- return err
- }
- }
- return nil
-}
-
-func (c *linuxContainer) updateState(process parentProcess) (*State, error) {
- if process != nil {
- c.initProcess = process
- }
- state, err := c.currentState()
- if err != nil {
- return nil, err
- }
- err = c.saveState(state)
- if err != nil {
- return nil, err
- }
- return state, nil
-}
-
-func (c *linuxContainer) saveState(s *State) error {
- f, err := os.Create(filepath.Join(c.root, stateFilename))
- if err != nil {
- return err
- }
- defer f.Close()
- return utils.WriteJSON(f, s)
-}
-
-func (c *linuxContainer) deleteState() error {
- return os.Remove(filepath.Join(c.root, stateFilename))
-}
-
-func (c *linuxContainer) currentStatus() (Status, error) {
- if err := c.refreshState(); err != nil {
- return -1, err
- }
- return c.state.status(), nil
-}
-
-// refreshState needs to be called to verify that the current state on the
-// container is what is true. Because consumers of libcontainer can use it
-// out of process we need to verify the container's status based on runtime
-// information and not rely on our in process info.
-func (c *linuxContainer) refreshState() error {
- paused, err := c.isPaused()
- if err != nil {
- return err
- }
- if paused {
- return c.state.transition(&pausedState{c: c})
- }
- t, err := c.runType()
- if err != nil {
- return err
- }
- switch t {
- case Created:
- return c.state.transition(&createdState{c: c})
- case Running:
- return c.state.transition(&runningState{c: c})
- }
- return c.state.transition(&stoppedState{c: c})
-}
-
-func (c *linuxContainer) runType() (Status, error) {
- if c.initProcess == nil {
- return Stopped, nil
- }
- pid := c.initProcess.pid()
- stat, err := system.Stat(pid)
- if err != nil {
- return Stopped, nil
- }
- if stat.StartTime != c.initProcessStartTime || stat.State == system.Zombie || stat.State == system.Dead {
- return Stopped, nil
- }
- // We'll create exec fifo and blocking on it after container is created,
- // and delete it after start container.
- if _, err := os.Stat(filepath.Join(c.root, execFifoFilename)); err == nil {
- return Created, nil
- }
- return Running, nil
-}
-
-func (c *linuxContainer) isPaused() (bool, error) {
- fcg := c.cgroupManager.GetPaths()["freezer"]
- if fcg == "" {
- // A container doesn't have a freezer cgroup
- return false, nil
- }
- data, err := ioutil.ReadFile(filepath.Join(fcg, "freezer.state"))
- if err != nil {
- // If freezer cgroup is not mounted, the container would just be not paused.
- if os.IsNotExist(err) {
- return false, nil
- }
- return false, newSystemErrorWithCause(err, "checking if container is paused")
- }
- return bytes.Equal(bytes.TrimSpace(data), []byte("FROZEN")), nil
-}
-
-func (c *linuxContainer) currentState() (*State, error) {
- var (
- startTime uint64
- externalDescriptors []string
- pid = -1
- )
- if c.initProcess != nil {
- pid = c.initProcess.pid()
- startTime, _ = c.initProcess.startTime()
- externalDescriptors = c.initProcess.externalDescriptors()
- }
- intelRdtPath, err := intelrdt.GetIntelRdtPath(c.ID())
- if err != nil {
- intelRdtPath = ""
- }
- state := &State{
- BaseState: BaseState{
- ID: c.ID(),
- Config: *c.config,
- InitProcessPid: pid,
- InitProcessStartTime: startTime,
- Created: c.created,
- },
- Rootless: c.config.Rootless,
- CgroupPaths: c.cgroupManager.GetPaths(),
- IntelRdtPath: intelRdtPath,
- NamespacePaths: make(map[configs.NamespaceType]string),
- ExternalDescriptors: externalDescriptors,
- }
- if pid > 0 {
- for _, ns := range c.config.Namespaces {
- state.NamespacePaths[ns.Type] = ns.GetPath(pid)
- }
- for _, nsType := range configs.NamespaceTypes() {
- if !configs.IsNamespaceSupported(nsType) {
- continue
- }
- if _, ok := state.NamespacePaths[nsType]; !ok {
- ns := configs.Namespace{Type: nsType}
- state.NamespacePaths[ns.Type] = ns.GetPath(pid)
- }
- }
- }
- return state, nil
-}
-
-// orderNamespacePaths sorts namespace paths into a list of paths that we
-// can setns in order.
-func (c *linuxContainer) orderNamespacePaths(namespaces map[configs.NamespaceType]string) ([]string, error) {
- paths := []string{}
-
- for _, ns := range configs.NamespaceTypes() {
-
- // Remove namespaces that we don't need to join.
- if !c.config.Namespaces.Contains(ns) {
- continue
- }
-
- if p, ok := namespaces[ns]; ok && p != "" {
- // check if the requested namespace is supported
- if !configs.IsNamespaceSupported(ns) {
- return nil, newSystemError(fmt.Errorf("namespace %s is not supported", ns))
- }
- // only set to join this namespace if it exists
- if _, err := os.Lstat(p); err != nil {
- return nil, newSystemErrorWithCausef(err, "running lstat on namespace path %q", p)
- }
- // do not allow namespace path with comma as we use it to separate
- // the namespace paths
- if strings.ContainsRune(p, ',') {
- return nil, newSystemError(fmt.Errorf("invalid path %s", p))
- }
- paths = append(paths, fmt.Sprintf("%s:%s", configs.NsName(ns), p))
- }
-
- }
-
- return paths, nil
-}
-
-func encodeIDMapping(idMap []configs.IDMap) ([]byte, error) {
- data := bytes.NewBuffer(nil)
- for _, im := range idMap {
- line := fmt.Sprintf("%d %d %d\n", im.ContainerID, im.HostID, im.Size)
- if _, err := data.WriteString(line); err != nil {
- return nil, err
- }
- }
- return data.Bytes(), nil
-}
-
-// bootstrapData encodes the necessary data in netlink binary format
-// as a io.Reader.
-// Consumer can write the data to a bootstrap program
-// such as one that uses nsenter package to bootstrap the container's
-// init process correctly, i.e. with correct namespaces, uid/gid
-// mapping etc.
-func (c *linuxContainer) bootstrapData(cloneFlags uintptr, nsMaps map[configs.NamespaceType]string) (io.Reader, error) {
- // create the netlink message
- r := nl.NewNetlinkRequest(int(InitMsg), 0)
-
- // write cloneFlags
- r.AddData(&Int32msg{
- Type: CloneFlagsAttr,
- Value: uint32(cloneFlags),
- })
-
- // write custom namespace paths
- if len(nsMaps) > 0 {
- nsPaths, err := c.orderNamespacePaths(nsMaps)
- if err != nil {
- return nil, err
- }
- r.AddData(&Bytemsg{
- Type: NsPathsAttr,
- Value: []byte(strings.Join(nsPaths, ",")),
- })
- }
-
- // write namespace paths only when we are not joining an existing user ns
- _, joinExistingUser := nsMaps[configs.NEWUSER]
- if !joinExistingUser {
- // write uid mappings
- if len(c.config.UidMappings) > 0 {
- if c.config.Rootless && c.newuidmapPath != "" {
- r.AddData(&Bytemsg{
- Type: UidmapPathAttr,
- Value: []byte(c.newuidmapPath),
- })
- }
- b, err := encodeIDMapping(c.config.UidMappings)
- if err != nil {
- return nil, err
- }
- r.AddData(&Bytemsg{
- Type: UidmapAttr,
- Value: b,
- })
- }
-
- // write gid mappings
- if len(c.config.GidMappings) > 0 {
- b, err := encodeIDMapping(c.config.GidMappings)
- if err != nil {
- return nil, err
- }
- r.AddData(&Bytemsg{
- Type: GidmapAttr,
- Value: b,
- })
- if c.config.Rootless && c.newgidmapPath != "" {
- r.AddData(&Bytemsg{
- Type: GidmapPathAttr,
- Value: []byte(c.newgidmapPath),
- })
- }
- // The following only applies if we are root.
- if !c.config.Rootless {
- // check if we have CAP_SETGID to setgroup properly
- pid, err := capability.NewPid(os.Getpid())
- if err != nil {
- return nil, err
- }
- if !pid.Get(capability.EFFECTIVE, capability.CAP_SETGID) {
- r.AddData(&Boolmsg{
- Type: SetgroupAttr,
- Value: true,
- })
- }
- }
- }
- }
-
- // write oom_score_adj
- r.AddData(&Bytemsg{
- Type: OomScoreAdjAttr,
- Value: []byte(fmt.Sprintf("%d", c.config.OomScoreAdj)),
- })
-
- // write rootless
- r.AddData(&Boolmsg{
- Type: RootlessAttr,
- Value: c.config.Rootless,
- })
-
- return bytes.NewReader(r.Serialize()), nil
-}
-
-// ignoreTerminateErrors returns nil if the given err matches an error known
-// to indicate that the terminate occurred successfully or err was nil, otherwise
-// err is returned unaltered.
-func ignoreTerminateErrors(err error) error {
- if err == nil {
- return nil
- }
- s := err.Error()
- switch {
- case strings.Contains(s, "process already finished"), strings.Contains(s, "Wait was already called"):
- return nil
- }
- return err
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go
deleted file mode 100644
index a2e344fc4..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package libcontainer
-
-// cgroup restoring strategy provided by criu
-type cgMode uint32
-
-const (
- CRIU_CG_MODE_SOFT cgMode = 3 + iota // restore cgroup properties if only dir created by criu
- CRIU_CG_MODE_FULL // always restore all cgroups and their properties
- CRIU_CG_MODE_STRICT // restore all, requiring them to not present in the system
- CRIU_CG_MODE_DEFAULT // the same as CRIU_CG_MODE_SOFT
-)
-
-type CriuPageServerInfo struct {
- Address string // IP address of CRIU page server
- Port int32 // port number of CRIU page server
-}
-
-type VethPairName struct {
- ContainerInterfaceName string
- HostInterfaceName string
-}
-
-type CriuOpts struct {
- ImagesDirectory string // directory for storing image files
- WorkDirectory string // directory to cd and write logs/pidfiles/stats to
- ParentImage string // directory for storing parent image files in pre-dump and dump
- LeaveRunning bool // leave container in running state after checkpoint
- TcpEstablished bool // checkpoint/restore established TCP connections
- ExternalUnixConnections bool // allow external unix connections
- ShellJob bool // allow to dump and restore shell jobs
- FileLocks bool // handle file locks, for safety
- PreDump bool // call criu predump to perform iterative checkpoint
- PageServer CriuPageServerInfo // allow to dump to criu page server
- VethPairs []VethPairName // pass the veth to criu when restore
- ManageCgroupsMode cgMode // dump or restore cgroup mode
- EmptyNs uint32 // don't c/r properties for namespace from this mask
- AutoDedup bool // auto deduplication for incremental dumps
- LazyPages bool // restore memory pages lazily using userfaultfd
- StatusFd string // fd for feedback when lazy server is ready
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/criurpc/criurpc.pb.go b/vendor/github.com/opencontainers/runc/libcontainer/criurpc/criurpc.pb.go
deleted file mode 100644
index 21af9db97..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/criurpc/criurpc.pb.go
+++ /dev/null
@@ -1,1178 +0,0 @@
-// Code generated by protoc-gen-go.
-// source: criurpc.proto
-// DO NOT EDIT!
-
-/*
-Package criurpc is a generated protocol buffer package.
-
-It is generated from these files:
- criurpc.proto
-
-It has these top-level messages:
- CriuPageServerInfo
- CriuVethPair
- ExtMountMap
- JoinNamespace
- InheritFd
- CgroupRoot
- UnixSk
- CriuOpts
- CriuDumpResp
- CriuRestoreResp
- CriuNotify
- CriuFeatures
- CriuReq
- CriuResp
- CriuVersion
-*/
-package criurpc
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import math "math"
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-type CriuCgMode int32
-
-const (
- CriuCgMode_IGNORE CriuCgMode = 0
- CriuCgMode_CG_NONE CriuCgMode = 1
- CriuCgMode_PROPS CriuCgMode = 2
- CriuCgMode_SOFT CriuCgMode = 3
- CriuCgMode_FULL CriuCgMode = 4
- CriuCgMode_STRICT CriuCgMode = 5
- CriuCgMode_DEFAULT CriuCgMode = 6
-)
-
-var CriuCgMode_name = map[int32]string{
- 0: "IGNORE",
- 1: "CG_NONE",
- 2: "PROPS",
- 3: "SOFT",
- 4: "FULL",
- 5: "STRICT",
- 6: "DEFAULT",
-}
-var CriuCgMode_value = map[string]int32{
- "IGNORE": 0,
- "CG_NONE": 1,
- "PROPS": 2,
- "SOFT": 3,
- "FULL": 4,
- "STRICT": 5,
- "DEFAULT": 6,
-}
-
-func (x CriuCgMode) Enum() *CriuCgMode {
- p := new(CriuCgMode)
- *p = x
- return p
-}
-func (x CriuCgMode) String() string {
- return proto.EnumName(CriuCgMode_name, int32(x))
-}
-func (x *CriuCgMode) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(CriuCgMode_value, data, "CriuCgMode")
- if err != nil {
- return err
- }
- *x = CriuCgMode(value)
- return nil
-}
-func (CriuCgMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
-
-type CriuReqType int32
-
-const (
- CriuReqType_EMPTY CriuReqType = 0
- CriuReqType_DUMP CriuReqType = 1
- CriuReqType_RESTORE CriuReqType = 2
- CriuReqType_CHECK CriuReqType = 3
- CriuReqType_PRE_DUMP CriuReqType = 4
- CriuReqType_PAGE_SERVER CriuReqType = 5
- CriuReqType_NOTIFY CriuReqType = 6
- CriuReqType_CPUINFO_DUMP CriuReqType = 7
- CriuReqType_CPUINFO_CHECK CriuReqType = 8
- CriuReqType_FEATURE_CHECK CriuReqType = 9
- CriuReqType_VERSION CriuReqType = 10
-)
-
-var CriuReqType_name = map[int32]string{
- 0: "EMPTY",
- 1: "DUMP",
- 2: "RESTORE",
- 3: "CHECK",
- 4: "PRE_DUMP",
- 5: "PAGE_SERVER",
- 6: "NOTIFY",
- 7: "CPUINFO_DUMP",
- 8: "CPUINFO_CHECK",
- 9: "FEATURE_CHECK",
- 10: "VERSION",
-}
-var CriuReqType_value = map[string]int32{
- "EMPTY": 0,
- "DUMP": 1,
- "RESTORE": 2,
- "CHECK": 3,
- "PRE_DUMP": 4,
- "PAGE_SERVER": 5,
- "NOTIFY": 6,
- "CPUINFO_DUMP": 7,
- "CPUINFO_CHECK": 8,
- "FEATURE_CHECK": 9,
- "VERSION": 10,
-}
-
-func (x CriuReqType) Enum() *CriuReqType {
- p := new(CriuReqType)
- *p = x
- return p
-}
-func (x CriuReqType) String() string {
- return proto.EnumName(CriuReqType_name, int32(x))
-}
-func (x *CriuReqType) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(CriuReqType_value, data, "CriuReqType")
- if err != nil {
- return err
- }
- *x = CriuReqType(value)
- return nil
-}
-func (CriuReqType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
-
-type CriuPageServerInfo struct {
- Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"`
- Port *int32 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"`
- Pid *int32 `protobuf:"varint,3,opt,name=pid" json:"pid,omitempty"`
- Fd *int32 `protobuf:"varint,4,opt,name=fd" json:"fd,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CriuPageServerInfo) Reset() { *m = CriuPageServerInfo{} }
-func (m *CriuPageServerInfo) String() string { return proto.CompactTextString(m) }
-func (*CriuPageServerInfo) ProtoMessage() {}
-func (*CriuPageServerInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
-
-func (m *CriuPageServerInfo) GetAddress() string {
- if m != nil && m.Address != nil {
- return *m.Address
- }
- return ""
-}
-
-func (m *CriuPageServerInfo) GetPort() int32 {
- if m != nil && m.Port != nil {
- return *m.Port
- }
- return 0
-}
-
-func (m *CriuPageServerInfo) GetPid() int32 {
- if m != nil && m.Pid != nil {
- return *m.Pid
- }
- return 0
-}
-
-func (m *CriuPageServerInfo) GetFd() int32 {
- if m != nil && m.Fd != nil {
- return *m.Fd
- }
- return 0
-}
-
-type CriuVethPair struct {
- IfIn *string `protobuf:"bytes,1,req,name=if_in,json=ifIn" json:"if_in,omitempty"`
- IfOut *string `protobuf:"bytes,2,req,name=if_out,json=ifOut" json:"if_out,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CriuVethPair) Reset() { *m = CriuVethPair{} }
-func (m *CriuVethPair) String() string { return proto.CompactTextString(m) }
-func (*CriuVethPair) ProtoMessage() {}
-func (*CriuVethPair) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
-
-func (m *CriuVethPair) GetIfIn() string {
- if m != nil && m.IfIn != nil {
- return *m.IfIn
- }
- return ""
-}
-
-func (m *CriuVethPair) GetIfOut() string {
- if m != nil && m.IfOut != nil {
- return *m.IfOut
- }
- return ""
-}
-
-type ExtMountMap struct {
- Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"`
- Val *string `protobuf:"bytes,2,req,name=val" json:"val,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *ExtMountMap) Reset() { *m = ExtMountMap{} }
-func (m *ExtMountMap) String() string { return proto.CompactTextString(m) }
-func (*ExtMountMap) ProtoMessage() {}
-func (*ExtMountMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
-
-func (m *ExtMountMap) GetKey() string {
- if m != nil && m.Key != nil {
- return *m.Key
- }
- return ""
-}
-
-func (m *ExtMountMap) GetVal() string {
- if m != nil && m.Val != nil {
- return *m.Val
- }
- return ""
-}
-
-type JoinNamespace struct {
- Ns *string `protobuf:"bytes,1,req,name=ns" json:"ns,omitempty"`
- NsFile *string `protobuf:"bytes,2,req,name=ns_file,json=nsFile" json:"ns_file,omitempty"`
- ExtraOpt *string `protobuf:"bytes,3,opt,name=extra_opt,json=extraOpt" json:"extra_opt,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *JoinNamespace) Reset() { *m = JoinNamespace{} }
-func (m *JoinNamespace) String() string { return proto.CompactTextString(m) }
-func (*JoinNamespace) ProtoMessage() {}
-func (*JoinNamespace) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
-
-func (m *JoinNamespace) GetNs() string {
- if m != nil && m.Ns != nil {
- return *m.Ns
- }
- return ""
-}
-
-func (m *JoinNamespace) GetNsFile() string {
- if m != nil && m.NsFile != nil {
- return *m.NsFile
- }
- return ""
-}
-
-func (m *JoinNamespace) GetExtraOpt() string {
- if m != nil && m.ExtraOpt != nil {
- return *m.ExtraOpt
- }
- return ""
-}
-
-type InheritFd struct {
- Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"`
- Fd *int32 `protobuf:"varint,2,req,name=fd" json:"fd,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *InheritFd) Reset() { *m = InheritFd{} }
-func (m *InheritFd) String() string { return proto.CompactTextString(m) }
-func (*InheritFd) ProtoMessage() {}
-func (*InheritFd) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
-
-func (m *InheritFd) GetKey() string {
- if m != nil && m.Key != nil {
- return *m.Key
- }
- return ""
-}
-
-func (m *InheritFd) GetFd() int32 {
- if m != nil && m.Fd != nil {
- return *m.Fd
- }
- return 0
-}
-
-type CgroupRoot struct {
- Ctrl *string `protobuf:"bytes,1,opt,name=ctrl" json:"ctrl,omitempty"`
- Path *string `protobuf:"bytes,2,req,name=path" json:"path,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CgroupRoot) Reset() { *m = CgroupRoot{} }
-func (m *CgroupRoot) String() string { return proto.CompactTextString(m) }
-func (*CgroupRoot) ProtoMessage() {}
-func (*CgroupRoot) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
-
-func (m *CgroupRoot) GetCtrl() string {
- if m != nil && m.Ctrl != nil {
- return *m.Ctrl
- }
- return ""
-}
-
-func (m *CgroupRoot) GetPath() string {
- if m != nil && m.Path != nil {
- return *m.Path
- }
- return ""
-}
-
-type UnixSk struct {
- Inode *uint32 `protobuf:"varint,1,req,name=inode" json:"inode,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *UnixSk) Reset() { *m = UnixSk{} }
-func (m *UnixSk) String() string { return proto.CompactTextString(m) }
-func (*UnixSk) ProtoMessage() {}
-func (*UnixSk) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
-
-func (m *UnixSk) GetInode() uint32 {
- if m != nil && m.Inode != nil {
- return *m.Inode
- }
- return 0
-}
-
-type CriuOpts struct {
- ImagesDirFd *int32 `protobuf:"varint,1,req,name=images_dir_fd,json=imagesDirFd" json:"images_dir_fd,omitempty"`
- Pid *int32 `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"`
- LeaveRunning *bool `protobuf:"varint,3,opt,name=leave_running,json=leaveRunning" json:"leave_running,omitempty"`
- ExtUnixSk *bool `protobuf:"varint,4,opt,name=ext_unix_sk,json=extUnixSk" json:"ext_unix_sk,omitempty"`
- TcpEstablished *bool `protobuf:"varint,5,opt,name=tcp_established,json=tcpEstablished" json:"tcp_established,omitempty"`
- EvasiveDevices *bool `protobuf:"varint,6,opt,name=evasive_devices,json=evasiveDevices" json:"evasive_devices,omitempty"`
- ShellJob *bool `protobuf:"varint,7,opt,name=shell_job,json=shellJob" json:"shell_job,omitempty"`
- FileLocks *bool `protobuf:"varint,8,opt,name=file_locks,json=fileLocks" json:"file_locks,omitempty"`
- LogLevel *int32 `protobuf:"varint,9,opt,name=log_level,json=logLevel,def=2" json:"log_level,omitempty"`
- LogFile *string `protobuf:"bytes,10,opt,name=log_file,json=logFile" json:"log_file,omitempty"`
- Ps *CriuPageServerInfo `protobuf:"bytes,11,opt,name=ps" json:"ps,omitempty"`
- NotifyScripts *bool `protobuf:"varint,12,opt,name=notify_scripts,json=notifyScripts" json:"notify_scripts,omitempty"`
- Root *string `protobuf:"bytes,13,opt,name=root" json:"root,omitempty"`
- ParentImg *string `protobuf:"bytes,14,opt,name=parent_img,json=parentImg" json:"parent_img,omitempty"`
- TrackMem *bool `protobuf:"varint,15,opt,name=track_mem,json=trackMem" json:"track_mem,omitempty"`
- AutoDedup *bool `protobuf:"varint,16,opt,name=auto_dedup,json=autoDedup" json:"auto_dedup,omitempty"`
- WorkDirFd *int32 `protobuf:"varint,17,opt,name=work_dir_fd,json=workDirFd" json:"work_dir_fd,omitempty"`
- LinkRemap *bool `protobuf:"varint,18,opt,name=link_remap,json=linkRemap" json:"link_remap,omitempty"`
- Veths []*CriuVethPair `protobuf:"bytes,19,rep,name=veths" json:"veths,omitempty"`
- CpuCap *uint32 `protobuf:"varint,20,opt,name=cpu_cap,json=cpuCap,def=4294967295" json:"cpu_cap,omitempty"`
- ForceIrmap *bool `protobuf:"varint,21,opt,name=force_irmap,json=forceIrmap" json:"force_irmap,omitempty"`
- ExecCmd []string `protobuf:"bytes,22,rep,name=exec_cmd,json=execCmd" json:"exec_cmd,omitempty"`
- ExtMnt []*ExtMountMap `protobuf:"bytes,23,rep,name=ext_mnt,json=extMnt" json:"ext_mnt,omitempty"`
- ManageCgroups *bool `protobuf:"varint,24,opt,name=manage_cgroups,json=manageCgroups" json:"manage_cgroups,omitempty"`
- CgRoot []*CgroupRoot `protobuf:"bytes,25,rep,name=cg_root,json=cgRoot" json:"cg_root,omitempty"`
- RstSibling *bool `protobuf:"varint,26,opt,name=rst_sibling,json=rstSibling" json:"rst_sibling,omitempty"`
- InheritFd []*InheritFd `protobuf:"bytes,27,rep,name=inherit_fd,json=inheritFd" json:"inherit_fd,omitempty"`
- AutoExtMnt *bool `protobuf:"varint,28,opt,name=auto_ext_mnt,json=autoExtMnt" json:"auto_ext_mnt,omitempty"`
- ExtSharing *bool `protobuf:"varint,29,opt,name=ext_sharing,json=extSharing" json:"ext_sharing,omitempty"`
- ExtMasters *bool `protobuf:"varint,30,opt,name=ext_masters,json=extMasters" json:"ext_masters,omitempty"`
- SkipMnt []string `protobuf:"bytes,31,rep,name=skip_mnt,json=skipMnt" json:"skip_mnt,omitempty"`
- EnableFs []string `protobuf:"bytes,32,rep,name=enable_fs,json=enableFs" json:"enable_fs,omitempty"`
- UnixSkIno []*UnixSk `protobuf:"bytes,33,rep,name=unix_sk_ino,json=unixSkIno" json:"unix_sk_ino,omitempty"`
- ManageCgroupsMode *CriuCgMode `protobuf:"varint,34,opt,name=manage_cgroups_mode,json=manageCgroupsMode,enum=CriuCgMode" json:"manage_cgroups_mode,omitempty"`
- GhostLimit *uint32 `protobuf:"varint,35,opt,name=ghost_limit,json=ghostLimit,def=1048576" json:"ghost_limit,omitempty"`
- IrmapScanPaths []string `protobuf:"bytes,36,rep,name=irmap_scan_paths,json=irmapScanPaths" json:"irmap_scan_paths,omitempty"`
- External []string `protobuf:"bytes,37,rep,name=external" json:"external,omitempty"`
- EmptyNs *uint32 `protobuf:"varint,38,opt,name=empty_ns,json=emptyNs" json:"empty_ns,omitempty"`
- JoinNs []*JoinNamespace `protobuf:"bytes,39,rep,name=join_ns,json=joinNs" json:"join_ns,omitempty"`
- CgroupProps *string `protobuf:"bytes,41,opt,name=cgroup_props,json=cgroupProps" json:"cgroup_props,omitempty"`
- CgroupPropsFile *string `protobuf:"bytes,42,opt,name=cgroup_props_file,json=cgroupPropsFile" json:"cgroup_props_file,omitempty"`
- CgroupDumpController []string `protobuf:"bytes,43,rep,name=cgroup_dump_controller,json=cgroupDumpController" json:"cgroup_dump_controller,omitempty"`
- FreezeCgroup *string `protobuf:"bytes,44,opt,name=freeze_cgroup,json=freezeCgroup" json:"freeze_cgroup,omitempty"`
- Timeout *uint32 `protobuf:"varint,45,opt,name=timeout" json:"timeout,omitempty"`
- TcpSkipInFlight *bool `protobuf:"varint,46,opt,name=tcp_skip_in_flight,json=tcpSkipInFlight" json:"tcp_skip_in_flight,omitempty"`
- WeakSysctls *bool `protobuf:"varint,47,opt,name=weak_sysctls,json=weakSysctls" json:"weak_sysctls,omitempty"`
- LazyPages *bool `protobuf:"varint,48,opt,name=lazy_pages,json=lazyPages" json:"lazy_pages,omitempty"`
- StatusFd *int32 `protobuf:"varint,49,opt,name=status_fd,json=statusFd" json:"status_fd,omitempty"`
- OrphanPtsMaster *bool `protobuf:"varint,50,opt,name=orphan_pts_master,json=orphanPtsMaster" json:"orphan_pts_master,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CriuOpts) Reset() { *m = CriuOpts{} }
-func (m *CriuOpts) String() string { return proto.CompactTextString(m) }
-func (*CriuOpts) ProtoMessage() {}
-func (*CriuOpts) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
-
-const Default_CriuOpts_LogLevel int32 = 2
-const Default_CriuOpts_CpuCap uint32 = 4294967295
-const Default_CriuOpts_GhostLimit uint32 = 1048576
-
-func (m *CriuOpts) GetImagesDirFd() int32 {
- if m != nil && m.ImagesDirFd != nil {
- return *m.ImagesDirFd
- }
- return 0
-}
-
-func (m *CriuOpts) GetPid() int32 {
- if m != nil && m.Pid != nil {
- return *m.Pid
- }
- return 0
-}
-
-func (m *CriuOpts) GetLeaveRunning() bool {
- if m != nil && m.LeaveRunning != nil {
- return *m.LeaveRunning
- }
- return false
-}
-
-func (m *CriuOpts) GetExtUnixSk() bool {
- if m != nil && m.ExtUnixSk != nil {
- return *m.ExtUnixSk
- }
- return false
-}
-
-func (m *CriuOpts) GetTcpEstablished() bool {
- if m != nil && m.TcpEstablished != nil {
- return *m.TcpEstablished
- }
- return false
-}
-
-func (m *CriuOpts) GetEvasiveDevices() bool {
- if m != nil && m.EvasiveDevices != nil {
- return *m.EvasiveDevices
- }
- return false
-}
-
-func (m *CriuOpts) GetShellJob() bool {
- if m != nil && m.ShellJob != nil {
- return *m.ShellJob
- }
- return false
-}
-
-func (m *CriuOpts) GetFileLocks() bool {
- if m != nil && m.FileLocks != nil {
- return *m.FileLocks
- }
- return false
-}
-
-func (m *CriuOpts) GetLogLevel() int32 {
- if m != nil && m.LogLevel != nil {
- return *m.LogLevel
- }
- return Default_CriuOpts_LogLevel
-}
-
-func (m *CriuOpts) GetLogFile() string {
- if m != nil && m.LogFile != nil {
- return *m.LogFile
- }
- return ""
-}
-
-func (m *CriuOpts) GetPs() *CriuPageServerInfo {
- if m != nil {
- return m.Ps
- }
- return nil
-}
-
-func (m *CriuOpts) GetNotifyScripts() bool {
- if m != nil && m.NotifyScripts != nil {
- return *m.NotifyScripts
- }
- return false
-}
-
-func (m *CriuOpts) GetRoot() string {
- if m != nil && m.Root != nil {
- return *m.Root
- }
- return ""
-}
-
-func (m *CriuOpts) GetParentImg() string {
- if m != nil && m.ParentImg != nil {
- return *m.ParentImg
- }
- return ""
-}
-
-func (m *CriuOpts) GetTrackMem() bool {
- if m != nil && m.TrackMem != nil {
- return *m.TrackMem
- }
- return false
-}
-
-func (m *CriuOpts) GetAutoDedup() bool {
- if m != nil && m.AutoDedup != nil {
- return *m.AutoDedup
- }
- return false
-}
-
-func (m *CriuOpts) GetWorkDirFd() int32 {
- if m != nil && m.WorkDirFd != nil {
- return *m.WorkDirFd
- }
- return 0
-}
-
-func (m *CriuOpts) GetLinkRemap() bool {
- if m != nil && m.LinkRemap != nil {
- return *m.LinkRemap
- }
- return false
-}
-
-func (m *CriuOpts) GetVeths() []*CriuVethPair {
- if m != nil {
- return m.Veths
- }
- return nil
-}
-
-func (m *CriuOpts) GetCpuCap() uint32 {
- if m != nil && m.CpuCap != nil {
- return *m.CpuCap
- }
- return Default_CriuOpts_CpuCap
-}
-
-func (m *CriuOpts) GetForceIrmap() bool {
- if m != nil && m.ForceIrmap != nil {
- return *m.ForceIrmap
- }
- return false
-}
-
-func (m *CriuOpts) GetExecCmd() []string {
- if m != nil {
- return m.ExecCmd
- }
- return nil
-}
-
-func (m *CriuOpts) GetExtMnt() []*ExtMountMap {
- if m != nil {
- return m.ExtMnt
- }
- return nil
-}
-
-func (m *CriuOpts) GetManageCgroups() bool {
- if m != nil && m.ManageCgroups != nil {
- return *m.ManageCgroups
- }
- return false
-}
-
-func (m *CriuOpts) GetCgRoot() []*CgroupRoot {
- if m != nil {
- return m.CgRoot
- }
- return nil
-}
-
-func (m *CriuOpts) GetRstSibling() bool {
- if m != nil && m.RstSibling != nil {
- return *m.RstSibling
- }
- return false
-}
-
-func (m *CriuOpts) GetInheritFd() []*InheritFd {
- if m != nil {
- return m.InheritFd
- }
- return nil
-}
-
-func (m *CriuOpts) GetAutoExtMnt() bool {
- if m != nil && m.AutoExtMnt != nil {
- return *m.AutoExtMnt
- }
- return false
-}
-
-func (m *CriuOpts) GetExtSharing() bool {
- if m != nil && m.ExtSharing != nil {
- return *m.ExtSharing
- }
- return false
-}
-
-func (m *CriuOpts) GetExtMasters() bool {
- if m != nil && m.ExtMasters != nil {
- return *m.ExtMasters
- }
- return false
-}
-
-func (m *CriuOpts) GetSkipMnt() []string {
- if m != nil {
- return m.SkipMnt
- }
- return nil
-}
-
-func (m *CriuOpts) GetEnableFs() []string {
- if m != nil {
- return m.EnableFs
- }
- return nil
-}
-
-func (m *CriuOpts) GetUnixSkIno() []*UnixSk {
- if m != nil {
- return m.UnixSkIno
- }
- return nil
-}
-
-func (m *CriuOpts) GetManageCgroupsMode() CriuCgMode {
- if m != nil && m.ManageCgroupsMode != nil {
- return *m.ManageCgroupsMode
- }
- return CriuCgMode_IGNORE
-}
-
-func (m *CriuOpts) GetGhostLimit() uint32 {
- if m != nil && m.GhostLimit != nil {
- return *m.GhostLimit
- }
- return Default_CriuOpts_GhostLimit
-}
-
-func (m *CriuOpts) GetIrmapScanPaths() []string {
- if m != nil {
- return m.IrmapScanPaths
- }
- return nil
-}
-
-func (m *CriuOpts) GetExternal() []string {
- if m != nil {
- return m.External
- }
- return nil
-}
-
-func (m *CriuOpts) GetEmptyNs() uint32 {
- if m != nil && m.EmptyNs != nil {
- return *m.EmptyNs
- }
- return 0
-}
-
-func (m *CriuOpts) GetJoinNs() []*JoinNamespace {
- if m != nil {
- return m.JoinNs
- }
- return nil
-}
-
-func (m *CriuOpts) GetCgroupProps() string {
- if m != nil && m.CgroupProps != nil {
- return *m.CgroupProps
- }
- return ""
-}
-
-func (m *CriuOpts) GetCgroupPropsFile() string {
- if m != nil && m.CgroupPropsFile != nil {
- return *m.CgroupPropsFile
- }
- return ""
-}
-
-func (m *CriuOpts) GetCgroupDumpController() []string {
- if m != nil {
- return m.CgroupDumpController
- }
- return nil
-}
-
-func (m *CriuOpts) GetFreezeCgroup() string {
- if m != nil && m.FreezeCgroup != nil {
- return *m.FreezeCgroup
- }
- return ""
-}
-
-func (m *CriuOpts) GetTimeout() uint32 {
- if m != nil && m.Timeout != nil {
- return *m.Timeout
- }
- return 0
-}
-
-func (m *CriuOpts) GetTcpSkipInFlight() bool {
- if m != nil && m.TcpSkipInFlight != nil {
- return *m.TcpSkipInFlight
- }
- return false
-}
-
-func (m *CriuOpts) GetWeakSysctls() bool {
- if m != nil && m.WeakSysctls != nil {
- return *m.WeakSysctls
- }
- return false
-}
-
-func (m *CriuOpts) GetLazyPages() bool {
- if m != nil && m.LazyPages != nil {
- return *m.LazyPages
- }
- return false
-}
-
-func (m *CriuOpts) GetStatusFd() int32 {
- if m != nil && m.StatusFd != nil {
- return *m.StatusFd
- }
- return 0
-}
-
-func (m *CriuOpts) GetOrphanPtsMaster() bool {
- if m != nil && m.OrphanPtsMaster != nil {
- return *m.OrphanPtsMaster
- }
- return false
-}
-
-type CriuDumpResp struct {
- Restored *bool `protobuf:"varint,1,opt,name=restored" json:"restored,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CriuDumpResp) Reset() { *m = CriuDumpResp{} }
-func (m *CriuDumpResp) String() string { return proto.CompactTextString(m) }
-func (*CriuDumpResp) ProtoMessage() {}
-func (*CriuDumpResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
-
-func (m *CriuDumpResp) GetRestored() bool {
- if m != nil && m.Restored != nil {
- return *m.Restored
- }
- return false
-}
-
-type CriuRestoreResp struct {
- Pid *int32 `protobuf:"varint,1,req,name=pid" json:"pid,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CriuRestoreResp) Reset() { *m = CriuRestoreResp{} }
-func (m *CriuRestoreResp) String() string { return proto.CompactTextString(m) }
-func (*CriuRestoreResp) ProtoMessage() {}
-func (*CriuRestoreResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
-
-func (m *CriuRestoreResp) GetPid() int32 {
- if m != nil && m.Pid != nil {
- return *m.Pid
- }
- return 0
-}
-
-type CriuNotify struct {
- Script *string `protobuf:"bytes,1,opt,name=script" json:"script,omitempty"`
- Pid *int32 `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CriuNotify) Reset() { *m = CriuNotify{} }
-func (m *CriuNotify) String() string { return proto.CompactTextString(m) }
-func (*CriuNotify) ProtoMessage() {}
-func (*CriuNotify) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
-
-func (m *CriuNotify) GetScript() string {
- if m != nil && m.Script != nil {
- return *m.Script
- }
- return ""
-}
-
-func (m *CriuNotify) GetPid() int32 {
- if m != nil && m.Pid != nil {
- return *m.Pid
- }
- return 0
-}
-
-//
-// List of features which can queried via
-// CRIU_REQ_TYPE__FEATURE_CHECK
-type CriuFeatures struct {
- MemTrack *bool `protobuf:"varint,1,opt,name=mem_track,json=memTrack" json:"mem_track,omitempty"`
- LazyPages *bool `protobuf:"varint,2,opt,name=lazy_pages,json=lazyPages" json:"lazy_pages,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CriuFeatures) Reset() { *m = CriuFeatures{} }
-func (m *CriuFeatures) String() string { return proto.CompactTextString(m) }
-func (*CriuFeatures) ProtoMessage() {}
-func (*CriuFeatures) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
-
-func (m *CriuFeatures) GetMemTrack() bool {
- if m != nil && m.MemTrack != nil {
- return *m.MemTrack
- }
- return false
-}
-
-func (m *CriuFeatures) GetLazyPages() bool {
- if m != nil && m.LazyPages != nil {
- return *m.LazyPages
- }
- return false
-}
-
-type CriuReq struct {
- Type *CriuReqType `protobuf:"varint,1,req,name=type,enum=CriuReqType" json:"type,omitempty"`
- Opts *CriuOpts `protobuf:"bytes,2,opt,name=opts" json:"opts,omitempty"`
- NotifySuccess *bool `protobuf:"varint,3,opt,name=notify_success,json=notifySuccess" json:"notify_success,omitempty"`
- //
- // When set service won't close the connection but
- // will wait for more req-s to appear. Works not
- // for all request types.
- KeepOpen *bool `protobuf:"varint,4,opt,name=keep_open,json=keepOpen" json:"keep_open,omitempty"`
- //
- // 'features' can be used to query which features
- // are supported by the installed criu/kernel
- // via RPC.
- Features *CriuFeatures `protobuf:"bytes,5,opt,name=features" json:"features,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CriuReq) Reset() { *m = CriuReq{} }
-func (m *CriuReq) String() string { return proto.CompactTextString(m) }
-func (*CriuReq) ProtoMessage() {}
-func (*CriuReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
-
-func (m *CriuReq) GetType() CriuReqType {
- if m != nil && m.Type != nil {
- return *m.Type
- }
- return CriuReqType_EMPTY
-}
-
-func (m *CriuReq) GetOpts() *CriuOpts {
- if m != nil {
- return m.Opts
- }
- return nil
-}
-
-func (m *CriuReq) GetNotifySuccess() bool {
- if m != nil && m.NotifySuccess != nil {
- return *m.NotifySuccess
- }
- return false
-}
-
-func (m *CriuReq) GetKeepOpen() bool {
- if m != nil && m.KeepOpen != nil {
- return *m.KeepOpen
- }
- return false
-}
-
-func (m *CriuReq) GetFeatures() *CriuFeatures {
- if m != nil {
- return m.Features
- }
- return nil
-}
-
-type CriuResp struct {
- Type *CriuReqType `protobuf:"varint,1,req,name=type,enum=CriuReqType" json:"type,omitempty"`
- Success *bool `protobuf:"varint,2,req,name=success" json:"success,omitempty"`
- Dump *CriuDumpResp `protobuf:"bytes,3,opt,name=dump" json:"dump,omitempty"`
- Restore *CriuRestoreResp `protobuf:"bytes,4,opt,name=restore" json:"restore,omitempty"`
- Notify *CriuNotify `protobuf:"bytes,5,opt,name=notify" json:"notify,omitempty"`
- Ps *CriuPageServerInfo `protobuf:"bytes,6,opt,name=ps" json:"ps,omitempty"`
- CrErrno *int32 `protobuf:"varint,7,opt,name=cr_errno,json=crErrno" json:"cr_errno,omitempty"`
- Features *CriuFeatures `protobuf:"bytes,8,opt,name=features" json:"features,omitempty"`
- CrErrmsg *string `protobuf:"bytes,9,opt,name=cr_errmsg,json=crErrmsg" json:"cr_errmsg,omitempty"`
- Version *CriuVersion `protobuf:"bytes,10,opt,name=version" json:"version,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CriuResp) Reset() { *m = CriuResp{} }
-func (m *CriuResp) String() string { return proto.CompactTextString(m) }
-func (*CriuResp) ProtoMessage() {}
-func (*CriuResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
-
-func (m *CriuResp) GetType() CriuReqType {
- if m != nil && m.Type != nil {
- return *m.Type
- }
- return CriuReqType_EMPTY
-}
-
-func (m *CriuResp) GetSuccess() bool {
- if m != nil && m.Success != nil {
- return *m.Success
- }
- return false
-}
-
-func (m *CriuResp) GetDump() *CriuDumpResp {
- if m != nil {
- return m.Dump
- }
- return nil
-}
-
-func (m *CriuResp) GetRestore() *CriuRestoreResp {
- if m != nil {
- return m.Restore
- }
- return nil
-}
-
-func (m *CriuResp) GetNotify() *CriuNotify {
- if m != nil {
- return m.Notify
- }
- return nil
-}
-
-func (m *CriuResp) GetPs() *CriuPageServerInfo {
- if m != nil {
- return m.Ps
- }
- return nil
-}
-
-func (m *CriuResp) GetCrErrno() int32 {
- if m != nil && m.CrErrno != nil {
- return *m.CrErrno
- }
- return 0
-}
-
-func (m *CriuResp) GetFeatures() *CriuFeatures {
- if m != nil {
- return m.Features
- }
- return nil
-}
-
-func (m *CriuResp) GetCrErrmsg() string {
- if m != nil && m.CrErrmsg != nil {
- return *m.CrErrmsg
- }
- return ""
-}
-
-func (m *CriuResp) GetVersion() *CriuVersion {
- if m != nil {
- return m.Version
- }
- return nil
-}
-
-// Answer for criu_req_type.VERSION requests
-type CriuVersion struct {
- Major *int32 `protobuf:"varint,1,req,name=major" json:"major,omitempty"`
- Minor *int32 `protobuf:"varint,2,req,name=minor" json:"minor,omitempty"`
- Gitid *string `protobuf:"bytes,3,opt,name=gitid" json:"gitid,omitempty"`
- Sublevel *int32 `protobuf:"varint,4,opt,name=sublevel" json:"sublevel,omitempty"`
- Extra *int32 `protobuf:"varint,5,opt,name=extra" json:"extra,omitempty"`
- Name *string `protobuf:"bytes,6,opt,name=name" json:"name,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CriuVersion) Reset() { *m = CriuVersion{} }
-func (m *CriuVersion) String() string { return proto.CompactTextString(m) }
-func (*CriuVersion) ProtoMessage() {}
-func (*CriuVersion) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
-
-func (m *CriuVersion) GetMajor() int32 {
- if m != nil && m.Major != nil {
- return *m.Major
- }
- return 0
-}
-
-func (m *CriuVersion) GetMinor() int32 {
- if m != nil && m.Minor != nil {
- return *m.Minor
- }
- return 0
-}
-
-func (m *CriuVersion) GetGitid() string {
- if m != nil && m.Gitid != nil {
- return *m.Gitid
- }
- return ""
-}
-
-func (m *CriuVersion) GetSublevel() int32 {
- if m != nil && m.Sublevel != nil {
- return *m.Sublevel
- }
- return 0
-}
-
-func (m *CriuVersion) GetExtra() int32 {
- if m != nil && m.Extra != nil {
- return *m.Extra
- }
- return 0
-}
-
-func (m *CriuVersion) GetName() string {
- if m != nil && m.Name != nil {
- return *m.Name
- }
- return ""
-}
-
-func init() {
- proto.RegisterType((*CriuPageServerInfo)(nil), "criu_page_server_info")
- proto.RegisterType((*CriuVethPair)(nil), "criu_veth_pair")
- proto.RegisterType((*ExtMountMap)(nil), "ext_mount_map")
- proto.RegisterType((*JoinNamespace)(nil), "join_namespace")
- proto.RegisterType((*InheritFd)(nil), "inherit_fd")
- proto.RegisterType((*CgroupRoot)(nil), "cgroup_root")
- proto.RegisterType((*UnixSk)(nil), "unix_sk")
- proto.RegisterType((*CriuOpts)(nil), "criu_opts")
- proto.RegisterType((*CriuDumpResp)(nil), "criu_dump_resp")
- proto.RegisterType((*CriuRestoreResp)(nil), "criu_restore_resp")
- proto.RegisterType((*CriuNotify)(nil), "criu_notify")
- proto.RegisterType((*CriuFeatures)(nil), "criu_features")
- proto.RegisterType((*CriuReq)(nil), "criu_req")
- proto.RegisterType((*CriuResp)(nil), "criu_resp")
- proto.RegisterType((*CriuVersion)(nil), "criu_version")
- proto.RegisterEnum("CriuCgMode", CriuCgMode_name, CriuCgMode_value)
- proto.RegisterEnum("CriuReqType", CriuReqType_name, CriuReqType_value)
-}
-
-func init() { proto.RegisterFile("criurpc.proto", fileDescriptor0) }
-
-var fileDescriptor0 = []byte{
- // 1781 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xdd, 0x72, 0x5b, 0xb7,
- 0x11, 0x0e, 0x29, 0xfe, 0x1c, 0x82, 0x3f, 0xa6, 0x10, 0xdb, 0x81, 0x93, 0xda, 0x62, 0xe8, 0x28,
- 0x51, 0x15, 0x97, 0x4d, 0x58, 0x3b, 0xae, 0x33, 0xed, 0x85, 0x47, 0x22, 0x5d, 0x36, 0x92, 0xc8,
- 0x01, 0x25, 0xcf, 0xe4, 0x0a, 0x73, 0x74, 0x0e, 0x48, 0xc1, 0x3c, 0x7f, 0x05, 0x40, 0x45, 0xf2,
- 0x83, 0xf4, 0x29, 0xfa, 0x0c, 0x7d, 0x84, 0xbe, 0x4e, 0x6f, 0x3b, 0xbb, 0x00, 0x65, 0x29, 0xc9,
- 0xb4, 0xbd, 0xc3, 0x7e, 0x58, 0x00, 0xbb, 0xfb, 0xed, 0x0f, 0x48, 0x3b, 0xd2, 0x6a, 0xad, 0x8b,
- 0x68, 0x50, 0xe8, 0xdc, 0xe6, 0xfd, 0x25, 0x79, 0x00, 0x80, 0x28, 0xc2, 0xa5, 0x14, 0x46, 0xea,
- 0x4b, 0xa9, 0x85, 0xca, 0x16, 0x39, 0x65, 0xa4, 0x1e, 0xc6, 0xb1, 0x96, 0xc6, 0xb0, 0x52, 0xaf,
- 0xb4, 0xd7, 0xe0, 0x1b, 0x91, 0x52, 0x52, 0x29, 0x72, 0x6d, 0x59, 0xb9, 0x57, 0xda, 0xab, 0x72,
- 0x5c, 0xd3, 0x2e, 0xd9, 0x2a, 0x54, 0xcc, 0xb6, 0x10, 0x82, 0x25, 0xed, 0x90, 0xf2, 0x22, 0x66,
- 0x15, 0x04, 0xca, 0x8b, 0xb8, 0xff, 0x27, 0xd2, 0xc1, 0x87, 0x2e, 0xa5, 0xbd, 0x10, 0x45, 0xa8,
- 0x34, 0xfd, 0x98, 0x54, 0xd5, 0x42, 0xa8, 0x8c, 0x95, 0x7a, 0xe5, 0xbd, 0x06, 0xaf, 0xa8, 0xc5,
- 0x24, 0xa3, 0x0f, 0x48, 0x4d, 0x2d, 0x44, 0xbe, 0x86, 0xeb, 0x01, 0xad, 0xaa, 0xc5, 0x74, 0x6d,
- 0xfb, 0x7f, 0x20, 0x6d, 0x79, 0x65, 0x45, 0x9a, 0xaf, 0x33, 0x2b, 0xd2, 0xb0, 0x80, 0x07, 0x57,
- 0xf2, 0xda, 0x1f, 0x85, 0x25, 0x20, 0x97, 0x61, 0xe2, 0x8f, 0xc1, 0xb2, 0xff, 0x96, 0x74, 0xde,
- 0xe5, 0x2a, 0x13, 0x59, 0x98, 0x4a, 0x53, 0x84, 0x91, 0x04, 0xa3, 0x32, 0xe3, 0x0f, 0x95, 0x33,
- 0x43, 0x3f, 0x21, 0xf5, 0xcc, 0x88, 0x85, 0x4a, 0xa4, 0x3f, 0x57, 0xcb, 0xcc, 0x58, 0x25, 0x92,
- 0x7e, 0x46, 0x1a, 0xf2, 0xca, 0xea, 0x50, 0xe4, 0x85, 0x45, 0xaf, 0x1a, 0x3c, 0x40, 0x60, 0x5a,
- 0xd8, 0xfe, 0x80, 0x10, 0x95, 0x5d, 0x48, 0xad, 0xac, 0x58, 0xc4, 0xbf, 0x62, 0x89, 0x73, 0x1d,
- 0x2e, 0x74, 0xae, 0xbf, 0x20, 0xcd, 0x68, 0xa9, 0xf3, 0x75, 0x21, 0x74, 0x9e, 0x5b, 0x88, 0x5f,
- 0x64, 0x75, 0xe2, 0xc3, 0x8a, 0x6b, 0x8c, 0x69, 0x68, 0x2f, 0xbc, 0x15, 0xb8, 0xee, 0xef, 0x90,
- 0xfa, 0x3a, 0x53, 0x57, 0xc2, 0xac, 0xe8, 0x7d, 0x52, 0x55, 0x59, 0x1e, 0x4b, 0x7c, 0xa5, 0xcd,
- 0x9d, 0xd0, 0xff, 0x57, 0x9b, 0x34, 0x30, 0xa6, 0x79, 0x61, 0x0d, 0xed, 0x93, 0xb6, 0x4a, 0xc3,
- 0xa5, 0x34, 0x22, 0x56, 0x5a, 0x2c, 0x62, 0xd4, 0xad, 0xf2, 0xa6, 0x03, 0x0f, 0x95, 0x1e, 0xc7,
- 0x1b, 0x9a, 0xca, 0x1f, 0x68, 0x7a, 0x4a, 0xda, 0x89, 0x0c, 0x2f, 0xa5, 0xd0, 0xeb, 0x2c, 0x53,
- 0xd9, 0x12, 0x9d, 0x0d, 0x78, 0x0b, 0x41, 0xee, 0x30, 0xfa, 0x84, 0x34, 0x21, 0xfa, 0xde, 0x1a,
- 0x24, 0x35, 0xe0, 0x10, 0xa0, 0xb3, 0x4c, 0x5d, 0xcd, 0x57, 0xf4, 0x2b, 0x72, 0xcf, 0x46, 0x85,
- 0x90, 0xc6, 0x86, 0xe7, 0x89, 0x32, 0x17, 0x32, 0x66, 0x55, 0xd4, 0xe9, 0xd8, 0xa8, 0x18, 0x7d,
- 0x40, 0x41, 0x51, 0x5e, 0x86, 0x46, 0x5d, 0x4a, 0x11, 0xcb, 0x4b, 0x15, 0x49, 0xc3, 0x6a, 0x4e,
- 0xd1, 0xc3, 0x87, 0x0e, 0x85, 0xf8, 0x9b, 0x0b, 0x99, 0x24, 0xe2, 0x5d, 0x7e, 0xce, 0xea, 0xa8,
- 0x12, 0x20, 0xf0, 0xd7, 0xfc, 0x9c, 0x3e, 0x26, 0x04, 0x28, 0x13, 0x49, 0x1e, 0xad, 0x0c, 0x0b,
- 0x9c, 0x35, 0x80, 0x1c, 0x01, 0x40, 0x9f, 0x90, 0x46, 0x92, 0x2f, 0x45, 0x22, 0x2f, 0x65, 0xc2,
- 0x1a, 0xe0, 0xea, 0xf7, 0xa5, 0x21, 0x0f, 0x92, 0x7c, 0x79, 0x04, 0x10, 0x7d, 0x44, 0x60, 0xed,
- 0x58, 0x27, 0x2e, 0xb5, 0x93, 0x7c, 0x89, 0xb4, 0x7f, 0x49, 0xca, 0x85, 0x61, 0xcd, 0x5e, 0x69,
- 0xaf, 0x39, 0x7c, 0x38, 0xf8, 0xd5, 0xc2, 0xe0, 0xe5, 0xc2, 0xd0, 0x5d, 0xd2, 0xc9, 0x72, 0xab,
- 0x16, 0xd7, 0xc2, 0x44, 0x5a, 0x15, 0xd6, 0xb0, 0x16, 0x5a, 0xd1, 0x76, 0xe8, 0xdc, 0x81, 0xc0,
- 0x2a, 0x30, 0xce, 0xda, 0x8e, 0x69, 0x64, 0xff, 0x31, 0x21, 0x45, 0xa8, 0x65, 0x66, 0x85, 0x4a,
- 0x97, 0xac, 0x83, 0x3b, 0x0d, 0x87, 0x4c, 0xd2, 0x25, 0x38, 0x6e, 0x75, 0x18, 0xad, 0x44, 0x2a,
- 0x53, 0x76, 0xcf, 0x39, 0x8e, 0xc0, 0xb1, 0x4c, 0xe1, 0x6c, 0xb8, 0xb6, 0xb9, 0x88, 0x65, 0xbc,
- 0x2e, 0x58, 0xd7, 0x39, 0x0e, 0xc8, 0x21, 0x00, 0x40, 0xd3, 0x4f, 0xb9, 0x5e, 0x6d, 0xf8, 0xdf,
- 0x46, 0x96, 0x1b, 0x00, 0x39, 0xf6, 0x1f, 0x13, 0x92, 0xa8, 0x6c, 0x25, 0xb4, 0x4c, 0xc3, 0x82,
- 0x51, 0x77, 0x1c, 0x10, 0x0e, 0x00, 0xdd, 0x25, 0x55, 0x28, 0x4e, 0xc3, 0x3e, 0xee, 0x6d, 0xed,
- 0x35, 0x87, 0xf7, 0x06, 0x77, 0xeb, 0x95, 0xbb, 0x5d, 0xfa, 0x94, 0xd4, 0xa3, 0x62, 0x2d, 0xa2,
- 0xb0, 0x60, 0xf7, 0x7b, 0xa5, 0xbd, 0xf6, 0xf7, 0xe4, 0xf9, 0xf0, 0xd5, 0xf3, 0x57, 0xdf, 0xbd,
- 0x1c, 0xbe, 0x7a, 0xc1, 0x6b, 0x51, 0xb1, 0x3e, 0x08, 0x0b, 0xba, 0x43, 0x9a, 0x8b, 0x5c, 0x47,
- 0x52, 0x28, 0x0d, 0x6f, 0x3d, 0xc0, 0xb7, 0x08, 0x42, 0x13, 0x40, 0x80, 0x04, 0x79, 0x25, 0x23,
- 0x11, 0xa5, 0x31, 0x7b, 0xd8, 0xdb, 0x02, 0x12, 0x40, 0x3e, 0x48, 0x21, 0x49, 0xea, 0x58, 0xeb,
- 0x99, 0x65, 0x9f, 0xa0, 0x25, 0x9d, 0xc1, 0x9d, 0xda, 0xe7, 0x35, 0x79, 0x65, 0x8f, 0x33, 0x0b,
- 0x2c, 0xa4, 0x61, 0x06, 0xfc, 0xb8, 0xf2, 0x32, 0x8c, 0x39, 0x16, 0x1c, 0x7a, 0xe0, 0x40, 0xba,
- 0x4b, 0xea, 0xd1, 0x12, 0x4b, 0x8f, 0x3d, 0xc2, 0xfb, 0x5a, 0x83, 0x5b, 0xe5, 0xc8, 0x6b, 0xd1,
- 0x92, 0x03, 0x31, 0x3b, 0xa4, 0xa9, 0x8d, 0x15, 0x46, 0x9d, 0x27, 0x50, 0x07, 0x9f, 0x3a, 0x93,
- 0xb5, 0xb1, 0x73, 0x87, 0xd0, 0xfd, 0xdb, 0x65, 0xcf, 0x3e, 0xc3, 0xab, 0x9a, 0x83, 0x0f, 0x10,
- 0x6f, 0xf8, 0xf5, 0x38, 0xa6, 0x3d, 0xd2, 0x42, 0xa6, 0x36, 0x8e, 0xfc, 0xc6, 0xdd, 0x06, 0xd8,
- 0xc8, 0x19, 0xbf, 0xe3, 0x6a, 0xca, 0x5c, 0x84, 0x1a, 0x9e, 0x7b, 0xec, 0x14, 0xe4, 0x95, 0x9d,
- 0x3b, 0x64, 0xa3, 0x90, 0x86, 0xc6, 0x4a, 0x6d, 0xd8, 0x93, 0x1b, 0x85, 0x63, 0x87, 0x40, 0x08,
- 0xcd, 0x4a, 0x15, 0x78, 0xff, 0x8e, 0x0b, 0x21, 0xc8, 0x70, 0x39, 0xb4, 0xaf, 0x2c, 0x3c, 0x4f,
- 0xa4, 0x58, 0x18, 0xd6, 0xc3, 0xbd, 0xc0, 0x01, 0x63, 0x43, 0xf7, 0x48, 0xd3, 0x57, 0xb2, 0x50,
- 0x59, 0xce, 0x3e, 0x47, 0x47, 0x82, 0x81, 0xc7, 0x78, 0x63, 0x8d, 0x45, 0x3d, 0xc9, 0x72, 0xfa,
- 0x67, 0xf2, 0xf1, 0xdd, 0x00, 0x8b, 0x14, 0x9a, 0x50, 0xbf, 0x57, 0xda, 0xeb, 0x0c, 0xdb, 0x2e,
- 0x3f, 0xa2, 0x25, 0x82, 0x7c, 0xfb, 0x4e, 0xd0, 0x8f, 0xf3, 0x58, 0xc2, 0x43, 0xcb, 0x8b, 0xdc,
- 0x58, 0x91, 0xa8, 0x54, 0x59, 0xf6, 0x14, 0xb3, 0xa5, 0xfe, 0xed, 0x37, 0xcf, 0xff, 0xf8, 0xe2,
- 0xe5, 0x77, 0x9c, 0xe0, 0xde, 0x11, 0x6c, 0xd1, 0x3d, 0xd2, 0xc5, 0x44, 0x11, 0x26, 0x0a, 0x33,
- 0x01, 0xdd, 0xcf, 0xb0, 0x2f, 0xd0, 0xec, 0x0e, 0xe2, 0xf3, 0x28, 0xcc, 0x66, 0x80, 0xd2, 0x4f,
- 0x21, 0x6f, 0xac, 0xd4, 0x59, 0x98, 0xb0, 0x5d, 0xef, 0x98, 0x97, 0x31, 0xa7, 0xd2, 0xc2, 0x5e,
- 0x8b, 0xcc, 0xb0, 0x2f, 0xe1, 0x31, 0x5e, 0x47, 0xf9, 0x04, 0x7c, 0xae, 0xbb, 0x51, 0x60, 0xd8,
- 0x57, 0x3e, 0xbb, 0xef, 0x8e, 0x06, 0x5e, 0x03, 0xf9, 0xc4, 0xd0, 0xcf, 0x49, 0xcb, 0x67, 0x47,
- 0xa1, 0xf3, 0xc2, 0xb0, 0xdf, 0x62, 0x85, 0xfa, 0x06, 0x3e, 0x03, 0x88, 0xee, 0x93, 0xed, 0xdb,
- 0x2a, 0xae, 0x93, 0xec, 0xa3, 0xde, 0xbd, 0x5b, 0x7a, 0xd8, 0x51, 0x9e, 0x93, 0x87, 0x5e, 0x37,
- 0x5e, 0xa7, 0x85, 0x88, 0xf2, 0xcc, 0xea, 0x3c, 0x49, 0xa4, 0x66, 0x5f, 0xa3, 0xf5, 0xf7, 0xdd,
- 0xee, 0xe1, 0x3a, 0x2d, 0x0e, 0x6e, 0xf6, 0xa0, 0x2b, 0x2f, 0xb4, 0x94, 0xef, 0x37, 0x81, 0x67,
- 0xcf, 0xf0, 0xf6, 0x96, 0x03, 0x5d, 0x8c, 0x61, 0x42, 0x5b, 0x95, 0x4a, 0x98, 0x95, 0xbf, 0x73,
- 0xde, 0x7a, 0x91, 0x7e, 0x4d, 0x28, 0xf4, 0x63, 0xcc, 0x0e, 0x95, 0x89, 0x45, 0xa2, 0x96, 0x17,
- 0x96, 0x0d, 0x30, 0x83, 0xa0, 0x53, 0xcf, 0x57, 0xaa, 0x98, 0x64, 0x63, 0x84, 0xc1, 0xe1, 0x9f,
- 0x64, 0xb8, 0x12, 0xe6, 0xda, 0x44, 0x36, 0x31, 0xec, 0xf7, 0xa8, 0xd6, 0x04, 0x6c, 0xee, 0x20,
- 0x6c, 0x1c, 0xe1, 0xfb, 0x6b, 0xec, 0x85, 0x86, 0x7d, 0xe3, 0x1b, 0x47, 0xf8, 0xfe, 0x7a, 0x06,
- 0x00, 0x36, 0x6b, 0x1b, 0xda, 0xb5, 0x81, 0xba, 0xf8, 0x16, 0xbb, 0x4e, 0xe0, 0x80, 0x71, 0x0c,
- 0xc1, 0xca, 0x75, 0x71, 0x01, 0xb4, 0x5a, 0xe3, 0xb3, 0x99, 0x0d, 0x9d, 0x29, 0x6e, 0x63, 0x66,
- 0x8d, 0x4b, 0xe9, 0xfe, 0x33, 0xff, 0x47, 0xc0, 0x50, 0x69, 0x69, 0x0a, 0xa0, 0x5b, 0x4b, 0x63,
- 0x73, 0x2d, 0x63, 0x9c, 0x97, 0x01, 0xbf, 0x91, 0xfb, 0xbb, 0x64, 0x1b, 0xb5, 0x3d, 0xe0, 0x0e,
- 0xf8, 0x09, 0xe7, 0x66, 0x1f, 0x2c, 0xfb, 0x2f, 0x49, 0x13, 0xd5, 0x5c, 0x6b, 0xa6, 0x0f, 0x49,
- 0xcd, 0xf5, 0x6c, 0x3f, 0x7f, 0xbd, 0xf4, 0xcb, 0xd1, 0xd8, 0xff, 0xc1, 0xfd, 0x95, 0xc4, 0x42,
- 0x86, 0x76, 0xad, 0x9d, 0x9f, 0xa9, 0x4c, 0x05, 0xb6, 0xe3, 0x8d, 0x35, 0xa9, 0x4c, 0x4f, 0x41,
- 0xfe, 0x59, 0x8c, 0xca, 0x3f, 0x8b, 0x51, 0xff, 0x9f, 0x25, 0x12, 0x78, 0x6b, 0xff, 0x46, 0xfb,
- 0xa4, 0x62, 0xaf, 0x0b, 0x37, 0xcd, 0x3b, 0xc3, 0xce, 0x60, 0xb3, 0x21, 0x00, 0xe5, 0xb8, 0x47,
- 0x9f, 0x90, 0x0a, 0x8c, 0x75, 0xbc, 0xa9, 0x39, 0x24, 0x83, 0x9b, 0x41, 0xcf, 0x11, 0xbf, 0x3d,
- 0x82, 0xd6, 0x51, 0x04, 0xdf, 0xb4, 0xad, 0x3b, 0x23, 0xc8, 0x81, 0x60, 0xf3, 0x4a, 0xca, 0x42,
- 0xe4, 0x85, 0xcc, 0xfc, 0xe0, 0x0e, 0x00, 0x98, 0x16, 0x32, 0xa3, 0xfb, 0x24, 0xd8, 0x38, 0x87,
- 0x03, 0xbb, 0xb9, 0xb1, 0x65, 0x83, 0xf2, 0x9b, 0xfd, 0xfe, 0xbf, 0xcb, 0xfe, 0xb3, 0x81, 0x61,
- 0xfe, 0x7f, 0x3c, 0x60, 0xa4, 0xbe, 0x31, 0x0d, 0xbe, 0x35, 0x01, 0xdf, 0x88, 0xf4, 0x29, 0xa9,
- 0x00, 0xc5, 0x68, 0xf1, 0xcd, 0xa0, 0xb9, 0x21, 0x9d, 0xe3, 0x26, 0x7d, 0x46, 0xea, 0x9e, 0x59,
- 0xb4, 0xbb, 0x39, 0xa4, 0x83, 0x5f, 0xd0, 0xcd, 0x37, 0x2a, 0xf4, 0x0b, 0x52, 0x73, 0x8e, 0x7b,
- 0x47, 0x5a, 0x83, 0x5b, 0xa4, 0x73, 0xbf, 0xe7, 0xe7, 0x7b, 0xed, 0x7f, 0xce, 0xf7, 0x47, 0x40,
- 0x96, 0x90, 0x5a, 0x67, 0x39, 0xfe, 0x3e, 0xaa, 0xbc, 0x1e, 0xe9, 0x11, 0x88, 0x77, 0x62, 0x16,
- 0xfc, 0xf7, 0x98, 0x41, 0xf0, 0xdd, 0x35, 0xa9, 0x59, 0xe2, 0x4f, 0xa4, 0xc1, 0x03, 0xbc, 0x27,
- 0x35, 0x4b, 0x18, 0x73, 0x97, 0x52, 0x1b, 0x95, 0x67, 0xf8, 0x0b, 0x69, 0x6e, 0x1a, 0xaa, 0x07,
- 0xf9, 0x66, 0xb7, 0xff, 0xf7, 0x12, 0x69, 0xdd, 0xde, 0x81, 0xdf, 0x60, 0x1a, 0xbe, 0xcb, 0xb5,
- 0xcf, 0x72, 0x27, 0x20, 0xaa, 0xb2, 0x5c, 0xfb, 0x8f, 0xa7, 0x13, 0x00, 0x5d, 0x2a, 0xeb, 0xbf,
- 0xe6, 0x0d, 0xee, 0x04, 0x28, 0x2b, 0xb3, 0x3e, 0x77, 0x3f, 0xa4, 0x8a, 0x2f, 0x58, 0x2f, 0xc3,
- 0x09, 0xfc, 0xe9, 0x62, 0x20, 0xab, 0xdc, 0x09, 0xf0, 0x95, 0x81, 0x5e, 0x89, 0xb1, 0x6b, 0x70,
- 0x5c, 0xef, 0x0b, 0x6f, 0x97, 0x1f, 0x01, 0x94, 0x90, 0xda, 0xe4, 0xcd, 0xc9, 0x94, 0x8f, 0xba,
- 0x1f, 0xd1, 0x26, 0xa9, 0x1f, 0xbc, 0x11, 0x27, 0xd3, 0x93, 0x51, 0xb7, 0x44, 0x1b, 0xa4, 0x3a,
- 0xe3, 0xd3, 0xd9, 0xbc, 0x5b, 0xa6, 0x01, 0xa9, 0xcc, 0xa7, 0xe3, 0xd3, 0xee, 0x16, 0xac, 0xc6,
- 0x67, 0x47, 0x47, 0xdd, 0x0a, 0x9c, 0x9b, 0x9f, 0xf2, 0xc9, 0xc1, 0x69, 0xb7, 0x0a, 0xe7, 0x0e,
- 0x47, 0xe3, 0xd7, 0x67, 0x47, 0xa7, 0xdd, 0xda, 0xfe, 0x3f, 0x4a, 0xbe, 0x04, 0x37, 0x99, 0x05,
- 0x37, 0x8d, 0x8e, 0x67, 0xa7, 0x3f, 0x76, 0x3f, 0x82, 0xf3, 0x87, 0x67, 0xc7, 0xb3, 0x6e, 0x09,
- 0xce, 0xf0, 0xd1, 0xfc, 0x14, 0x1e, 0x2e, 0x83, 0xc6, 0xc1, 0x5f, 0x46, 0x07, 0x3f, 0x74, 0xb7,
- 0x68, 0x8b, 0x04, 0x33, 0x3e, 0x12, 0xa8, 0x55, 0xa1, 0xf7, 0x48, 0x73, 0xf6, 0xfa, 0xcd, 0x48,
- 0xcc, 0x47, 0xfc, 0xed, 0x88, 0x77, 0xab, 0xf0, 0xec, 0xc9, 0xf4, 0x74, 0x32, 0xfe, 0xb1, 0x5b,
- 0xa3, 0x5d, 0xd2, 0x3a, 0x98, 0x9d, 0x4d, 0x4e, 0xc6, 0x53, 0xa7, 0x5e, 0xa7, 0xdb, 0xa4, 0xbd,
- 0x41, 0xdc, 0x7d, 0x01, 0x40, 0xe3, 0xd1, 0xeb, 0xd3, 0x33, 0x3e, 0xf2, 0x50, 0x03, 0x9e, 0x7e,
- 0x3b, 0xe2, 0xf3, 0xc9, 0xf4, 0xa4, 0x4b, 0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x2a, 0xaf,
- 0x49, 0x5b, 0x0d, 0x00, 0x00,
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/criurpc/criurpc.proto b/vendor/github.com/opencontainers/runc/libcontainer/criurpc/criurpc.proto
deleted file mode 100644
index 48e42e26e..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/criurpc/criurpc.proto
+++ /dev/null
@@ -1,209 +0,0 @@
-syntax = "proto2";
-
-message criu_page_server_info {
- optional string address = 1;
- optional int32 port = 2;
- optional int32 pid = 3;
- optional int32 fd = 4;
-}
-
-message criu_veth_pair {
- required string if_in = 1;
- required string if_out = 2;
-};
-
-message ext_mount_map {
- required string key = 1;
- required string val = 2;
-};
-
-message join_namespace {
- required string ns = 1;
- required string ns_file = 2;
- optional string extra_opt = 3;
-}
-
-message inherit_fd {
- required string key = 1;
- required int32 fd = 2;
-};
-
-message cgroup_root {
- optional string ctrl = 1;
- required string path = 2;
-};
-
-message unix_sk {
- required uint32 inode = 1;
-};
-
-enum criu_cg_mode {
- IGNORE = 0;
- CG_NONE = 1;
- PROPS = 2;
- SOFT = 3;
- FULL = 4;
- STRICT = 5;
- DEFAULT = 6;
-};
-
-message criu_opts {
- required int32 images_dir_fd = 1;
- optional int32 pid = 2; /* if not set on dump, will dump requesting process */
-
- optional bool leave_running = 3;
- optional bool ext_unix_sk = 4;
- optional bool tcp_established = 5;
- optional bool evasive_devices = 6;
- optional bool shell_job = 7;
- optional bool file_locks = 8;
- optional int32 log_level = 9 [default = 2];
- optional string log_file = 10; /* No subdirs are allowed. Consider using work-dir */
-
- optional criu_page_server_info ps = 11;
-
- optional bool notify_scripts = 12;
-
- optional string root = 13;
- optional string parent_img = 14;
- optional bool track_mem = 15;
- optional bool auto_dedup = 16;
-
- optional int32 work_dir_fd = 17;
- optional bool link_remap = 18;
- repeated criu_veth_pair veths = 19; /* DEPRECATED, use external instead */
-
- optional uint32 cpu_cap = 20 [default = 0xffffffff];
- optional bool force_irmap = 21;
- repeated string exec_cmd = 22;
-
- repeated ext_mount_map ext_mnt = 23; /* DEPRECATED, use external instead */
- optional bool manage_cgroups = 24; /* backward compatibility */
- repeated cgroup_root cg_root = 25;
-
- optional bool rst_sibling = 26; /* swrk only */
- repeated inherit_fd inherit_fd = 27; /* swrk only */
-
- optional bool auto_ext_mnt = 28;
- optional bool ext_sharing = 29;
- optional bool ext_masters = 30;
-
- repeated string skip_mnt = 31;
- repeated string enable_fs = 32;
-
- repeated unix_sk unix_sk_ino = 33; /* DEPRECATED, use external instead */
-
- optional criu_cg_mode manage_cgroups_mode = 34;
- optional uint32 ghost_limit = 35 [default = 0x100000];
- repeated string irmap_scan_paths = 36;
- repeated string external = 37;
- optional uint32 empty_ns = 38;
- repeated join_namespace join_ns = 39;
-
- optional string cgroup_props = 41;
- optional string cgroup_props_file = 42;
- repeated string cgroup_dump_controller = 43;
-
- optional string freeze_cgroup = 44;
- optional uint32 timeout = 45;
- optional bool tcp_skip_in_flight = 46;
- optional bool weak_sysctls = 47;
- optional bool lazy_pages = 48;
- optional int32 status_fd = 49;
- optional bool orphan_pts_master = 50;
-}
-
-message criu_dump_resp {
- optional bool restored = 1;
-}
-
-message criu_restore_resp {
- required int32 pid = 1;
-}
-
-message criu_notify {
- optional string script = 1;
- optional int32 pid = 2;
-}
-
-enum criu_req_type {
- EMPTY = 0;
- DUMP = 1;
- RESTORE = 2;
- CHECK = 3;
- PRE_DUMP = 4;
- PAGE_SERVER = 5;
-
- NOTIFY = 6;
-
- CPUINFO_DUMP = 7;
- CPUINFO_CHECK = 8;
-
- FEATURE_CHECK = 9;
-
- VERSION = 10;
-}
-
-/*
- * List of features which can queried via
- * CRIU_REQ_TYPE__FEATURE_CHECK
- */
-message criu_features {
- optional bool mem_track = 1;
- optional bool lazy_pages = 2;
-}
-
-/*
- * Request -- each type corresponds to must-be-there
- * request arguments of respective type
- */
-
-message criu_req {
- required criu_req_type type = 1;
-
- optional criu_opts opts = 2;
- optional bool notify_success = 3;
-
- /*
- * When set service won't close the connection but
- * will wait for more req-s to appear. Works not
- * for all request types.
- */
- optional bool keep_open = 4;
- /*
- * 'features' can be used to query which features
- * are supported by the installed criu/kernel
- * via RPC.
- */
- optional criu_features features = 5;
-}
-
-/*
- * Response -- it states whether the request was served
- * and additional request-specific information
- */
-
-message criu_resp {
- required criu_req_type type = 1;
- required bool success = 2;
-
- optional criu_dump_resp dump = 3;
- optional criu_restore_resp restore = 4;
- optional criu_notify notify = 5;
- optional criu_page_server_info ps = 6;
-
- optional int32 cr_errno = 7;
- optional criu_features features = 8;
- optional string cr_errmsg = 9;
- optional criu_version version = 10;
-}
-
-/* Answer for criu_req_type.VERSION requests */
-message criu_version {
- required int32 major = 1;
- required int32 minor = 2;
- optional string gitid = 3;
- optional int32 sublevel = 4;
- optional int32 extra = 5;
- optional string name = 6;
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/error.go b/vendor/github.com/opencontainers/runc/libcontainer/error.go
deleted file mode 100644
index 21a3789ba..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/error.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package libcontainer
-
-import "io"
-
-// ErrorCode is the API error code type.
-type ErrorCode int
-
-// API error codes.
-const (
- // Factory errors
- IdInUse ErrorCode = iota
- InvalidIdFormat
-
- // Container errors
- ContainerNotExists
- ContainerPaused
- ContainerNotStopped
- ContainerNotRunning
- ContainerNotPaused
-
- // Process errors
- NoProcessOps
-
- // Common errors
- ConfigInvalid
- ConsoleExists
- SystemError
-)
-
-func (c ErrorCode) String() string {
- switch c {
- case IdInUse:
- return "Id already in use"
- case InvalidIdFormat:
- return "Invalid format"
- case ContainerPaused:
- return "Container paused"
- case ConfigInvalid:
- return "Invalid configuration"
- case SystemError:
- return "System error"
- case ContainerNotExists:
- return "Container does not exist"
- case ContainerNotStopped:
- return "Container is not stopped"
- case ContainerNotRunning:
- return "Container is not running"
- case ConsoleExists:
- return "Console exists for process"
- case ContainerNotPaused:
- return "Container is not paused"
- case NoProcessOps:
- return "No process operations"
- default:
- return "Unknown error"
- }
-}
-
-// Error is the API error type.
-type Error interface {
- error
-
- // Returns an error if it failed to write the detail of the Error to w.
- // The detail of the Error may include the error message and a
- // representation of the stack trace.
- Detail(w io.Writer) error
-
- // Returns the error code for this error.
- Code() ErrorCode
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/factory.go b/vendor/github.com/opencontainers/runc/libcontainer/factory.go
deleted file mode 100644
index 0986cd77e..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/factory.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package libcontainer
-
-import (
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type Factory interface {
- // Creates a new container with the given id and starts the initial process inside it.
- // id must be a string containing only letters, digits and underscores and must contain
- // between 1 and 1024 characters, inclusive.
- //
- // The id must not already be in use by an existing container. Containers created using
- // a factory with the same path (and filesystem) must have distinct ids.
- //
- // Returns the new container with a running process.
- //
- // errors:
- // IdInUse - id is already in use by a container
- // InvalidIdFormat - id has incorrect format
- // ConfigInvalid - config is invalid
- // Systemerror - System error
- //
- // On error, any partially created container parts are cleaned up (the operation is atomic).
- Create(id string, config *configs.Config) (Container, error)
-
- // Load takes an ID for an existing container and returns the container information
- // from the state. This presents a read only view of the container.
- //
- // errors:
- // Path does not exist
- // System error
- Load(id string) (Container, error)
-
- // StartInitialization is an internal API to libcontainer used during the reexec of the
- // container.
- //
- // Errors:
- // Pipe connection error
- // System error
- StartInitialization() error
-
- // Type returns info string about factory type (e.g. lxc, libcontainer...)
- Type() string
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go
deleted file mode 100644
index 7d53d5e04..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go
+++ /dev/null
@@ -1,364 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "encoding/json"
- "fmt"
- "os"
- "path/filepath"
- "regexp"
- "runtime/debug"
- "strconv"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/cgroups/fs"
- "github.com/opencontainers/runc/libcontainer/cgroups/systemd"
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/configs/validate"
- "github.com/opencontainers/runc/libcontainer/intelrdt"
- "github.com/opencontainers/runc/libcontainer/mount"
- "github.com/opencontainers/runc/libcontainer/utils"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- stateFilename = "state.json"
- execFifoFilename = "exec.fifo"
-)
-
-var idRegex = regexp.MustCompile(`^[\w+-\.]+$`)
-
-// InitArgs returns an options func to configure a LinuxFactory with the
-// provided init binary path and arguments.
-func InitArgs(args ...string) func(*LinuxFactory) error {
- return func(l *LinuxFactory) (err error) {
- if len(args) > 0 {
- // Resolve relative paths to ensure that its available
- // after directory changes.
- if args[0], err = filepath.Abs(args[0]); err != nil {
- return newGenericError(err, ConfigInvalid)
- }
- }
-
- l.InitArgs = args
- return nil
- }
-}
-
-// SystemdCgroups is an options func to configure a LinuxFactory to return
-// containers that use systemd to create and manage cgroups.
-func SystemdCgroups(l *LinuxFactory) error {
- l.NewCgroupsManager = func(config *configs.Cgroup, paths map[string]string) cgroups.Manager {
- return &systemd.Manager{
- Cgroups: config,
- Paths: paths,
- }
- }
- return nil
-}
-
-// Cgroupfs is an options func to configure a LinuxFactory to return
-// containers that use the native cgroups filesystem implementation to
-// create and manage cgroups.
-func Cgroupfs(l *LinuxFactory) error {
- l.NewCgroupsManager = func(config *configs.Cgroup, paths map[string]string) cgroups.Manager {
- return &fs.Manager{
- Cgroups: config,
- Paths: paths,
- }
- }
- return nil
-}
-
-// IntelRdtfs is an options func to configure a LinuxFactory to return
-// containers that use the Intel RDT "resource control" filesystem to
-// create and manage Intel Xeon platform shared resources (e.g., L3 cache).
-func IntelRdtFs(l *LinuxFactory) error {
- l.NewIntelRdtManager = func(config *configs.Config, id string, path string) intelrdt.Manager {
- return &intelrdt.IntelRdtManager{
- Config: config,
- Id: id,
- Path: path,
- }
- }
- return nil
-}
-
-// TmpfsRoot is an option func to mount LinuxFactory.Root to tmpfs.
-func TmpfsRoot(l *LinuxFactory) error {
- mounted, err := mount.Mounted(l.Root)
- if err != nil {
- return err
- }
- if !mounted {
- if err := unix.Mount("tmpfs", l.Root, "tmpfs", 0, ""); err != nil {
- return err
- }
- }
- return nil
-}
-
-// CriuPath returns an option func to configure a LinuxFactory with the
-// provided criupath
-func CriuPath(criupath string) func(*LinuxFactory) error {
- return func(l *LinuxFactory) error {
- l.CriuPath = criupath
- return nil
- }
-}
-
-// New returns a linux based container factory based in the root directory and
-// configures the factory with the provided option funcs.
-func New(root string, options ...func(*LinuxFactory) error) (Factory, error) {
- if root != "" {
- if err := os.MkdirAll(root, 0700); err != nil {
- return nil, newGenericError(err, SystemError)
- }
- }
- l := &LinuxFactory{
- Root: root,
- InitPath: "/proc/self/exe",
- InitArgs: []string{os.Args[0], "init"},
- Validator: validate.New(),
- CriuPath: "criu",
- }
- Cgroupfs(l)
- for _, opt := range options {
- if opt == nil {
- continue
- }
- if err := opt(l); err != nil {
- return nil, err
- }
- }
- return l, nil
-}
-
-// LinuxFactory implements the default factory interface for linux based systems.
-type LinuxFactory struct {
- // Root directory for the factory to store state.
- Root string
-
- // InitPath is the path for calling the init responsibilities for spawning
- // a container.
- InitPath string
-
- // InitArgs are arguments for calling the init responsibilities for spawning
- // a container.
- InitArgs []string
-
- // CriuPath is the path to the criu binary used for checkpoint and restore of
- // containers.
- CriuPath string
-
- // New{u,g}uidmapPath is the path to the binaries used for mapping with
- // rootless containers.
- NewuidmapPath string
- NewgidmapPath string
-
- // Validator provides validation to container configurations.
- Validator validate.Validator
-
- // NewCgroupsManager returns an initialized cgroups manager for a single container.
- NewCgroupsManager func(config *configs.Cgroup, paths map[string]string) cgroups.Manager
-
- // NewIntelRdtManager returns an initialized Intel RDT manager for a single container.
- NewIntelRdtManager func(config *configs.Config, id string, path string) intelrdt.Manager
-}
-
-func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, error) {
- if l.Root == "" {
- return nil, newGenericError(fmt.Errorf("invalid root"), ConfigInvalid)
- }
- if err := l.validateID(id); err != nil {
- return nil, err
- }
- if err := l.Validator.Validate(config); err != nil {
- return nil, newGenericError(err, ConfigInvalid)
- }
- containerRoot := filepath.Join(l.Root, id)
- if _, err := os.Stat(containerRoot); err == nil {
- return nil, newGenericError(fmt.Errorf("container with id exists: %v", id), IdInUse)
- } else if !os.IsNotExist(err) {
- return nil, newGenericError(err, SystemError)
- }
- if err := os.MkdirAll(containerRoot, 0711); err != nil {
- return nil, newGenericError(err, SystemError)
- }
- if err := os.Chown(containerRoot, unix.Geteuid(), unix.Getegid()); err != nil {
- return nil, newGenericError(err, SystemError)
- }
- c := &linuxContainer{
- id: id,
- root: containerRoot,
- config: config,
- initPath: l.InitPath,
- initArgs: l.InitArgs,
- criuPath: l.CriuPath,
- newuidmapPath: l.NewuidmapPath,
- newgidmapPath: l.NewgidmapPath,
- cgroupManager: l.NewCgroupsManager(config.Cgroups, nil),
- }
- if intelrdt.IsEnabled() {
- c.intelRdtManager = l.NewIntelRdtManager(config, id, "")
- }
- c.state = &stoppedState{c: c}
- return c, nil
-}
-
-func (l *LinuxFactory) Load(id string) (Container, error) {
- if l.Root == "" {
- return nil, newGenericError(fmt.Errorf("invalid root"), ConfigInvalid)
- }
- containerRoot := filepath.Join(l.Root, id)
- state, err := l.loadState(containerRoot, id)
- if err != nil {
- return nil, err
- }
- r := &nonChildProcess{
- processPid: state.InitProcessPid,
- processStartTime: state.InitProcessStartTime,
- fds: state.ExternalDescriptors,
- }
- c := &linuxContainer{
- initProcess: r,
- initProcessStartTime: state.InitProcessStartTime,
- id: id,
- config: &state.Config,
- initPath: l.InitPath,
- initArgs: l.InitArgs,
- criuPath: l.CriuPath,
- newuidmapPath: l.NewuidmapPath,
- newgidmapPath: l.NewgidmapPath,
- cgroupManager: l.NewCgroupsManager(state.Config.Cgroups, state.CgroupPaths),
- root: containerRoot,
- created: state.Created,
- }
- c.state = &loadedState{c: c}
- if err := c.refreshState(); err != nil {
- return nil, err
- }
- if intelrdt.IsEnabled() {
- c.intelRdtManager = l.NewIntelRdtManager(&state.Config, id, state.IntelRdtPath)
- }
- return c, nil
-}
-
-func (l *LinuxFactory) Type() string {
- return "libcontainer"
-}
-
-// StartInitialization loads a container by opening the pipe fd from the parent to read the configuration and state
-// This is a low level implementation detail of the reexec and should not be consumed externally
-func (l *LinuxFactory) StartInitialization() (err error) {
- var (
- pipefd, fifofd int
- consoleSocket *os.File
- envInitPipe = os.Getenv("_LIBCONTAINER_INITPIPE")
- envFifoFd = os.Getenv("_LIBCONTAINER_FIFOFD")
- envConsole = os.Getenv("_LIBCONTAINER_CONSOLE")
- )
-
- // Get the INITPIPE.
- pipefd, err = strconv.Atoi(envInitPipe)
- if err != nil {
- return fmt.Errorf("unable to convert _LIBCONTAINER_INITPIPE=%s to int: %s", envInitPipe, err)
- }
-
- var (
- pipe = os.NewFile(uintptr(pipefd), "pipe")
- it = initType(os.Getenv("_LIBCONTAINER_INITTYPE"))
- )
- defer pipe.Close()
-
- // Only init processes have FIFOFD.
- fifofd = -1
- if it == initStandard {
- if fifofd, err = strconv.Atoi(envFifoFd); err != nil {
- return fmt.Errorf("unable to convert _LIBCONTAINER_FIFOFD=%s to int: %s", envFifoFd, err)
- }
- }
-
- if envConsole != "" {
- console, err := strconv.Atoi(envConsole)
- if err != nil {
- return fmt.Errorf("unable to convert _LIBCONTAINER_CONSOLE=%s to int: %s", envConsole, err)
- }
- consoleSocket = os.NewFile(uintptr(console), "console-socket")
- defer consoleSocket.Close()
- }
-
- // clear the current process's environment to clean any libcontainer
- // specific env vars.
- os.Clearenv()
-
- defer func() {
- // We have an error during the initialization of the container's init,
- // send it back to the parent process in the form of an initError.
- if werr := utils.WriteJSON(pipe, syncT{procError}); werr != nil {
- fmt.Fprintln(os.Stderr, err)
- return
- }
- if werr := utils.WriteJSON(pipe, newSystemError(err)); werr != nil {
- fmt.Fprintln(os.Stderr, err)
- return
- }
- }()
- defer func() {
- if e := recover(); e != nil {
- err = fmt.Errorf("panic from initialization: %v, %v", e, string(debug.Stack()))
- }
- }()
-
- i, err := newContainerInit(it, pipe, consoleSocket, fifofd)
- if err != nil {
- return err
- }
-
- // If Init succeeds, syscall.Exec will not return, hence none of the defers will be called.
- return i.Init()
-}
-
-func (l *LinuxFactory) loadState(root, id string) (*State, error) {
- f, err := os.Open(filepath.Join(root, stateFilename))
- if err != nil {
- if os.IsNotExist(err) {
- return nil, newGenericError(fmt.Errorf("container %q does not exist", id), ContainerNotExists)
- }
- return nil, newGenericError(err, SystemError)
- }
- defer f.Close()
- var state *State
- if err := json.NewDecoder(f).Decode(&state); err != nil {
- return nil, newGenericError(err, SystemError)
- }
- return state, nil
-}
-
-func (l *LinuxFactory) validateID(id string) error {
- if !idRegex.MatchString(id) {
- return newGenericError(fmt.Errorf("invalid id format: %v", id), InvalidIdFormat)
- }
-
- return nil
-}
-
-// NewuidmapPath returns an option func to configure a LinuxFactory with the
-// provided ..
-func NewuidmapPath(newuidmapPath string) func(*LinuxFactory) error {
- return func(l *LinuxFactory) error {
- l.NewuidmapPath = newuidmapPath
- return nil
- }
-}
-
-// NewgidmapPath returns an option func to configure a LinuxFactory with the
-// provided ..
-func NewgidmapPath(newgidmapPath string) func(*LinuxFactory) error {
- return func(l *LinuxFactory) error {
- l.NewgidmapPath = newgidmapPath
- return nil
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/generic_error.go b/vendor/github.com/opencontainers/runc/libcontainer/generic_error.go
deleted file mode 100644
index 6e7de2fe7..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/generic_error.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package libcontainer
-
-import (
- "fmt"
- "io"
- "text/template"
- "time"
-
- "github.com/opencontainers/runc/libcontainer/stacktrace"
-)
-
-var errorTemplate = template.Must(template.New("error").Parse(`Timestamp: {{.Timestamp}}
-Code: {{.ECode}}
-{{if .Message }}
-Message: {{.Message}}
-{{end}}
-Frames:{{range $i, $frame := .Stack.Frames}}
----
-{{$i}}: {{$frame.Function}}
-Package: {{$frame.Package}}
-File: {{$frame.File}}@{{$frame.Line}}{{end}}
-`))
-
-func newGenericError(err error, c ErrorCode) Error {
- if le, ok := err.(Error); ok {
- return le
- }
- gerr := &genericError{
- Timestamp: time.Now(),
- Err: err,
- ECode: c,
- Stack: stacktrace.Capture(1),
- }
- if err != nil {
- gerr.Message = err.Error()
- }
- return gerr
-}
-
-func newSystemError(err error) Error {
- return createSystemError(err, "")
-}
-
-func newSystemErrorWithCausef(err error, cause string, v ...interface{}) Error {
- return createSystemError(err, fmt.Sprintf(cause, v...))
-}
-
-func newSystemErrorWithCause(err error, cause string) Error {
- return createSystemError(err, cause)
-}
-
-// createSystemError creates the specified error with the correct number of
-// stack frames skipped. This is only to be called by the other functions for
-// formatting the error.
-func createSystemError(err error, cause string) Error {
- gerr := &genericError{
- Timestamp: time.Now(),
- Err: err,
- ECode: SystemError,
- Cause: cause,
- Stack: stacktrace.Capture(2),
- }
- if err != nil {
- gerr.Message = err.Error()
- }
- return gerr
-}
-
-type genericError struct {
- Timestamp time.Time
- ECode ErrorCode
- Err error `json:"-"`
- Cause string
- Message string
- Stack stacktrace.Stacktrace
-}
-
-func (e *genericError) Error() string {
- if e.Cause == "" {
- return e.Message
- }
- frame := e.Stack.Frames[0]
- return fmt.Sprintf("%s:%d: %s caused %q", frame.File, frame.Line, e.Cause, e.Message)
-}
-
-func (e *genericError) Code() ErrorCode {
- return e.ECode
-}
-
-func (e *genericError) Detail(w io.Writer) error {
- return errorTemplate.Execute(w, e)
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go
deleted file mode 100644
index 2770be307..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go
+++ /dev/null
@@ -1,534 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "encoding/json"
- "fmt"
- "io"
- "net"
- "os"
- "strings"
- "syscall" // only for Errno
- "unsafe"
-
- "golang.org/x/sys/unix"
-
- "github.com/containerd/console"
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/system"
- "github.com/opencontainers/runc/libcontainer/user"
- "github.com/opencontainers/runc/libcontainer/utils"
- "github.com/sirupsen/logrus"
- "github.com/vishvananda/netlink"
-)
-
-type initType string
-
-const (
- initSetns initType = "setns"
- initStandard initType = "standard"
-)
-
-type pid struct {
- Pid int `json:"pid"`
- PidFirstChild int `json:"pid_first"`
-}
-
-// network is an internal struct used to setup container networks.
-type network struct {
- configs.Network
-
- // TempVethPeerName is a unique temporary veth peer name that was placed into
- // the container's namespace.
- TempVethPeerName string `json:"temp_veth_peer_name"`
-}
-
-// initConfig is used for transferring parameters from Exec() to Init()
-type initConfig struct {
- Args []string `json:"args"`
- Env []string `json:"env"`
- Cwd string `json:"cwd"`
- Capabilities *configs.Capabilities `json:"capabilities"`
- ProcessLabel string `json:"process_label"`
- AppArmorProfile string `json:"apparmor_profile"`
- NoNewPrivileges bool `json:"no_new_privileges"`
- User string `json:"user"`
- AdditionalGroups []string `json:"additional_groups"`
- Config *configs.Config `json:"config"`
- Networks []*network `json:"network"`
- PassedFilesCount int `json:"passed_files_count"`
- ContainerId string `json:"containerid"`
- Rlimits []configs.Rlimit `json:"rlimits"`
- CreateConsole bool `json:"create_console"`
- ConsoleWidth uint16 `json:"console_width"`
- ConsoleHeight uint16 `json:"console_height"`
- Rootless bool `json:"rootless"`
-}
-
-type initer interface {
- Init() error
-}
-
-func newContainerInit(t initType, pipe *os.File, consoleSocket *os.File, fifoFd int) (initer, error) {
- var config *initConfig
- if err := json.NewDecoder(pipe).Decode(&config); err != nil {
- return nil, err
- }
- if err := populateProcessEnvironment(config.Env); err != nil {
- return nil, err
- }
- switch t {
- case initSetns:
- return &linuxSetnsInit{
- pipe: pipe,
- consoleSocket: consoleSocket,
- config: config,
- }, nil
- case initStandard:
- return &linuxStandardInit{
- pipe: pipe,
- consoleSocket: consoleSocket,
- parentPid: unix.Getppid(),
- config: config,
- fifoFd: fifoFd,
- }, nil
- }
- return nil, fmt.Errorf("unknown init type %q", t)
-}
-
-// populateProcessEnvironment loads the provided environment variables into the
-// current processes's environment.
-func populateProcessEnvironment(env []string) error {
- for _, pair := range env {
- p := strings.SplitN(pair, "=", 2)
- if len(p) < 2 {
- return fmt.Errorf("invalid environment '%v'", pair)
- }
- if err := os.Setenv(p[0], p[1]); err != nil {
- return err
- }
- }
- return nil
-}
-
-// finalizeNamespace drops the caps, sets the correct user
-// and working dir, and closes any leaked file descriptors
-// before executing the command inside the namespace
-func finalizeNamespace(config *initConfig) error {
- // Ensure that all unwanted fds we may have accidentally
- // inherited are marked close-on-exec so they stay out of the
- // container
- if err := utils.CloseExecFrom(config.PassedFilesCount + 3); err != nil {
- return err
- }
-
- capabilities := &configs.Capabilities{}
- if config.Capabilities != nil {
- capabilities = config.Capabilities
- } else if config.Config.Capabilities != nil {
- capabilities = config.Config.Capabilities
- }
- w, err := newContainerCapList(capabilities)
- if err != nil {
- return err
- }
- // drop capabilities in bounding set before changing user
- if err := w.ApplyBoundingSet(); err != nil {
- return err
- }
- // preserve existing capabilities while we change users
- if err := system.SetKeepCaps(); err != nil {
- return err
- }
- if err := setupUser(config); err != nil {
- return err
- }
- if err := system.ClearKeepCaps(); err != nil {
- return err
- }
- if err := w.ApplyCaps(); err != nil {
- return err
- }
- if config.Cwd != "" {
- if err := unix.Chdir(config.Cwd); err != nil {
- return fmt.Errorf("chdir to cwd (%q) set in config.json failed: %v", config.Cwd, err)
- }
- }
- return nil
-}
-
-// setupConsole sets up the console from inside the container, and sends the
-// master pty fd to the config.Pipe (using cmsg). This is done to ensure that
-// consoles are scoped to a container properly (see runc#814 and the many
-// issues related to that). This has to be run *after* we've pivoted to the new
-// rootfs (and the users' configuration is entirely set up).
-func setupConsole(socket *os.File, config *initConfig, mount bool) error {
- defer socket.Close()
- // At this point, /dev/ptmx points to something that we would expect. We
- // used to change the owner of the slave path, but since the /dev/pts mount
- // can have gid=X set (at the users' option). So touching the owner of the
- // slave PTY is not necessary, as the kernel will handle that for us. Note
- // however, that setupUser (specifically fixStdioPermissions) *will* change
- // the UID owner of the console to be the user the process will run as (so
- // they can actually control their console).
-
- pty, slavePath, err := console.NewPty()
- if err != nil {
- return err
- }
-
- if config.ConsoleHeight != 0 && config.ConsoleWidth != 0 {
- err = pty.Resize(console.WinSize{
- Height: config.ConsoleHeight,
- Width: config.ConsoleWidth,
- })
-
- if err != nil {
- return err
- }
- }
-
- // After we return from here, we don't need the console anymore.
- defer pty.Close()
-
- // Mount the console inside our rootfs.
- if mount {
- if err := mountConsole(slavePath); err != nil {
- return err
- }
- }
- // While we can access console.master, using the API is a good idea.
- if err := utils.SendFd(socket, pty.Name(), pty.Fd()); err != nil {
- return err
- }
- // Now, dup over all the things.
- return dupStdio(slavePath)
-}
-
-// syncParentReady sends to the given pipe a JSON payload which indicates that
-// the init is ready to Exec the child process. It then waits for the parent to
-// indicate that it is cleared to Exec.
-func syncParentReady(pipe io.ReadWriter) error {
- // Tell parent.
- if err := writeSync(pipe, procReady); err != nil {
- return err
- }
-
- // Wait for parent to give the all-clear.
- if err := readSync(pipe, procRun); err != nil {
- return err
- }
-
- return nil
-}
-
-// syncParentHooks sends to the given pipe a JSON payload which indicates that
-// the parent should execute pre-start hooks. It then waits for the parent to
-// indicate that it is cleared to resume.
-func syncParentHooks(pipe io.ReadWriter) error {
- // Tell parent.
- if err := writeSync(pipe, procHooks); err != nil {
- return err
- }
-
- // Wait for parent to give the all-clear.
- if err := readSync(pipe, procResume); err != nil {
- return err
- }
-
- return nil
-}
-
-// setupUser changes the groups, gid, and uid for the user inside the container
-func setupUser(config *initConfig) error {
- // Set up defaults.
- defaultExecUser := user.ExecUser{
- Uid: 0,
- Gid: 0,
- Home: "/",
- }
-
- passwdPath, err := user.GetPasswdPath()
- if err != nil {
- return err
- }
-
- groupPath, err := user.GetGroupPath()
- if err != nil {
- return err
- }
-
- execUser, err := user.GetExecUserPath(config.User, &defaultExecUser, passwdPath, groupPath)
- if err != nil {
- return err
- }
-
- var addGroups []int
- if len(config.AdditionalGroups) > 0 {
- addGroups, err = user.GetAdditionalGroupsPath(config.AdditionalGroups, groupPath)
- if err != nil {
- return err
- }
- }
-
- // Rather than just erroring out later in setuid(2) and setgid(2), check
- // that the user is mapped here.
- if _, err := config.Config.HostUID(execUser.Uid); err != nil {
- return fmt.Errorf("cannot set uid to unmapped user in user namespace")
- }
- if _, err := config.Config.HostGID(execUser.Gid); err != nil {
- return fmt.Errorf("cannot set gid to unmapped user in user namespace")
- }
-
- if config.Rootless {
- // We cannot set any additional groups in a rootless container and thus
- // we bail if the user asked us to do so. TODO: We currently can't do
- // this check earlier, but if libcontainer.Process.User was typesafe
- // this might work.
- if len(addGroups) > 0 {
- return fmt.Errorf("cannot set any additional groups in a rootless container")
- }
- }
-
- // Before we change to the container's user make sure that the processes
- // STDIO is correctly owned by the user that we are switching to.
- if err := fixStdioPermissions(config, execUser); err != nil {
- return err
- }
-
- // This isn't allowed in an unprivileged user namespace since Linux 3.19.
- // There's nothing we can do about /etc/group entries, so we silently
- // ignore setting groups here (since the user didn't explicitly ask us to
- // set the group).
- if !config.Rootless {
- suppGroups := append(execUser.Sgids, addGroups...)
- if err := unix.Setgroups(suppGroups); err != nil {
- return err
- }
- }
-
- if err := system.Setgid(execUser.Gid); err != nil {
- return err
- }
- if err := system.Setuid(execUser.Uid); err != nil {
- return err
- }
-
- // if we didn't get HOME already, set it based on the user's HOME
- if envHome := os.Getenv("HOME"); envHome == "" {
- if err := os.Setenv("HOME", execUser.Home); err != nil {
- return err
- }
- }
- return nil
-}
-
-// fixStdioPermissions fixes the permissions of PID 1's STDIO within the container to the specified user.
-// The ownership needs to match because it is created outside of the container and needs to be
-// localized.
-func fixStdioPermissions(config *initConfig, u *user.ExecUser) error {
- var null unix.Stat_t
- if err := unix.Stat("/dev/null", &null); err != nil {
- return err
- }
- for _, fd := range []uintptr{
- os.Stdin.Fd(),
- os.Stderr.Fd(),
- os.Stdout.Fd(),
- } {
- var s unix.Stat_t
- if err := unix.Fstat(int(fd), &s); err != nil {
- return err
- }
-
- // Skip chown of /dev/null if it was used as one of the STDIO fds.
- if s.Rdev == null.Rdev {
- continue
- }
-
- // We only change the uid owner (as it is possible for the mount to
- // prefer a different gid, and there's no reason for us to change it).
- // The reason why we don't just leave the default uid=X mount setup is
- // that users expect to be able to actually use their console. Without
- // this code, you couldn't effectively run as a non-root user inside a
- // container and also have a console set up.
- if err := unix.Fchown(int(fd), u.Uid, int(s.Gid)); err != nil {
- // If we've hit an EINVAL then s.Gid isn't mapped in the user
- // namespace. If we've hit an EPERM then the inode's current owner
- // is not mapped in our user namespace (in particular,
- // privileged_wrt_inode_uidgid() has failed). In either case, we
- // are in a configuration where it's better for us to just not
- // touch the stdio rather than bail at this point.
- if err == unix.EINVAL || err == unix.EPERM {
- continue
- }
- return err
- }
- }
- return nil
-}
-
-// setupNetwork sets up and initializes any network interface inside the container.
-func setupNetwork(config *initConfig) error {
- for _, config := range config.Networks {
- strategy, err := getStrategy(config.Type)
- if err != nil {
- return err
- }
- if err := strategy.initialize(config); err != nil {
- return err
- }
- }
- return nil
-}
-
-func setupRoute(config *configs.Config) error {
- for _, config := range config.Routes {
- _, dst, err := net.ParseCIDR(config.Destination)
- if err != nil {
- return err
- }
- src := net.ParseIP(config.Source)
- if src == nil {
- return fmt.Errorf("Invalid source for route: %s", config.Source)
- }
- gw := net.ParseIP(config.Gateway)
- if gw == nil {
- return fmt.Errorf("Invalid gateway for route: %s", config.Gateway)
- }
- l, err := netlink.LinkByName(config.InterfaceName)
- if err != nil {
- return err
- }
- route := &netlink.Route{
- Scope: netlink.SCOPE_UNIVERSE,
- Dst: dst,
- Src: src,
- Gw: gw,
- LinkIndex: l.Attrs().Index,
- }
- if err := netlink.RouteAdd(route); err != nil {
- return err
- }
- }
- return nil
-}
-
-func setupRlimits(limits []configs.Rlimit, pid int) error {
- for _, rlimit := range limits {
- if err := system.Prlimit(pid, rlimit.Type, unix.Rlimit{Max: rlimit.Hard, Cur: rlimit.Soft}); err != nil {
- return fmt.Errorf("error setting rlimit type %v: %v", rlimit.Type, err)
- }
- }
- return nil
-}
-
-const _P_PID = 1
-
-type siginfo struct {
- si_signo int32
- si_errno int32
- si_code int32
- // below here is a union; si_pid is the only field we use
- si_pid int32
- // Pad to 128 bytes as detailed in blockUntilWaitable
- pad [96]byte
-}
-
-// isWaitable returns true if the process has exited false otherwise.
-// Its based off blockUntilWaitable in src/os/wait_waitid.go
-func isWaitable(pid int) (bool, error) {
- si := &siginfo{}
- _, _, e := unix.Syscall6(unix.SYS_WAITID, _P_PID, uintptr(pid), uintptr(unsafe.Pointer(si)), unix.WEXITED|unix.WNOWAIT|unix.WNOHANG, 0, 0)
- if e != 0 {
- return false, os.NewSyscallError("waitid", e)
- }
-
- return si.si_pid != 0, nil
-}
-
-// isNoChildren returns true if err represents a unix.ECHILD (formerly syscall.ECHILD) false otherwise
-func isNoChildren(err error) bool {
- switch err := err.(type) {
- case syscall.Errno:
- if err == unix.ECHILD {
- return true
- }
- case *os.SyscallError:
- if err.Err == unix.ECHILD {
- return true
- }
- }
- return false
-}
-
-// signalAllProcesses freezes then iterates over all the processes inside the
-// manager's cgroups sending the signal s to them.
-// If s is SIGKILL then it will wait for each process to exit.
-// For all other signals it will check if the process is ready to report its
-// exit status and only if it is will a wait be performed.
-func signalAllProcesses(m cgroups.Manager, s os.Signal) error {
- var procs []*os.Process
- if err := m.Freeze(configs.Frozen); err != nil {
- logrus.Warn(err)
- }
- pids, err := m.GetAllPids()
- if err != nil {
- m.Freeze(configs.Thawed)
- return err
- }
- for _, pid := range pids {
- p, err := os.FindProcess(pid)
- if err != nil {
- logrus.Warn(err)
- continue
- }
- procs = append(procs, p)
- if err := p.Signal(s); err != nil {
- logrus.Warn(err)
- }
- }
- if err := m.Freeze(configs.Thawed); err != nil {
- logrus.Warn(err)
- }
-
- subreaper, err := system.GetSubreaper()
- if err != nil {
- // The error here means that PR_GET_CHILD_SUBREAPER is not
- // supported because this code might run on a kernel older
- // than 3.4. We don't want to throw an error in that case,
- // and we simplify things, considering there is no subreaper
- // set.
- subreaper = 0
- }
-
- for _, p := range procs {
- if s != unix.SIGKILL {
- if ok, err := isWaitable(p.Pid); err != nil {
- if !isNoChildren(err) {
- logrus.Warn("signalAllProcesses: ", p.Pid, err)
- }
- continue
- } else if !ok {
- // Not ready to report so don't wait
- continue
- }
- }
-
- // In case a subreaper has been setup, this code must not
- // wait for the process. Otherwise, we cannot be sure the
- // current process will be reaped by the subreaper, while
- // the subreaper might be waiting for this process in order
- // to retrieve its exit code.
- if subreaper == 0 {
- if _, err := p.Wait(); err != nil {
- if !isNoChildren(err) {
- logrus.Warn("wait: ", err)
- }
- }
- }
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/intelrdt.go b/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/intelrdt.go
deleted file mode 100644
index 487c630af..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/intelrdt.go
+++ /dev/null
@@ -1,553 +0,0 @@
-// +build linux
-
-package intelrdt
-
-import (
- "bufio"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "strconv"
- "strings"
- "sync"
-
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-/*
- * About Intel RDT/CAT feature:
- * Intel platforms with new Xeon CPU support Resource Director Technology (RDT).
- * Intel Cache Allocation Technology (CAT) is a sub-feature of RDT. Currently L3
- * Cache is the only resource that is supported in RDT.
- *
- * This feature provides a way for the software to restrict cache allocation to a
- * defined 'subset' of L3 cache which may be overlapping with other 'subsets'.
- * The different subsets are identified by class of service (CLOS) and each CLOS
- * has a capacity bitmask (CBM).
- *
- * For more information about Intel RDT/CAT can be found in the section 17.17
- * of Intel Software Developer Manual.
- *
- * About Intel RDT/CAT kernel interface:
- * In Linux 4.10 kernel or newer, the interface is defined and exposed via
- * "resource control" filesystem, which is a "cgroup-like" interface.
- *
- * Comparing with cgroups, it has similar process management lifecycle and
- * interfaces in a container. But unlike cgroups' hierarchy, it has single level
- * filesystem layout.
- *
- * Intel RDT "resource control" filesystem hierarchy:
- * mount -t resctrl resctrl /sys/fs/resctrl
- * tree /sys/fs/resctrl
- * /sys/fs/resctrl/
- * |-- info
- * | |-- L3
- * | |-- cbm_mask
- * | |-- min_cbm_bits
- * | |-- num_closids
- * |-- cpus
- * |-- schemata
- * |-- tasks
- * |-- <container_id>
- * |-- cpus
- * |-- schemata
- * |-- tasks
- *
- * For runc, we can make use of `tasks` and `schemata` configuration for L3 cache
- * resource constraints.
- *
- * The file `tasks` has a list of tasks that belongs to this group (e.g.,
- * <container_id>" group). Tasks can be added to a group by writing the task ID
- * to the "tasks" file (which will automatically remove them from the previous
- * group to which they belonged). New tasks created by fork(2) and clone(2) are
- * added to the same group as their parent. If a pid is not in any sub group, it is
- * in root group.
- *
- * The file `schemata` has allocation bitmasks/values for L3 cache on each socket,
- * which contains L3 cache id and capacity bitmask (CBM).
- * Format: "L3:<cache_id0>=<cbm0>;<cache_id1>=<cbm1>;..."
- * For example, on a two-socket machine, L3's schema line could be `L3:0=ff;1=c0`
- * which means L3 cache id 0's CBM is 0xff, and L3 cache id 1's CBM is 0xc0.
- *
- * The valid L3 cache CBM is a *contiguous bits set* and number of bits that can
- * be set is less than the max bit. The max bits in the CBM is varied among
- * supported Intel Xeon platforms. In Intel RDT "resource control" filesystem
- * layout, the CBM in a group should be a subset of the CBM in root. Kernel will
- * check if it is valid when writing. e.g., 0xfffff in root indicates the max bits
- * of CBM is 20 bits, which mapping to entire L3 cache capacity. Some valid CBM
- * values to set in a group: 0xf, 0xf0, 0x3ff, 0x1f00 and etc.
- *
- * For more information about Intel RDT/CAT kernel interface:
- * https://www.kernel.org/doc/Documentation/x86/intel_rdt_ui.txt
- *
- * An example for runc:
- * Consider a two-socket machine with two L3 caches where the default CBM is
- * 0xfffff and the max CBM length is 20 bits. With this configuration, tasks
- * inside the container only have access to the "upper" 80% of L3 cache id 0 and
- * the "lower" 50% L3 cache id 1:
- *
- * "linux": {
- * "intelRdt": {
- * "l3CacheSchema": "L3:0=ffff0;1=3ff"
- * }
- * }
- */
-
-type Manager interface {
- // Applies Intel RDT configuration to the process with the specified pid
- Apply(pid int) error
-
- // Returns statistics for Intel RDT
- GetStats() (*Stats, error)
-
- // Destroys the Intel RDT 'container_id' group
- Destroy() error
-
- // Returns Intel RDT path to save in a state file and to be able to
- // restore the object later
- GetPath() string
-
- // Set Intel RDT "resource control" filesystem as configured.
- Set(container *configs.Config) error
-}
-
-// This implements interface Manager
-type IntelRdtManager struct {
- mu sync.Mutex
- Config *configs.Config
- Id string
- Path string
-}
-
-const (
- IntelRdtTasks = "tasks"
-)
-
-var (
- // The absolute root path of the Intel RDT "resource control" filesystem
- intelRdtRoot string
- intelRdtRootLock sync.Mutex
-
- // The flag to indicate if Intel RDT is supported
- isEnabled bool
-)
-
-type intelRdtData struct {
- root string
- config *configs.Config
- pid int
-}
-
-// Check if Intel RDT is enabled in init()
-func init() {
- // 1. Check if hardware and kernel support Intel RDT/CAT feature
- // "cat_l3" flag is set if supported
- isFlagSet, err := parseCpuInfoFile("/proc/cpuinfo")
- if !isFlagSet || err != nil {
- isEnabled = false
- return
- }
-
- // 2. Check if Intel RDT "resource control" filesystem is mounted
- // The user guarantees to mount the filesystem
- isEnabled = isIntelRdtMounted()
-}
-
-// Return the mount point path of Intel RDT "resource control" filesysem
-func findIntelRdtMountpointDir() (string, error) {
- f, err := os.Open("/proc/self/mountinfo")
- if err != nil {
- return "", err
- }
- defer f.Close()
-
- s := bufio.NewScanner(f)
- for s.Scan() {
- text := s.Text()
- fields := strings.Split(text, " ")
- // Safe as mountinfo encodes mountpoints with spaces as \040.
- index := strings.Index(text, " - ")
- postSeparatorFields := strings.Fields(text[index+3:])
- numPostFields := len(postSeparatorFields)
-
- // This is an error as we can't detect if the mount is for "Intel RDT"
- if numPostFields == 0 {
- return "", fmt.Errorf("Found no fields post '-' in %q", text)
- }
-
- if postSeparatorFields[0] == "resctrl" {
- // Check that the mount is properly formated.
- if numPostFields < 3 {
- return "", fmt.Errorf("Error found less than 3 fields post '-' in %q", text)
- }
-
- return fields[4], nil
- }
- }
- if err := s.Err(); err != nil {
- return "", err
- }
-
- return "", NewNotFoundError("Intel RDT")
-}
-
-// Gets the root path of Intel RDT "resource control" filesystem
-func getIntelRdtRoot() (string, error) {
- intelRdtRootLock.Lock()
- defer intelRdtRootLock.Unlock()
-
- if intelRdtRoot != "" {
- return intelRdtRoot, nil
- }
-
- root, err := findIntelRdtMountpointDir()
- if err != nil {
- return "", err
- }
-
- if _, err := os.Stat(root); err != nil {
- return "", err
- }
-
- intelRdtRoot = root
- return intelRdtRoot, nil
-}
-
-func isIntelRdtMounted() bool {
- _, err := getIntelRdtRoot()
- if err != nil {
- return false
- }
-
- return true
-}
-
-func parseCpuInfoFile(path string) (bool, error) {
- f, err := os.Open(path)
- if err != nil {
- return false, err
- }
- defer f.Close()
-
- s := bufio.NewScanner(f)
- for s.Scan() {
- if err := s.Err(); err != nil {
- return false, err
- }
-
- text := s.Text()
- flags := strings.Split(text, " ")
-
- // "cat_l3" flag is set if Intel RDT/CAT is supported
- for _, flag := range flags {
- if flag == "cat_l3" {
- return true, nil
- }
- }
- }
- return false, nil
-}
-
-func parseUint(s string, base, bitSize int) (uint64, error) {
- value, err := strconv.ParseUint(s, base, bitSize)
- if err != nil {
- intValue, intErr := strconv.ParseInt(s, base, bitSize)
- // 1. Handle negative values greater than MinInt64 (and)
- // 2. Handle negative values lesser than MinInt64
- if intErr == nil && intValue < 0 {
- return 0, nil
- } else if intErr != nil && intErr.(*strconv.NumError).Err == strconv.ErrRange && intValue < 0 {
- return 0, nil
- }
-
- return value, err
- }
-
- return value, nil
-}
-
-// Gets a single uint64 value from the specified file.
-func getIntelRdtParamUint(path, file string) (uint64, error) {
- fileName := filepath.Join(path, file)
- contents, err := ioutil.ReadFile(fileName)
- if err != nil {
- return 0, err
- }
-
- res, err := parseUint(strings.TrimSpace(string(contents)), 10, 64)
- if err != nil {
- return res, fmt.Errorf("unable to parse %q as a uint from file %q", string(contents), fileName)
- }
- return res, nil
-}
-
-// Gets a string value from the specified file
-func getIntelRdtParamString(path, file string) (string, error) {
- contents, err := ioutil.ReadFile(filepath.Join(path, file))
- if err != nil {
- return "", err
- }
-
- return strings.TrimSpace(string(contents)), nil
-}
-
-func readTasksFile(dir string) ([]int, error) {
- f, err := os.Open(filepath.Join(dir, IntelRdtTasks))
- if err != nil {
- return nil, err
- }
- defer f.Close()
-
- var (
- s = bufio.NewScanner(f)
- out = []int{}
- )
-
- for s.Scan() {
- if t := s.Text(); t != "" {
- pid, err := strconv.Atoi(t)
- if err != nil {
- return nil, err
- }
- out = append(out, pid)
- }
- }
- return out, nil
-}
-
-func writeFile(dir, file, data string) error {
- if dir == "" {
- return fmt.Errorf("no such directory for %s", file)
- }
- if err := ioutil.WriteFile(filepath.Join(dir, file), []byte(data+"\n"), 0700); err != nil {
- return fmt.Errorf("failed to write %v to %v: %v", data, file, err)
- }
- return nil
-}
-
-func getIntelRdtData(c *configs.Config, pid int) (*intelRdtData, error) {
- rootPath, err := getIntelRdtRoot()
- if err != nil {
- return nil, err
- }
- return &intelRdtData{
- root: rootPath,
- config: c,
- pid: pid,
- }, nil
-}
-
-// Get the read-only L3 cache information
-func getL3CacheInfo() (*L3CacheInfo, error) {
- l3CacheInfo := &L3CacheInfo{}
-
- rootPath, err := getIntelRdtRoot()
- if err != nil {
- return l3CacheInfo, err
- }
-
- path := filepath.Join(rootPath, "info", "L3")
- cbmMask, err := getIntelRdtParamString(path, "cbm_mask")
- if err != nil {
- return l3CacheInfo, err
- }
- minCbmBits, err := getIntelRdtParamUint(path, "min_cbm_bits")
- if err != nil {
- return l3CacheInfo, err
- }
- numClosids, err := getIntelRdtParamUint(path, "num_closids")
- if err != nil {
- return l3CacheInfo, err
- }
-
- l3CacheInfo.CbmMask = cbmMask
- l3CacheInfo.MinCbmBits = minCbmBits
- l3CacheInfo.NumClosids = numClosids
-
- return l3CacheInfo, nil
-}
-
-// WriteIntelRdtTasks writes the specified pid into the "tasks" file
-func WriteIntelRdtTasks(dir string, pid int) error {
- if dir == "" {
- return fmt.Errorf("no such directory for %s", IntelRdtTasks)
- }
-
- // Dont attach any pid if -1 is specified as a pid
- if pid != -1 {
- if err := ioutil.WriteFile(filepath.Join(dir, IntelRdtTasks), []byte(strconv.Itoa(pid)), 0700); err != nil {
- return fmt.Errorf("failed to write %v to %v: %v", pid, IntelRdtTasks, err)
- }
- }
- return nil
-}
-
-// Check if Intel RDT is enabled
-func IsEnabled() bool {
- return isEnabled
-}
-
-// Get the 'container_id' path in Intel RDT "resource control" filesystem
-func GetIntelRdtPath(id string) (string, error) {
- rootPath, err := getIntelRdtRoot()
- if err != nil {
- return "", err
- }
-
- path := filepath.Join(rootPath, id)
- return path, nil
-}
-
-// Applies Intel RDT configuration to the process with the specified pid
-func (m *IntelRdtManager) Apply(pid int) (err error) {
- // If intelRdt is not specified in config, we do nothing
- if m.Config.IntelRdt == nil {
- return nil
- }
- d, err := getIntelRdtData(m.Config, pid)
- if err != nil && !IsNotFound(err) {
- return err
- }
-
- m.mu.Lock()
- defer m.mu.Unlock()
- path, err := d.join(m.Id)
- if err != nil {
- return err
- }
-
- m.Path = path
- return nil
-}
-
-// Destroys the Intel RDT 'container_id' group
-func (m *IntelRdtManager) Destroy() error {
- m.mu.Lock()
- defer m.mu.Unlock()
- if err := os.RemoveAll(m.Path); err != nil {
- return err
- }
- m.Path = ""
- return nil
-}
-
-// Returns Intel RDT path to save in a state file and to be able to
-// restore the object later
-func (m *IntelRdtManager) GetPath() string {
- if m.Path == "" {
- m.Path, _ = GetIntelRdtPath(m.Id)
- }
- return m.Path
-}
-
-// Returns statistics for Intel RDT
-func (m *IntelRdtManager) GetStats() (*Stats, error) {
- // If intelRdt is not specified in config
- if m.Config.IntelRdt == nil {
- return nil, nil
- }
-
- m.mu.Lock()
- defer m.mu.Unlock()
- stats := NewStats()
-
- // The read-only L3 cache information
- l3CacheInfo, err := getL3CacheInfo()
- if err != nil {
- return nil, err
- }
- stats.L3CacheInfo = l3CacheInfo
-
- // The read-only L3 cache schema in root
- rootPath, err := getIntelRdtRoot()
- if err != nil {
- return nil, err
- }
- tmpRootStrings, err := getIntelRdtParamString(rootPath, "schemata")
- if err != nil {
- return nil, err
- }
- // L3 cache schema is in the first line
- schemaRootStrings := strings.Split(tmpRootStrings, "\n")
- stats.L3CacheSchemaRoot = schemaRootStrings[0]
-
- // The L3 cache schema in 'container_id' group
- tmpStrings, err := getIntelRdtParamString(m.GetPath(), "schemata")
- if err != nil {
- return nil, err
- }
- // L3 cache schema is in the first line
- schemaStrings := strings.Split(tmpStrings, "\n")
- stats.L3CacheSchema = schemaStrings[0]
-
- return stats, nil
-}
-
-// Set Intel RDT "resource control" filesystem as configured.
-func (m *IntelRdtManager) Set(container *configs.Config) error {
- path := m.GetPath()
-
- // About L3 cache schema file:
- // The schema has allocation masks/values for L3 cache on each socket,
- // which contains L3 cache id and capacity bitmask (CBM).
- // Format: "L3:<cache_id0>=<cbm0>;<cache_id1>=<cbm1>;..."
- // For example, on a two-socket machine, L3's schema line could be:
- // L3:0=ff;1=c0
- // Which means L3 cache id 0's CBM is 0xff, and L3 cache id 1's CBM is 0xc0.
- //
- // About L3 cache CBM validity:
- // The valid L3 cache CBM is a *contiguous bits set* and number of
- // bits that can be set is less than the max bit. The max bits in the
- // CBM is varied among supported Intel Xeon platforms. In Intel RDT
- // "resource control" filesystem layout, the CBM in a group should
- // be a subset of the CBM in root. Kernel will check if it is valid
- // when writing.
- // e.g., 0xfffff in root indicates the max bits of CBM is 20 bits,
- // which mapping to entire L3 cache capacity. Some valid CBM values
- // to set in a group: 0xf, 0xf0, 0x3ff, 0x1f00 and etc.
- if container.IntelRdt != nil {
- l3CacheSchema := container.IntelRdt.L3CacheSchema
- if l3CacheSchema != "" {
- if err := writeFile(path, "schemata", l3CacheSchema); err != nil {
- return err
- }
- }
- }
-
- return nil
-}
-
-func (raw *intelRdtData) join(id string) (string, error) {
- path := filepath.Join(raw.root, id)
- if err := os.MkdirAll(path, 0755); err != nil {
- return "", err
- }
-
- if err := WriteIntelRdtTasks(path, raw.pid); err != nil {
- return "", err
- }
- return path, nil
-}
-
-type NotFoundError struct {
- ResourceControl string
-}
-
-func (e *NotFoundError) Error() string {
- return fmt.Sprintf("mountpoint for %s not found", e.ResourceControl)
-}
-
-func NewNotFoundError(res string) error {
- return &NotFoundError{
- ResourceControl: res,
- }
-}
-
-func IsNotFound(err error) bool {
- if err == nil {
- return false
- }
- _, ok := err.(*NotFoundError)
- return ok
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/stats.go b/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/stats.go
deleted file mode 100644
index 095c0a380..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/stats.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// +build linux
-
-package intelrdt
-
-type L3CacheInfo struct {
- CbmMask string `json:"cbm_mask,omitempty"`
- MinCbmBits uint64 `json:"min_cbm_bits,omitempty"`
- NumClosids uint64 `json:"num_closids,omitempty"`
-}
-
-type Stats struct {
- // The read-only L3 cache information
- L3CacheInfo *L3CacheInfo `json:"l3_cache_info,omitempty"`
-
- // The read-only L3 cache schema in root
- L3CacheSchemaRoot string `json:"l3_cache_schema_root,omitempty"`
-
- // The L3 cache schema in 'container_id' group
- L3CacheSchema string `json:"l3_cache_schema,omitempty"`
-}
-
-func NewStats() *Stats {
- return &Stats{}
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go b/vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go
deleted file mode 100644
index ce8b4e6b0..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// +build linux
-
-package keys
-
-import (
- "fmt"
- "strconv"
- "strings"
-
- "golang.org/x/sys/unix"
-)
-
-type KeySerial uint32
-
-func JoinSessionKeyring(name string) (KeySerial, error) {
- sessKeyId, err := unix.KeyctlJoinSessionKeyring(name)
- if err != nil {
- return 0, fmt.Errorf("could not create session key: %v", err)
- }
- return KeySerial(sessKeyId), nil
-}
-
-// ModKeyringPerm modifies permissions on a keyring by reading the current permissions,
-// anding the bits with the given mask (clearing permissions) and setting
-// additional permission bits
-func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
- dest, err := unix.KeyctlString(unix.KEYCTL_DESCRIBE, int(ringId))
- if err != nil {
- return err
- }
-
- res := strings.Split(dest, ";")
- if len(res) < 5 {
- return fmt.Errorf("Destination buffer for key description is too small")
- }
-
- // parse permissions
- perm64, err := strconv.ParseUint(res[3], 16, 32)
- if err != nil {
- return err
- }
-
- perm := (uint32(perm64) & mask) | setbits
-
- if err := unix.KeyctlSetperm(int(ringId), perm); err != nil {
- return err
- }
-
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/message_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/message_linux.go
deleted file mode 100644
index ab453cde9..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/message_linux.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "github.com/vishvananda/netlink/nl"
- "golang.org/x/sys/unix"
-)
-
-// list of known message types we want to send to bootstrap program
-// The number is randomly chosen to not conflict with known netlink types
-const (
- InitMsg uint16 = 62000
- CloneFlagsAttr uint16 = 27281
- NsPathsAttr uint16 = 27282
- UidmapAttr uint16 = 27283
- GidmapAttr uint16 = 27284
- SetgroupAttr uint16 = 27285
- OomScoreAdjAttr uint16 = 27286
- RootlessAttr uint16 = 27287
- UidmapPathAttr uint16 = 27288
- GidmapPathAttr uint16 = 27289
-)
-
-type Int32msg struct {
- Type uint16
- Value uint32
-}
-
-// Serialize serializes the message.
-// Int32msg has the following representation
-// | nlattr len | nlattr type |
-// | uint32 value |
-func (msg *Int32msg) Serialize() []byte {
- buf := make([]byte, msg.Len())
- native := nl.NativeEndian()
- native.PutUint16(buf[0:2], uint16(msg.Len()))
- native.PutUint16(buf[2:4], msg.Type)
- native.PutUint32(buf[4:8], msg.Value)
- return buf
-}
-
-func (msg *Int32msg) Len() int {
- return unix.NLA_HDRLEN + 4
-}
-
-// Bytemsg has the following representation
-// | nlattr len | nlattr type |
-// | value | pad |
-type Bytemsg struct {
- Type uint16
- Value []byte
-}
-
-func (msg *Bytemsg) Serialize() []byte {
- l := msg.Len()
- buf := make([]byte, (l+unix.NLA_ALIGNTO-1) & ^(unix.NLA_ALIGNTO-1))
- native := nl.NativeEndian()
- native.PutUint16(buf[0:2], uint16(l))
- native.PutUint16(buf[2:4], msg.Type)
- copy(buf[4:], msg.Value)
- return buf
-}
-
-func (msg *Bytemsg) Len() int {
- return unix.NLA_HDRLEN + len(msg.Value) + 1 // null-terminated
-}
-
-type Boolmsg struct {
- Type uint16
- Value bool
-}
-
-func (msg *Boolmsg) Serialize() []byte {
- buf := make([]byte, msg.Len())
- native := nl.NativeEndian()
- native.PutUint16(buf[0:2], uint16(msg.Len()))
- native.PutUint16(buf[2:4], msg.Type)
- if msg.Value {
- buf[4] = 1
- } else {
- buf[4] = 0
- }
- return buf
-}
-
-func (msg *Boolmsg) Len() int {
- return unix.NLA_HDRLEN + 1
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/mount/mount.go b/vendor/github.com/opencontainers/runc/libcontainer/mount/mount.go
deleted file mode 100644
index e8965e081..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/mount/mount.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package mount
-
-// GetMounts retrieves a list of mounts for the current running process.
-func GetMounts() ([]*Info, error) {
- return parseMountTable()
-}
-
-// Mounted looks at /proc/self/mountinfo to determine of the specified
-// mountpoint has been mounted
-func Mounted(mountpoint string) (bool, error) {
- entries, err := parseMountTable()
- if err != nil {
- return false, err
- }
-
- // Search the table for the mountpoint
- for _, e := range entries {
- if e.Mountpoint == mountpoint {
- return true, nil
- }
- }
- return false, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/mount/mount_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/mount/mount_linux.go
deleted file mode 100644
index 1e5191928..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/mount/mount_linux.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// +build linux
-
-package mount
-
-import (
- "bufio"
- "fmt"
- "io"
- "os"
- "strings"
-)
-
-const (
- /* 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
- (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11)
-
- (1) mount ID: unique identifier of the mount (may be reused after umount)
- (2) parent ID: ID of parent (or of self for the top of the mount tree)
- (3) major:minor: value of st_dev for files on filesystem
- (4) root: root of the mount within the filesystem
- (5) mount point: mount point relative to the process's root
- (6) mount options: per mount options
- (7) optional fields: zero or more fields of the form "tag[:value]"
- (8) separator: marks the end of the optional fields
- (9) filesystem type: name of filesystem of the form "type[.subtype]"
- (10) mount source: filesystem specific information or "none"
- (11) super options: per super block options*/
- mountinfoFormat = "%d %d %d:%d %s %s %s %s"
-)
-
-// Parse /proc/self/mountinfo because comparing Dev and ino does not work from
-// bind mounts
-func parseMountTable() ([]*Info, error) {
- f, err := os.Open("/proc/self/mountinfo")
- if err != nil {
- return nil, err
- }
- defer f.Close()
-
- return parseInfoFile(f)
-}
-
-func parseInfoFile(r io.Reader) ([]*Info, error) {
- var (
- s = bufio.NewScanner(r)
- out = []*Info{}
- )
-
- for s.Scan() {
- if err := s.Err(); err != nil {
- return nil, err
- }
-
- var (
- p = &Info{}
- text = s.Text()
- optionalFields string
- )
-
- if _, err := fmt.Sscanf(text, mountinfoFormat,
- &p.ID, &p.Parent, &p.Major, &p.Minor,
- &p.Root, &p.Mountpoint, &p.Opts, &optionalFields); err != nil {
- return nil, fmt.Errorf("Scanning '%s' failed: %s", text, err)
- }
- // Safe as mountinfo encodes mountpoints with spaces as \040.
- index := strings.Index(text, " - ")
- postSeparatorFields := strings.Fields(text[index+3:])
- if len(postSeparatorFields) < 3 {
- return nil, fmt.Errorf("Error found less than 3 fields post '-' in %q", text)
- }
-
- if optionalFields != "-" {
- p.Optional = optionalFields
- }
-
- p.Fstype = postSeparatorFields[0]
- p.Source = postSeparatorFields[1]
- p.VfsOpts = strings.Join(postSeparatorFields[2:], " ")
- out = append(out, p)
- }
- return out, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/mount/mountinfo.go b/vendor/github.com/opencontainers/runc/libcontainer/mount/mountinfo.go
deleted file mode 100644
index e3fc3535e..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/mount/mountinfo.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package mount
-
-// Info reveals information about a particular mounted filesystem. This
-// struct is populated from the content in the /proc/<pid>/mountinfo file.
-type Info struct {
- // ID is a unique identifier of the mount (may be reused after umount).
- ID int
-
- // Parent indicates the ID of the mount parent (or of self for the top of the
- // mount tree).
- Parent int
-
- // Major indicates one half of the device ID which identifies the device class.
- Major int
-
- // Minor indicates one half of the device ID which identifies a specific
- // instance of device.
- Minor int
-
- // Root of the mount within the filesystem.
- Root string
-
- // Mountpoint indicates the mount point relative to the process's root.
- Mountpoint string
-
- // Opts represents mount-specific options.
- Opts string
-
- // Optional represents optional fields.
- Optional string
-
- // Fstype indicates the type of filesystem, such as EXT3.
- Fstype string
-
- // Source indicates filesystem specific information or "none".
- Source string
-
- // VfsOpts represents per super block options.
- VfsOpts string
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/network_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/network_linux.go
deleted file mode 100644
index 5075bee4d..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/network_linux.go
+++ /dev/null
@@ -1,259 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "fmt"
- "io/ioutil"
- "net"
- "path/filepath"
- "strconv"
- "strings"
-
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/utils"
- "github.com/vishvananda/netlink"
-)
-
-var strategies = map[string]networkStrategy{
- "veth": &veth{},
- "loopback": &loopback{},
-}
-
-// networkStrategy represents a specific network configuration for
-// a container's networking stack
-type networkStrategy interface {
- create(*network, int) error
- initialize(*network) error
- detach(*configs.Network) error
- attach(*configs.Network) error
-}
-
-// getStrategy returns the specific network strategy for the
-// provided type.
-func getStrategy(tpe string) (networkStrategy, error) {
- s, exists := strategies[tpe]
- if !exists {
- return nil, fmt.Errorf("unknown strategy type %q", tpe)
- }
- return s, nil
-}
-
-// Returns the network statistics for the network interfaces represented by the NetworkRuntimeInfo.
-func getNetworkInterfaceStats(interfaceName string) (*NetworkInterface, error) {
- out := &NetworkInterface{Name: interfaceName}
- // This can happen if the network runtime information is missing - possible if the
- // container was created by an old version of libcontainer.
- if interfaceName == "" {
- return out, nil
- }
- type netStatsPair struct {
- // Where to write the output.
- Out *uint64
- // The network stats file to read.
- File string
- }
- // Ingress for host veth is from the container. Hence tx_bytes stat on the host veth is actually number of bytes received by the container.
- netStats := []netStatsPair{
- {Out: &out.RxBytes, File: "tx_bytes"},
- {Out: &out.RxPackets, File: "tx_packets"},
- {Out: &out.RxErrors, File: "tx_errors"},
- {Out: &out.RxDropped, File: "tx_dropped"},
-
- {Out: &out.TxBytes, File: "rx_bytes"},
- {Out: &out.TxPackets, File: "rx_packets"},
- {Out: &out.TxErrors, File: "rx_errors"},
- {Out: &out.TxDropped, File: "rx_dropped"},
- }
- for _, netStat := range netStats {
- data, err := readSysfsNetworkStats(interfaceName, netStat.File)
- if err != nil {
- return nil, err
- }
- *(netStat.Out) = data
- }
- return out, nil
-}
-
-// Reads the specified statistics available under /sys/class/net/<EthInterface>/statistics
-func readSysfsNetworkStats(ethInterface, statsFile string) (uint64, error) {
- data, err := ioutil.ReadFile(filepath.Join("/sys/class/net", ethInterface, "statistics", statsFile))
- if err != nil {
- return 0, err
- }
- return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
-}
-
-// loopback is a network strategy that provides a basic loopback device
-type loopback struct {
-}
-
-func (l *loopback) create(n *network, nspid int) error {
- return nil
-}
-
-func (l *loopback) initialize(config *network) error {
- return netlink.LinkSetUp(&netlink.Device{LinkAttrs: netlink.LinkAttrs{Name: "lo"}})
-}
-
-func (l *loopback) attach(n *configs.Network) (err error) {
- return nil
-}
-
-func (l *loopback) detach(n *configs.Network) (err error) {
- return nil
-}
-
-// veth is a network strategy that uses a bridge and creates
-// a veth pair, one that is attached to the bridge on the host and the other
-// is placed inside the container's namespace
-type veth struct {
-}
-
-func (v *veth) detach(n *configs.Network) (err error) {
- return netlink.LinkSetMaster(&netlink.Device{LinkAttrs: netlink.LinkAttrs{Name: n.HostInterfaceName}}, nil)
-}
-
-// attach a container network interface to an external network
-func (v *veth) attach(n *configs.Network) (err error) {
- brl, err := netlink.LinkByName(n.Bridge)
- if err != nil {
- return err
- }
- br, ok := brl.(*netlink.Bridge)
- if !ok {
- return fmt.Errorf("Wrong device type %T", brl)
- }
- host, err := netlink.LinkByName(n.HostInterfaceName)
- if err != nil {
- return err
- }
-
- if err := netlink.LinkSetMaster(host, br); err != nil {
- return err
- }
- if err := netlink.LinkSetMTU(host, n.Mtu); err != nil {
- return err
- }
- if n.HairpinMode {
- if err := netlink.LinkSetHairpin(host, true); err != nil {
- return err
- }
- }
- if err := netlink.LinkSetUp(host); err != nil {
- return err
- }
-
- return nil
-}
-
-func (v *veth) create(n *network, nspid int) (err error) {
- tmpName, err := v.generateTempPeerName()
- if err != nil {
- return err
- }
- n.TempVethPeerName = tmpName
- if n.Bridge == "" {
- return fmt.Errorf("bridge is not specified")
- }
- veth := &netlink.Veth{
- LinkAttrs: netlink.LinkAttrs{
- Name: n.HostInterfaceName,
- TxQLen: n.TxQueueLen,
- },
- PeerName: n.TempVethPeerName,
- }
- if err := netlink.LinkAdd(veth); err != nil {
- return err
- }
- defer func() {
- if err != nil {
- netlink.LinkDel(veth)
- }
- }()
- if err := v.attach(&n.Network); err != nil {
- return err
- }
- child, err := netlink.LinkByName(n.TempVethPeerName)
- if err != nil {
- return err
- }
- return netlink.LinkSetNsPid(child, nspid)
-}
-
-func (v *veth) generateTempPeerName() (string, error) {
- return utils.GenerateRandomName("veth", 7)
-}
-
-func (v *veth) initialize(config *network) error {
- peer := config.TempVethPeerName
- if peer == "" {
- return fmt.Errorf("peer is not specified")
- }
- child, err := netlink.LinkByName(peer)
- if err != nil {
- return err
- }
- if err := netlink.LinkSetDown(child); err != nil {
- return err
- }
- if err := netlink.LinkSetName(child, config.Name); err != nil {
- return err
- }
- // get the interface again after we changed the name as the index also changes.
- if child, err = netlink.LinkByName(config.Name); err != nil {
- return err
- }
- if config.MacAddress != "" {
- mac, err := net.ParseMAC(config.MacAddress)
- if err != nil {
- return err
- }
- if err := netlink.LinkSetHardwareAddr(child, mac); err != nil {
- return err
- }
- }
- ip, err := netlink.ParseAddr(config.Address)
- if err != nil {
- return err
- }
- if err := netlink.AddrAdd(child, ip); err != nil {
- return err
- }
- if config.IPv6Address != "" {
- ip6, err := netlink.ParseAddr(config.IPv6Address)
- if err != nil {
- return err
- }
- if err := netlink.AddrAdd(child, ip6); err != nil {
- return err
- }
- }
- if err := netlink.LinkSetMTU(child, config.Mtu); err != nil {
- return err
- }
- if err := netlink.LinkSetUp(child); err != nil {
- return err
- }
- if config.Gateway != "" {
- gw := net.ParseIP(config.Gateway)
- if err := netlink.RouteAdd(&netlink.Route{
- Scope: netlink.SCOPE_UNIVERSE,
- LinkIndex: child.Attrs().Index,
- Gw: gw,
- }); err != nil {
- return err
- }
- }
- if config.IPv6Gateway != "" {
- gw := net.ParseIP(config.IPv6Gateway)
- if err := netlink.RouteAdd(&netlink.Route{
- Scope: netlink.SCOPE_UNIVERSE,
- LinkIndex: child.Attrs().Index,
- Gw: gw,
- }); err != nil {
- return err
- }
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/notify_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/notify_linux.go
deleted file mode 100644
index 47a06783d..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/notify_linux.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
-
- "golang.org/x/sys/unix"
-)
-
-const oomCgroupName = "memory"
-
-type PressureLevel uint
-
-const (
- LowPressure PressureLevel = iota
- MediumPressure
- CriticalPressure
-)
-
-func registerMemoryEvent(cgDir string, evName string, arg string) (<-chan struct{}, error) {
- evFile, err := os.Open(filepath.Join(cgDir, evName))
- if err != nil {
- return nil, err
- }
- fd, err := unix.Eventfd(0, unix.EFD_CLOEXEC)
- if err != nil {
- evFile.Close()
- return nil, err
- }
-
- eventfd := os.NewFile(uintptr(fd), "eventfd")
-
- eventControlPath := filepath.Join(cgDir, "cgroup.event_control")
- data := fmt.Sprintf("%d %d %s", eventfd.Fd(), evFile.Fd(), arg)
- if err := ioutil.WriteFile(eventControlPath, []byte(data), 0700); err != nil {
- eventfd.Close()
- evFile.Close()
- return nil, err
- }
- ch := make(chan struct{})
- go func() {
- defer func() {
- eventfd.Close()
- evFile.Close()
- close(ch)
- }()
- buf := make([]byte, 8)
- for {
- if _, err := eventfd.Read(buf); err != nil {
- return
- }
- // When a cgroup is destroyed, an event is sent to eventfd.
- // So if the control path is gone, return instead of notifying.
- if _, err := os.Lstat(eventControlPath); os.IsNotExist(err) {
- return
- }
- ch <- struct{}{}
- }
- }()
- return ch, nil
-}
-
-// notifyOnOOM returns channel on which you can expect event about OOM,
-// if process died without OOM this channel will be closed.
-func notifyOnOOM(paths map[string]string) (<-chan struct{}, error) {
- dir := paths[oomCgroupName]
- if dir == "" {
- return nil, fmt.Errorf("path %q missing", oomCgroupName)
- }
-
- return registerMemoryEvent(dir, "memory.oom_control", "")
-}
-
-func notifyMemoryPressure(paths map[string]string, level PressureLevel) (<-chan struct{}, error) {
- dir := paths[oomCgroupName]
- if dir == "" {
- return nil, fmt.Errorf("path %q missing", oomCgroupName)
- }
-
- if level > CriticalPressure {
- return nil, fmt.Errorf("invalid pressure level %d", level)
- }
-
- levelStr := []string{"low", "medium", "critical"}[level]
- return registerMemoryEvent(dir, "memory.pressure_level", levelStr)
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/process.go b/vendor/github.com/opencontainers/runc/libcontainer/process.go
deleted file mode 100644
index 86bf7387f..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/process.go
+++ /dev/null
@@ -1,110 +0,0 @@
-package libcontainer
-
-import (
- "fmt"
- "io"
- "math"
- "os"
-
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-type processOperations interface {
- wait() (*os.ProcessState, error)
- signal(sig os.Signal) error
- pid() int
-}
-
-// Process specifies the configuration and IO for a process inside
-// a container.
-type Process struct {
- // The command to be run followed by any arguments.
- Args []string
-
- // Env specifies the environment variables for the process.
- Env []string
-
- // User will set the uid and gid of the executing process running inside the container
- // local to the container's user and group configuration.
- User string
-
- // AdditionalGroups specifies the gids that should be added to supplementary groups
- // in addition to those that the user belongs to.
- AdditionalGroups []string
-
- // Cwd will change the processes current working directory inside the container's rootfs.
- Cwd string
-
- // Stdin is a pointer to a reader which provides the standard input stream.
- Stdin io.Reader
-
- // Stdout is a pointer to a writer which receives the standard output stream.
- Stdout io.Writer
-
- // Stderr is a pointer to a writer which receives the standard error stream.
- Stderr io.Writer
-
- // ExtraFiles specifies additional open files to be inherited by the container
- ExtraFiles []*os.File
-
- // Initial sizings for the console
- ConsoleWidth uint16
- ConsoleHeight uint16
-
- // Capabilities specify the capabilities to keep when executing the process inside the container
- // All capabilities not specified will be dropped from the processes capability mask
- Capabilities *configs.Capabilities
-
- // AppArmorProfile specifies the profile to apply to the process and is
- // changed at the time the process is execed
- AppArmorProfile string
-
- // Label specifies the label to apply to the process. It is commonly used by selinux
- Label string
-
- // NoNewPrivileges controls whether processes can gain additional privileges.
- NoNewPrivileges *bool
-
- // Rlimits specifies the resource limits, such as max open files, to set in the container
- // If Rlimits are not set, the container will inherit rlimits from the parent process
- Rlimits []configs.Rlimit
-
- // ConsoleSocket provides the masterfd console.
- ConsoleSocket *os.File
-
- ops processOperations
-}
-
-// Wait waits for the process to exit.
-// Wait releases any resources associated with the Process
-func (p Process) Wait() (*os.ProcessState, error) {
- if p.ops == nil {
- return nil, newGenericError(fmt.Errorf("invalid process"), NoProcessOps)
- }
- return p.ops.wait()
-}
-
-// Pid returns the process ID
-func (p Process) Pid() (int, error) {
- // math.MinInt32 is returned here, because it's invalid value
- // for the kill() system call.
- if p.ops == nil {
- return math.MinInt32, newGenericError(fmt.Errorf("invalid process"), NoProcessOps)
- }
- return p.ops.pid(), nil
-}
-
-// Signal sends a signal to the Process.
-func (p Process) Signal(sig os.Signal) error {
- if p.ops == nil {
- return newGenericError(fmt.Errorf("invalid process"), NoProcessOps)
- }
- return p.ops.signal(sig)
-}
-
-// IO holds the process's STDIO
-type IO struct {
- Stdin io.WriteCloser
- Stdout io.ReadCloser
- Stderr io.ReadCloser
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go
deleted file mode 100644
index 58980b059..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go
+++ /dev/null
@@ -1,547 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "os"
- "os/exec"
- "path/filepath"
- "strconv"
- "syscall" // only for Signal
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/intelrdt"
- "github.com/opencontainers/runc/libcontainer/system"
- "github.com/opencontainers/runc/libcontainer/utils"
-
- "golang.org/x/sys/unix"
-)
-
-type parentProcess interface {
- // pid returns the pid for the running process.
- pid() int
-
- // start starts the process execution.
- start() error
-
- // send a SIGKILL to the process and wait for the exit.
- terminate() error
-
- // wait waits on the process returning the process state.
- wait() (*os.ProcessState, error)
-
- // startTime returns the process start time.
- startTime() (uint64, error)
-
- signal(os.Signal) error
-
- externalDescriptors() []string
-
- setExternalDescriptors(fds []string)
-}
-
-type setnsProcess struct {
- cmd *exec.Cmd
- parentPipe *os.File
- childPipe *os.File
- cgroupPaths map[string]string
- intelRdtPath string
- config *initConfig
- fds []string
- process *Process
- bootstrapData io.Reader
-}
-
-func (p *setnsProcess) startTime() (uint64, error) {
- stat, err := system.Stat(p.pid())
- return stat.StartTime, err
-}
-
-func (p *setnsProcess) signal(sig os.Signal) error {
- s, ok := sig.(syscall.Signal)
- if !ok {
- return errors.New("os: unsupported signal type")
- }
- return unix.Kill(p.pid(), s)
-}
-
-func (p *setnsProcess) start() (err error) {
- defer p.parentPipe.Close()
- err = p.cmd.Start()
- p.childPipe.Close()
- if err != nil {
- return newSystemErrorWithCause(err, "starting setns process")
- }
- if p.bootstrapData != nil {
- if _, err := io.Copy(p.parentPipe, p.bootstrapData); err != nil {
- return newSystemErrorWithCause(err, "copying bootstrap data to pipe")
- }
- }
- if err = p.execSetns(); err != nil {
- return newSystemErrorWithCause(err, "executing setns process")
- }
- if len(p.cgroupPaths) > 0 {
- if err := cgroups.EnterPid(p.cgroupPaths, p.pid()); err != nil {
- return newSystemErrorWithCausef(err, "adding pid %d to cgroups", p.pid())
- }
- }
- if p.intelRdtPath != "" {
- // if Intel RDT "resource control" filesystem path exists
- _, err := os.Stat(p.intelRdtPath)
- if err == nil {
- if err := intelrdt.WriteIntelRdtTasks(p.intelRdtPath, p.pid()); err != nil {
- return newSystemErrorWithCausef(err, "adding pid %d to Intel RDT resource control filesystem", p.pid())
- }
- }
- }
- // set rlimits, this has to be done here because we lose permissions
- // to raise the limits once we enter a user-namespace
- if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil {
- return newSystemErrorWithCause(err, "setting rlimits for process")
- }
- if err := utils.WriteJSON(p.parentPipe, p.config); err != nil {
- return newSystemErrorWithCause(err, "writing config to pipe")
- }
-
- ierr := parseSync(p.parentPipe, func(sync *syncT) error {
- switch sync.Type {
- case procReady:
- // This shouldn't happen.
- panic("unexpected procReady in setns")
- case procHooks:
- // This shouldn't happen.
- panic("unexpected procHooks in setns")
- default:
- return newSystemError(fmt.Errorf("invalid JSON payload from child"))
- }
- })
-
- if err := unix.Shutdown(int(p.parentPipe.Fd()), unix.SHUT_WR); err != nil {
- return newSystemErrorWithCause(err, "calling shutdown on init pipe")
- }
- // Must be done after Shutdown so the child will exit and we can wait for it.
- if ierr != nil {
- p.wait()
- return ierr
- }
- return nil
-}
-
-// execSetns runs the process that executes C code to perform the setns calls
-// because setns support requires the C process to fork off a child and perform the setns
-// before the go runtime boots, we wait on the process to die and receive the child's pid
-// over the provided pipe.
-func (p *setnsProcess) execSetns() error {
- status, err := p.cmd.Process.Wait()
- if err != nil {
- p.cmd.Wait()
- return newSystemErrorWithCause(err, "waiting on setns process to finish")
- }
- if !status.Success() {
- p.cmd.Wait()
- return newSystemError(&exec.ExitError{ProcessState: status})
- }
- var pid *pid
- if err := json.NewDecoder(p.parentPipe).Decode(&pid); err != nil {
- p.cmd.Wait()
- return newSystemErrorWithCause(err, "reading pid from init pipe")
- }
-
- // Clean up the zombie parent process
- firstChildProcess, err := os.FindProcess(pid.PidFirstChild)
- if err != nil {
- return err
- }
-
- // Ignore the error in case the child has already been reaped for any reason
- _, _ = firstChildProcess.Wait()
-
- process, err := os.FindProcess(pid.Pid)
- if err != nil {
- return err
- }
- p.cmd.Process = process
- p.process.ops = p
- return nil
-}
-
-// terminate sends a SIGKILL to the forked process for the setns routine then waits to
-// avoid the process becoming a zombie.
-func (p *setnsProcess) terminate() error {
- if p.cmd.Process == nil {
- return nil
- }
- err := p.cmd.Process.Kill()
- if _, werr := p.wait(); err == nil {
- err = werr
- }
- return err
-}
-
-func (p *setnsProcess) wait() (*os.ProcessState, error) {
- err := p.cmd.Wait()
-
- // Return actual ProcessState even on Wait error
- return p.cmd.ProcessState, err
-}
-
-func (p *setnsProcess) pid() int {
- return p.cmd.Process.Pid
-}
-
-func (p *setnsProcess) externalDescriptors() []string {
- return p.fds
-}
-
-func (p *setnsProcess) setExternalDescriptors(newFds []string) {
- p.fds = newFds
-}
-
-type initProcess struct {
- cmd *exec.Cmd
- parentPipe *os.File
- childPipe *os.File
- config *initConfig
- manager cgroups.Manager
- intelRdtManager intelrdt.Manager
- container *linuxContainer
- fds []string
- process *Process
- bootstrapData io.Reader
- sharePidns bool
-}
-
-func (p *initProcess) pid() int {
- return p.cmd.Process.Pid
-}
-
-func (p *initProcess) externalDescriptors() []string {
- return p.fds
-}
-
-// execSetns runs the process that executes C code to perform the setns calls
-// because setns support requires the C process to fork off a child and perform the setns
-// before the go runtime boots, we wait on the process to die and receive the child's pid
-// over the provided pipe.
-// This is called by initProcess.start function
-func (p *initProcess) execSetns() error {
- status, err := p.cmd.Process.Wait()
- if err != nil {
- p.cmd.Wait()
- return err
- }
- if !status.Success() {
- p.cmd.Wait()
- return &exec.ExitError{ProcessState: status}
- }
- var pid *pid
- if err := json.NewDecoder(p.parentPipe).Decode(&pid); err != nil {
- p.cmd.Wait()
- return err
- }
-
- // Clean up the zombie parent process
- firstChildProcess, err := os.FindProcess(pid.PidFirstChild)
- if err != nil {
- return err
- }
-
- // Ignore the error in case the child has already been reaped for any reason
- _, _ = firstChildProcess.Wait()
-
- process, err := os.FindProcess(pid.Pid)
- if err != nil {
- return err
- }
- p.cmd.Process = process
- p.process.ops = p
- return nil
-}
-
-func (p *initProcess) start() error {
- defer p.parentPipe.Close()
- err := p.cmd.Start()
- p.process.ops = p
- p.childPipe.Close()
- if err != nil {
- p.process.ops = nil
- return newSystemErrorWithCause(err, "starting init process command")
- }
- // Do this before syncing with child so that no children can escape the
- // cgroup. We don't need to worry about not doing this and not being root
- // because we'd be using the rootless cgroup manager in that case.
- if err := p.manager.Apply(p.pid()); err != nil {
- return newSystemErrorWithCause(err, "applying cgroup configuration for process")
- }
- if p.intelRdtManager != nil {
- if err := p.intelRdtManager.Apply(p.pid()); err != nil {
- return newSystemErrorWithCause(err, "applying Intel RDT configuration for process")
- }
- }
- defer func() {
- if err != nil {
- // TODO: should not be the responsibility to call here
- p.manager.Destroy()
- if p.intelRdtManager != nil {
- p.intelRdtManager.Destroy()
- }
- }
- }()
-
- if _, err := io.Copy(p.parentPipe, p.bootstrapData); err != nil {
- return newSystemErrorWithCause(err, "copying bootstrap data to pipe")
- }
-
- if err := p.execSetns(); err != nil {
- return newSystemErrorWithCause(err, "running exec setns process for init")
- }
-
- // Save the standard descriptor names before the container process
- // can potentially move them (e.g., via dup2()). If we don't do this now,
- // we won't know at checkpoint time which file descriptor to look up.
- fds, err := getPipeFds(p.pid())
- if err != nil {
- return newSystemErrorWithCausef(err, "getting pipe fds for pid %d", p.pid())
- }
- p.setExternalDescriptors(fds)
- if err := p.createNetworkInterfaces(); err != nil {
- return newSystemErrorWithCause(err, "creating network interfaces")
- }
- if err := p.sendConfig(); err != nil {
- return newSystemErrorWithCause(err, "sending config to init process")
- }
- var (
- sentRun bool
- sentResume bool
- )
-
- ierr := parseSync(p.parentPipe, func(sync *syncT) error {
- switch sync.Type {
- case procReady:
- // set rlimits, this has to be done here because we lose permissions
- // to raise the limits once we enter a user-namespace
- if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil {
- return newSystemErrorWithCause(err, "setting rlimits for ready process")
- }
- // call prestart hooks
- if !p.config.Config.Namespaces.Contains(configs.NEWNS) {
- // Setup cgroup before prestart hook, so that the prestart hook could apply cgroup permissions.
- if err := p.manager.Set(p.config.Config); err != nil {
- return newSystemErrorWithCause(err, "setting cgroup config for ready process")
- }
- if p.intelRdtManager != nil {
- if err := p.intelRdtManager.Set(p.config.Config); err != nil {
- return newSystemErrorWithCause(err, "setting Intel RDT config for ready process")
- }
- }
-
- if p.config.Config.Hooks != nil {
- bundle, annotations := utils.Annotations(p.container.config.Labels)
- s := configs.HookState{
- Version: p.container.config.Version,
- ID: p.container.id,
- Pid: p.pid(),
- Bundle: bundle,
- Annotations: annotations,
- }
- for i, hook := range p.config.Config.Hooks.Prestart {
- if err := hook.Run(s); err != nil {
- return newSystemErrorWithCausef(err, "running prestart hook %d", i)
- }
- }
- }
- }
- // Sync with child.
- if err := writeSync(p.parentPipe, procRun); err != nil {
- return newSystemErrorWithCause(err, "writing syncT 'run'")
- }
- sentRun = true
- case procHooks:
- // Setup cgroup before prestart hook, so that the prestart hook could apply cgroup permissions.
- if err := p.manager.Set(p.config.Config); err != nil {
- return newSystemErrorWithCause(err, "setting cgroup config for procHooks process")
- }
- if p.intelRdtManager != nil {
- if err := p.intelRdtManager.Set(p.config.Config); err != nil {
- return newSystemErrorWithCause(err, "setting Intel RDT config for procHooks process")
- }
- }
- if p.config.Config.Hooks != nil {
- bundle, annotations := utils.Annotations(p.container.config.Labels)
- s := configs.HookState{
- Version: p.container.config.Version,
- ID: p.container.id,
- Pid: p.pid(),
- Bundle: bundle,
- Annotations: annotations,
- }
- for i, hook := range p.config.Config.Hooks.Prestart {
- if err := hook.Run(s); err != nil {
- return newSystemErrorWithCausef(err, "running prestart hook %d", i)
- }
- }
- }
- // Sync with child.
- if err := writeSync(p.parentPipe, procResume); err != nil {
- return newSystemErrorWithCause(err, "writing syncT 'resume'")
- }
- sentResume = true
- default:
- return newSystemError(fmt.Errorf("invalid JSON payload from child"))
- }
-
- return nil
- })
-
- if !sentRun {
- return newSystemErrorWithCause(ierr, "container init")
- }
- if p.config.Config.Namespaces.Contains(configs.NEWNS) && !sentResume {
- return newSystemError(fmt.Errorf("could not synchronise after executing prestart hooks with container process"))
- }
- if err := unix.Shutdown(int(p.parentPipe.Fd()), unix.SHUT_WR); err != nil {
- return newSystemErrorWithCause(err, "shutting down init pipe")
- }
-
- // Must be done after Shutdown so the child will exit and we can wait for it.
- if ierr != nil {
- p.wait()
- return ierr
- }
- return nil
-}
-
-func (p *initProcess) wait() (*os.ProcessState, error) {
- err := p.cmd.Wait()
- if err != nil {
- return p.cmd.ProcessState, err
- }
- // we should kill all processes in cgroup when init is died if we use host PID namespace
- if p.sharePidns {
- signalAllProcesses(p.manager, unix.SIGKILL)
- }
- return p.cmd.ProcessState, nil
-}
-
-func (p *initProcess) terminate() error {
- if p.cmd.Process == nil {
- return nil
- }
- err := p.cmd.Process.Kill()
- if _, werr := p.wait(); err == nil {
- err = werr
- }
- return err
-}
-
-func (p *initProcess) startTime() (uint64, error) {
- stat, err := system.Stat(p.pid())
- return stat.StartTime, err
-}
-
-func (p *initProcess) sendConfig() error {
- // send the config to the container's init process, we don't use JSON Encode
- // here because there might be a problem in JSON decoder in some cases, see:
- // https://github.com/docker/docker/issues/14203#issuecomment-174177790
- return utils.WriteJSON(p.parentPipe, p.config)
-}
-
-func (p *initProcess) createNetworkInterfaces() error {
- for _, config := range p.config.Config.Networks {
- strategy, err := getStrategy(config.Type)
- if err != nil {
- return err
- }
- n := &network{
- Network: *config,
- }
- if err := strategy.create(n, p.pid()); err != nil {
- return err
- }
- p.config.Networks = append(p.config.Networks, n)
- }
- return nil
-}
-
-func (p *initProcess) signal(sig os.Signal) error {
- s, ok := sig.(syscall.Signal)
- if !ok {
- return errors.New("os: unsupported signal type")
- }
- return unix.Kill(p.pid(), s)
-}
-
-func (p *initProcess) setExternalDescriptors(newFds []string) {
- p.fds = newFds
-}
-
-func getPipeFds(pid int) ([]string, error) {
- fds := make([]string, 3)
-
- dirPath := filepath.Join("/proc", strconv.Itoa(pid), "/fd")
- for i := 0; i < 3; i++ {
- // XXX: This breaks if the path is not a valid symlink (which can
- // happen in certain particularly unlucky mount namespace setups).
- f := filepath.Join(dirPath, strconv.Itoa(i))
- target, err := os.Readlink(f)
- if err != nil {
- // Ignore permission errors, for rootless containers and other
- // non-dumpable processes. if we can't get the fd for a particular
- // file, there's not much we can do.
- if os.IsPermission(err) {
- continue
- }
- return fds, err
- }
- fds[i] = target
- }
- return fds, nil
-}
-
-// InitializeIO creates pipes for use with the process's stdio and returns the
-// opposite side for each. Do not use this if you want to have a pseudoterminal
-// set up for you by libcontainer (TODO: fix that too).
-// TODO: This is mostly unnecessary, and should be handled by clients.
-func (p *Process) InitializeIO(rootuid, rootgid int) (i *IO, err error) {
- var fds []uintptr
- i = &IO{}
- // cleanup in case of an error
- defer func() {
- if err != nil {
- for _, fd := range fds {
- unix.Close(int(fd))
- }
- }
- }()
- // STDIN
- r, w, err := os.Pipe()
- if err != nil {
- return nil, err
- }
- fds = append(fds, r.Fd(), w.Fd())
- p.Stdin, i.Stdin = r, w
- // STDOUT
- if r, w, err = os.Pipe(); err != nil {
- return nil, err
- }
- fds = append(fds, r.Fd(), w.Fd())
- p.Stdout, i.Stdout = w, r
- // STDERR
- if r, w, err = os.Pipe(); err != nil {
- return nil, err
- }
- fds = append(fds, r.Fd(), w.Fd())
- p.Stderr, i.Stderr = w, r
- // change ownership of the pipes incase we are in a user namespace
- for _, fd := range fds {
- if err := unix.Fchown(int(fd), rootuid, rootgid); err != nil {
- return nil, err
- }
- }
- return i, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/restored_process.go b/vendor/github.com/opencontainers/runc/libcontainer/restored_process.go
deleted file mode 100644
index 408916ad9..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/restored_process.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "fmt"
- "os"
-
- "github.com/opencontainers/runc/libcontainer/system"
-)
-
-func newRestoredProcess(pid int, fds []string) (*restoredProcess, error) {
- var (
- err error
- )
- proc, err := os.FindProcess(pid)
- if err != nil {
- return nil, err
- }
- stat, err := system.Stat(pid)
- if err != nil {
- return nil, err
- }
- return &restoredProcess{
- proc: proc,
- processStartTime: stat.StartTime,
- fds: fds,
- }, nil
-}
-
-type restoredProcess struct {
- proc *os.Process
- processStartTime uint64
- fds []string
-}
-
-func (p *restoredProcess) start() error {
- return newGenericError(fmt.Errorf("restored process cannot be started"), SystemError)
-}
-
-func (p *restoredProcess) pid() int {
- return p.proc.Pid
-}
-
-func (p *restoredProcess) terminate() error {
- err := p.proc.Kill()
- if _, werr := p.wait(); err == nil {
- err = werr
- }
- return err
-}
-
-func (p *restoredProcess) wait() (*os.ProcessState, error) {
- // TODO: how do we wait on the actual process?
- // maybe use --exec-cmd in criu
- st, err := p.proc.Wait()
- if err != nil {
- return nil, err
- }
- return st, nil
-}
-
-func (p *restoredProcess) startTime() (uint64, error) {
- return p.processStartTime, nil
-}
-
-func (p *restoredProcess) signal(s os.Signal) error {
- return p.proc.Signal(s)
-}
-
-func (p *restoredProcess) externalDescriptors() []string {
- return p.fds
-}
-
-func (p *restoredProcess) setExternalDescriptors(newFds []string) {
- p.fds = newFds
-}
-
-// nonChildProcess represents a process where the calling process is not
-// the parent process. This process is created when a factory loads a container from
-// a persisted state.
-type nonChildProcess struct {
- processPid int
- processStartTime uint64
- fds []string
-}
-
-func (p *nonChildProcess) start() error {
- return newGenericError(fmt.Errorf("restored process cannot be started"), SystemError)
-}
-
-func (p *nonChildProcess) pid() int {
- return p.processPid
-}
-
-func (p *nonChildProcess) terminate() error {
- return newGenericError(fmt.Errorf("restored process cannot be terminated"), SystemError)
-}
-
-func (p *nonChildProcess) wait() (*os.ProcessState, error) {
- return nil, newGenericError(fmt.Errorf("restored process cannot be waited on"), SystemError)
-}
-
-func (p *nonChildProcess) startTime() (uint64, error) {
- return p.processStartTime, nil
-}
-
-func (p *nonChildProcess) signal(s os.Signal) error {
- proc, err := os.FindProcess(p.processPid)
- if err != nil {
- return err
- }
- return proc.Signal(s)
-}
-
-func (p *nonChildProcess) externalDescriptors() []string {
- return p.fds
-}
-
-func (p *nonChildProcess) setExternalDescriptors(newFds []string) {
- p.fds = newFds
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go
deleted file mode 100644
index 73ee2bd69..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go
+++ /dev/null
@@ -1,838 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "os/exec"
- "path"
- "path/filepath"
- "strings"
- "time"
-
- "github.com/cyphar/filepath-securejoin"
- "github.com/mrunalp/fileutils"
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/mount"
- "github.com/opencontainers/runc/libcontainer/system"
- libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
- "github.com/opencontainers/selinux/go-selinux/label"
-
- "golang.org/x/sys/unix"
-)
-
-const defaultMountFlags = unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV
-
-// needsSetupDev returns true if /dev needs to be set up.
-func needsSetupDev(config *configs.Config) bool {
- for _, m := range config.Mounts {
- if m.Device == "bind" && libcontainerUtils.CleanPath(m.Destination) == "/dev" {
- return false
- }
- }
- return true
-}
-
-// prepareRootfs sets up the devices, mount points, and filesystems for use
-// inside a new mount namespace. It doesn't set anything as ro. You must call
-// finalizeRootfs after this function to finish setting up the rootfs.
-func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig) (err error) {
- config := iConfig.Config
- if err := prepareRoot(config); err != nil {
- return newSystemErrorWithCause(err, "preparing rootfs")
- }
-
- setupDev := needsSetupDev(config)
- for _, m := range config.Mounts {
- for _, precmd := range m.PremountCmds {
- if err := mountCmd(precmd); err != nil {
- return newSystemErrorWithCause(err, "running premount command")
- }
- }
-
- if err := mountToRootfs(m, config.Rootfs, config.MountLabel); err != nil {
- return newSystemErrorWithCausef(err, "mounting %q to rootfs %q at %q", m.Source, config.Rootfs, m.Destination)
- }
-
- for _, postcmd := range m.PostmountCmds {
- if err := mountCmd(postcmd); err != nil {
- return newSystemErrorWithCause(err, "running postmount command")
- }
- }
- }
-
- if setupDev {
- if err := createDevices(config); err != nil {
- return newSystemErrorWithCause(err, "creating device nodes")
- }
- if err := setupPtmx(config); err != nil {
- return newSystemErrorWithCause(err, "setting up ptmx")
- }
- if err := setupDevSymlinks(config.Rootfs); err != nil {
- return newSystemErrorWithCause(err, "setting up /dev symlinks")
- }
- }
-
- // Signal the parent to run the pre-start hooks.
- // The hooks are run after the mounts are setup, but before we switch to the new
- // root, so that the old root is still available in the hooks for any mount
- // manipulations.
- // Note that iConfig.Cwd is not guaranteed to exist here.
- if err := syncParentHooks(pipe); err != nil {
- return err
- }
-
- // The reason these operations are done here rather than in finalizeRootfs
- // is because the console-handling code gets quite sticky if we have to set
- // up the console before doing the pivot_root(2). This is because the
- // Console API has to also work with the ExecIn case, which means that the
- // API must be able to deal with being inside as well as outside the
- // container. It's just cleaner to do this here (at the expense of the
- // operation not being perfectly split).
-
- if err := unix.Chdir(config.Rootfs); err != nil {
- return newSystemErrorWithCausef(err, "changing dir to %q", config.Rootfs)
- }
-
- if config.NoPivotRoot {
- err = msMoveRoot(config.Rootfs)
- } else if config.Namespaces.Contains(configs.NEWNS) {
- err = pivotRoot(config.Rootfs)
- } else {
- err = chroot(config.Rootfs)
- }
- if err != nil {
- return newSystemErrorWithCause(err, "jailing process inside rootfs")
- }
-
- if setupDev {
- if err := reOpenDevNull(); err != nil {
- return newSystemErrorWithCause(err, "reopening /dev/null inside container")
- }
- }
-
- if cwd := iConfig.Cwd; cwd != "" {
- // Note that spec.Process.Cwd can contain unclean value like "../../../../foo/bar...".
- // However, we are safe to call MkDirAll directly because we are in the jail here.
- if err := os.MkdirAll(cwd, 0755); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// finalizeRootfs sets anything to ro if necessary. You must call
-// prepareRootfs first.
-func finalizeRootfs(config *configs.Config) (err error) {
- // remount dev as ro if specified
- for _, m := range config.Mounts {
- if libcontainerUtils.CleanPath(m.Destination) == "/dev" {
- if m.Flags&unix.MS_RDONLY == unix.MS_RDONLY {
- if err := remountReadonly(m); err != nil {
- return newSystemErrorWithCausef(err, "remounting %q as readonly", m.Destination)
- }
- }
- break
- }
- }
-
- // set rootfs ( / ) as readonly
- if config.Readonlyfs {
- if err := setReadonly(); err != nil {
- return newSystemErrorWithCause(err, "setting rootfs as readonly")
- }
- }
-
- unix.Umask(0022)
- return nil
-}
-
-func mountCmd(cmd configs.Command) error {
- command := exec.Command(cmd.Path, cmd.Args[:]...)
- command.Env = cmd.Env
- command.Dir = cmd.Dir
- if out, err := command.CombinedOutput(); err != nil {
- return fmt.Errorf("%#v failed: %s: %v", cmd, string(out), err)
- }
- return nil
-}
-
-func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
- var (
- dest = m.Destination
- )
- if !strings.HasPrefix(dest, rootfs) {
- dest = filepath.Join(rootfs, dest)
- }
-
- switch m.Device {
- case "proc", "sysfs":
- if err := os.MkdirAll(dest, 0755); err != nil {
- return err
- }
- // Selinux kernels do not support labeling of /proc or /sys
- return mountPropagate(m, rootfs, "")
- case "mqueue":
- if err := os.MkdirAll(dest, 0755); err != nil {
- return err
- }
- if err := mountPropagate(m, rootfs, mountLabel); err != nil {
- // older kernels do not support labeling of /dev/mqueue
- if err := mountPropagate(m, rootfs, ""); err != nil {
- return err
- }
- return label.SetFileLabel(dest, mountLabel)
- }
- return nil
- case "tmpfs":
- copyUp := m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP
- tmpDir := ""
- stat, err := os.Stat(dest)
- if err != nil {
- if err := os.MkdirAll(dest, 0755); err != nil {
- return err
- }
- }
- if copyUp {
- tmpDir, err = ioutil.TempDir("/tmp", "runctmpdir")
- if err != nil {
- return newSystemErrorWithCause(err, "tmpcopyup: failed to create tmpdir")
- }
- defer os.RemoveAll(tmpDir)
- m.Destination = tmpDir
- }
- if err := mountPropagate(m, rootfs, mountLabel); err != nil {
- return err
- }
- if copyUp {
- if err := fileutils.CopyDirectory(dest, tmpDir); err != nil {
- errMsg := fmt.Errorf("tmpcopyup: failed to copy %s to %s: %v", dest, tmpDir, err)
- if err1 := unix.Unmount(tmpDir, unix.MNT_DETACH); err1 != nil {
- return newSystemErrorWithCausef(err1, "tmpcopyup: %v: failed to unmount", errMsg)
- }
- return errMsg
- }
- if err := unix.Mount(tmpDir, dest, "", unix.MS_MOVE, ""); err != nil {
- errMsg := fmt.Errorf("tmpcopyup: failed to move mount %s to %s: %v", tmpDir, dest, err)
- if err1 := unix.Unmount(tmpDir, unix.MNT_DETACH); err1 != nil {
- return newSystemErrorWithCausef(err1, "tmpcopyup: %v: failed to unmount", errMsg)
- }
- return errMsg
- }
- }
- if stat != nil {
- if err = os.Chmod(dest, stat.Mode()); err != nil {
- return err
- }
- }
- return nil
- case "bind":
- stat, err := os.Stat(m.Source)
- if err != nil {
- // error out if the source of a bind mount does not exist as we will be
- // unable to bind anything to it.
- return err
- }
- // ensure that the destination of the bind mount is resolved of symlinks at mount time because
- // any previous mounts can invalidate the next mount's destination.
- // this can happen when a user specifies mounts within other mounts to cause breakouts or other
- // evil stuff to try to escape the container's rootfs.
- if dest, err = securejoin.SecureJoin(rootfs, m.Destination); err != nil {
- return err
- }
- if err := checkMountDestination(rootfs, dest); err != nil {
- return err
- }
- // update the mount with the correct dest after symlinks are resolved.
- m.Destination = dest
- if err := createIfNotExists(dest, stat.IsDir()); err != nil {
- return err
- }
- if err := mountPropagate(m, rootfs, mountLabel); err != nil {
- return err
- }
- // bind mount won't change mount options, we need remount to make mount options effective.
- // first check that we have non-default options required before attempting a remount
- if m.Flags&^(unix.MS_REC|unix.MS_REMOUNT|unix.MS_BIND) != 0 {
- // only remount if unique mount options are set
- if err := remount(m, rootfs); err != nil {
- return err
- }
- }
-
- if m.Relabel != "" {
- if err := label.Validate(m.Relabel); err != nil {
- return err
- }
- shared := label.IsShared(m.Relabel)
- if err := label.Relabel(m.Source, mountLabel, shared); err != nil {
- return err
- }
- }
- case "cgroup":
- binds, err := getCgroupMounts(m)
- if err != nil {
- return err
- }
- var merged []string
- for _, b := range binds {
- ss := filepath.Base(b.Destination)
- if strings.Contains(ss, ",") {
- merged = append(merged, ss)
- }
- }
- tmpfs := &configs.Mount{
- Source: "tmpfs",
- Device: "tmpfs",
- Destination: m.Destination,
- Flags: defaultMountFlags,
- Data: "mode=755",
- PropagationFlags: m.PropagationFlags,
- }
- if err := mountToRootfs(tmpfs, rootfs, mountLabel); err != nil {
- return err
- }
- for _, b := range binds {
- if err := mountToRootfs(b, rootfs, mountLabel); err != nil {
- return err
- }
- }
- for _, mc := range merged {
- for _, ss := range strings.Split(mc, ",") {
- // symlink(2) is very dumb, it will just shove the path into
- // the link and doesn't do any checks or relative path
- // conversion. Also, don't error out if the cgroup already exists.
- if err := os.Symlink(mc, filepath.Join(rootfs, m.Destination, ss)); err != nil && !os.IsExist(err) {
- return err
- }
- }
- }
- if m.Flags&unix.MS_RDONLY != 0 {
- // remount cgroup root as readonly
- mcgrouproot := &configs.Mount{
- Source: m.Destination,
- Device: "bind",
- Destination: m.Destination,
- Flags: defaultMountFlags | unix.MS_RDONLY | unix.MS_BIND,
- }
- if err := remount(mcgrouproot, rootfs); err != nil {
- return err
- }
- }
- default:
- // ensure that the destination of the mount is resolved of symlinks at mount time because
- // any previous mounts can invalidate the next mount's destination.
- // this can happen when a user specifies mounts within other mounts to cause breakouts or other
- // evil stuff to try to escape the container's rootfs.
- var err error
- if dest, err = securejoin.SecureJoin(rootfs, m.Destination); err != nil {
- return err
- }
- if err := checkMountDestination(rootfs, dest); err != nil {
- return err
- }
- // update the mount with the correct dest after symlinks are resolved.
- m.Destination = dest
- if err := os.MkdirAll(dest, 0755); err != nil {
- return err
- }
- return mountPropagate(m, rootfs, mountLabel)
- }
- return nil
-}
-
-func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) {
- mounts, err := cgroups.GetCgroupMounts(false)
- if err != nil {
- return nil, err
- }
-
- cgroupPaths, err := cgroups.ParseCgroupFile("/proc/self/cgroup")
- if err != nil {
- return nil, err
- }
-
- var binds []*configs.Mount
-
- for _, mm := range mounts {
- dir, err := mm.GetOwnCgroup(cgroupPaths)
- if err != nil {
- return nil, err
- }
- relDir, err := filepath.Rel(mm.Root, dir)
- if err != nil {
- return nil, err
- }
- binds = append(binds, &configs.Mount{
- Device: "bind",
- Source: filepath.Join(mm.Mountpoint, relDir),
- Destination: filepath.Join(m.Destination, filepath.Base(mm.Mountpoint)),
- Flags: unix.MS_BIND | unix.MS_REC | m.Flags,
- PropagationFlags: m.PropagationFlags,
- })
- }
-
- return binds, nil
-}
-
-// checkMountDestination checks to ensure that the mount destination is not over the top of /proc.
-// dest is required to be an abs path and have any symlinks resolved before calling this function.
-func checkMountDestination(rootfs, dest string) error {
- invalidDestinations := []string{
- "/proc",
- }
- // White list, it should be sub directories of invalid destinations
- validDestinations := []string{
- // These entries can be bind mounted by files emulated by fuse,
- // so commands like top, free displays stats in container.
- "/proc/cpuinfo",
- "/proc/diskstats",
- "/proc/meminfo",
- "/proc/stat",
- "/proc/swaps",
- "/proc/uptime",
- "/proc/net/dev",
- }
- for _, valid := range validDestinations {
- path, err := filepath.Rel(filepath.Join(rootfs, valid), dest)
- if err != nil {
- return err
- }
- if path == "." {
- return nil
- }
- }
- for _, invalid := range invalidDestinations {
- path, err := filepath.Rel(filepath.Join(rootfs, invalid), dest)
- if err != nil {
- return err
- }
- if path == "." || !strings.HasPrefix(path, "..") {
- return fmt.Errorf("%q cannot be mounted because it is located inside %q", dest, invalid)
- }
- }
- return nil
-}
-
-func setupDevSymlinks(rootfs string) error {
- var links = [][2]string{
- {"/proc/self/fd", "/dev/fd"},
- {"/proc/self/fd/0", "/dev/stdin"},
- {"/proc/self/fd/1", "/dev/stdout"},
- {"/proc/self/fd/2", "/dev/stderr"},
- }
- // kcore support can be toggled with CONFIG_PROC_KCORE; only create a symlink
- // in /dev if it exists in /proc.
- if _, err := os.Stat("/proc/kcore"); err == nil {
- links = append(links, [2]string{"/proc/kcore", "/dev/core"})
- }
- for _, link := range links {
- var (
- src = link[0]
- dst = filepath.Join(rootfs, link[1])
- )
- if err := os.Symlink(src, dst); err != nil && !os.IsExist(err) {
- return fmt.Errorf("symlink %s %s %s", src, dst, err)
- }
- }
- return nil
-}
-
-// If stdin, stdout, and/or stderr are pointing to `/dev/null` in the parent's rootfs
-// this method will make them point to `/dev/null` in this container's rootfs. This
-// needs to be called after we chroot/pivot into the container's rootfs so that any
-// symlinks are resolved locally.
-func reOpenDevNull() error {
- var stat, devNullStat unix.Stat_t
- file, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
- if err != nil {
- return fmt.Errorf("Failed to open /dev/null - %s", err)
- }
- defer file.Close()
- if err := unix.Fstat(int(file.Fd()), &devNullStat); err != nil {
- return err
- }
- for fd := 0; fd < 3; fd++ {
- if err := unix.Fstat(fd, &stat); err != nil {
- return err
- }
- if stat.Rdev == devNullStat.Rdev {
- // Close and re-open the fd.
- if err := unix.Dup3(int(file.Fd()), fd, 0); err != nil {
- return err
- }
- }
- }
- return nil
-}
-
-// Create the device nodes in the container.
-func createDevices(config *configs.Config) error {
- useBindMount := system.RunningInUserNS() || config.Namespaces.Contains(configs.NEWUSER)
- oldMask := unix.Umask(0000)
- for _, node := range config.Devices {
- // containers running in a user namespace are not allowed to mknod
- // devices so we can just bind mount it from the host.
- if err := createDeviceNode(config.Rootfs, node, useBindMount); err != nil {
- unix.Umask(oldMask)
- return err
- }
- }
- unix.Umask(oldMask)
- return nil
-}
-
-func bindMountDeviceNode(dest string, node *configs.Device) error {
- f, err := os.Create(dest)
- if err != nil && !os.IsExist(err) {
- return err
- }
- if f != nil {
- f.Close()
- }
- return unix.Mount(node.Path, dest, "bind", unix.MS_BIND, "")
-}
-
-// Creates the device node in the rootfs of the container.
-func createDeviceNode(rootfs string, node *configs.Device, bind bool) error {
- dest := filepath.Join(rootfs, node.Path)
- if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil {
- return err
- }
-
- if bind {
- return bindMountDeviceNode(dest, node)
- }
- if err := mknodDevice(dest, node); err != nil {
- if os.IsExist(err) {
- return nil
- } else if os.IsPermission(err) {
- return bindMountDeviceNode(dest, node)
- }
- return err
- }
- return nil
-}
-
-func mknodDevice(dest string, node *configs.Device) error {
- fileMode := node.FileMode
- switch node.Type {
- case 'c', 'u':
- fileMode |= unix.S_IFCHR
- case 'b':
- fileMode |= unix.S_IFBLK
- case 'p':
- fileMode |= unix.S_IFIFO
- default:
- return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path)
- }
- if err := unix.Mknod(dest, uint32(fileMode), node.Mkdev()); err != nil {
- return err
- }
- return unix.Chown(dest, int(node.Uid), int(node.Gid))
-}
-
-func getMountInfo(mountinfo []*mount.Info, dir string) *mount.Info {
- for _, m := range mountinfo {
- if m.Mountpoint == dir {
- return m
- }
- }
- return nil
-}
-
-// Get the parent mount point of directory passed in as argument. Also return
-// optional fields.
-func getParentMount(rootfs string) (string, string, error) {
- var path string
-
- mountinfos, err := mount.GetMounts()
- if err != nil {
- return "", "", err
- }
-
- mountinfo := getMountInfo(mountinfos, rootfs)
- if mountinfo != nil {
- return rootfs, mountinfo.Optional, nil
- }
-
- path = rootfs
- for {
- path = filepath.Dir(path)
-
- mountinfo = getMountInfo(mountinfos, path)
- if mountinfo != nil {
- return path, mountinfo.Optional, nil
- }
-
- if path == "/" {
- break
- }
- }
-
- // If we are here, we did not find parent mount. Something is wrong.
- return "", "", fmt.Errorf("Could not find parent mount of %s", rootfs)
-}
-
-// Make parent mount private if it was shared
-func rootfsParentMountPrivate(rootfs string) error {
- sharedMount := false
-
- parentMount, optionalOpts, err := getParentMount(rootfs)
- if err != nil {
- return err
- }
-
- optsSplit := strings.Split(optionalOpts, " ")
- for _, opt := range optsSplit {
- if strings.HasPrefix(opt, "shared:") {
- sharedMount = true
- break
- }
- }
-
- // Make parent mount PRIVATE if it was shared. It is needed for two
- // reasons. First of all pivot_root() will fail if parent mount is
- // shared. Secondly when we bind mount rootfs it will propagate to
- // parent namespace and we don't want that to happen.
- if sharedMount {
- return unix.Mount("", parentMount, "", unix.MS_PRIVATE, "")
- }
-
- return nil
-}
-
-func prepareRoot(config *configs.Config) error {
- flag := unix.MS_SLAVE | unix.MS_REC
- if config.RootPropagation != 0 {
- flag = config.RootPropagation
- }
- if err := unix.Mount("", "/", "", uintptr(flag), ""); err != nil {
- return err
- }
-
- // Make parent mount private to make sure following bind mount does
- // not propagate in other namespaces. Also it will help with kernel
- // check pass in pivot_root. (IS_SHARED(new_mnt->mnt_parent))
- if err := rootfsParentMountPrivate(config.Rootfs); err != nil {
- return err
- }
-
- return unix.Mount(config.Rootfs, config.Rootfs, "bind", unix.MS_BIND|unix.MS_REC, "")
-}
-
-func setReadonly() error {
- return unix.Mount("/", "/", "bind", unix.MS_BIND|unix.MS_REMOUNT|unix.MS_RDONLY|unix.MS_REC, "")
-}
-
-func setupPtmx(config *configs.Config) error {
- ptmx := filepath.Join(config.Rootfs, "dev/ptmx")
- if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) {
- return err
- }
- if err := os.Symlink("pts/ptmx", ptmx); err != nil {
- return fmt.Errorf("symlink dev ptmx %s", err)
- }
- return nil
-}
-
-// pivotRoot will call pivot_root such that rootfs becomes the new root
-// filesystem, and everything else is cleaned up.
-func pivotRoot(rootfs string) error {
- // While the documentation may claim otherwise, pivot_root(".", ".") is
- // actually valid. What this results in is / being the new root but
- // /proc/self/cwd being the old root. Since we can play around with the cwd
- // with pivot_root this allows us to pivot without creating directories in
- // the rootfs. Shout-outs to the LXC developers for giving us this idea.
-
- oldroot, err := unix.Open("/", unix.O_DIRECTORY|unix.O_RDONLY, 0)
- if err != nil {
- return err
- }
- defer unix.Close(oldroot)
-
- newroot, err := unix.Open(rootfs, unix.O_DIRECTORY|unix.O_RDONLY, 0)
- if err != nil {
- return err
- }
- defer unix.Close(newroot)
-
- // Change to the new root so that the pivot_root actually acts on it.
- if err := unix.Fchdir(newroot); err != nil {
- return err
- }
-
- if err := unix.PivotRoot(".", "."); err != nil {
- return fmt.Errorf("pivot_root %s", err)
- }
-
- // Currently our "." is oldroot (according to the current kernel code).
- // However, purely for safety, we will fchdir(oldroot) since there isn't
- // really any guarantee from the kernel what /proc/self/cwd will be after a
- // pivot_root(2).
-
- if err := unix.Fchdir(oldroot); err != nil {
- return err
- }
-
- // Make oldroot rslave to make sure our unmounts don't propagate to the
- // host (and thus bork the machine). We don't use rprivate because this is
- // known to cause issues due to races where we still have a reference to a
- // mount while a process in the host namespace are trying to operate on
- // something they think has no mounts (devicemapper in particular).
- if err := unix.Mount("", ".", "", unix.MS_SLAVE|unix.MS_REC, ""); err != nil {
- return err
- }
- // Preform the unmount. MNT_DETACH allows us to unmount /proc/self/cwd.
- if err := unix.Unmount(".", unix.MNT_DETACH); err != nil {
- return err
- }
-
- // Switch back to our shiny new root.
- if err := unix.Chdir("/"); err != nil {
- return fmt.Errorf("chdir / %s", err)
- }
- return nil
-}
-
-func msMoveRoot(rootfs string) error {
- if err := unix.Mount(rootfs, "/", "", unix.MS_MOVE, ""); err != nil {
- return err
- }
- return chroot(rootfs)
-}
-
-func chroot(rootfs string) error {
- if err := unix.Chroot("."); err != nil {
- return err
- }
- return unix.Chdir("/")
-}
-
-// createIfNotExists creates a file or a directory only if it does not already exist.
-func createIfNotExists(path string, isDir bool) error {
- if _, err := os.Stat(path); err != nil {
- if os.IsNotExist(err) {
- if isDir {
- return os.MkdirAll(path, 0755)
- }
- if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
- return err
- }
- f, err := os.OpenFile(path, os.O_CREATE, 0755)
- if err != nil {
- return err
- }
- f.Close()
- }
- }
- return nil
-}
-
-// readonlyPath will make a path read only.
-func readonlyPath(path string) error {
- if err := unix.Mount(path, path, "", unix.MS_BIND|unix.MS_REC, ""); err != nil {
- if os.IsNotExist(err) {
- return nil
- }
- return err
- }
- return unix.Mount(path, path, "", unix.MS_BIND|unix.MS_REMOUNT|unix.MS_RDONLY|unix.MS_REC, "")
-}
-
-// remountReadonly will remount an existing mount point and ensure that it is read-only.
-func remountReadonly(m *configs.Mount) error {
- var (
- dest = m.Destination
- flags = m.Flags
- )
- for i := 0; i < 5; i++ {
- // There is a special case in the kernel for
- // MS_REMOUNT | MS_BIND, which allows us to change only the
- // flags even as an unprivileged user (i.e. user namespace)
- // assuming we don't drop any security related flags (nodev,
- // nosuid, etc.). So, let's use that case so that we can do
- // this re-mount without failing in a userns.
- flags |= unix.MS_REMOUNT | unix.MS_BIND | unix.MS_RDONLY
- if err := unix.Mount("", dest, "", uintptr(flags), ""); err != nil {
- switch err {
- case unix.EBUSY:
- time.Sleep(100 * time.Millisecond)
- continue
- default:
- return err
- }
- }
- return nil
- }
- return fmt.Errorf("unable to mount %s as readonly max retries reached", dest)
-}
-
-// maskPath masks the top of the specified path inside a container to avoid
-// security issues from processes reading information from non-namespace aware
-// mounts ( proc/kcore ).
-// For files, maskPath bind mounts /dev/null over the top of the specified path.
-// For directories, maskPath mounts read-only tmpfs over the top of the specified path.
-func maskPath(path string) error {
- if err := unix.Mount("/dev/null", path, "", unix.MS_BIND, ""); err != nil && !os.IsNotExist(err) {
- if err == unix.ENOTDIR {
- return unix.Mount("tmpfs", path, "tmpfs", unix.MS_RDONLY, "")
- }
- return err
- }
- return nil
-}
-
-// writeSystemProperty writes the value to a path under /proc/sys as determined from the key.
-// For e.g. net.ipv4.ip_forward translated to /proc/sys/net/ipv4/ip_forward.
-func writeSystemProperty(key, value string) error {
- keyPath := strings.Replace(key, ".", "/", -1)
- return ioutil.WriteFile(path.Join("/proc/sys", keyPath), []byte(value), 0644)
-}
-
-func remount(m *configs.Mount, rootfs string) error {
- var (
- dest = m.Destination
- )
- if !strings.HasPrefix(dest, rootfs) {
- dest = filepath.Join(rootfs, dest)
- }
- if err := unix.Mount(m.Source, dest, m.Device, uintptr(m.Flags|unix.MS_REMOUNT), ""); err != nil {
- return err
- }
- return nil
-}
-
-// Do the mount operation followed by additional mounts required to take care
-// of propagation flags.
-func mountPropagate(m *configs.Mount, rootfs string, mountLabel string) error {
- var (
- dest = m.Destination
- data = label.FormatMountLabel(m.Data, mountLabel)
- flags = m.Flags
- )
- if libcontainerUtils.CleanPath(dest) == "/dev" {
- flags &= ^unix.MS_RDONLY
- }
-
- copyUp := m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP
- if !(copyUp || strings.HasPrefix(dest, rootfs)) {
- dest = filepath.Join(rootfs, dest)
- }
-
- if err := unix.Mount(m.Source, dest, m.Device, uintptr(flags), data); err != nil {
- return err
- }
-
- for _, pflag := range m.PropagationFlags {
- if err := unix.Mount("", dest, "", uintptr(pflag), ""); err != nil {
- return err
- }
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go
deleted file mode 100644
index ded5a6bbc..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package seccomp
-
-import (
- "fmt"
-
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-var operators = map[string]configs.Operator{
- "SCMP_CMP_NE": configs.NotEqualTo,
- "SCMP_CMP_LT": configs.LessThan,
- "SCMP_CMP_LE": configs.LessThanOrEqualTo,
- "SCMP_CMP_EQ": configs.EqualTo,
- "SCMP_CMP_GE": configs.GreaterThanOrEqualTo,
- "SCMP_CMP_GT": configs.GreaterThan,
- "SCMP_CMP_MASKED_EQ": configs.MaskEqualTo,
-}
-
-var actions = map[string]configs.Action{
- "SCMP_ACT_KILL": configs.Kill,
- "SCMP_ACT_ERRNO": configs.Errno,
- "SCMP_ACT_TRAP": configs.Trap,
- "SCMP_ACT_ALLOW": configs.Allow,
- "SCMP_ACT_TRACE": configs.Trace,
-}
-
-var archs = map[string]string{
- "SCMP_ARCH_X86": "x86",
- "SCMP_ARCH_X86_64": "amd64",
- "SCMP_ARCH_X32": "x32",
- "SCMP_ARCH_ARM": "arm",
- "SCMP_ARCH_AARCH64": "arm64",
- "SCMP_ARCH_MIPS": "mips",
- "SCMP_ARCH_MIPS64": "mips64",
- "SCMP_ARCH_MIPS64N32": "mips64n32",
- "SCMP_ARCH_MIPSEL": "mipsel",
- "SCMP_ARCH_MIPSEL64": "mipsel64",
- "SCMP_ARCH_MIPSEL64N32": "mipsel64n32",
- "SCMP_ARCH_PPC": "ppc",
- "SCMP_ARCH_PPC64": "ppc64",
- "SCMP_ARCH_PPC64LE": "ppc64le",
- "SCMP_ARCH_S390": "s390",
- "SCMP_ARCH_S390X": "s390x",
-}
-
-// ConvertStringToOperator converts a string into a Seccomp comparison operator.
-// Comparison operators use the names they are assigned by Libseccomp's header.
-// Attempting to convert a string that is not a valid operator results in an
-// error.
-func ConvertStringToOperator(in string) (configs.Operator, error) {
- if op, ok := operators[in]; ok == true {
- return op, nil
- }
- return 0, fmt.Errorf("string %s is not a valid operator for seccomp", in)
-}
-
-// ConvertStringToAction converts a string into a Seccomp rule match action.
-// Actions use the names they are assigned in Libseccomp's header, though some
-// (notable, SCMP_ACT_TRACE) are not available in this implementation and will
-// return errors.
-// Attempting to convert a string that is not a valid action results in an
-// error.
-func ConvertStringToAction(in string) (configs.Action, error) {
- if act, ok := actions[in]; ok == true {
- return act, nil
- }
- return 0, fmt.Errorf("string %s is not a valid action for seccomp", in)
-}
-
-// ConvertStringToArch converts a string into a Seccomp comparison arch.
-func ConvertStringToArch(in string) (string, error) {
- if arch, ok := archs[in]; ok == true {
- return arch, nil
- }
- return "", fmt.Errorf("string %s is not a valid arch for seccomp", in)
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go
deleted file mode 100644
index d99f3fe64..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go
+++ /dev/null
@@ -1,258 +0,0 @@
-// +build linux,cgo,seccomp
-
-package seccomp
-
-import (
- "bufio"
- "fmt"
- "os"
- "strings"
-
- "github.com/opencontainers/runc/libcontainer/configs"
- libseccomp "github.com/seccomp/libseccomp-golang"
-
- "golang.org/x/sys/unix"
-)
-
-var (
- actAllow = libseccomp.ActAllow
- actTrap = libseccomp.ActTrap
- actKill = libseccomp.ActKill
- actTrace = libseccomp.ActTrace.SetReturnCode(int16(unix.EPERM))
- actErrno = libseccomp.ActErrno.SetReturnCode(int16(unix.EPERM))
-)
-
-const (
- // Linux system calls can have at most 6 arguments
- syscallMaxArguments int = 6
-)
-
-// Filters given syscalls in a container, preventing them from being used
-// Started in the container init process, and carried over to all child processes
-// Setns calls, however, require a separate invocation, as they are not children
-// of the init until they join the namespace
-func InitSeccomp(config *configs.Seccomp) error {
- if config == nil {
- return fmt.Errorf("cannot initialize Seccomp - nil config passed")
- }
-
- defaultAction, err := getAction(config.DefaultAction)
- if err != nil {
- return fmt.Errorf("error initializing seccomp - invalid default action")
- }
-
- filter, err := libseccomp.NewFilter(defaultAction)
- if err != nil {
- return fmt.Errorf("error creating filter: %s", err)
- }
-
- // Add extra architectures
- for _, arch := range config.Architectures {
- scmpArch, err := libseccomp.GetArchFromString(arch)
- if err != nil {
- return fmt.Errorf("error validating Seccomp architecture: %s", err)
- }
-
- if err := filter.AddArch(scmpArch); err != nil {
- return fmt.Errorf("error adding architecture to seccomp filter: %s", err)
- }
- }
-
- // Unset no new privs bit
- if err := filter.SetNoNewPrivsBit(false); err != nil {
- return fmt.Errorf("error setting no new privileges: %s", err)
- }
-
- // Add a rule for each syscall
- for _, call := range config.Syscalls {
- if call == nil {
- return fmt.Errorf("encountered nil syscall while initializing Seccomp")
- }
-
- if err = matchCall(filter, call); err != nil {
- return err
- }
- }
-
- if err = filter.Load(); err != nil {
- return fmt.Errorf("error loading seccomp filter into kernel: %s", err)
- }
-
- return nil
-}
-
-// IsEnabled returns if the kernel has been configured to support seccomp.
-func IsEnabled() bool {
- // Try to read from /proc/self/status for kernels > 3.8
- s, err := parseStatusFile("/proc/self/status")
- if err != nil {
- // Check if Seccomp is supported, via CONFIG_SECCOMP.
- if err := unix.Prctl(unix.PR_GET_SECCOMP, 0, 0, 0, 0); err != unix.EINVAL {
- // Make sure the kernel has CONFIG_SECCOMP_FILTER.
- if err := unix.Prctl(unix.PR_SET_SECCOMP, unix.SECCOMP_MODE_FILTER, 0, 0, 0); err != unix.EINVAL {
- return true
- }
- }
- return false
- }
- _, ok := s["Seccomp"]
- return ok
-}
-
-// Convert Libcontainer Action to Libseccomp ScmpAction
-func getAction(act configs.Action) (libseccomp.ScmpAction, error) {
- switch act {
- case configs.Kill:
- return actKill, nil
- case configs.Errno:
- return actErrno, nil
- case configs.Trap:
- return actTrap, nil
- case configs.Allow:
- return actAllow, nil
- case configs.Trace:
- return actTrace, nil
- default:
- return libseccomp.ActInvalid, fmt.Errorf("invalid action, cannot use in rule")
- }
-}
-
-// Convert Libcontainer Operator to Libseccomp ScmpCompareOp
-func getOperator(op configs.Operator) (libseccomp.ScmpCompareOp, error) {
- switch op {
- case configs.EqualTo:
- return libseccomp.CompareEqual, nil
- case configs.NotEqualTo:
- return libseccomp.CompareNotEqual, nil
- case configs.GreaterThan:
- return libseccomp.CompareGreater, nil
- case configs.GreaterThanOrEqualTo:
- return libseccomp.CompareGreaterEqual, nil
- case configs.LessThan:
- return libseccomp.CompareLess, nil
- case configs.LessThanOrEqualTo:
- return libseccomp.CompareLessOrEqual, nil
- case configs.MaskEqualTo:
- return libseccomp.CompareMaskedEqual, nil
- default:
- return libseccomp.CompareInvalid, fmt.Errorf("invalid operator, cannot use in rule")
- }
-}
-
-// Convert Libcontainer Arg to Libseccomp ScmpCondition
-func getCondition(arg *configs.Arg) (libseccomp.ScmpCondition, error) {
- cond := libseccomp.ScmpCondition{}
-
- if arg == nil {
- return cond, fmt.Errorf("cannot convert nil to syscall condition")
- }
-
- op, err := getOperator(arg.Op)
- if err != nil {
- return cond, err
- }
-
- return libseccomp.MakeCondition(arg.Index, op, arg.Value, arg.ValueTwo)
-}
-
-// Add a rule to match a single syscall
-func matchCall(filter *libseccomp.ScmpFilter, call *configs.Syscall) error {
- if call == nil || filter == nil {
- return fmt.Errorf("cannot use nil as syscall to block")
- }
-
- if len(call.Name) == 0 {
- return fmt.Errorf("empty string is not a valid syscall")
- }
-
- // If we can't resolve the syscall, assume it's not supported on this kernel
- // Ignore it, don't error out
- callNum, err := libseccomp.GetSyscallFromName(call.Name)
- if err != nil {
- return nil
- }
-
- // Convert the call's action to the libseccomp equivalent
- callAct, err := getAction(call.Action)
- if err != nil {
- return fmt.Errorf("action in seccomp profile is invalid: %s", err)
- }
-
- // Unconditional match - just add the rule
- if len(call.Args) == 0 {
- if err = filter.AddRule(callNum, callAct); err != nil {
- return fmt.Errorf("error adding seccomp filter rule for syscall %s: %s", call.Name, err)
- }
- } else {
- // If two or more arguments have the same condition,
- // Revert to old behavior, adding each condition as a separate rule
- argCounts := make([]uint, syscallMaxArguments)
- conditions := []libseccomp.ScmpCondition{}
-
- for _, cond := range call.Args {
- newCond, err := getCondition(cond)
- if err != nil {
- return fmt.Errorf("error creating seccomp syscall condition for syscall %s: %s", call.Name, err)
- }
-
- argCounts[cond.Index] += 1
-
- conditions = append(conditions, newCond)
- }
-
- hasMultipleArgs := false
- for _, count := range argCounts {
- if count > 1 {
- hasMultipleArgs = true
- break
- }
- }
-
- if hasMultipleArgs {
- // Revert to old behavior
- // Add each condition attached to a separate rule
- for _, cond := range conditions {
- condArr := []libseccomp.ScmpCondition{cond}
-
- if err = filter.AddRuleConditional(callNum, callAct, condArr); err != nil {
- return fmt.Errorf("error adding seccomp rule for syscall %s: %s", call.Name, err)
- }
- }
- } else {
- // No conditions share same argument
- // Use new, proper behavior
- if err = filter.AddRuleConditional(callNum, callAct, conditions); err != nil {
- return fmt.Errorf("error adding seccomp rule for syscall %s: %s", call.Name, err)
- }
- }
- }
-
- return nil
-}
-
-func parseStatusFile(path string) (map[string]string, error) {
- f, err := os.Open(path)
- if err != nil {
- return nil, err
- }
- defer f.Close()
-
- s := bufio.NewScanner(f)
- status := make(map[string]string)
-
- for s.Scan() {
- text := s.Text()
- parts := strings.Split(text, ":")
-
- if len(parts) <= 1 {
- continue
- }
-
- status[parts[0]] = parts[1]
- }
- if err := s.Err(); err != nil {
- return nil, err
- }
-
- return status, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go
deleted file mode 100644
index 44df1ad4c..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// +build !linux !cgo !seccomp
-
-package seccomp
-
-import (
- "errors"
-
- "github.com/opencontainers/runc/libcontainer/configs"
-)
-
-var ErrSeccompNotEnabled = errors.New("seccomp: config provided but seccomp not supported")
-
-// InitSeccomp does nothing because seccomp is not supported.
-func InitSeccomp(config *configs.Seccomp) error {
- if config != nil {
- return ErrSeccompNotEnabled
- }
- return nil
-}
-
-// IsEnabled returns false, because it is not supported.
-func IsEnabled() bool {
- return false
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go
deleted file mode 100644
index 096c601e7..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "fmt"
- "os"
-
- "github.com/opencontainers/runc/libcontainer/apparmor"
- "github.com/opencontainers/runc/libcontainer/keys"
- "github.com/opencontainers/runc/libcontainer/seccomp"
- "github.com/opencontainers/runc/libcontainer/system"
- "github.com/opencontainers/selinux/go-selinux/label"
-
- "golang.org/x/sys/unix"
-)
-
-// linuxSetnsInit performs the container's initialization for running a new process
-// inside an existing container.
-type linuxSetnsInit struct {
- pipe *os.File
- consoleSocket *os.File
- config *initConfig
-}
-
-func (l *linuxSetnsInit) getSessionRingName() string {
- return fmt.Sprintf("_ses.%s", l.config.ContainerId)
-}
-
-func (l *linuxSetnsInit) Init() error {
- if !l.config.Config.NoNewKeyring {
- // do not inherit the parent's session keyring
- if _, err := keys.JoinSessionKeyring(l.getSessionRingName()); err != nil {
- return err
- }
- }
- if l.config.CreateConsole {
- if err := setupConsole(l.consoleSocket, l.config, false); err != nil {
- return err
- }
- if err := system.Setctty(); err != nil {
- return err
- }
- }
- if l.config.NoNewPrivileges {
- if err := unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
- return err
- }
- }
- // Without NoNewPrivileges seccomp is a privileged operation, so we need to
- // do this before dropping capabilities; otherwise do it as late as possible
- // just before execve so as few syscalls take place after it as possible.
- if l.config.Config.Seccomp != nil && !l.config.NoNewPrivileges {
- if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
- return err
- }
- }
- if err := finalizeNamespace(l.config); err != nil {
- return err
- }
- if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil {
- return err
- }
- if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil {
- return err
- }
- // Set seccomp as close to execve as possible, so as few syscalls take
- // place afterward (reducing the amount of syscalls that users need to
- // enable in their seccomp profiles).
- if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges {
- if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
- return newSystemErrorWithCause(err, "init seccomp")
- }
- }
- return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture.go b/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture.go
deleted file mode 100644
index 0bbe14950..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package stacktrace
-
-import "runtime"
-
-// Capture captures a stacktrace for the current calling go program
-//
-// skip is the number of frames to skip
-func Capture(userSkip int) Stacktrace {
- var (
- skip = userSkip + 1 // add one for our own function
- frames []Frame
- prevPc uintptr
- )
- for i := skip; ; i++ {
- pc, file, line, ok := runtime.Caller(i)
- //detect if caller is repeated to avoid loop, gccgo
- //currently runs into a loop without this check
- if !ok || pc == prevPc {
- break
- }
- frames = append(frames, NewFrame(pc, file, line))
- prevPc = pc
- }
- return Stacktrace{
- Frames: frames,
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/frame.go b/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/frame.go
deleted file mode 100644
index 0d590d9a5..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/frame.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package stacktrace
-
-import (
- "path/filepath"
- "runtime"
- "strings"
-)
-
-// NewFrame returns a new stack frame for the provided information
-func NewFrame(pc uintptr, file string, line int) Frame {
- fn := runtime.FuncForPC(pc)
- if fn == nil {
- return Frame{}
- }
- pack, name := parseFunctionName(fn.Name())
- return Frame{
- Line: line,
- File: filepath.Base(file),
- Package: pack,
- Function: name,
- }
-}
-
-func parseFunctionName(name string) (string, string) {
- i := strings.LastIndex(name, ".")
- if i == -1 {
- return "", name
- }
- return name[:i], name[i+1:]
-}
-
-// Frame contains all the information for a stack frame within a go program
-type Frame struct {
- File string
- Function string
- Package string
- Line int
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/stacktrace.go b/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/stacktrace.go
deleted file mode 100644
index 5e8b58d2d..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/stacktrace.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package stacktrace
-
-type Stacktrace struct {
- Frames []Frame
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go
deleted file mode 100644
index 02ea753ed..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "fmt"
- "os"
- "os/exec"
- "syscall" //only for Exec
-
- "github.com/opencontainers/runc/libcontainer/apparmor"
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/keys"
- "github.com/opencontainers/runc/libcontainer/seccomp"
- "github.com/opencontainers/runc/libcontainer/system"
- "github.com/opencontainers/selinux/go-selinux/label"
-
- "golang.org/x/sys/unix"
-)
-
-type linuxStandardInit struct {
- pipe *os.File
- consoleSocket *os.File
- parentPid int
- fifoFd int
- config *initConfig
-}
-
-func (l *linuxStandardInit) getSessionRingParams() (string, uint32, uint32) {
- var newperms uint32
-
- if l.config.Config.Namespaces.Contains(configs.NEWUSER) {
- // With user ns we need 'other' search permissions.
- newperms = 0x8
- } else {
- // Without user ns we need 'UID' search permissions.
- newperms = 0x80000
- }
-
- // Create a unique per session container name that we can join in setns;
- // However, other containers can also join it.
- return fmt.Sprintf("_ses.%s", l.config.ContainerId), 0xffffffff, newperms
-}
-
-func (l *linuxStandardInit) Init() error {
- if !l.config.Config.NoNewKeyring {
- ringname, keepperms, newperms := l.getSessionRingParams()
-
- // Do not inherit the parent's session keyring.
- sessKeyId, err := keys.JoinSessionKeyring(ringname)
- if err != nil {
- return err
- }
- // Make session keyring searcheable.
- if err := keys.ModKeyringPerm(sessKeyId, keepperms, newperms); err != nil {
- return err
- }
- }
-
- if err := setupNetwork(l.config); err != nil {
- return err
- }
- if err := setupRoute(l.config.Config); err != nil {
- return err
- }
-
- label.Init()
- if err := prepareRootfs(l.pipe, l.config); err != nil {
- return err
- }
- // Set up the console. This has to be done *before* we finalize the rootfs,
- // but *after* we've given the user the chance to set up all of the mounts
- // they wanted.
- if l.config.CreateConsole {
- if err := setupConsole(l.consoleSocket, l.config, true); err != nil {
- return err
- }
- if err := system.Setctty(); err != nil {
- return err
- }
- }
-
- // Finish the rootfs setup.
- if l.config.Config.Namespaces.Contains(configs.NEWNS) {
- if err := finalizeRootfs(l.config.Config); err != nil {
- return err
- }
- }
-
- if hostname := l.config.Config.Hostname; hostname != "" {
- if err := unix.Sethostname([]byte(hostname)); err != nil {
- return err
- }
- }
- if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil {
- return err
- }
- if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil {
- return err
- }
-
- for key, value := range l.config.Config.Sysctl {
- if err := writeSystemProperty(key, value); err != nil {
- return err
- }
- }
- for _, path := range l.config.Config.ReadonlyPaths {
- if err := readonlyPath(path); err != nil {
- return err
- }
- }
- for _, path := range l.config.Config.MaskPaths {
- if err := maskPath(path); err != nil {
- return err
- }
- }
- pdeath, err := system.GetParentDeathSignal()
- if err != nil {
- return err
- }
- if l.config.NoNewPrivileges {
- if err := unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
- return err
- }
- }
- // Tell our parent that we're ready to Execv. This must be done before the
- // Seccomp rules have been applied, because we need to be able to read and
- // write to a socket.
- if err := syncParentReady(l.pipe); err != nil {
- return err
- }
- // Without NoNewPrivileges seccomp is a privileged operation, so we need to
- // do this before dropping capabilities; otherwise do it as late as possible
- // just before execve so as few syscalls take place after it as possible.
- if l.config.Config.Seccomp != nil && !l.config.NoNewPrivileges {
- if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
- return err
- }
- }
- if err := finalizeNamespace(l.config); err != nil {
- return err
- }
- // finalizeNamespace can change user/group which clears the parent death
- // signal, so we restore it here.
- if err := pdeath.Restore(); err != nil {
- return err
- }
- // Compare the parent from the initial start of the init process and make
- // sure that it did not change. if the parent changes that means it died
- // and we were reparented to something else so we should just kill ourself
- // and not cause problems for someone else.
- if unix.Getppid() != l.parentPid {
- return unix.Kill(unix.Getpid(), unix.SIGKILL)
- }
- // Check for the arg before waiting to make sure it exists and it is
- // returned as a create time error.
- name, err := exec.LookPath(l.config.Args[0])
- if err != nil {
- return err
- }
- // Close the pipe to signal that we have completed our init.
- l.pipe.Close()
- // Wait for the FIFO to be opened on the other side before exec-ing the
- // user process. We open it through /proc/self/fd/$fd, because the fd that
- // was given to us was an O_PATH fd to the fifo itself. Linux allows us to
- // re-open an O_PATH fd through /proc.
- fd, err := unix.Open(fmt.Sprintf("/proc/self/fd/%d", l.fifoFd), unix.O_WRONLY|unix.O_CLOEXEC, 0)
- if err != nil {
- return newSystemErrorWithCause(err, "open exec fifo")
- }
- if _, err := unix.Write(fd, []byte("0")); err != nil {
- return newSystemErrorWithCause(err, "write 0 exec fifo")
- }
- // Close the O_PATH fifofd fd before exec because the kernel resets
- // dumpable in the wrong order. This has been fixed in newer kernels, but
- // we keep this to ensure CVE-2016-9962 doesn't re-emerge on older kernels.
- // N.B. the core issue itself (passing dirfds to the host filesystem) has
- // since been resolved.
- // https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
- unix.Close(l.fifoFd)
- // Set seccomp as close to execve as possible, so as few syscalls take
- // place afterward (reducing the amount of syscalls that users need to
- // enable in their seccomp profiles).
- if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges {
- if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
- return newSystemErrorWithCause(err, "init seccomp")
- }
- }
- if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil {
- return newSystemErrorWithCause(err, "exec user process")
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go
deleted file mode 100644
index b45ce23e4..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go
+++ /dev/null
@@ -1,255 +0,0 @@
-// +build linux
-
-package libcontainer
-
-import (
- "fmt"
- "os"
- "path/filepath"
-
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/utils"
-
- "github.com/sirupsen/logrus"
- "golang.org/x/sys/unix"
-)
-
-func newStateTransitionError(from, to containerState) error {
- return &stateTransitionError{
- From: from.status().String(),
- To: to.status().String(),
- }
-}
-
-// stateTransitionError is returned when an invalid state transition happens from one
-// state to another.
-type stateTransitionError struct {
- From string
- To string
-}
-
-func (s *stateTransitionError) Error() string {
- return fmt.Sprintf("invalid state transition from %s to %s", s.From, s.To)
-}
-
-type containerState interface {
- transition(containerState) error
- destroy() error
- status() Status
-}
-
-func destroy(c *linuxContainer) error {
- if !c.config.Namespaces.Contains(configs.NEWPID) {
- if err := signalAllProcesses(c.cgroupManager, unix.SIGKILL); err != nil {
- logrus.Warn(err)
- }
- }
- err := c.cgroupManager.Destroy()
- if c.intelRdtManager != nil {
- if ierr := c.intelRdtManager.Destroy(); err == nil {
- err = ierr
- }
- }
- if rerr := os.RemoveAll(c.root); err == nil {
- err = rerr
- }
- c.initProcess = nil
- if herr := runPoststopHooks(c); err == nil {
- err = herr
- }
- c.state = &stoppedState{c: c}
- return err
-}
-
-func runPoststopHooks(c *linuxContainer) error {
- if c.config.Hooks != nil {
- bundle, annotations := utils.Annotations(c.config.Labels)
- s := configs.HookState{
- Version: c.config.Version,
- ID: c.id,
- Bundle: bundle,
- Annotations: annotations,
- }
- for _, hook := range c.config.Hooks.Poststop {
- if err := hook.Run(s); err != nil {
- return err
- }
- }
- }
- return nil
-}
-
-// stoppedState represents a container is a stopped/destroyed state.
-type stoppedState struct {
- c *linuxContainer
-}
-
-func (b *stoppedState) status() Status {
- return Stopped
-}
-
-func (b *stoppedState) transition(s containerState) error {
- switch s.(type) {
- case *runningState, *restoredState:
- b.c.state = s
- return nil
- case *stoppedState:
- return nil
- }
- return newStateTransitionError(b, s)
-}
-
-func (b *stoppedState) destroy() error {
- return destroy(b.c)
-}
-
-// runningState represents a container that is currently running.
-type runningState struct {
- c *linuxContainer
-}
-
-func (r *runningState) status() Status {
- return Running
-}
-
-func (r *runningState) transition(s containerState) error {
- switch s.(type) {
- case *stoppedState:
- t, err := r.c.runType()
- if err != nil {
- return err
- }
- if t == Running {
- return newGenericError(fmt.Errorf("container still running"), ContainerNotStopped)
- }
- r.c.state = s
- return nil
- case *pausedState:
- r.c.state = s
- return nil
- case *runningState:
- return nil
- }
- return newStateTransitionError(r, s)
-}
-
-func (r *runningState) destroy() error {
- t, err := r.c.runType()
- if err != nil {
- return err
- }
- if t == Running {
- return newGenericError(fmt.Errorf("container is not destroyed"), ContainerNotStopped)
- }
- return destroy(r.c)
-}
-
-type createdState struct {
- c *linuxContainer
-}
-
-func (i *createdState) status() Status {
- return Created
-}
-
-func (i *createdState) transition(s containerState) error {
- switch s.(type) {
- case *runningState, *pausedState, *stoppedState:
- i.c.state = s
- return nil
- case *createdState:
- return nil
- }
- return newStateTransitionError(i, s)
-}
-
-func (i *createdState) destroy() error {
- i.c.initProcess.signal(unix.SIGKILL)
- return destroy(i.c)
-}
-
-// pausedState represents a container that is currently pause. It cannot be destroyed in a
-// paused state and must transition back to running first.
-type pausedState struct {
- c *linuxContainer
-}
-
-func (p *pausedState) status() Status {
- return Paused
-}
-
-func (p *pausedState) transition(s containerState) error {
- switch s.(type) {
- case *runningState, *stoppedState:
- p.c.state = s
- return nil
- case *pausedState:
- return nil
- }
- return newStateTransitionError(p, s)
-}
-
-func (p *pausedState) destroy() error {
- t, err := p.c.runType()
- if err != nil {
- return err
- }
- if t != Running && t != Created {
- if err := p.c.cgroupManager.Freeze(configs.Thawed); err != nil {
- return err
- }
- return destroy(p.c)
- }
- return newGenericError(fmt.Errorf("container is paused"), ContainerPaused)
-}
-
-// restoredState is the same as the running state but also has associated checkpoint
-// information that maybe need destroyed when the container is stopped and destroy is called.
-type restoredState struct {
- imageDir string
- c *linuxContainer
-}
-
-func (r *restoredState) status() Status {
- return Running
-}
-
-func (r *restoredState) transition(s containerState) error {
- switch s.(type) {
- case *stoppedState, *runningState:
- return nil
- }
- return newStateTransitionError(r, s)
-}
-
-func (r *restoredState) destroy() error {
- if _, err := os.Stat(filepath.Join(r.c.root, "checkpoint")); err != nil {
- if !os.IsNotExist(err) {
- return err
- }
- }
- return destroy(r.c)
-}
-
-// loadedState is used whenever a container is restored, loaded, or setting additional
-// processes inside and it should not be destroyed when it is exiting.
-type loadedState struct {
- c *linuxContainer
- s Status
-}
-
-func (n *loadedState) status() Status {
- return n.s
-}
-
-func (n *loadedState) transition(s containerState) error {
- n.c.state = s
- return nil
-}
-
-func (n *loadedState) destroy() error {
- if err := n.c.refreshState(); err != nil {
- return err
- }
- return n.c.state.destroy()
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/stats.go b/vendor/github.com/opencontainers/runc/libcontainer/stats.go
deleted file mode 100644
index 303e4b94c..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/stats.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package libcontainer
-
-type NetworkInterface struct {
- // Name is the name of the network interface.
- Name string
-
- RxBytes uint64
- RxPackets uint64
- RxErrors uint64
- RxDropped uint64
- TxBytes uint64
- TxPackets uint64
- TxErrors uint64
- TxDropped uint64
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/stats_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/stats_linux.go
deleted file mode 100644
index 29fd641e9..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/stats_linux.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package libcontainer
-
-import "github.com/opencontainers/runc/libcontainer/cgroups"
-import "github.com/opencontainers/runc/libcontainer/intelrdt"
-
-type Stats struct {
- Interfaces []*NetworkInterface
- CgroupStats *cgroups.Stats
- IntelRdtStats *intelrdt.Stats
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/sync.go b/vendor/github.com/opencontainers/runc/libcontainer/sync.go
deleted file mode 100644
index cf7b45bc3..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/sync.go
+++ /dev/null
@@ -1,107 +0,0 @@
-package libcontainer
-
-import (
- "encoding/json"
- "fmt"
- "io"
-
- "github.com/opencontainers/runc/libcontainer/utils"
-)
-
-type syncType string
-
-// Constants that are used for synchronisation between the parent and child
-// during container setup. They come in pairs (with procError being a generic
-// response which is followed by a &genericError).
-//
-// [ child ] <-> [ parent ]
-//
-// procHooks --> [run hooks]
-// <-- procResume
-//
-// procConsole -->
-// <-- procConsoleReq
-// [send(fd)] --> [recv(fd)]
-// <-- procConsoleAck
-//
-// procReady --> [final setup]
-// <-- procRun
-const (
- procError syncType = "procError"
- procReady syncType = "procReady"
- procRun syncType = "procRun"
- procHooks syncType = "procHooks"
- procResume syncType = "procResume"
-)
-
-type syncT struct {
- Type syncType `json:"type"`
-}
-
-// writeSync is used to write to a synchronisation pipe. An error is returned
-// if there was a problem writing the payload.
-func writeSync(pipe io.Writer, sync syncType) error {
- if err := utils.WriteJSON(pipe, syncT{sync}); err != nil {
- return err
- }
- return nil
-}
-
-// readSync is used to read from a synchronisation pipe. An error is returned
-// if we got a genericError, the pipe was closed, or we got an unexpected flag.
-func readSync(pipe io.Reader, expected syncType) error {
- var procSync syncT
- if err := json.NewDecoder(pipe).Decode(&procSync); err != nil {
- if err == io.EOF {
- return fmt.Errorf("parent closed synchronisation channel")
- }
-
- if procSync.Type == procError {
- var ierr genericError
-
- if err := json.NewDecoder(pipe).Decode(&ierr); err != nil {
- return fmt.Errorf("failed reading error from parent: %v", err)
- }
-
- return &ierr
- }
-
- if procSync.Type != expected {
- return fmt.Errorf("invalid synchronisation flag from parent")
- }
- }
- return nil
-}
-
-// parseSync runs the given callback function on each syncT received from the
-// child. It will return once io.EOF is returned from the given pipe.
-func parseSync(pipe io.Reader, fn func(*syncT) error) error {
- dec := json.NewDecoder(pipe)
- for {
- var sync syncT
- if err := dec.Decode(&sync); err != nil {
- if err == io.EOF {
- break
- }
- return err
- }
-
- // We handle this case outside fn for cleanliness reasons.
- var ierr *genericError
- if sync.Type == procError {
- if err := dec.Decode(&ierr); err != nil && err != io.EOF {
- return newSystemErrorWithCause(err, "decoding proc error from init")
- }
- if ierr != nil {
- return ierr
- }
- // Programmer error.
- panic("No error following JSON procError payload.")
- }
-
- if err := fn(&sync); err != nil {
- return err
- }
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go b/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go
deleted file mode 100644
index c8a9364d5..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// +build linux
-
-package utils
-
-/*
- * Copyright 2016, 2017 SUSE LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import (
- "fmt"
- "os"
-
- "golang.org/x/sys/unix"
-)
-
-// MaxSendfdLen is the maximum length of the name of a file descriptor being
-// sent using SendFd. The name of the file handle returned by RecvFd will never
-// be larger than this value.
-const MaxNameLen = 4096
-
-// oobSpace is the size of the oob slice required to store a single FD. Note
-// that unix.UnixRights appears to make the assumption that fd is always int32,
-// so sizeof(fd) = 4.
-var oobSpace = unix.CmsgSpace(4)
-
-// RecvFd waits for a file descriptor to be sent over the given AF_UNIX
-// socket. The file name of the remote file descriptor will be recreated
-// locally (it is sent as non-auxiliary data in the same payload).
-func RecvFd(socket *os.File) (*os.File, error) {
- // For some reason, unix.Recvmsg uses the length rather than the capacity
- // when passing the msg_controllen and other attributes to recvmsg. So we
- // have to actually set the length.
- name := make([]byte, MaxNameLen)
- oob := make([]byte, oobSpace)
-
- sockfd := socket.Fd()
- n, oobn, _, _, err := unix.Recvmsg(int(sockfd), name, oob, 0)
- if err != nil {
- return nil, err
- }
-
- if n >= MaxNameLen || oobn != oobSpace {
- return nil, fmt.Errorf("recvfd: incorrect number of bytes read (n=%d oobn=%d)", n, oobn)
- }
-
- // Truncate.
- name = name[:n]
- oob = oob[:oobn]
-
- scms, err := unix.ParseSocketControlMessage(oob)
- if err != nil {
- return nil, err
- }
- if len(scms) != 1 {
- return nil, fmt.Errorf("recvfd: number of SCMs is not 1: %d", len(scms))
- }
- scm := scms[0]
-
- fds, err := unix.ParseUnixRights(&scm)
- if err != nil {
- return nil, err
- }
- if len(fds) != 1 {
- return nil, fmt.Errorf("recvfd: number of fds is not 1: %d", len(fds))
- }
- fd := uintptr(fds[0])
-
- return os.NewFile(fd, string(name)), nil
-}
-
-// SendFd sends a file descriptor over the given AF_UNIX socket. In
-// addition, the file.Name() of the given file will also be sent as
-// non-auxiliary data in the same payload (allowing to send contextual
-// information for a file descriptor).
-func SendFd(socket *os.File, name string, fd uintptr) error {
- if len(name) >= MaxNameLen {
- return fmt.Errorf("sendfd: filename too long: %s", name)
- }
- oob := unix.UnixRights(int(fd))
- return unix.Sendmsg(int(socket.Fd()), []byte(name), oob, nil, 0)
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go b/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go
deleted file mode 100644
index baa54c9ba..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go
+++ /dev/null
@@ -1,127 +0,0 @@
-package utils
-
-import (
- "crypto/rand"
- "encoding/hex"
- "encoding/json"
- "io"
- "os"
- "path/filepath"
- "strings"
- "unsafe"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- exitSignalOffset = 128
-)
-
-// GenerateRandomName returns a new name joined with a prefix. This size
-// specified is used to truncate the randomly generated value
-func GenerateRandomName(prefix string, size int) (string, error) {
- id := make([]byte, 32)
- if _, err := io.ReadFull(rand.Reader, id); err != nil {
- return "", err
- }
- if size > 64 {
- size = 64
- }
- return prefix + hex.EncodeToString(id)[:size], nil
-}
-
-// ResolveRootfs ensures that the current working directory is
-// not a symlink and returns the absolute path to the rootfs
-func ResolveRootfs(uncleanRootfs string) (string, error) {
- rootfs, err := filepath.Abs(uncleanRootfs)
- if err != nil {
- return "", err
- }
- return filepath.EvalSymlinks(rootfs)
-}
-
-// ExitStatus returns the correct exit status for a process based on if it
-// was signaled or exited cleanly
-func ExitStatus(status unix.WaitStatus) int {
- if status.Signaled() {
- return exitSignalOffset + int(status.Signal())
- }
- return status.ExitStatus()
-}
-
-// WriteJSON writes the provided struct v to w using standard json marshaling
-func WriteJSON(w io.Writer, v interface{}) error {
- data, err := json.Marshal(v)
- if err != nil {
- return err
- }
- _, err = w.Write(data)
- return err
-}
-
-// CleanPath makes a path safe for use with filepath.Join. This is done by not
-// only cleaning the path, but also (if the path is relative) adding a leading
-// '/' and cleaning it (then removing the leading '/'). This ensures that a
-// path resulting from prepending another path will always resolve to lexically
-// be a subdirectory of the prefixed path. This is all done lexically, so paths
-// that include symlinks won't be safe as a result of using CleanPath.
-func CleanPath(path string) string {
- // Deal with empty strings nicely.
- if path == "" {
- return ""
- }
-
- // Ensure that all paths are cleaned (especially problematic ones like
- // "/../../../../../" which can cause lots of issues).
- path = filepath.Clean(path)
-
- // If the path isn't absolute, we need to do more processing to fix paths
- // such as "../../../../<etc>/some/path". We also shouldn't convert absolute
- // paths to relative ones.
- if !filepath.IsAbs(path) {
- path = filepath.Clean(string(os.PathSeparator) + path)
- // This can't fail, as (by definition) all paths are relative to root.
- path, _ = filepath.Rel(string(os.PathSeparator), path)
- }
-
- // Clean the path again for good measure.
- return filepath.Clean(path)
-}
-
-// SearchLabels searches a list of key-value pairs for the provided key and
-// returns the corresponding value. The pairs must be separated with '='.
-func SearchLabels(labels []string, query string) string {
- for _, l := range labels {
- parts := strings.SplitN(l, "=", 2)
- if len(parts) < 2 {
- continue
- }
- if parts[0] == query {
- return parts[1]
- }
- }
- return ""
-}
-
-// Annotations returns the bundle path and user defined annotations from the
-// libcontainer state. We need to remove the bundle because that is a label
-// added by libcontainer.
-func Annotations(labels []string) (bundle string, userAnnotations map[string]string) {
- userAnnotations = make(map[string]string)
- for _, l := range labels {
- parts := strings.SplitN(l, "=", 2)
- if len(parts) < 2 {
- continue
- }
- if parts[0] == "bundle" {
- bundle = parts[1]
- } else {
- userAnnotations[parts[0]] = parts[1]
- }
- }
- return
-}
-
-func GetIntSize() int {
- return int(unsafe.Sizeof(1))
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go
deleted file mode 100644
index c96088988..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// +build !windows
-
-package utils
-
-import (
- "io/ioutil"
- "os"
- "strconv"
-
- "golang.org/x/sys/unix"
-)
-
-func CloseExecFrom(minFd int) error {
- fdList, err := ioutil.ReadDir("/proc/self/fd")
- if err != nil {
- return err
- }
- for _, fi := range fdList {
- fd, err := strconv.Atoi(fi.Name())
- if err != nil {
- // ignore non-numeric file names
- continue
- }
-
- if fd < minFd {
- // ignore descriptors lower than our specified minimum
- continue
- }
-
- // intentionally ignore errors from unix.CloseOnExec
- unix.CloseOnExec(fd)
- // the cases where this might fail are basically file descriptors that have already been closed (including and especially the one that was created when ioutil.ReadDir did the "opendir" syscall)
- }
- return nil
-}
-
-// NewSockPair returns a new unix socket pair
-func NewSockPair(name string) (parent *os.File, child *os.File, err error) {
- fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
- if err != nil {
- return nil, nil, err
- }
- return os.NewFile(uintptr(fds[1]), name+"-p"), os.NewFile(uintptr(fds[0]), name+"-c"), nil
-}