@@ -20,6 +20,8 @@ import (
2020 "tags.cncf.io/container-device-interface/pkg/cdi"
2121 "tags.cncf.io/container-device-interface/specs-go"
2222
23+ "github.com/opencontainers/runc/libcontainer/devices"
24+
2325 "github.com/NVIDIA/nvidia-container-toolkit/internal/discover"
2426)
2527
@@ -43,19 +45,37 @@ func (d device) toEdits() (*cdi.ContainerEdits, error) {
4345// toSpec converts a discovered Device to a CDI Spec Device. Note
4446// that missing info is filled in when edits are applied by querying the Device node.
4547func (d device ) toSpec () (* specs.DeviceNode , error ) {
48+ s := d .fromPathOrDefault ()
4649 // The HostPath field was added in the v0.5.0 CDI specification.
4750 // The cdi package uses strict unmarshalling when loading specs from file causing failures for
4851 // unexpected fields.
4952 // Since the behaviour for HostPath == "" and HostPath == Path are equivalent, we clear HostPath
5053 // if it is equal to Path to ensure compatibility with the widest range of specs.
51- hostPath := d .HostPath
52- if hostPath == d .Path {
53- hostPath = ""
54+ if s .HostPath == d .Path {
55+ s .HostPath = ""
5456 }
55- s := specs.DeviceNode {
56- HostPath : hostPath ,
57- Path : d .Path ,
57+
58+ return s , nil
59+ }
60+
61+ // fromPathOrDefault attempts to return the returns the information about the
62+ // CDI device from the specified host path.
63+ // If this fails a minimal device is returned so that this information can be
64+ // queried by the container runtime such as containerd.
65+ func (d device ) fromPathOrDefault () * specs.DeviceNode {
66+ dn , err := devices .DeviceFromPath (d .HostPath , "rwm" )
67+ if err != nil {
68+ return & specs.DeviceNode {
69+ HostPath : d .HostPath ,
70+ Path : d .Path ,
71+ }
5872 }
5973
60- return & s , nil
74+ return & specs.DeviceNode {
75+ HostPath : d .HostPath ,
76+ Path : d .Path ,
77+ Major : dn .Major ,
78+ Minor : dn .Minor ,
79+ FileMode : & dn .FileMode ,
80+ }
6181}
0 commit comments