/
attach_cgroup.go
69 lines (59 loc) · 1.92 KB
/
attach_cgroup.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium
package probes
import (
"errors"
"fmt"
"sync"
"github.com/cilium/ebpf"
"github.com/cilium/ebpf/asm"
"github.com/cilium/ebpf/link"
"golang.org/x/sys/unix"
)
// HaveAttachCgroup returns nil if the kernel is compiled with
// CONFIG_CGROUP_BPF.
//
// It's only an approximation and doesn't execute a successful cgroup attachment
// under the hood. If any unexpected errors are encountered, the original error
// is returned.
func HaveAttachCgroup() error {
attachCgroupOnce.Do(func() {
attachCgroupResult = haveAttachCgroup()
})
return attachCgroupResult
}
func haveAttachCgroup() error {
// Load known-good program supported by the earliest kernels with cgroup
// support.
spec := &ebpf.ProgramSpec{
Type: ebpf.CGroupSKB,
AttachType: ebpf.AttachCGroupInetIngress,
Instructions: asm.Instructions{
asm.LoadImm(asm.R0, 0, asm.DWord),
asm.Return(),
},
}
p, err := ebpf.NewProgramWithOptions(spec, ebpf.ProgramOptions{
LogDisabled: true,
})
if err != nil {
return fmt.Errorf("create cgroup program: %w: %w", err, ebpf.ErrNotSupported)
}
defer p.Close()
// Attaching to a non-cgroup node should result in EBADF when creating the
// link, compared to EINVAL if the kernel does not support or was compiled
// without CONFIG_CGROUP_BPF.
_, err = link.AttachCgroup(link.CgroupOptions{Path: "/dev/null", Program: p, Attach: spec.AttachType})
if errors.Is(err, unix.EBADF) {
// The kernel checked the given file descriptor from within the cgroup prog
// attach handler. Assume it supports attaching cgroup progs.
return nil
}
if err != nil {
// Preserve the original error in the error string. Needs Go 1.20.
return fmt.Errorf("link cgroup program to /dev/null: %w: %w", err, ebpf.ErrNotSupported)
}
return errors.New("attaching prog to /dev/null did not result in error")
}
var attachCgroupOnce sync.Once
var attachCgroupResult error