Skip to content

Commit e6455a4

Browse files
committed
tetragon: Add execve-map-entries option
Adding execve-map-entries option to setup entries of execve_map map. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
1 parent bb408fb commit e6455a4

File tree

5 files changed

+77
-3
lines changed

5 files changed

+77
-3
lines changed

docs/data/tetragon_flags.yaml

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/option/config.go

+2
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ type config struct {
110110
EventCacheRetryDelay int
111111

112112
CompatibilitySyscall64SizeType bool
113+
114+
ExecveMapEntries string
113115
}
114116

115117
var (

pkg/option/flags.go

+5
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ const (
118118
KeyEventCacheRetryDelay = "event-cache-retry-delay"
119119

120120
KeyCompatibilitySyscall64SizeType = "enable-compatibility-syscall64-size-type"
121+
122+
KeyExecveMapEntries = "execve-map-entries"
121123
)
122124

123125
type UsernameMetadaCode int
@@ -252,6 +254,7 @@ func ReadAndSetFlags() error {
252254

253255
Config.CompatibilitySyscall64SizeType = viper.GetBool(KeyCompatibilitySyscall64SizeType)
254256

257+
Config.ExecveMapEntries = viper.GetString(KeyExecveMapEntries)
255258
return nil
256259
}
257260

@@ -419,4 +422,6 @@ func AddFlags(flags *pflag.FlagSet) {
419422
flags.Int(KeyEventCacheRetryDelay, defaults.DefaultEventCacheRetryDelay, "Delay in seconds between event cache retries")
420423

421424
flags.Bool(KeyCompatibilitySyscall64SizeType, false, "syscall64 type will produce output of type size (compatibility flag, will be removed in v1.4)")
425+
426+
flags.String(KeyExecveMapEntries, "32768", "Set entries for execve_map table (entries/size/max)")
422427
}

pkg/sensors/base/base.go

+52-2
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,27 @@ package base
55

66
import (
77
"log"
8+
"os"
9+
"strconv"
10+
"strings"
811
"sync"
912
"testing"
13+
"unsafe"
1014

1115
"github.com/cilium/tetragon/pkg/errmetrics"
1216
"github.com/cilium/tetragon/pkg/ksyms"
1317
"github.com/cilium/tetragon/pkg/logger"
1418
"github.com/cilium/tetragon/pkg/mbset"
19+
"github.com/cilium/tetragon/pkg/option"
1520
"github.com/cilium/tetragon/pkg/sensors"
1621
"github.com/cilium/tetragon/pkg/sensors/exec/config"
22+
"github.com/cilium/tetragon/pkg/sensors/exec/execvemap"
1723
"github.com/cilium/tetragon/pkg/sensors/program"
24+
"github.com/cilium/tetragon/pkg/strutils"
1825
)
1926

2027
const (
21-
execveMapMaxEntries = 32768
28+
ExecveMapMaxEntries = 32768
2229
)
2330

2431
var (
@@ -77,6 +84,43 @@ var (
7784
ErrMetricsMap = program.MapBuilder(errmetrics.MapName, Execve)
7885
)
7986

87+
func readThreadsMax(path string) (int64, error) {
88+
data, err := os.ReadFile(path)
89+
if err != nil {
90+
return 0, err
91+
}
92+
str := strings.TrimRight(string(data), "\n")
93+
return strconv.ParseInt(str, 10, 32)
94+
}
95+
96+
func GetExecveMapEntries(str string) int {
97+
entry := int(unsafe.Sizeof(execvemap.ExecveValue{}))
98+
99+
if len(str) == 0 {
100+
return ExecveMapMaxEntries
101+
}
102+
// pure number of entries
103+
if val, err := strconv.Atoi(str); err == nil {
104+
return val
105+
}
106+
// follow threads-max entries
107+
if str == "max" {
108+
if val, err := readThreadsMax("/proc/sys/kernel/threads-max"); err == nil {
109+
return int(val)
110+
}
111+
logger.GetLogger().Warn("Failed to read /proc/sys/kernel/threads-max file, falling back to default")
112+
return ExecveMapMaxEntries
113+
}
114+
// set entries based on size
115+
size, err := strutils.ParseSize(str)
116+
if err != nil {
117+
logger.GetLogger().Warn("Failed to parse --execve-map-max value, falling back to default")
118+
return ExecveMapMaxEntries
119+
}
120+
val := size / entry
121+
return val
122+
}
123+
80124
func setupSensor() {
81125
// exit program function
82126
ks, err := ksyms.KernelSymbols()
@@ -97,7 +141,13 @@ func setupSensor() {
97141
}
98142
logger.GetLogger().Infof("Exit probe on %s", Exit.Attach)
99143

100-
ExecveMap.SetMaxEntries(execveMapMaxEntries)
144+
entries := GetExecveMapEntries(option.Config.ExecveMapEntries)
145+
ExecveMap.SetMaxEntries(entries)
146+
147+
logger.GetLogger().
148+
WithField("size", strutils.SizeWithSuffix(entries*int(unsafe.Sizeof(execvemap.ExecveValue{})))).
149+
WithField("config", option.Config.ExecveMapEntries).
150+
Infof("Set execve_map entries %d", entries)
101151
}
102152

103153
func GetExecveMap() *program.Map {

pkg/sensors/exec/procevents/proc_reader.go

+15-1
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,15 @@ func writeExecveMap(procs []procs) {
335335
panic(err)
336336
}
337337
}
338+
339+
entries, ok := base.ExecveMap.GetMaxEntries()
340+
if !ok {
341+
logger.GetLogger().Warnf("Failed to get number of execve_map entries, using default.")
342+
entries = base.ExecveMapMaxEntries
343+
}
344+
logger.GetLogger().Infof("Maximum execve_map entries %d, need to add %d.", entries, len(procs))
345+
i := uint32(0)
346+
338347
for _, p := range procs {
339348
k := &execvemap.ExecveKey{Pid: p.pid}
340349
v := &execvemap.ExecveValue{}
@@ -365,6 +374,11 @@ func writeExecveMap(procs []procs) {
365374
if err != nil {
366375
logger.GetLogger().WithField("value", v).WithError(err).Warn("failed to put value in execve_map")
367376
}
377+
378+
i++
379+
if i == entries {
380+
break
381+
}
368382
}
369383
// In order for kprobe events from kernel ctx to not abort we need the
370384
// execve lookup to map to a valid entry. So to simplify the kernel side
@@ -381,7 +395,7 @@ func writeExecveMap(procs []procs) {
381395
})
382396
m.Close()
383397

384-
updateExecveMapStats(int64(len(procs)))
398+
updateExecveMapStats(int64(entries))
385399
}
386400

387401
func pushEvents(ps []procs) {

0 commit comments

Comments
 (0)