Skip to content

Commit fcd966f

Browse files
committed
Remove kmem Initialization check
Signed-off-by: Buddha Prakash <[email protected]>
1 parent fb22165 commit fcd966f

File tree

4 files changed

+52
-43
lines changed

4 files changed

+52
-43
lines changed

libcontainer/cgroups/fs/memory.go

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,19 @@ package fs
55
import (
66
"bufio"
77
"fmt"
8-
"math"
8+
"io/ioutil"
99
"os"
1010
"path/filepath"
1111
"strconv"
1212
"strings"
13+
"syscall"
1314

1415
"github.com/opencontainers/runc/libcontainer/cgroups"
1516
"github.com/opencontainers/runc/libcontainer/configs"
16-
"github.com/opencontainers/runc/libcontainer/system"
17+
)
18+
19+
const (
20+
cgroupKernelMemoryLimit = "memory.kmem.limit_in_bytes"
1721
)
1822

1923
type MemoryGroup struct {
@@ -34,9 +38,7 @@ func (s *MemoryGroup) Apply(d *cgroupData) (err error) {
3438
return err
3539
}
3640
}
37-
// We have to set kernel memory here, as we can't change it once
38-
// processes have been attached to the cgroup.
39-
if err := s.SetKernelMemory(path, d.config); err != nil {
41+
if err := EnableKernelMemoryAccounting(path); err != nil {
4042
return err
4143
}
4244
}
@@ -55,38 +57,43 @@ func (s *MemoryGroup) Apply(d *cgroupData) (err error) {
5557
return nil
5658
}
5759

58-
func (s *MemoryGroup) SetKernelMemory(path string, cgroup *configs.Cgroup) error {
59-
// This has to be done separately because it has special
60-
// constraints (it can only be initialized before setting up a
61-
// hierarchy or adding a task to the cgroups. However, if
62-
// sucessfully initialized, it can be updated anytime afterwards)
63-
if cgroup.Resources.KernelMemory != 0 {
64-
kmemInitialized := false
65-
// Is kmem.limit_in_bytes already set?
66-
kmemValue, err := getCgroupParamUint(path, "memory.kmem.limit_in_bytes")
67-
if err != nil {
68-
return err
69-
}
70-
switch system.GetLongBit() {
71-
case 32:
72-
kmemInitialized = uint32(kmemValue) != uint32(math.MaxUint32)
73-
case 64:
74-
kmemInitialized = kmemValue != uint64(math.MaxUint64)
75-
}
76-
if !kmemInitialized {
77-
// If there's already tasks in the cgroup, we can't change the limit either
78-
tasks, err := getCgroupParamString(path, "tasks")
79-
if err != nil {
80-
return err
81-
}
82-
if tasks != "" {
83-
return fmt.Errorf("cannot set kmem.limit_in_bytes after task have joined this cgroup")
84-
}
85-
}
60+
func EnableKernelMemoryAccounting(path string) error {
61+
// Check if kernel memory is enabled
62+
// We have to limit the kernel memory here as it won't be accounted at all
63+
// until a limit is set on the cgroup and limit cannot be set once the
64+
// cgroup has children, or if there are already tasks in the cgroup.
65+
kernelMemoryLimit := int64(1)
66+
if err := setKernelMemory(path, kernelMemoryLimit); err != nil {
67+
return err
68+
}
69+
kernelMemoryLimit = int64(-1)
70+
if err := setKernelMemory(path, kernelMemoryLimit); err != nil {
71+
return err
72+
}
73+
return nil
74+
}
8675

87-
if err := writeFile(path, "memory.kmem.limit_in_bytes", strconv.FormatInt(cgroup.Resources.KernelMemory, 10)); err != nil {
88-
return err
76+
func setKernelMemory(path string, kernelMemoryLimit int64) error {
77+
if path == "" {
78+
return fmt.Errorf("no such directory for %s", cgroupKernelMemoryLimit)
79+
}
80+
if !cgroups.PathExists(filepath.Join(path, cgroupKernelMemoryLimit)) {
81+
// kernel memory is not enabled on the system so we should do nothing
82+
return nil
83+
}
84+
if err := ioutil.WriteFile(filepath.Join(path, cgroupKernelMemoryLimit), []byte(strconv.FormatInt(kernelMemoryLimit, 10)), 0700); err != nil {
85+
// Check if the error number returned by the syscall is "EBUSY"
86+
// The EBUSY signal is returned on attempts to write to the
87+
// memory.kmem.limit_in_bytes file if the cgroup has children or
88+
// once tasks have been attached to the cgroup
89+
if pathErr, ok := err.(*os.PathError); ok {
90+
if errNo, ok := pathErr.Err.(syscall.Errno); ok {
91+
if errNo == syscall.EBUSY {
92+
return fmt.Errorf("failed to set %s, because either tasks have already joined this cgroup or it has children", cgroupKernelMemoryLimit)
93+
}
94+
}
8995
}
96+
return fmt.Errorf("failed to write %v to %v: %v", kernelMemoryLimit, cgroupKernelMemoryLimit, err)
9097
}
9198
return nil
9299
}
@@ -139,15 +146,18 @@ func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error {
139146
return err
140147
}
141148

142-
if err := s.SetKernelMemory(path, cgroup); err != nil {
143-
return err
149+
if cgroup.Resources.KernelMemory != 0 {
150+
if err := setKernelMemory(path, cgroup.Resources.KernelMemory); err != nil {
151+
return err
152+
}
144153
}
145154

146155
if cgroup.Resources.MemoryReservation != 0 {
147156
if err := writeFile(path, "memory.soft_limit_in_bytes", strconv.FormatInt(cgroup.Resources.MemoryReservation, 10)); err != nil {
148157
return err
149158
}
150159
}
160+
151161
if cgroup.Resources.KernelMemoryTCP != 0 {
152162
if err := writeFile(path, "memory.kmem.tcp.limit_in_bytes", strconv.FormatInt(cgroup.Resources.KernelMemoryTCP, 10)); err != nil {
153163
return err

libcontainer/cgroups/fs/memory_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ func TestMemorySetKernelMemory(t *testing.T) {
230230

231231
helper.CgroupData.config.Resources.KernelMemory = kernelMemoryAfter
232232
memory := &MemoryGroup{}
233-
if err := memory.SetKernelMemory(helper.CgroupPath, helper.CgroupData.config); err != nil {
233+
if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
234234
t.Fatal(err)
235235
}
236236

libcontainer/cgroups/systemd/apply_systemd.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,5 +490,8 @@ func setKernelMemory(c *configs.Cgroup) error {
490490
return err
491491
}
492492

493-
return os.MkdirAll(path, 0755)
493+
if err := os.MkdirAll(path, 0755); err != nil {
494+
return err
495+
}
496+
return fs.EnableKernelMemoryAccounting(path)
494497
}

libcontainer/system/sysconfig.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,3 @@ import "C"
2525
func GetClockTicks() int {
2626
return int(C.sysconf(C._SC_CLK_TCK))
2727
}
28-
29-
func GetLongBit() int {
30-
return int(C.GetLongBit())
31-
}

0 commit comments

Comments
 (0)