#1957·ebpf

support StructOps declarative initialization in bpf2go

Author: shun159Created Feb 28, 2026Updated Mar 29, 2026
Labelsenhancement

This proposal introduces StructOps Initialization Structs in bpf2go. This allows users to define the initial state of a struct_ops map (currently, I consider scalar values such as flags) using standard Go struct literals, which are then synchronized with the MapSpec during the LoadAndAssign process.

Initialization Struct Generation: bpf2go generates Go structs that mirror the BTF definition of struct_ops members. These structs are used as templates for map creation.

Pre-load Synchronization: It patches the MapSpec.Contents with the provided values before the map is created in the kernel.

example:

generated code

go
// bpfStructOpsMinimalSched is a struct type for the struct_ops map.
type bpfStructOpsMinimalSched struct {
	_         structs.HostLayout
	Init      *ebpf.Program `ebpf:"init"`
	Flags     uint64        `ebpf:"flags"`
	TimeoutMs uint32        `ebpf:"timeout_ms"`
	Name      [128]int8     `ebpf:"name"`
}

user code

go
func main() {
	if err := rlimit.RemoveMemlock(); err != nil {
		log.Fatal(err)
	}

	objs := bpfObjects{}
	objs.bpfStructOps.StructOpsMinimalSched.Flags = ScxOpsSwitchPartial
	objs.bpfStructOps.StructOpsMinimalSched.TimeoutMs = 1000
	if err := loadBpfObjects(&objs, nil); err != nil {
		log.Fatalf("loading objects: %v", err)
	}
	defer objs.Close()

	m := objs.MinimalSched
	l, err := link.AttachStructOps(link.StructOpsOptions{Map: m})
	if err != nil {
		log.Fatalf("failed to attach sched_ext: %s", err)
	}
	defer l.Close()

	stopper := make(chan os.Signal, 1)
	signal.Notify(stopper, os.Interrupt, syscall.SIGTERM)

	<-stopper

	log.Print("quit sched_ext")
}