WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit d2ef0dc

Browse files
author
Iti Agrawal
committed
feat: Implement CheckAndMountFilesystems for required filesystem checks in DNS and TCP retrans plugins
1 parent ee25170 commit d2ef0dc

File tree

3 files changed

+92
-2
lines changed

3 files changed

+92
-2
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
//go:build linux
5+
// +build linux
6+
7+
package common
8+
9+
import (
10+
"github.com/microsoft/retina/pkg/log"
11+
"go.uber.org/zap"
12+
"golang.org/x/sys/unix"
13+
)
14+
15+
// CheckAndMountFilesystems checks if required filesystems are mounted.
16+
// Returns an error if any required filesystem is not available.
17+
// This helps prevent os.Exit() calls from dependencies that expect these filesystems.
18+
func CheckAndMountFilesystems(l *log.ZapLogger) error {
19+
filesystems := []struct {
20+
name string
21+
paths []string
22+
magic int64
23+
required bool // if true, return error if not available
24+
}{
25+
{
26+
name: "bpf",
27+
paths: []string{"/sys/fs/bpf"},
28+
magic: unix.BPF_FS_MAGIC,
29+
required: false, // bpffs is less critical
30+
},
31+
{
32+
name: "debugfs",
33+
paths: []string{"/sys/kernel/debug"},
34+
magic: unix.DEBUGFS_MAGIC,
35+
required: true,
36+
},
37+
{
38+
name: "tracefs",
39+
paths: []string{"/sys/kernel/tracing", "/sys/kernel/debug/tracing"},
40+
magic: unix.TRACEFS_MAGIC,
41+
required: true,
42+
},
43+
}
44+
45+
var firstError error
46+
filesystemLoop:
47+
for _, fs := range filesystems {
48+
var statfs unix.Statfs_t
49+
for _, path := range fs.paths {
50+
if err := unix.Statfs(path, &statfs); err != nil {
51+
l.Debug("statfs returned error", zap.String("fs", fs.name), zap.String("path", path), zap.Error(err))
52+
continue
53+
}
54+
if statfs.Type == fs.magic {
55+
l.Debug("Filesystem already mounted", zap.String("fs", fs.name), zap.String("path", path))
56+
continue filesystemLoop
57+
}
58+
}
59+
60+
// Filesystem not found or not mounted
61+
l.Error("Filesystem not mounted", zap.String("fs", fs.name), zap.Strings("paths", fs.paths))
62+
if fs.required && firstError == nil {
63+
firstError = unix.ENOENT
64+
}
65+
}
66+
return firstError
67+
}

pkg/plugin/dns/dns_linux.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package dns
66

77
import (
88
"context"
9+
"fmt"
910
"net"
1011
"os"
1112

@@ -47,8 +48,21 @@ func (d *dns) Compile(ctx context.Context) error {
4748
}
4849

4950
func (d *dns) Init() error {
50-
// Create tracer. In this case no parameters are passed.
51-
err := host.Init(host.Config{})
51+
// Check and mount filesystems before calling host.Init to avoid os.Exit()
52+
if err := common.CheckAndMountFilesystems(d.l); err != nil {
53+
d.l.Error("Required filesystems not available for DNS plugin", zap.Error(err))
54+
// Return error to let retina decide whether to continue without DNS plugin
55+
// or fail the entire agent initialization
56+
return fmt.Errorf("required filesystems not available: %w", err)
57+
}
58+
59+
// Filesystems are available, safe to call host.Init()
60+
if err := host.Init(host.Config{}); err != nil {
61+
d.l.Error("Host initialization failed", zap.Error(err))
62+
return fmt.Errorf("host initialization failed: %w", err)
63+
}
64+
65+
// Create tracer
5266
tracer, err := tracer.NewTracer()
5367
if err != nil {
5468
d.l.Error("Failed to create tracer", zap.Error(err))

pkg/plugin/tcpretrans/tcpretrans_linux.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
kcfg "github.com/microsoft/retina/pkg/config"
2020
"github.com/microsoft/retina/pkg/enricher"
2121
"github.com/microsoft/retina/pkg/log"
22+
"github.com/microsoft/retina/pkg/plugin/common"
2223
"github.com/microsoft/retina/pkg/plugin/registry"
2324
"github.com/microsoft/retina/pkg/utils"
2425
"go.uber.org/zap"
@@ -53,6 +54,14 @@ func (t *tcpretrans) Init() error {
5354
t.l.Warn("tcpretrans will not init because pod level is disabled")
5455
return nil
5556
}
57+
58+
if err := common.CheckAndMountFilesystems(t.l); err != nil {
59+
t.l.Error("Required filesystems not available for tcpretrans plugin", zap.Error(err))
60+
// Return error to let retina decide whether to continue without tcpretrans plugin
61+
// or fail the entire agent initialization
62+
return fmt.Errorf("required filesystems not available: %w", err)
63+
}
64+
5665
// Create tracer. In this case no parameters are passed.
5766
if err := host.Init(host.Config{}); err != nil {
5867
t.l.Error("failed to init host", zap.Error(err))

0 commit comments

Comments
 (0)