vendor: update google/cadvisor and opencontainers/runc
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
102
vendor/github.com/opencontainers/runc/libcontainer/notify_linux_v2.go
generated
vendored
Normal file
102
vendor/github.com/opencontainers/runc/libcontainer/notify_linux_v2.go
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
// +build linux
|
||||
|
||||
package libcontainer
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func getValueFromCgroup(path, key string) (int, error) {
|
||||
content, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
lines := strings.Split(string(content), "\n")
|
||||
for _, line := range lines {
|
||||
arr := strings.Split(line, " ")
|
||||
if len(arr) == 2 && arr[0] == key {
|
||||
return strconv.Atoi(arr[1])
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func registerMemoryEventV2(cgDir, evName, cgEvName string) (<-chan struct{}, error) {
|
||||
eventControlPath := filepath.Join(cgDir, evName)
|
||||
cgEvPath := filepath.Join(cgDir, cgEvName)
|
||||
fd, err := unix.InotifyInit()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to init inotify")
|
||||
}
|
||||
// watching oom kill
|
||||
evFd, err := unix.InotifyAddWatch(fd, eventControlPath, unix.IN_MODIFY)
|
||||
if err != nil {
|
||||
unix.Close(fd)
|
||||
return nil, errors.Wrap(err, "unable to add inotify watch")
|
||||
}
|
||||
// Because no `unix.IN_DELETE|unix.IN_DELETE_SELF` event for cgroup file system, so watching all process exited
|
||||
cgFd, err := unix.InotifyAddWatch(fd, cgEvPath, unix.IN_MODIFY)
|
||||
if err != nil {
|
||||
unix.Close(fd)
|
||||
return nil, errors.Wrap(err, "unable to add inotify watch")
|
||||
}
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
var (
|
||||
buffer [unix.SizeofInotifyEvent + unix.PathMax + 1]byte
|
||||
offset uint32
|
||||
)
|
||||
defer func() {
|
||||
unix.Close(fd)
|
||||
close(ch)
|
||||
}()
|
||||
|
||||
for {
|
||||
n, err := unix.Read(fd, buffer[:])
|
||||
if err != nil {
|
||||
logrus.Warnf("unable to read event data from inotify, got error: %v", err)
|
||||
return
|
||||
}
|
||||
if n < unix.SizeofInotifyEvent {
|
||||
logrus.Warnf("we should read at least %d bytes from inotify, but got %d bytes.", unix.SizeofInotifyEvent, n)
|
||||
return
|
||||
}
|
||||
offset = 0
|
||||
for offset <= uint32(n-unix.SizeofInotifyEvent) {
|
||||
rawEvent := (*unix.InotifyEvent)(unsafe.Pointer(&buffer[offset]))
|
||||
offset += unix.SizeofInotifyEvent + uint32(rawEvent.Len)
|
||||
if rawEvent.Mask&unix.IN_MODIFY != unix.IN_MODIFY {
|
||||
continue
|
||||
}
|
||||
switch int(rawEvent.Wd) {
|
||||
case evFd:
|
||||
oom, err := getValueFromCgroup(eventControlPath, "oom_kill")
|
||||
if err != nil || oom > 0 {
|
||||
ch <- struct{}{}
|
||||
}
|
||||
case cgFd:
|
||||
pids, err := getValueFromCgroup(cgEvPath, "populated")
|
||||
if err != nil || pids == 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
return ch, nil
|
||||
}
|
||||
|
||||
// notifyOnOOMV2 returns channel on which you can expect event about OOM,
|
||||
// if process died without OOM this channel will be closed.
|
||||
func notifyOnOOMV2(path string) (<-chan struct{}, error) {
|
||||
return registerMemoryEventV2(path, "memory.events", "cgroup.events")
|
||||
}
|
Reference in New Issue
Block a user