Skip to content

Commit 3a9ca0b

Browse files
Eric Suenbobrik
authored andcommitted
Enabled support for external BTF
1 parent cb58665 commit 3a9ca0b

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,15 @@ The following additional capabilities might be needed:
167167
which is the preferred way, but only available since Linux v6.6.
168168
See: https://github.com/torvalds/linux/commit/0ce7c12e88cf
169169

170+
## External BTF Support
171+
172+
Execution of eBPF programs requires kernel data types normally available
173+
in `/sys/kernel/btf/vmlinux`, which is created during kernel build process.
174+
However, on some older kernel configurations, this file might not be available.
175+
If that's the case, an external BTF file can be supplied with `--btf.path`.
176+
An archive of BTFs for all some older distros and kernel versions can be
177+
found [here](https://github.com/aquasecurity/btfhub-archive).
178+
170179
## Supported scenarios
171180

172181
Currently the only supported way of getting data out of the kernel is via maps.

cmd/ebpf_exporter/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func main() {
2727
listenAddress := kingpin.Flag("web.listen-address", "The address to listen on for HTTP requests (fd://0 for systemd activation).").Default(":9435").String()
2828
metricsPath := kingpin.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String()
2929
capabilities := kingpin.Flag("capabilities.keep", "Comma separated list of capabilities to keep (cap_syslog, cap_bpf, etc.), 'all' or 'none'").Default("all").String()
30+
btfPath := kingpin.Flag("btf.path", "Optional BTF file path.").Default("").String()
3031
kingpin.Version(version.Print("ebpf_exporter"))
3132
kingpin.HelpFlag.Short('h')
3233
kingpin.Parse()
@@ -55,7 +56,7 @@ func main() {
5556
log.Fatalf("Error parsing configs: %v", err)
5657
}
5758

58-
e, err := exporter.New(configs)
59+
e, err := exporter.New(configs, *btfPath)
5960
if err != nil {
6061
log.Fatalf("Error creating exporter: %s", err)
6162
}

exporter/exporter.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package exporter
33
import (
44
"bufio"
55
"bytes"
6+
"errors"
67
"fmt"
78
"log"
89
"net/http"
@@ -41,10 +42,11 @@ type Exporter struct {
4142
attachedProgs map[string]map[*libbpfgo.BPFProg]bool
4243
descs map[string]map[string]*prometheus.Desc
4344
decoders *decoder.Set
45+
btfPath string
4446
}
4547

4648
// New creates a new exporter with the provided config
47-
func New(configs []config.Config) (*Exporter, error) {
49+
func New(configs []config.Config, btfPath string) (*Exporter, error) {
4850
enabledConfigsDesc := prometheus.NewDesc(
4951
prometheus.BuildFQName(prometheusNamespace, "", "enabled_configs"),
5052
"The set of enabled configs",
@@ -97,6 +99,7 @@ func New(configs []config.Config) (*Exporter, error) {
9799
attachedProgs: map[string]map[*libbpfgo.BPFProg]bool{},
98100
descs: map[string]map[string]*prometheus.Desc{},
99101
decoders: decoders,
102+
btfPath: btfPath,
100103
}, nil
101104
}
102105

@@ -116,10 +119,22 @@ func (e *Exporter) Attach() error {
116119
return fmt.Errorf("multiple configs with name %q", cfg.Name)
117120
}
118121

119-
module, err := libbpfgo.NewModuleFromFileArgs(libbpfgo.NewModuleArgs{
122+
args := libbpfgo.NewModuleArgs{
120123
BPFObjPath: cfg.BPFPath,
121124
SkipMemlockBump: true, // Let libbpf itself decide whether it is needed
122-
})
125+
}
126+
127+
if e.btfPath != "" {
128+
if _, err := os.Stat(e.btfPath); err == nil {
129+
args.BTFObjPath = e.btfPath
130+
} else if errors.Is(err, os.ErrNotExist) {
131+
return fmt.Errorf("could not find BTF file %q", e.btfPath)
132+
} else {
133+
return fmt.Errorf("failed to retrieve file info for %q: %v", e.btfPath, err)
134+
}
135+
}
136+
137+
module, err := libbpfgo.NewModuleFromFileArgs(args)
123138
if err != nil {
124139
return fmt.Errorf("error creating module from %q for config %q: %v", cfg.BPFPath, cfg.Name, err)
125140
}

0 commit comments

Comments
 (0)