diff --git a/README.md b/README.md index 895b9cb4..d9b9984a 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,11 @@ The following additional capabilities might be needed: which is the preferred way, but only available since Linux v6.6. See: https://github.com/torvalds/linux/commit/0ce7c12e88cf +## Cgroup Discovery + +Use `--cgroup.disable-fanotify` to force walk-based cgroup discovery instead of +fanotify; the exporter will then not require or use fanotify on the cgroup mount. + ## External BTF Support Execution of eBPF programs requires kernel data types normally available diff --git a/cgroup/monitor.go b/cgroup/monitor.go index 90248ce9..13ed8205 100644 --- a/cgroup/monitor.go +++ b/cgroup/monitor.go @@ -27,20 +27,21 @@ type Monitor struct { } // NewMonitor returns a new cgroup monitor for a given path -func NewMonitor(path string) (*Monitor, error) { - fm, err := newFanotifyMonitor(path) - if err != nil { - log.Printf("Using on-demand resolution for cgroups (fanotify not available)") - - wm, err := newWalkerMonitor(path) - if err != nil { - return nil, err +func NewMonitor(path string, disableFanotify bool) (*Monitor, error) { + if !disableFanotify { + if fm, err := newFanotifyMonitor(path); err == nil { + return &Monitor{inner: fm}, nil } - - return &Monitor{inner: wm}, nil + log.Printf("Using on-demand resolution for cgroups (fanotify not available)") + } else { + log.Printf("Using on-demand resolution for cgroups (fanotify disabled by flag)") } - return &Monitor{inner: fm}, nil + wm, err := newWalkerMonitor(path) + if err != nil { + return nil, err + } + return &Monitor{inner: wm}, nil } // Resolve resolves an id to a path for a cgroup diff --git a/cgroup/monitor_test.go b/cgroup/monitor_test.go index b85fdb11..75031a6d 100644 --- a/cgroup/monitor_test.go +++ b/cgroup/monitor_test.go @@ -19,7 +19,13 @@ func TestMonitor(t *testing.T) { { kind: "Monitor", factory: func(path string) (monitor, error) { - return NewMonitor(path) + return NewMonitor(path, false) + }, + }, + { + kind: "Monitor (fanotify disabled)", + factory: func(path string) (monitor, error) { + return NewMonitor(path, true) }, }, { diff --git a/cmd/ebpf_exporter/main.go b/cmd/ebpf_exporter/main.go index 054b7ece..d0c96f5d 100644 --- a/cmd/ebpf_exporter/main.go +++ b/cmd/ebpf_exporter/main.go @@ -42,6 +42,7 @@ func main() { capabilities := kingpin.Flag("capabilities.keep", "Comma separated list of capabilities to keep (cap_syslog, cap_bpf, etc.), 'all' or 'none'").Default("all").String() btfPath := kingpin.Flag("btf.path", "Optional BTF file path.").Default("").String() skipCacheSize := kingpin.Flag("config.skip-cache-size", "Size of the LRU skip cache").Int() + cgroupDisableFanotify := kingpin.Flag("cgroup.disable-fanotify", "Disable fanotify-based cgroup discovery; use walk-based discovery only.").Default("false").Bool() kingpin.Version(version.Print("ebpf_exporter")) kingpin.HelpFlag.Short('h') kingpin.Parse() @@ -93,7 +94,7 @@ func main() { notify("creating exporter...") - e, err := exporter.New(configs, *skipCacheSize, tracing.NewProvider(processor), *btfPath) + e, err := exporter.New(configs, *skipCacheSize, tracing.NewProvider(processor), *btfPath, *cgroupDisableFanotify) if err != nil { log.Fatalf("Error creating exporter: %s", err) } diff --git a/exporter/exporter.go b/exporter/exporter.go index e673b4fc..aa12bb38 100644 --- a/exporter/exporter.go +++ b/exporter/exporter.go @@ -59,7 +59,7 @@ type Exporter struct { } // New creates a new exporter with the provided config -func New(configs []config.Config, skipCacheSize int, tracingProvider tracing.Provider, btfPath string) (*Exporter, error) { +func New(configs []config.Config, skipCacheSize int, tracingProvider tracing.Provider, btfPath string, cgroupDisableFanotify bool) (*Exporter, error) { enabledConfigsDesc := prometheus.NewDesc( prometheus.BuildFQName(prometheusNamespace, "", "enabled_configs"), "The set of enabled configs", @@ -104,7 +104,7 @@ func New(configs []config.Config, skipCacheSize int, tracingProvider tracing.Pro decoderErrorCount.WithLabelValues(config.Name).Add(0.0) } - monitor, err := cgroup.NewMonitor("/sys/fs/cgroup") + monitor, err := cgroup.NewMonitor("/sys/fs/cgroup", cgroupDisableFanotify) if err != nil { return nil, fmt.Errorf("error creating cgroup monitor: %w", err) }