summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/event/event.go1
-rw-r--r--internal/eventloop.go4
-rw-r--r--internal/file/file.go56
-rw-r--r--internal/file/flags.go16
-rw-r--r--internal/generated/types/types.go2
5 files changed, 65 insertions, 14 deletions
diff --git a/internal/event/event.go b/internal/event/event.go
index 9118f65..680ee62 100644
--- a/internal/event/event.go
+++ b/internal/event/event.go
@@ -13,7 +13,6 @@ var poolOfEventPairs = sync.Pool{
New: func() interface{} { return &Pair{} },
}
-// TODO: A way to get the open flags? Trace them as well? sync vs non-sync?
type Event interface {
String() string
GetTraceId() TraceId
diff --git a/internal/eventloop.go b/internal/eventloop.go
index 3963cf6..e17095a 100644
--- a/internal/eventloop.go
+++ b/internal/eventloop.go
@@ -16,7 +16,6 @@ import (
. "ior/internal/generated/types"
)
-// TODO: Move in its own package?
type eventLoop struct {
flags flags.Flags
filter *eventFilter
@@ -150,6 +149,7 @@ func (e *eventLoop) syscallEnter(enterEv event.Event) {
// Only, when we have a comm name
if _, ok := e.comms[tid]; ok {
e.enterEvs[tid] = event.NewPair(enterEv)
+ // TODO } else { .... what if not? }
}
}
}
@@ -180,7 +180,7 @@ func (e *eventLoop) syscallExit(exitEv event.Event, ch chan<- *event.Pair) {
fd := int32(ev.ExitEv.(*RetEvent).Ret)
// It's from an array, so only create string from array until first 0 byte
// TODO: This could speed up the path filter as well
- file := file.NewFd(fd, openEv.Filename[:])
+ file := file.NewFd(fd, openEv.Filename[:], v.Flags)
if fd >= 0 {
e.files[fd] = file
}
diff --git a/internal/file/file.go b/internal/file/file.go
index 31c119e..364ee33 100644
--- a/internal/file/file.go
+++ b/internal/file/file.go
@@ -1,6 +1,7 @@
package file
import (
+ "bufio"
"bytes"
"fmt"
"os"
@@ -11,28 +12,53 @@ import (
type File interface {
String() string
Name() string
+ Flags() string
}
type fdFile struct {
- fd int32
- name string
+ fd int32
+ name string
+ flags int32
}
-func NewFd(fd int32, name []byte) fdFile {
- return fdFile{fd, stringValue(name)}
+func NewFd(fd int32, name []byte, flags int32) fdFile {
+ return fdFile{fd, stringValue(name), flags}
}
func NewFdWithPid(fd int32, pid uint32) fdFile {
- if linkName, err := os.Readlink(fmt.Sprintf("/proc/%d/fd/%d", pid, fd)); err == nil {
- return fdFile{fd, linkName}
+ linkName, err := os.Readlink(fmt.Sprintf("/proc/%d/fd/%d", pid, fd))
+ if err != nil {
+ return fdFile{fd, "?", -1}
}
- return fdFile{fd, "?"}
+ flags, _ := readFlagsFromFdInfo(fd, pid)
+ return fdFile{fd, linkName, flags}
+}
+
+func readFlagsFromFdInfo(fd int32, pid uint32) (int32, error) {
+ data, err := os.ReadFile(fmt.Sprintf("/proc/%d/fdinfo/%d", pid, fd))
+ if err != nil {
+ return -1, err
+ }
+ scanner := bufio.NewScanner(bytes.NewReader(data))
+ for scanner.Scan() {
+ line := scanner.Text()
+ if strings.HasPrefix(line, "flags:") {
+ flagsStr := strings.Fields(line)[1]
+ flags, err := strconv.ParseUint(flagsStr, 8, 32)
+ return int32(flags), err
+ }
+ }
+ return -1, scanner.Err()
}
func (f fdFile) Name() string {
return f.name
}
+func (f fdFile) Flags() string {
+ return flagsToStr(f.flags)
+}
+
func (f fdFile) String() string {
var sb strings.Builder
@@ -42,6 +68,8 @@ func (f fdFile) String() string {
sb.WriteString(f.name)
sb.WriteString(" (")
sb.WriteString(strconv.FormatInt(int64(f.fd), 10))
+ sb.WriteString(",")
+ sb.WriteString(f.Flags())
sb.WriteString(")")
}
@@ -60,6 +88,10 @@ func (f oldnameNewnameFile) Name() string {
return f.Newname
}
+func (f oldnameNewnameFile) Flags() string {
+ return ""
+}
+
func (f oldnameNewnameFile) String() string {
var sb strings.Builder
@@ -67,6 +99,9 @@ func (f oldnameNewnameFile) String() string {
sb.WriteString(f.Oldname)
sb.WriteString(" ->new:")
sb.WriteString(f.Newname)
+ sb.WriteString(" (")
+ sb.WriteString(f.Flags())
+ sb.WriteString(")")
return sb.String()
}
@@ -83,11 +118,18 @@ func (f pathnameFile) Name() string {
return f.Pathname
}
+func (f pathnameFile) Flags() string {
+ return ""
+}
+
func (f pathnameFile) String() string {
var sb strings.Builder
sb.WriteString("pathname:")
sb.WriteString(f.Pathname)
+ sb.WriteString(" (")
+ sb.WriteString(f.Flags())
+ sb.WriteString(")")
return sb.String()
}
diff --git a/internal/file/flags.go b/internal/file/flags.go
index fcba927..3589833 100644
--- a/internal/file/flags.go
+++ b/internal/file/flags.go
@@ -5,6 +5,11 @@ import (
"syscall"
)
+// TODO: syscalls fcntl and dup3 and many more can also manipulate open flags
+// Check the tracepoint formates for 'flags'
+// Maybe need new BPF type and pass through the ring
+var flagsToHumanCache = map[int32]string{-1: "O_?"}
+
var flagsToHuman = map[int]string{
syscall.O_ACCMODE: "O_ACCMODE",
syscall.O_APPEND: "O_APPEND",
@@ -26,11 +31,16 @@ var flagsToHuman = map[int]string{
syscall.O_WRONLY: "O_WRONLY",
}
-func FlagsToStr(flags int32) string {
- return strings.Join(FlagsToStrs(flags), "|")
+func flagsToStr(flags int32) string {
+ if str, ok := flagsToHumanCache[flags]; ok {
+ return str
+ }
+ str := strings.Join(flagsToStrs(flags), "|")
+ flagsToHumanCache[flags] = str
+ return str
}
-func FlagsToStrs(flags int32) (result []string) {
+func flagsToStrs(flags int32) (result []string) {
for flag, name := range flagsToHuman {
if int(flags)&flag == flag {
result = append(result, name)
diff --git a/internal/generated/types/types.go b/internal/generated/types/types.go
index 374c062..8587143 100644
--- a/internal/generated/types/types.go
+++ b/internal/generated/types/types.go
@@ -1,4 +1,5 @@
// Code generated - don't change manually!
+// TODO: Rename all generate files to *_generated.go, and don't keep them in a generated directory anymore
package types
import (
@@ -95,7 +96,6 @@ func NewOpenEvent(raw []byte) *OpenEvent {
fmt.Println(o, raw, len(raw), err)
panic(raw)
}
- fmt.Println("DEBUG, ", o)
return o
}