@@ -124,6 +124,16 @@ type pciAddress struct {
124124 function string
125125}
126126
127+ // The PCI root is the root PCI device, derived from the
128+ // pciAddress of a device. Spec is defined from the DRA KEP.
129+ // https://github.com/kubernetes/enhancements/pull/5316
130+ type pciRoot struct {
131+ domain string
132+ // The root may have a different host bus than the PCI device.
133+ // e.g https://uefi.org/specs/UEFI/2.10/14_Protocols_PCI_Bus_Support.html#server-system-with-four-pci-root-bridges
134+ bus string
135+ }
136+
127137func bdfAddress (ifName string , path string ) (* pciAddress , error ) {
128138 address := & pciAddress {}
129139 // https://docs.kernel.org/PCI/sysfs-pci.html
@@ -164,6 +174,28 @@ func bdfAddress(ifName string, path string) (*pciAddress, error) {
164174 return address , nil
165175}
166176
177+ // Obtain the root of the pci device for the interface.
178+ // TODO(@michaelasp): Change this to use k8s helper function when available for consistency with other DRA solutions.
179+ func bdfRoot (ifName , path string ) (* pciRoot , error ) {
180+ root := & pciRoot {}
181+
182+ sysfsPath := realpath (ifName , path )
183+ bfd := strings .Split (sysfsPath , "/" )
184+ if len (bfd ) < 5 {
185+ return nil , fmt .Errorf ("could not find corresponding PCI address: %v" , bfd )
186+ }
187+ klog .V (4 ).Infof ("pci root: %s" , bfd [3 ])
188+ rootString := strings .Split (bfd [3 ], ":" )
189+ switch len (rootString ) {
190+ case 2 :
191+ root .domain = strings .TrimPrefix (rootString [0 ], "pci" )
192+ root .bus = rootString [1 ]
193+ default :
194+ return nil , fmt .Errorf ("could not find corresponding PCI root: %v" , rootString )
195+ }
196+ return root , nil
197+ }
198+
167199func ids (ifName string , path string ) (* pcidb.Entry , error ) {
168200 // PCI data
169201 var device , subsystemVendor , subsystemDevice []byte
0 commit comments