Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tetragon: un/pin fixes #3079

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/tetragon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ func tetragonExecute() error {
cancel()
}()

if err := obs.InitSensorManager(); err != nil {
if err := obs.InitSensorManager(option.Config.KeepSensorsOnExit); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/bench/bench.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func runTetragon(ctx context.Context, configFile string, args *Arguments, summar
option.Config.BpfDir = bpf.MapPrefixPath()
obs := observer.NewObserver()

if err := obs.InitSensorManager(); err != nil {
if err := obs.InitSensorManager(false); err != nil {
logger.GetLogger().Fatalf("InitSensorManager failed: %v", err)
}

Expand Down
8 changes: 2 additions & 6 deletions pkg/bugtool/maps.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ func FindPinnedMaps(path string) ([]bpf.ExtendedMapInfo, error) {
if d.IsDir() {
return nil // skip directories
}
m, err := ebpf.LoadPinnedMap(path, &ebpf.LoadPinOptions{
ReadOnly: true,
})
m, err := ebpf.LoadPinnedMap(path, nil)
if err != nil {
return fmt.Errorf("failed to load pinned map %q: %w", path, err)
}
Expand Down Expand Up @@ -159,9 +157,7 @@ func mapIDsFromPinnedProgs(path string) ([]int, error) {
if d.IsDir() {
return nil // skip directories
}
prog, err := ebpf.LoadPinnedProgram(path, &ebpf.LoadPinOptions{
ReadOnly: true,
})
prog, err := ebpf.LoadPinnedProgram(path, nil)
if err != nil {
return fmt.Errorf("failed to load pinned object %q: %w", path, err)
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/observer/observer.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,8 @@ func (k *Observer) Start(ctx context.Context) error {
}

// InitSensorManager starts the sensor controller
func (k *Observer) InitSensorManager() error {
mgr, err := sensors.StartSensorManager(option.Config.BpfDir)
func (k *Observer) InitSensorManager(keepSensorsOnExit bool) error {
mgr, err := sensors.StartSensorManager(option.Config.BpfDir, keepSensorsOnExit)
if err != nil {
return err
}
Expand Down
12 changes: 10 additions & 2 deletions pkg/observer/observertesthelper/observer_test_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ var (

type testObserverOptions struct {
crd bool
keep bool
config string
lib string
}
Expand Down Expand Up @@ -101,6 +102,12 @@ func WithConfig(config string) TestOption {
}
}

func WithKeepOnExit(keep bool) TestOption {
return func(o *TestOptions) {
o.observer.keep = keep
}
}

func withK8sWatcher(w watcher.K8sResourceWatcher) TestOption {
return func(o *TestOptions) {
o.exporter.watcher = w
Expand Down Expand Up @@ -168,6 +175,7 @@ func newDefaultTestOptions(opts ...TestOption) *TestOptions {
crd: false,
config: "",
lib: "",
keep: false,
},
exporter: testExporterOptions{
watcher: watcher.NewFakeK8sWatcher(nil),
Expand Down Expand Up @@ -358,7 +366,7 @@ func loadExporter(tb testing.TB, ctx context.Context, obs *observer.Observer, op
processCacheSize := 32768
dataCacheSize := 1024

if err := obs.InitSensorManager(); err != nil {
if err := obs.InitSensorManager(oo.keep); err != nil {
return err
}

Expand Down Expand Up @@ -434,7 +442,7 @@ func loadObserver(tb testing.TB, ctx context.Context, base *sensors.Sensor,
tb.Fatalf("Load base error: %s\n", err)
}
tb.Cleanup(func() {
base.Unload()
base.Unload(true)
})

if tp != nil {
Expand Down
10 changes: 5 additions & 5 deletions pkg/sensors/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (c *collection) load(bpfDir string) error {
if err != nil {
// NB: we could try to unload sensors going back from the one that failed, but since
// unload() checks s.IsLoaded, is easier to just to use unload().
if unloadErr := c.unload(); unloadErr != nil {
if unloadErr := c.unload(true); unloadErr != nil {
err = multierr.Append(err, fmt.Errorf("unloading after loading failure failed: %w", unloadErr))
}
}
Expand All @@ -121,13 +121,13 @@ func (c *collection) load(bpfDir string) error {
}

// unload will attempt to unload all the sensors in a collection
func (c *collection) unload() error {
func (c *collection) unload(unpin bool) error {
var err error
for _, s := range c.sensors {
if !s.IsLoaded() {
continue
}
unloadErr := s.Unload()
unloadErr := s.Unload(unpin)
err = multierr.Append(err, unloadErr)
}

Expand All @@ -138,8 +138,8 @@ func (c *collection) unload() error {
}

// destroy will attempt to destroy all the sensors in a collection
func (c *collection) destroy() {
func (c *collection) destroy(unpin bool) {
for _, s := range c.sensors {
s.Destroy()
s.Destroy(unpin)
}
}
4 changes: 2 additions & 2 deletions pkg/sensors/delayed_sensor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (tds *TestDelayedSensor) Load(_ string) error {
return nil
}

func (tds *TestDelayedSensor) Unload() error {
func (tds *TestDelayedSensor) Unload(_ bool) error {
select {
case <-tds.ch:
case <-time.After(10 * time.Second):
Expand All @@ -67,7 +67,7 @@ func (tds *TestDelayedSensor) Unload() error {
return nil
}

func (tds *TestDelayedSensor) Destroy() {
func (tds *TestDelayedSensor) Destroy(_ bool) {
tds.loaded = false
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/sensors/exec/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ func TestLoadInitialSensor(t *testing.T) {

tus.CheckSensorLoad([]*sensors.Sensor{sensor}, sensorMaps, sensorProgs, t)

sensor.Unload()
sensor.Unload(true)
}

func TestDocker(t *testing.T) {
Expand Down
18 changes: 9 additions & 9 deletions pkg/sensors/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ func (h *handler) load(col *collection) error {
return col.load(h.bpfDir)
}

func (h *handler) unload(col *collection) error {
func (h *handler) unload(col *collection, unpin bool) error {
h.muLoad.Lock()
defer h.muLoad.Unlock()
return col.unload()
return col.unload(unpin)
}

func (h *handler) allocPolicyID() uint64 {
Expand Down Expand Up @@ -179,7 +179,7 @@ func (h *handler) deleteTracingPolicy(op *tracingPolicyDelete) error {
// that the collection is gone
h.collections.mu.Unlock()

col.destroy()
col.destroy(true)

filterID := policyfilter.PolicyID(col.policyfilterID)
err := h.pfState.DelPolicy(filterID)
Expand All @@ -206,7 +206,7 @@ func (h *handler) disableTracingPolicy(op *tracingPolicyDisable) error {
col.state = UnloadingState
// unlock so that policyLister can access the collections (read-only) while we are unloading.
h.collections.mu.Unlock()
err := h.unload(col)
err := h.unload(col, true)
h.collections.mu.Lock()

if err != nil {
Expand Down Expand Up @@ -266,12 +266,12 @@ func (h *handler) addSensor(op *sensorAdd) error {
return nil
}

func removeAllSensors(h *handler) {
func removeAllSensors(h *handler, unpin bool) {
h.collections.mu.Lock()
defer h.collections.mu.Unlock()
collections := h.collections.c
for ck, col := range collections {
col.destroy()
col.destroy(unpin)
delete(collections, ck)
}
}
Expand All @@ -282,7 +282,7 @@ func (h *handler) removeSensor(op *sensorRemove) error {
return fmt.Errorf("removeSensor called with all flag and sensor name %s",
op.name)
}
removeAllSensors(h)
removeAllSensors(h, !op.keep)
return nil
}

Expand All @@ -296,7 +296,7 @@ func (h *handler) removeSensor(op *sensorRemove) error {
return fmt.Errorf("sensor %s does not exist", ck)
}

col.destroy()
col.destroy(true)
delete(collections, ck)
return nil
}
Expand Down Expand Up @@ -324,7 +324,7 @@ func (h *handler) disableSensor(op *sensorDisable) error {
if !exists {
return fmt.Errorf("sensor %s does not exist", ck)
}
return h.unload(col)
return h.unload(col, true)
}

func (h *handler) listSensors(op *sensorList) error {
Expand Down
28 changes: 15 additions & 13 deletions pkg/sensors/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ func (s *Sensor) Load(bpfDir string) (err error) {
defer func() {
if err != nil {
for _, m := range loadedMaps {
m.Unload()
m.Unload(true)
}
for _, p := range loadedProgs {
unloadProgram(p)
unloadProgram(p, true)
}
s.removeDirs()
}
Expand Down Expand Up @@ -190,7 +190,7 @@ func (s *Sensor) Load(bpfDir string) (err error) {
return nil
}

func (s *Sensor) Unload() error {
func (s *Sensor) Unload(unpin bool) error {
logger.GetLogger().Infof("Unloading sensor %s", s.Name)
if !s.Loaded {
return fmt.Errorf("unload of sensor %s failed: sensor not loaded", s.Name)
Expand All @@ -203,16 +203,18 @@ func (s *Sensor) Unload() error {
}

for _, p := range s.Progs {
unloadProgram(p)
unloadProgram(p, unpin)
}

for _, m := range s.Maps {
if err := m.Unload(); err != nil {
if err := m.Unload(unpin); err != nil {
logger.GetLogger().WithError(err).WithField("map", s.Name).Warn("Failed to unload map")
}
}

s.removeDirs()
if unpin {
s.removeDirs()
}

s.Loaded = false

Expand All @@ -228,8 +230,8 @@ func (s *Sensor) Unload() error {

// Destroy will unload the hook and call DestroyHook, this hook is usually used
// to clean up resources that were created during creation of the sensor.
func (s *Sensor) Destroy() {
err := s.Unload()
func (s *Sensor) Destroy(unpin bool) {
err := s.Unload(unpin)
if err != nil {
// do not return on error but just log since Unload can only error on
// sensor being already not loaded
Expand Down Expand Up @@ -398,7 +400,7 @@ func observerLoadInstance(bpfDir string, load *program.Program) error {
l.WithField(
"tracepoint", load.Name,
).Info("Failed to load, trying to remove and retrying")
load.Unload()
load.Unload(true)
err = loadInstance(bpfDir, load, version, option.Config.Verbosity)
}
if err != nil {
Expand All @@ -411,7 +413,7 @@ func observerLoadInstance(bpfDir string, load *program.Program) error {
l.WithField(
"raw_tracepoint", load.Name,
).Info("Failed to load, trying to remove and retrying")
load.Unload()
load.Unload(true)
err = loadInstance(bpfDir, load, version, option.Config.Verbosity)
}
if err != nil {
Expand Down Expand Up @@ -466,7 +468,7 @@ func observerMinReqs() (bool, error) {
return true, nil
}

func unloadProgram(prog *program.Program) {
func unloadProgram(prog *program.Program, unpin bool) {
log := logger.GetLogger().WithField("label", prog.Label).WithField("pin", prog.PinPath)

if !prog.LoadState.IsLoaded() {
Expand All @@ -478,7 +480,7 @@ func unloadProgram(prog *program.Program) {
return
}

if err := prog.Unload(); err != nil {
if err := prog.Unload(unpin); err != nil {
logger.GetLogger().WithField("name", prog.Name).WithError(err).Warn("Failed to unload program")
}

Expand All @@ -487,7 +489,7 @@ func unloadProgram(prog *program.Program) {

func UnloadSensors(sens []SensorIface) {
for i := range sens {
if err := sens[i].Unload(); err != nil {
if err := sens[i].Unload(true); err != nil {
logger.GetLogger().Warnf("Failed to unload sensor: %s", err)
}
}
Expand Down
16 changes: 12 additions & 4 deletions pkg/sensors/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,19 @@ type SensorStatus struct {
// clients).
func StartSensorManager(
bpfDir string,
keepOnExit bool,
) (*Manager, error) {
pfState, err := policyfilter.GetState()
if err != nil {
return nil, fmt.Errorf("failed to initialize policy filter state: %w", err)
}
return StartSensorManagerWithPF(bpfDir, pfState)
return StartSensorManagerWithPF(bpfDir, pfState, keepOnExit)
}

func StartSensorManagerWithPF(
bpfDir string,
pfState policyfilter.State,
keepOnExit bool,
) (*Manager, error) {
colMap := newCollectionMap()

Expand All @@ -49,7 +51,8 @@ func StartSensorManagerWithPF(
}

m := Manager{
handler: handler,
handler: handler,
keepOnExit: keepOnExit,
}
return &m, nil
}
Expand Down Expand Up @@ -185,8 +188,9 @@ func (h *Manager) RemoveSensor(ctx context.Context, sensorName string) error {

func (h *Manager) RemoveAllSensors(ctx context.Context) error {
op := &sensorRemove{
ctx: ctx,
all: true,
ctx: ctx,
all: true,
keep: h.keepOnExit,
}

return h.handler.removeSensor(op)
Expand Down Expand Up @@ -223,6 +227,9 @@ func (h *Manager) LogSensorsAndProbes(ctx context.Context) {
type Manager struct {
// channel to communicate with the controller goroutine
handler *handler

// keep or unpin sensors on exit
keepOnExit bool
}

// There are 6 commands that can be passed to the controller goroutine:
Expand Down Expand Up @@ -267,6 +274,7 @@ type sensorRemove struct {
ctx context.Context
name string
all bool
keep bool
}

// sensorEnable enables a sensor
Expand Down
Loading
Loading