summaryrefslogtreecommitdiff
path: root/vendor/github.com/opencontainers/runc/libcontainer/cgroups
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2018-02-14 12:51:06 -0600
committerAtomic Bot <atomic-devel@projectatomic.io>2018-02-15 00:20:47 +0000
commitbe9ed1cfacc19d1ad3c09e10481da445615b8b8e (patch)
tree1c0c01daf5b43c6139e37408be601475c1dcea41 /vendor/github.com/opencontainers/runc/libcontainer/cgroups
parentd051dc38d81920c94c37b20ceba0d33b35299bca (diff)
downloadpodman-be9ed1cfacc19d1ad3c09e10481da445615b8b8e.tar.gz
podman-be9ed1cfacc19d1ad3c09e10481da445615b8b8e.tar.bz2
podman-be9ed1cfacc19d1ad3c09e10481da445615b8b8e.zip
Privileged containers should inherit host devices
When running a privileged container, it should inherit the same devices the host has. Signed-off-by: baude <bbaude@redhat.com> Closes: #330 Approved by: mheon
Diffstat (limited to 'vendor/github.com/opencontainers/runc/libcontainer/cgroups')
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go13
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go13
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/rootless/rootless.go128
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_nosystemd.go4
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go16
5 files changed, 37 insertions, 137 deletions
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
index 22d82acb4..43bdccf3e 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go
@@ -145,8 +145,17 @@ func (m *Manager) Apply(pid int) (err error) {
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
}
@@ -198,6 +207,10 @@ func (m *Manager) Set(container *configs.Config) error {
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
}
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go
index e70dfe3b9..4b19f8a97 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go
@@ -29,11 +29,15 @@ func (s *FreezerGroup) Apply(d *cgroupData) error {
func (s *FreezerGroup) Set(path string, cgroup *configs.Cgroup) error {
switch cgroup.Resources.Freezer {
case configs.Frozen, configs.Thawed:
- if err := writeFile(path, "freezer.state", string(cgroup.Resources.Freezer)); err != nil {
- return err
- }
-
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
@@ -41,6 +45,7 @@ func (s *FreezerGroup) Set(path string, cgroup *configs.Cgroup) error {
if strings.TrimSpace(state) == string(cgroup.Resources.Freezer) {
break
}
+
time.Sleep(1 * time.Millisecond)
}
case configs.Undefined:
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/rootless/rootless.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/rootless/rootless.go
deleted file mode 100644
index b1efbfd99..000000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/rootless/rootless.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// +build linux
-
-package rootless
-
-import (
- "fmt"
-
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/cgroups/fs"
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/configs/validate"
-)
-
-// TODO: This is copied from libcontainer/cgroups/fs, which duplicates this code
-// needlessly. We should probably export this list.
-
-var subsystems = []subsystem{
- &fs.CpusetGroup{},
- &fs.DevicesGroup{},
- &fs.MemoryGroup{},
- &fs.CpuGroup{},
- &fs.CpuacctGroup{},
- &fs.PidsGroup{},
- &fs.BlkioGroup{},
- &fs.HugetlbGroup{},
- &fs.NetClsGroup{},
- &fs.NetPrioGroup{},
- &fs.PerfEventGroup{},
- &fs.FreezerGroup{},
- &fs.NameGroup{GroupName: "name=systemd"},
-}
-
-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
-}
-
-// The noop cgroup manager is used for rootless containers, because we currently
-// cannot manage cgroups if we are in a rootless setup. This manager is chosen
-// by factory if we are in rootless mode. We error out if any cgroup options are
-// set in the config -- this may change in the future with upcoming kernel features
-// like the cgroup namespace.
-
-type Manager struct {
- Cgroups *configs.Cgroup
- Paths map[string]string
-}
-
-func (m *Manager) Apply(pid int) error {
- // If there are no cgroup settings, there's nothing to do.
- if m.Cgroups == nil {
- return nil
- }
-
- // We can't set paths.
- // TODO(cyphar): Implement the case where the runner of a rootless container
- // owns their own cgroup, which would allow us to set up a
- // cgroup for each path.
- if m.Cgroups.Paths != nil {
- return fmt.Errorf("cannot change cgroup path in rootless container")
- }
-
- // We load the paths into the manager.
- paths := make(map[string]string)
- for _, sys := range subsystems {
- name := sys.Name()
-
- path, err := cgroups.GetOwnCgroupPath(name)
- if err != nil {
- // Ignore paths we couldn't resolve.
- continue
- }
-
- paths[name] = path
- }
-
- m.Paths = paths
- return nil
-}
-
-func (m *Manager) GetPaths() map[string]string {
- return m.Paths
-}
-
-func (m *Manager) Set(container *configs.Config) error {
- // We have to re-do the validation here, since someone might decide to
- // update a rootless container.
- return validate.New().Validate(container)
-}
-
-func (m *Manager) GetPids() ([]int, error) {
- dir, err := cgroups.GetOwnCgroupPath("devices")
- if err != nil {
- return nil, err
- }
- return cgroups.GetPids(dir)
-}
-
-func (m *Manager) GetAllPids() ([]int, error) {
- dir, err := cgroups.GetOwnCgroupPath("devices")
- if err != nil {
- return nil, err
- }
- return cgroups.GetAllPids(dir)
-}
-
-func (m *Manager) GetStats() (*cgroups.Stats, error) {
- // TODO(cyphar): We can make this work if we figure out a way to allow usage
- // of cgroups with a rootless container. While this doesn't
- // actually require write access to a cgroup directory, the
- // statistics are not useful if they can be affected by
- // non-container processes.
- return nil, fmt.Errorf("cannot get cgroup stats in rootless container")
-}
-
-func (m *Manager) Freeze(state configs.FreezerState) error {
- // TODO(cyphar): We can make this work if we figure out a way to allow usage
- // of cgroups with a rootless container.
- return fmt.Errorf("cannot use freezer cgroup in rootless container")
-}
-
-func (m *Manager) Destroy() error {
- // We don't have to do anything here because we didn't do any setup.
- return 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
index 7de9ae605..a65d8e443 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_nosystemd.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_nosystemd.go
@@ -1,4 +1,4 @@
-// +build !linux
+// +build !linux static_build
package systemd
@@ -43,7 +43,7 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) {
}
func (m *Manager) Set(container *configs.Config) error {
- return nil, fmt.Errorf("Systemd not supported")
+ return fmt.Errorf("Systemd not supported")
}
func (m *Manager) Freeze(state configs.FreezerState) error {
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
index b010b4b32..45bd3acce 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
@@ -1,4 +1,4 @@
-// +build linux
+// +build linux,!static_build
package systemd
@@ -260,7 +260,7 @@ func (m *Manager) Apply(pid int) error {
if c.Resources.Memory != 0 {
properties = append(properties,
- newProp("MemoryLimit", c.Resources.Memory))
+ newProp("MemoryLimit", uint64(c.Resources.Memory)))
}
if c.Resources.CpuShares != 0 {
@@ -271,6 +271,13 @@ func (m *Manager) Apply(pid int) error {
// 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))
}
@@ -288,10 +295,13 @@ func (m *Manager) Apply(pid int) error {
}
}
- if _, err := theConn.StartTransientUnit(unitName, "replace", properties, nil); err != nil && !isUnitExists(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
}