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

file events: skip reading fdinfo for previously seen mounts #149

Merged
merged 1 commit into from
Dec 4, 2024
Merged
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
19 changes: 16 additions & 3 deletions containers/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ type Container struct {
oomKills int
pythonThreadLockWaitTime time.Duration

mounts map[string]proc.MountInfo
mounts map[string]proc.MountInfo
seenMounts map[uint64]struct{}

logParsers map[string]*LogParser

Expand Down Expand Up @@ -172,7 +173,8 @@ func NewContainer(id ContainerID, cg *cgroup.Cgroup, md *ContainerMetadata, pid
l7Stats: L7Stats{},
dnsStats: &L7Metrics{},

mounts: map[string]proc.MountInfo{},
mounts: map[string]proc.MountInfo{},
seenMounts: map[uint64]struct{}{},

logParsers: map[string]*LogParser{},

Expand Down Expand Up @@ -424,13 +426,24 @@ func (c *Container) onProcessExit(pid uint32, oomKill bool) {
}
}

func (c *Container) onFileOpen(pid uint32, fd uint64) {
func (c *Container) onFileOpen(pid uint32, fd uint64, mnt uint64, log bool) {
if mnt > 0 && !log {
c.lock.Lock()
_, ok := c.seenMounts[mnt]
c.lock.Unlock()
if ok {
return
}
}
mntId, logPath := resolveFd(pid, fd)
func() {
if mntId == "" {
return
}
c.lock.Lock()
if mnt > 0 {
c.seenMounts[mnt] = struct{}{}
}
_, ok := c.mounts[mntId]
c.lock.Unlock()
if ok {
Expand Down
2 changes: 1 addition & 1 deletion containers/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ func (r *Registry) handleEvents(ch <-chan ebpftracer.Event) {

case ebpftracer.EventTypeFileOpen:
if c := r.getOrCreateContainer(e.Pid); c != nil {
c.onFileOpen(e.Pid, e.Fd)
c.onFileOpen(e.Pid, e.Fd, e.Mnt, e.Log)
}

case ebpftracer.EventTypeListenOpen:
Expand Down
4 changes: 4 additions & 0 deletions ebpftracer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ WORKDIR /tmp/ebpf
RUN clang -g -O2 -target bpf -D__KERNEL_FROM=416 -D__TARGET_ARCH_x86 -c ebpf.c -o ebpf416x86.o && llvm-strip --strip-debug ebpf416x86.o
RUN clang -g -O2 -target bpf -D__KERNEL_FROM=420 -D__TARGET_ARCH_x86 -c ebpf.c -o ebpf420x86.o && llvm-strip --strip-debug ebpf420x86.o
RUN clang -g -O2 -target bpf -D__KERNEL_FROM=506 -D__TARGET_ARCH_x86 -c ebpf.c -o ebpf506x86.o && llvm-strip --strip-debug ebpf506x86.o
RUN clang -g -O2 -target bpf -D__KERNEL_FROM=507 -D__TARGET_ARCH_x86 -c ebpf.c -o ebpf507x86.o && llvm-strip --strip-debug ebpf507x86.o
RUN clang -g -O2 -target bpf -D__KERNEL_FROM=512 -D__TARGET_ARCH_x86 -c ebpf.c -o ebpf512x86.o && llvm-strip --strip-debug ebpf512x86.o
RUN clang -g -O2 -target bpf -D__KERNEL_FROM=512 -D__TARGET_ARCH_x86 -D__CTX_EXTRA_PADDING -c ebpf.c -o ebpf512x86cep.o && llvm-strip --strip-debug ebpf512x86cep.o
RUN clang -g -O2 -target bpf -D__KERNEL_FROM=416 -D__TARGET_ARCH_arm64 -c ebpf.c -o ebpf416arm64.o && llvm-strip --strip-debug ebpf416arm64.o
RUN clang -g -O2 -target bpf -D__KERNEL_FROM=420 -D__TARGET_ARCH_arm64 -c ebpf.c -o ebpf420arm64.o && llvm-strip --strip-debug ebpf420arm64.o
RUN clang -g -O2 -target bpf -D__KERNEL_FROM=506 -D__TARGET_ARCH_arm64 -c ebpf.c -o ebpf506arm64.o && llvm-strip --strip-debug ebpf506arm64.o
RUN clang -g -O2 -target bpf -D__KERNEL_FROM=507 -D__TARGET_ARCH_arm64 -c ebpf.c -o ebpf507arm64.o && llvm-strip --strip-debug ebpf507arm64.o
RUN clang -g -O2 -target bpf -D__KERNEL_FROM=512 -D__TARGET_ARCH_arm64 -c ebpf.c -o ebpf512arm64.o && llvm-strip --strip-debug ebpf512arm64.o
RUN clang -g -O2 -target bpf -D__KERNEL_FROM=512 -D__TARGET_ARCH_arm64 -D__CTX_EXTRA_PADDING -c ebpf.c -o ebpf512arm64cep.o && llvm-strip --strip-debug ebpf512arm64cep.o

Expand All @@ -25,13 +27,15 @@ RUN echo -en '// generated - do not edit\npackage ebpftracer\n\nvar ebpfProgs =
&& echo -en '\t\t{"5.12", "ctx-extra-padding", []byte("' >> ebpf.go && gzip -c ebpf512x86cep.o | base64 -w0 >> ebpf.go && echo '")},' >> ebpf.go \
&& echo -en '\t\t{"5.12", "", []byte("' >> ebpf.go && gzip -c ebpf512x86.o | base64 -w0 >> ebpf.go && echo '")},' >> ebpf.go \
&& echo -en '\t\t{"5.6", "", []byte("' >> ebpf.go && gzip -c ebpf506x86.o | base64 -w0 >> ebpf.go && echo '")},' >> ebpf.go \
&& echo -en '\t\t{"5.7", "", []byte("' >> ebpf.go && gzip -c ebpf507x86.o | base64 -w0 >> ebpf.go && echo '")},' >> ebpf.go \
&& echo -en '\t\t{"4.20", "", []byte("' >> ebpf.go && gzip -c ebpf420x86.o | base64 -w0 >> ebpf.go && echo '")},' >> ebpf.go \
&& echo -en '\t\t{"4.16", "", []byte("' >> ebpf.go && gzip -c ebpf416x86.o | base64 -w0 >> ebpf.go && echo '")},' >> ebpf.go \
&& echo -en '\t},\n'>> ebpf.go \
&& echo -en '\t"arm64": {\n' >> ebpf.go \
&& echo -en '\t\t{"5.12", "ctx-extra-padding", []byte("' >> ebpf.go && gzip -c ebpf512arm64cep.o | base64 -w0 >> ebpf.go && echo '")},' >> ebpf.go \
&& echo -en '\t\t{"5.12", "", []byte("' >> ebpf.go && gzip -c ebpf512arm64.o | base64 -w0 >> ebpf.go && echo '")},' >> ebpf.go \
&& echo -en '\t\t{"5.6", "", []byte("' >> ebpf.go && gzip -c ebpf506arm64.o | base64 -w0 >> ebpf.go && echo '")},' >> ebpf.go \
&& echo -en '\t\t{"5.7", "", []byte("' >> ebpf.go && gzip -c ebpf507arm64.o | base64 -w0 >> ebpf.go && echo '")},' >> ebpf.go \
&& echo -en '\t\t{"4.20", "", []byte("' >> ebpf.go && gzip -c ebpf420arm64.o | base64 -w0 >> ebpf.go && echo '")},' >> ebpf.go \
&& echo -en '\t\t{"4.16", "", []byte("' >> ebpf.go && gzip -c ebpf416arm64.o | base64 -w0 >> ebpf.go && echo '")},' >> ebpf.go \
&& echo -en '\t},\n'>> ebpf.go \
Expand Down
22 changes: 12 additions & 10 deletions ebpftracer/ebpf.go

Large diffs are not rendered by default.

82 changes: 67 additions & 15 deletions ebpftracer/ebpf/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ struct file_event {
__u32 type;
__u32 pid;
__u64 fd;
__u64 mnt;
__u64 log;
};

struct {
Expand All @@ -12,11 +14,24 @@ struct {
__uint(value_size, sizeof(int));
} file_events SEC(".maps");

struct path {
__u64 mnt;
};

struct nameidata {
struct path path;
};

struct file_info {
__u64 mnt;
__u64 log;
};

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(key_size, sizeof(__u64));
__uint(value_size, sizeof(__u32));
__uint(max_entries, 10240);
__uint(type, BPF_MAP_TYPE_HASH);
__uint(key_size, sizeof(__u64));
__uint(value_size, sizeof(struct file_info));
__uint(max_entries, 10240);
} open_file_info SEC(".maps");

struct trace_event_raw_sys_enter_open__stub {
Expand All @@ -34,46 +49,83 @@ struct trace_event_raw_sys_enter_openat__stub {
long int flags;
};

static __always_inline
int do_open(struct pt_regs *ctx) {
__u64 id = bpf_get_current_pid_tgid();
struct nameidata nd;
if (bpf_probe_read_kernel(&nd, sizeof(nd), (void *)PT_REGS_PARM1(ctx)) != 0) {
return 0;
}
struct file_info *i = bpf_map_lookup_elem(&open_file_info, &id);
if (!i) {
return 0;
}
i->mnt = nd.path.mnt;
return 0;
}

#if __KERNEL_FROM >= 507
SEC("kprobe/do_open")
int do_open_kprobe(struct pt_regs *ctx) {
return do_open(ctx);
}
#else
SEC("kprobe/do_last")
int do_last_kprobe(struct pt_regs *ctx) {
return do_open(ctx);
}
#endif

static __always_inline
int trace_enter_open(long int flags, char *filename)
{
if (!(flags & O_ACCMODE & (O_WRONLY | O_RDWR))) {
return 0;
}
char p[7];
long res = bpf_probe_read_str(&p, sizeof(p), (void *)filename);
if (p[0]=='/' && p[1]=='p' && p[2]=='r' && p[3]=='o' && p[4]=='c' && p[5]=='/') {
char p[10];
bpf_probe_read_str(&p, sizeof(p), (void *)filename);
if (p[0] != '/') {
return 0;
}
if (p[1]=='p' && p[2]=='r' && p[3]=='o' && p[4]=='c' && p[5]=='/') {
return 0;
}
if (p[0]=='/' && p[1]=='d' && p[2]=='e' && p[3]=='v' && p[4]=='/') {
if (p[1]=='d' && p[2]=='e' && p[3]=='v' && p[4]=='/') {
return 0;
}
if (p[0]=='/' && p[1]=='s' && p[2]=='y' && p[3]=='s' && p[4]=='/') {
if (p[1]=='s' && p[2]=='y' && p[3]=='s' && p[4]=='/') {
return 0;
}
struct file_info i = {};
if (p[1]=='v' && p[2]=='a' && p[3]=='r' && p[4]=='/' && p[5]=='l' && p[6] == 'o' && p[7] == 'g' && p[8] == '/') {
i.log = 1;
}
__u64 id = bpf_get_current_pid_tgid();
__u32 v = 1;
bpf_map_update_elem(&open_file_info, &id, &v, BPF_ANY);
bpf_map_update_elem(&open_file_info, &id, &i, BPF_ANY);
return 0;
}

static __always_inline
int trace_exit_open(struct trace_event_raw_sys_exit__stub* ctx)
{
__u64 id = bpf_get_current_pid_tgid();
if (!bpf_map_lookup_elem(&open_file_info, &id)) {
return 0;
struct file_info *i = bpf_map_lookup_elem(&open_file_info, &id);
if (!i) {
return 0;
}
bpf_map_delete_elem(&open_file_info, &id);
if (ctx->ret < 0) {
if (ctx->ret < 0 || i->mnt == 0) {
bpf_map_delete_elem(&open_file_info, &id);
return 0;
}
struct file_event e = {
.type = EVENT_TYPE_FILE_OPEN,
.pid = id >> 32,
.fd = ctx->ret,
.mnt = i->mnt,
.log = i->log,
};
bpf_perf_event_output(ctx, &file_events, BPF_F_CURRENT_CPU, &e, sizeof(e));
bpf_map_delete_elem(&open_file_info, &id);
return 0;
}

Expand Down
15 changes: 2 additions & 13 deletions ebpftracer/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ const (
IPProtoTCP uint8 = 6
)

type file struct {
pid uint32
fd uint64
}

type sock struct {
pid uint32
fd uint64
Expand Down Expand Up @@ -100,10 +95,7 @@ func (t *Tracer) init(ch chan<- Event) error {
return err
}
nss := map[string]map[string]sock{}
var (
files []file
socks []sock
)
var socks []sock

for _, pid := range pids {
ns, err := proc.GetNetNs(pid)
Expand Down Expand Up @@ -151,14 +143,11 @@ func (t *Tracer) init(ch chan<- Event) error {
socks = append(socks, s)
}
case strings.HasPrefix(fd.Dest, "/"):
files = append(files, file{pid: pid, fd: fd.Fd})
ch <- Event{Type: EventTypeFileOpen, Pid: pid, Fd: fd.Fd, Log: strings.HasPrefix(fd.Dest, "/var/log/")}
}
}
}

for _, fd := range files {
ch <- Event{Type: EventTypeFileOpen, Pid: fd.pid, Fd: fd.fd}
}
listens := map[uint64]bool{}
for _, s := range socks {
if s.Listen {
Expand Down
6 changes: 5 additions & 1 deletion ebpftracer/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ type Event struct {
Duration time.Duration
L7Request *l7.RequestData
TrafficStats *TrafficStats
Mnt uint64
Log bool
}

type perfMapType uint8
Expand Down Expand Up @@ -328,6 +330,8 @@ type fileEvent struct {
Type EventType
Pid uint32
Fd uint64
Mnt uint64
Log uint64
}

type l7Event struct {
Expand Down Expand Up @@ -398,7 +402,7 @@ func runEventsReader(name string, r *perf.Reader, ch chan<- Event, typ perfMapTy
klog.Warningln("failed to read msg:", err)
continue
}
event = Event{Type: v.Type, Pid: v.Pid, Fd: v.Fd}
event = Event{Type: v.Type, Pid: v.Pid, Fd: v.Fd, Mnt: v.Mnt, Log: v.Log > 0}
case perfMapTypeProcEvents:
v := &procEvent{}
if err := binary.Read(bytes.NewBuffer(rec.RawSample), binary.LittleEndian, v); err != nil {
Expand Down
Loading