@@ -42,6 +42,7 @@ const (
4242 cdiClaimKind = cdiVendor + "/" + cdiClaimClass
4343
4444 cdiBaseSpecIdentifier = "base"
45+ cdiVfioSpecIdentifier = "vfio"
4546
4647 defaultCDIRoot = "/var/run/cdi"
4748)
@@ -139,7 +140,69 @@ func NewCDIHandler(opts ...cdiOption) (*CDIHandler, error) {
139140 return h , nil
140141}
141142
143+ func (cdi * CDIHandler ) writeSpec (spec spec.Interface , specName string ) error {
144+ // Transform the spec to make it aware that it is running inside a container.
145+ err := transformroot .New (
146+ transformroot .WithRoot (cdi .driverRoot ),
147+ transformroot .WithTargetRoot (cdi .targetDriverRoot ),
148+ transformroot .WithRelativeTo ("host" ),
149+ ).Transform (spec .Raw ())
150+ if err != nil {
151+ return fmt .Errorf ("failed to transform driver root in CDI spec: %w" , err )
152+ }
153+
154+ // Update the spec to include only the minimum version necessary.
155+ minVersion , err := cdispec .MinimumRequiredVersion (spec .Raw ())
156+ if err != nil {
157+ return fmt .Errorf ("failed to get minimum required CDI spec version: %w" , err )
158+ }
159+ spec .Raw ().Version = minVersion
160+
161+ // Write the spec out to disk.
162+ return cdi .cache .WriteSpec (spec .Raw (), specName )
163+
164+ }
165+
142166func (cdi * CDIHandler ) CreateStandardDeviceSpecFile (allocatable AllocatableDevices ) error {
167+ if err := cdi .createStandardNvidiaDeviceSpecFile (allocatable ); err != nil {
168+ return err
169+ }
170+ if err := cdi .createStandardVfioDeviceSpecFile (allocatable ); err != nil {
171+ return err
172+ }
173+ return nil
174+ }
175+
176+ func (cdi * CDIHandler ) createStandardVfioDeviceSpecFile (allocatable AllocatableDevices ) error {
177+ commonEdits := GetVfioCommonCDIContainerEdits ()
178+ var deviceSpecs []cdispec.Device
179+ for _ , device := range allocatable {
180+ if device .Type () != VfioDeviceType {
181+ continue
182+ }
183+ edits := GetVfioCDIContainerEdits (device .Vfio )
184+ dspec := cdispec.Device {
185+ Name : device .CanonicalName (),
186+ ContainerEdits : * edits .ContainerEdits ,
187+ }
188+ deviceSpecs = append (deviceSpecs , dspec )
189+ }
190+
191+ spec , err := spec .New (
192+ spec .WithVendor (cdiVendor ),
193+ spec .WithClass (cdiDeviceClass ),
194+ spec .WithDeviceSpecs (deviceSpecs ),
195+ spec .WithEdits (* commonEdits .ContainerEdits ),
196+ )
197+ if err != nil {
198+ return fmt .Errorf ("failed to creat CDI spec: %w" , err )
199+ }
200+
201+ specName := cdiapi .GenerateTransientSpecName (cdiVendor , cdiDeviceClass , cdiVfioSpecIdentifier )
202+ return cdi .writeSpec (spec , specName )
203+ }
204+
205+ func (cdi * CDIHandler ) createStandardNvidiaDeviceSpecFile (allocatable AllocatableDevices ) error {
143206 // Initialize NVML in order to get the device edits.
144207 if r := cdi .nvml .Init (); r != nvml .SUCCESS {
145208 return fmt .Errorf ("failed to initialize NVML: %v" , r )
@@ -166,6 +229,10 @@ func (cdi *CDIHandler) CreateStandardDeviceSpecFile(allocatable AllocatableDevic
166229 // Generate device specs for all full GPUs and MIG devices.
167230 var deviceSpecs []cdispec.Device
168231 for _ , device := range allocatable {
232+ if device .Type () == VfioDeviceType {
233+ continue
234+ }
235+
169236 dspecs , err := cdi .nvcdiDevice .GetDeviceSpecsByID (device .UUID ())
170237 if err != nil {
171238 return fmt .Errorf ("unable to get device spec for %s: %w" , device .CanonicalName (), err )
@@ -185,26 +252,8 @@ func (cdi *CDIHandler) CreateStandardDeviceSpecFile(allocatable AllocatableDevic
185252 return fmt .Errorf ("failed to creat CDI spec: %w" , err )
186253 }
187254
188- // Transform the spec to make it aware that it is running inside a container.
189- err = transformroot .New (
190- transformroot .WithRoot (cdi .driverRoot ),
191- transformroot .WithTargetRoot (cdi .targetDriverRoot ),
192- transformroot .WithRelativeTo ("host" ),
193- ).Transform (spec .Raw ())
194- if err != nil {
195- return fmt .Errorf ("failed to transform driver root in CDI spec: %w" , err )
196- }
197-
198- // Update the spec to include only the minimum version necessary.
199- minVersion , err := cdispec .MinimumRequiredVersion (spec .Raw ())
200- if err != nil {
201- return fmt .Errorf ("failed to get minimum required CDI spec version: %w" , err )
202- }
203- spec .Raw ().Version = minVersion
204-
205- // Write the spec out to disk.
206- specName := cdiapi .GenerateTransientSpecName (cdiVendor , cdiDeviceClass , cdiBaseSpecIdentifier )
207- return cdi .cache .WriteSpec (spec .Raw (), specName )
255+ specName := cdiapi .GenerateTransientSpecName (cdiVendor , cdiDeviceClass , cdiVfioSpecIdentifier )
256+ return cdi .writeSpec (spec , specName )
208257}
209258
210259func (cdi * CDIHandler ) CreateClaimSpecFile (claimUID string , preparedDevices PreparedDevices ) error {
0 commit comments