in pkg/tracepoint/tracepoint.go [32:93]
func TracepointAttach(progFD int, subSystem, eventName string) error {
if progFD <= 0 {
log.Infof("Invalid BPF prog FD %d", progFD)
return fmt.Errorf("invalid BPF prog FD %d", progFD)
}
if len(subSystem) == 0 || len(eventName) == 0 {
return fmt.Errorf("invalid Arguement")
}
//Get the TP ID
tracepointIDpath := fmt.Sprintf("%s/%s/%s/id", constdef.TRACEPOINT_EVENTS, subSystem, eventName)
data, err := os.ReadFile(tracepointIDpath)
if err != nil {
log.Errorf("unable to read the tracepointID: %v", err)
return err
}
id := strings.TrimSpace(string(data))
eventID, err := strconv.Atoi(id)
if err != nil {
log.Errorf("invalid ID during parsing: %s - %w", id, err)
return err
}
log.Infof("Got eventID %d", eventID)
attr := unix.PerfEventAttr{
Type: unix.PERF_TYPE_TRACEPOINT,
Sample: 1,
Wakeup: 1,
Config: uint64(eventID),
}
attr.Size = uint32(unsafe.Sizeof(attr))
/*
* Ref : https://man7.org/linux/man-pages/man2/perf_event_open.2.html
* pid = -1 and cpu = 0 [This measures all processes/threads on the specified CPU]
* group_fd = -1 Creates event group with leader first.
*/
fd, err := unix.PerfEventOpen(&attr, -1, 0, -1, unix.PERF_FLAG_FD_CLOEXEC)
if err != nil {
log.Errorf("failed to open perf event %v", err)
return err
}
log.Infof("Attach bpf program to perf event Prog FD %d Event FD %d", progFD, fd)
if _, _, err := unix.Syscall(unix.SYS_IOCTL, uintptr(int(fd)), uintptr(uint(unix.PERF_EVENT_IOC_SET_BPF)), uintptr(progFD)); err != 0 {
log.Errorf("error attaching bpf program to perf event: %v", err)
return err
}
if _, _, err := unix.Syscall(unix.SYS_IOCTL, uintptr(int(fd)), uintptr(uint(unix.PERF_EVENT_IOC_ENABLE)), 0); err != 0 {
log.Errorf("error enabling perf event: %v", err)
return err
}
log.Infof("Tracepoint attach done!!! %d", fd)
return nil
}