...
1 package libcontainer
2
3 import (
4 "fmt"
5 "path/filepath"
6 "unsafe"
7
8 "github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
9 "github.com/sirupsen/logrus"
10 "golang.org/x/sys/unix"
11 )
12
13 func registerMemoryEventV2(cgDir, evName, cgEvName string) (<-chan struct{}, error) {
14 fd, err := unix.InotifyInit()
15 if err != nil {
16 return nil, fmt.Errorf("unable to init inotify: %w", err)
17 }
18
19 evFd, err := unix.InotifyAddWatch(fd, filepath.Join(cgDir, evName), unix.IN_MODIFY)
20 if err != nil {
21 unix.Close(fd)
22 return nil, fmt.Errorf("unable to add inotify watch: %w", err)
23 }
24
25 cgFd, err := unix.InotifyAddWatch(fd, filepath.Join(cgDir, cgEvName), unix.IN_MODIFY)
26 if err != nil {
27 unix.Close(fd)
28 return nil, fmt.Errorf("unable to add inotify watch: %w", err)
29 }
30 ch := make(chan struct{})
31 go func() {
32 var (
33 buffer [unix.SizeofInotifyEvent + unix.PathMax + 1]byte
34 offset uint32
35 )
36 defer func() {
37 unix.Close(fd)
38 close(ch)
39 }()
40
41 for {
42 n, err := unix.Read(fd, buffer[:])
43 if err != nil {
44 logrus.Warnf("unable to read event data from inotify, got error: %v", err)
45 return
46 }
47 if n < unix.SizeofInotifyEvent {
48 logrus.Warnf("we should read at least %d bytes from inotify, but got %d bytes.", unix.SizeofInotifyEvent, n)
49 return
50 }
51 offset = 0
52 for offset <= uint32(n-unix.SizeofInotifyEvent) {
53 rawEvent := (*unix.InotifyEvent)(unsafe.Pointer(&buffer[offset]))
54 offset += unix.SizeofInotifyEvent + rawEvent.Len
55 if rawEvent.Mask&unix.IN_MODIFY != unix.IN_MODIFY {
56 continue
57 }
58 switch int(rawEvent.Wd) {
59 case evFd:
60 oom, err := fscommon.GetValueByKey(cgDir, evName, "oom_kill")
61 if err != nil || oom > 0 {
62 ch <- struct{}{}
63 }
64 case cgFd:
65 pids, err := fscommon.GetValueByKey(cgDir, cgEvName, "populated")
66 if err != nil || pids == 0 {
67 return
68 }
69 }
70 }
71 }
72 }()
73 return ch, nil
74 }
75
76
77
78 func notifyOnOOMV2(path string) (<-chan struct{}, error) {
79 return registerMemoryEventV2(path, "memory.events", "cgroup.events")
80 }
81
View as plain text