in pkg/kprobe/kprobe.go [71:147]
func (k *bpfKprobe) KprobeAttach() error {
if k.progFD <= 0 {
log.Errorf("invalid BPF prog FD %d", k.progFD)
return fmt.Errorf("Invalid BPF prog FD %d", k.progFD)
}
// if event is nil, we pick funcName
if len(k.eventName) == 0 {
k.eventName = k.funcName
}
// Register the Kprobe event
file, err := os.OpenFile(constdef.KPROBE_SYS_EVENTS, os.O_WRONLY|os.O_APPEND, 0)
if err != nil {
log.Errorf("error opening kprobe_events file: %v", err)
return err
}
defer file.Close()
eventString := fmt.Sprintf("p:kprobes/%s %s", k.eventName, k.funcName)
_, err = file.WriteString(eventString)
if err != nil {
log.Errorf("error writing to kprobe_events file: %v", err)
return err
}
//Get the Kprobe ID
kprobeIDpath := fmt.Sprintf("%s/%s/id", constdef.KPROBE_SYS_DEBUG, k.eventName)
data, err := os.ReadFile(kprobeIDpath)
if err != nil {
log.Errorf("unable to read the kprobeID: %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))
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", k.progFD, fd)
if _, _, err := unix.Syscall(unix.SYS_IOCTL, uintptr(int(fd)), uintptr(uint(unix.PERF_EVENT_IOC_SET_BPF)), uintptr(k.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
}
k.SetPerfFD(fd)
log.Infof("KPROBE Attach done!!! %d", fd)
return nil
}