Skip to content

Commit

Permalink
helpers/kernel_features: allow kconfig override
Browse files Browse the repository at this point in the history
Reference: #60
Reference: #61
  • Loading branch information
rafaeldtinoco authored and Rafael David Tinoco committed Sep 2, 2021
1 parent 5fde94f commit 1e07685
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 23 deletions.
27 changes: 22 additions & 5 deletions helpers/kernel_features.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,17 +175,33 @@ var KernelConfigKeyIDToString = map[KernelConfigOption]string{

// KernelConfig is a set of kernel configuration options (currently for running OS only)
type KernelConfig struct {
configs map[KernelConfigOption]interface{} // predominantly KernelConfigOptionValue, sometimes string
needed map[KernelConfigOption]interface{}
configs map[KernelConfigOption]interface{} // predominantly KernelConfigOptionValue, sometimes string
needed map[KernelConfigOption]interface{}
KConfigFilePath string
}

// InitKernelConfig inits external KernelConfig object
func InitKernelConfig() (*KernelConfig, error) {
func InitKernelConfig(OSKConfigFilePath string) (*KernelConfig, error) {
config := KernelConfig{}

// special case: user provided kconfig file (it MUST exist)
if len(OSKConfigFilePath) > 2 {
if _, err := os.Stat(OSKConfigFilePath); err != nil {
return nil, err
}
config.KConfigFilePath = OSKConfigFilePath // user might need to know used KConfig file in order to override kconfig for libbpf (example)
if err := config.initKernelConfig(OSKConfigFilePath); err != nil {
return nil, err
}

return &config, nil
}

// fastpath: check config.gz in procfs first
if _, err1 := os.Stat("/proc/config.gz"); err1 == nil {
if err2 := config.initKernelConfig("/proc/config.gz"); err2 != nil {
configGZ := "/proc/config.gz"
if _, err1 := os.Stat(configGZ); err1 == nil {
config.KConfigFilePath = configGZ // same thing here
if err2 := config.initKernelConfig(configGZ); err2 != nil {
return nil, err2
}

Expand All @@ -200,6 +216,7 @@ func InitKernelConfig() (*KernelConfig, error) {

releaseVersion := bytes.TrimRight(x.Release[:], "\x00")
releaseFilePath := fmt.Sprintf("/boot/config-%s", releaseVersion)
config.KConfigFilePath = releaseFilePath // and here

if err := config.initKernelConfig(releaseFilePath); err != nil {
return nil, err
Expand Down
63 changes: 45 additions & 18 deletions libbpfgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,28 +296,45 @@ func errptrError(ptr unsafe.Pointer, format string, args ...interface{}) error {
return fmt.Errorf(format+": %v", args...)
}

type NewModuleArgs struct {
KConfigFilePath string
BTFObjPath string
BPFObjName string
BPFObjPath string
BPFObjBuff []byte
}

func NewModuleFromFile(bpfObjPath string) (*Module, error) {
return NewModuleFromFileBTF("", bpfObjPath)

return NewModuleFromFileArgs(NewModuleArgs{
BPFObjPath: bpfObjPath,
})
}

func NewModuleFromFileBTF(btfObjPath string, bpfObjPath string) (*Module, error) {
func NewModuleFromFileArgs(args NewModuleArgs) (*Module, error) {
C.set_print_fn()
if err := bumpMemlockRlimit(); err != nil {
return nil, err
}
if btfObjPath == "" {
btfObjPath = "/sys/kernel/btf/vmlinux"
if args.BTFObjPath == "" {
args.BTFObjPath = "/sys/kernel/btf/vmlinux"
}
btfFile := C.CString(btfObjPath)
bpfFile := C.CString(bpfObjPath)
btfFile := C.CString(args.BTFObjPath)
bpfFile := C.CString(args.BPFObjPath)

opts := C.struct_bpf_object_open_opts{}
opts.sz = C.sizeof_struct_bpf_object_open_opts
opts.btf_custom_path = btfFile
opts.btf_custom_path = btfFile // instruct libbpf to use user provided kernel BTF file

if strings.Compare(args.KConfigFilePath, "") != 0 {
kConfigFile := C.CString(args.KConfigFilePath)
opts.kconfig = kConfigFile // instruct libbpf to use user provided KConfigFile
defer C.free(unsafe.Pointer(kConfigFile))
}

obj := C.bpf_object__open_file(bpfFile, &opts)
if C.IS_ERR_OR_NULL(unsafe.Pointer(obj)) {
return nil, errptrError(unsafe.Pointer(obj), "failed to open BPF object %s", bpfObjPath)
return nil, errptrError(unsafe.Pointer(obj), "failed to open BPF object %s", args.BPFObjPath)
}

C.free(unsafe.Pointer(bpfFile))
Expand All @@ -329,30 +346,40 @@ func NewModuleFromFileBTF(btfObjPath string, bpfObjPath string) (*Module, error)
}

func NewModuleFromBuffer(bpfObjBuff []byte, bpfObjName string) (*Module, error) {
return NewModuleFromBufferBtf("", bpfObjBuff, bpfObjName)

return NewModuleFromFileArgs(NewModuleArgs{
BPFObjBuff: bpfObjBuff,
BPFObjName: bpfObjName,
})
}

func NewModuleFromBufferBtf(btfObjPath string, bpfObjBuff []byte, bpfObjName string) (*Module, error) {
func NewModuleFromBufferArgs(args NewModuleArgs) (*Module, error) {
C.set_print_fn()
if err := bumpMemlockRlimit(); err != nil {
return nil, err
}
if btfObjPath == "" {
btfObjPath = "/sys/kernel/btf/vmlinux"
if args.BTFObjPath == "" {
args.BTFObjPath = "/sys/kernel/btf/vmlinux"
}
btfFile := C.CString(btfObjPath)
bpfName := C.CString(bpfObjName)
bpfBuff := unsafe.Pointer(C.CBytes(bpfObjBuff))
bpfBuffSize := C.size_t(len(bpfObjBuff))
btfFile := C.CString(args.BTFObjPath)
bpfName := C.CString(args.BPFObjName)
bpfBuff := unsafe.Pointer(C.CBytes(args.BPFObjBuff))
bpfBuffSize := C.size_t(len(args.BPFObjBuff))

opts := C.struct_bpf_object_open_opts{}
opts.object_name = bpfName
opts.sz = C.sizeof_struct_bpf_object_open_opts
opts.btf_custom_path = btfFile
opts.btf_custom_path = btfFile // instruct libbpf to use user provided kernel BTF file

if len(args.KConfigFilePath) > 2 {
kConfigFile := C.CString(args.KConfigFilePath)
opts.kconfig = kConfigFile // instruct libbpf to use user provided KConfigFile
defer C.free(unsafe.Pointer(kConfigFile))
}

obj := C.bpf_object__open_mem(bpfBuff, bpfBuffSize, &opts)
if C.IS_ERR_OR_NULL(unsafe.Pointer(obj)) {
return nil, errptrError(unsafe.Pointer(obj), "failed to open BPF object %s: %v", bpfObjName, bpfObjBuff[:20])
return nil, errptrError(unsafe.Pointer(obj), "failed to open BPF object %s: %v", args.BPFObjName, args.BPFObjBuff[:20])
}

C.free(bpfBuff)
Expand Down

0 comments on commit 1e07685

Please sign in to comment.