Skip to content

Commit 3d2e6f8

Browse files
committed
feat: enable namespace PID translation
- Add simple test checking struct offset computation used by namespace pid translation. - Tracer initialization fails if BTF is not available but namespace PID translation is enabled.
1 parent cce2246 commit 3d2e6f8

3 files changed

Lines changed: 87 additions & 18 deletions

File tree

tracer/ebpf_integration_test.go

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package tracer_test
77

88
import (
9+
"fmt"
910
"math"
1011
"runtime"
1112
"slices"
@@ -186,16 +187,32 @@ Loop:
186187
}
187188

188189
func TestAllTracers(t *testing.T) {
189-
tr, err := tracer.NewTracer(t.Context(), &tracer.Config{
190-
Intervals: &mockIntervals{},
191-
IncludeTracers: tracertypes.AllTracers(),
192-
SamplesPerSecond: 20,
193-
ProbabilisticInterval: 100,
194-
ProbabilisticThreshold: 100,
195-
OffCPUThreshold: uint32(math.MaxUint32 / 100),
196-
VerboseMode: true,
197-
LoadProbe: true,
198-
})
199-
require.NoError(t, err)
200-
defer tr.Close()
190+
testcases := []struct {
191+
enablePidTranslation bool
192+
}{
193+
{
194+
enablePidTranslation: true,
195+
},
196+
{
197+
enablePidTranslation: false,
198+
},
199+
}
200+
201+
for _, testcase := range testcases {
202+
t.Run(fmt.Sprintf("enablePidTranslation=%t", testcase.enablePidTranslation), func(t *testing.T) {
203+
tr, err := tracer.NewTracer(t.Context(), &tracer.Config{
204+
Intervals: &mockIntervals{},
205+
IncludeTracers: tracertypes.AllTracers(),
206+
SamplesPerSecond: 20,
207+
ProbabilisticInterval: 100,
208+
ProbabilisticThreshold: 100,
209+
OffCPUThreshold: uint32(math.MaxUint32 / 100),
210+
VerboseMode: true,
211+
LoadProbe: true,
212+
EnableNamespacePID: testcase.enablePidTranslation,
213+
})
214+
require.NoError(t, err)
215+
defer tr.Close()
216+
})
217+
}
201218
}

tracer/systemconfig.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -402,12 +402,14 @@ func determineSysConfig(coll *cebpf.CollectionSpec, maps map[string]*cebpf.Map,
402402
if err := parseBTF(vars, spec); err != nil {
403403
btfResolution = false
404404
}
405-
// parseBTFForNsTranslation is only called if
406-
// namespace PID translation is enabled and BTF resolution is successful.
407-
if enableNamespacePID && btfResolution {
408-
err := parseBTFForNsTranslation(vars, spec)
409-
log.Debugf("parseBTFForNsTranslation err %v", err)
410-
log.Debugf("vars.ns_translation_enabled %+v", vars)
405+
}
406+
407+
if enableNamespacePID {
408+
if !btfResolution {
409+
return fmt.Errorf("configuration error: namespace PID translation is enabled but BTF resolution is not available")
410+
}
411+
if err := parseBTFForNsTranslation(vars, spec); err != nil {
412+
return err
411413
}
412414
}
413415

tracer/systemconfig_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package tracer
5+
6+
import (
7+
"os"
8+
"runtime"
9+
"testing"
10+
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
func TestGetCurrentNS_FileNotFound(t *testing.T) {
15+
_, _, err := getCurrentNS("/nonexistent/path/pid")
16+
require.Error(t, err)
17+
require.True(t, os.IsNotExist(err))
18+
}
19+
20+
func TestGetCurrentNS_ProcSelfNsPid(t *testing.T) {
21+
if runtime.GOOS != "linux" {
22+
t.Skipf("skipping: /proc/self/ns/pid is Linux-specific (GOOS=%s)", runtime.GOOS)
23+
}
24+
const procSelfNsPid = "/proc/self/ns/pid"
25+
if _, err := os.Stat(procSelfNsPid); err != nil {
26+
t.Skipf("skipping: %s not available: %v", procSelfNsPid, err)
27+
}
28+
_, ino, err := getCurrentNS(procSelfNsPid)
29+
require.NoError(t, err)
30+
require.NotZero(t, ino, "pid namespace inode should be non-zero")
31+
}
32+
33+
// TestParseBTFForNsTranslation verifies that namespace PID translation offsets
34+
// can be resolved from kernel BTF when available. Skips when BTF is not present.
35+
func TestParseBTFForNsTranslation(t *testing.T) {
36+
if runtime.GOARCH != "amd64" && runtime.GOARCH != "arm64" {
37+
t.Skipf("skipping: unsupported GOARCH=%s", runtime.GOARCH)
38+
}
39+
spec, err := loadBTFSpec()
40+
if err != nil {
41+
t.Skipf("skipping: kernel BTF not available: %v", err)
42+
}
43+
var vars sysConfigVars
44+
err = parseBTFForNsTranslation(&vars, spec)
45+
require.NoError(t, err)
46+
require.True(t, vars.ns_translation_enabled)
47+
require.Greater(t, vars.task_stack_offset, uint32(0))
48+
require.Greater(t, vars.task_nsproxy_off, uint32(0))
49+
require.Greater(t, vars.upid_size, uint32(0))
50+
}

0 commit comments

Comments
 (0)