mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
67840cce4b
Commit b2f8a74d "clothed" the naked return as inflicted by gofumpt
v0.9.0. Since gofumpt v0.9.2 this rule was moved to "extra" category,
not enabled by default. The only other "extra" rule is to group adjacent
parameters with the same type, which also makes sense.
Enable gofumpt "extra" rules, and reformat the code accordingly.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
85 lines
1.9 KiB
Go
85 lines
1.9 KiB
Go
package libcontainer
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
type PressureLevel uint
|
|
|
|
const (
|
|
LowPressure PressureLevel = iota
|
|
MediumPressure
|
|
CriticalPressure
|
|
)
|
|
|
|
func registerMemoryEvent(cgDir, evName, 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 := os.WriteFile(eventControlPath, []byte(data), 0o700); 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(dir string) (<-chan struct{}, error) {
|
|
if dir == "" {
|
|
return nil, errors.New("memory controller missing")
|
|
}
|
|
|
|
return registerMemoryEvent(dir, "memory.oom_control", "")
|
|
}
|
|
|
|
func notifyMemoryPressure(dir string, level PressureLevel) (<-chan struct{}, error) {
|
|
if dir == "" {
|
|
return nil, errors.New("memory controller missing")
|
|
}
|
|
|
|
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)
|
|
}
|