@@ -547,60 +547,65 @@ func (spec *MapSpec) createMap(inner *sys.FD) (_ *Map, err error) {
547
547
}
548
548
549
549
if spec .Key != nil || spec .Value != nil {
550
- handle , keyTypeID , valueTypeID , err := btf .MarshalMapKV (spec .Key , spec .Value )
551
- if err != nil && ! errors .Is (err , btf .ErrNotSupported ) {
552
- return nil , fmt .Errorf ("load BTF: %w" , err )
553
- }
550
+ if spec .Type == StructOpsMap {
551
+ // we need drop meta entry here
552
+ if len (spec .Contents ) > 0 {
553
+ spec .Contents = spec .Contents [1 :]
554
+ }
554
555
555
- if handle != nil {
556
- defer handle .Close ()
556
+ var b btf.Builder
557
+ h , err := btf .NewHandle (& b )
558
+ if err != nil {
559
+ return nil , err
560
+ }
561
+ defer h .Close ()
557
562
558
- // Use BTF k/v during map creation.
559
- attr .BtfFd = uint32 (handle .FD ())
560
- attr .BtfKeyTypeId = keyTypeID
561
- attr .BtfValueTypeId = valueTypeID
562
- }
563
- }
563
+ s , err := btf .LoadKernelSpec ()
564
+ if err != nil {
565
+ return nil , fmt .Errorf ("open vmlinux BTF: %w" , err )
566
+ }
564
567
565
- if spec .Type == StructOpsMap {
566
- meta , err := extractStructOpsMeta (spec .Contents )
567
- if err != nil {
568
- return nil , err
569
- }
568
+ if spec .Value == nil {
569
+ return nil , fmt .Errorf ("Struct type is not specified as Value" )
570
+ }
570
571
571
- // we need drop meta entry here
572
- if len (spec .Contents ) > 0 {
573
- spec .Contents = spec .Contents [1 :]
574
- }
572
+ userStructTypeName := spec .Value .TypeName ()
573
+ t , err := s .AnyTypeByName (structOpsValuePrefix + userStructTypeName )
574
+ if errors .Is (err , btf .ErrNotFound ) {
575
+ return nil , fmt .Errorf ("struct_ops kernel type %q: %w" , userStructTypeName , btf .ErrNotFound )
576
+ }
577
+ if err != nil {
578
+ return nil , fmt .Errorf ("lookup kernel type %q: %w" , userStructTypeName , err )
579
+ }
575
580
576
- var b btf.Builder
577
- h , err := btf .NewHandle (& b )
578
- if err != nil {
579
- return nil , err
580
- }
581
- defer h .Close ()
581
+ userStructType , ok := t .(* btf.Struct )
582
+ if ! ok {
583
+ return nil , fmt .Errorf ("Value must be Struct type" )
584
+ }
582
585
583
- s , err := btf . LoadKernelSpec ( )
584
- if err != nil {
585
- return nil , fmt .Errorf ("open vmlinux BTF : %w" , err )
586
- }
586
+ btfValueTypeId , err := s . TypeID ( userStructType )
587
+ if err != nil {
588
+ return nil , fmt .Errorf ("lookup type_id : %w" , err )
589
+ }
587
590
588
- typeSpec , err := s .AnyTypeByName (meta .kernTypeName )
589
- if errors .Is (err , btf .ErrNotFound ) {
590
- return nil , fmt .Errorf ("struct_ops kernel type %q: %w" , meta .kernTypeName , ErrNotSupported )
591
- }
592
- if err != nil {
593
- return nil , fmt .Errorf ("lookup kernel type %q: %w" , meta .kernTypeName , err )
594
- }
591
+ attr .ValueSize = spec .ValueSize
592
+ attr .BtfVmlinuxValueTypeId = btfValueTypeId
593
+ attr .BtfFd = uint32 (h .FD ())
594
+ } else {
595
+ handle , keyTypeID , valueTypeID , err := btf .MarshalMapKV (spec .Key , spec .Value )
596
+ if err != nil && ! errors .Is (err , btf .ErrNotSupported ) {
597
+ return nil , fmt .Errorf ("load BTF: %w" , err )
598
+ }
595
599
596
- btfValueTypeId , err := s .TypeID (typeSpec )
597
- if err != nil {
598
- return nil , fmt .Errorf ("lookup type_id of %s: %w" , typeSpec .TypeName (), err )
599
- }
600
+ if handle != nil {
601
+ defer handle .Close ()
600
602
601
- attr .ValueSize = spec .ValueSize
602
- attr .BtfVmlinuxValueTypeId = btfValueTypeId
603
- attr .BtfFd = uint32 (h .FD ())
603
+ // Use BTF k/v during map creation.
604
+ attr .BtfFd = uint32 (handle .FD ())
605
+ attr .BtfKeyTypeId = keyTypeID
606
+ attr .BtfValueTypeId = valueTypeID
607
+ }
608
+ }
604
609
}
605
610
606
611
fd , err := sys .MapCreate (& attr )
0 commit comments