diff --git a/processmanager/ebpf/ebpf.go b/processmanager/ebpf/ebpf.go index 071bf81b3..9b9a1812b 100644 --- a/processmanager/ebpf/ebpf.go +++ b/processmanager/ebpf/ebpf.go @@ -15,6 +15,7 @@ import ( cebpf "github.com/cilium/ebpf" "github.com/cilium/ebpf/features" "go.opentelemetry.io/ebpf-profiler/internal/log" + "go.opentelemetry.io/ebpf-profiler/tracer/types" "golang.org/x/exp/constraints" "go.opentelemetry.io/ebpf-profiler/host" @@ -78,7 +79,8 @@ var _ ebpfapi.EbpfHandler = &ebpfMapsImpl{} // // It further spawns background workers for deferred map updates; the given // context can be used to terminate them on shutdown. -func LoadMaps(ctx context.Context, maps map[string]*cebpf.Map, stackdeltaInnerMapSpec *cebpf.MapSpec) (ebpfapi.EbpfHandler, error) { +func LoadMaps(ctx context.Context, includeTracers types.IncludedTracers, + maps map[string]*cebpf.Map, stackdeltaInnerMapSpec *cebpf.MapSpec) (ebpfapi.EbpfHandler, error) { impl := &ebpfMapsImpl{ stackdeltaInnerMapTemplate: stackdeltaInnerMapSpec, } @@ -94,6 +96,9 @@ func LoadMaps(ctx context.Context, maps map[string]*cebpf.Map, stackdeltaInnerMa } mapVal, ok := maps[nameTag] if !ok { + if !types.IsMapEnabled(nameTag, includeTracers) { + continue + } log.Fatalf("Map %v is not available", nameTag) } implRefVal.Field(i).Set(reflect.ValueOf(mapVal)) diff --git a/tracer/tracer.go b/tracer/tracer.go index f25bec4c4..f77c9bee8 100644 --- a/tracer/tracer.go +++ b/tracer/tracer.go @@ -225,7 +225,7 @@ func NewTracer(ctx context.Context, cfg *Config) (*Tracer, error) { return nil, fmt.Errorf("failed to load eBPF code: %v", err) } - ebpfHandler, err := pmebpf.LoadMaps(ctx, ebpfMaps, stackdeltaInnerMapSpec) + ebpfHandler, err := pmebpf.LoadMaps(ctx, cfg.IncludeTracers, ebpfMaps, stackdeltaInnerMapSpec) if err != nil { return nil, fmt.Errorf("failed to load eBPF maps: %v", err) } @@ -559,6 +559,11 @@ func loadAllMaps(coll *cebpf.CollectionSpec, cfg *Config, // Off CPU Profiling is disabled. So do not load this map. continue } + + if !types.IsMapEnabled(mapName, cfg.IncludeTracers) { + log.Debugf("Skipping eBPF map %s: tracer not enabled", mapName) + continue + } if newSize, ok := adaption[mapName]; ok { log.Debugf("Size of eBPF map %s: %v", mapName, newSize) mapSpec.MaxEntries = newSize diff --git a/tracer/types/parse.go b/tracer/types/parse.go index ed36934fc..78b55eacf 100644 --- a/tracer/types/parse.go +++ b/tracer/types/parse.go @@ -51,6 +51,34 @@ func init() { } } +// IsMapEnabled checks if the given map is enabled and should be loaded. +func IsMapEnabled(mapName string, includeTracers IncludedTracers) bool { + switch mapName { + case "perl_procs": + return includeTracers.Has(PerlTracer) + case "php_procs": + return includeTracers.Has(PHPTracer) + case "py_procs": + return includeTracers.Has(PythonTracer) + case "hotspot_procs": + return includeTracers.Has(HotspotTracer) + case "ruby_procs": + return includeTracers.Has(RubyTracer) + case "v8_procs": + return includeTracers.Has(V8Tracer) + case "dotnet_procs": + return includeTracers.Has(DotnetTracer) + case "beam_procs": + return includeTracers.Has(BEAMTracer) + case "go_labels_procs", "apm_int_procs": + // go_labels_procs and apm_int_procs are called from + // unwind_stop and therefore need to be available all the time. + return true + default: + return true // Not an interpreter map, so it should be loaded + } +} + // tracerTypeFromName returns the tracer type for the given name. func tracerTypeFromName(s string) (tracerType, bool) { tt, ok := tracerNameToType[s]