@@ -33,41 +33,62 @@ import (
3333// findDevicePath finds path of device and verifies its existence
3434// if the device is not nvme, return the path directly
3535// if the device is nvme, finds and returns the nvme device path eg. /dev/nvme1n1
36- func (d * nodeService ) findDevicePath (devicePath , volumeID string , partition string ) (string , error ) {
36+ func (d * nodeService ) findDevicePath (devicePath , volumeID , partition string ) (string , error ) {
37+ canonicalDevicePath := ""
38+
39+ // If the given path exists, the device MAY be nvme. Further, it MAY be a
40+ // symlink to the nvme device path like:
41+ // | $ stat /dev/xvdba
42+ // | File: ‘/dev/xvdba’ -> ‘nvme1n1’
43+ // Since these are maybes, not guarantees, the search for the nvme device
44+ // path below must happen and must rely on volume ID
3745 exists , err := d .mounter .PathExists (devicePath )
3846 if err != nil {
39- return "" , err
47+ return "" , fmt . Errorf ( "failed to check if path %q exists: %v" , devicePath , err )
4048 }
4149
42- // If the path exists, assume it is not nvme device
4350 if exists {
4451 if partition != "" {
4552 devicePath = devicePath + diskPartitionSuffix + partition
4653 }
47- return devicePath , nil
54+ canonicalDevicePath = devicePath
4855 }
4956
50- // Else find the nvme device path using volume ID
51- // This is the magic name on which AWS presents NVME devices under /dev/disk/by-id/
52- // For example, vol-0fab1d5e3f72a5e23 creates a symlink at
57+ // AWS recommends identifying devices by volume ID
58+ // (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html),
59+ // so find the nvme device path using volume ID. This is the magic name on
60+ // which AWS presents NVME devices under /dev/disk/by-id/. For example,
61+ // vol-0fab1d5e3f72a5e23 creates a symlink at
5362 // /dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_vol0fab1d5e3f72a5e23
5463 nvmeName := "nvme-Amazon_Elastic_Block_Store_" + strings .Replace (volumeID , "-" , "" , - 1 )
5564
56- nvmeDevicePath , err := findNvmeVolume (nvmeName )
57- if err != nil {
58- return "" , err
65+ nvmeDevicePath , err := findNvmeVolume (d .deviceIdentifier , nvmeName )
66+
67+ if err == nil {
68+ if partition != "" {
69+ nvmeDevicePath = nvmeDevicePath + nvmeDiskPartitionSuffix + partition
70+ }
71+ canonicalDevicePath = nvmeDevicePath
72+ } else {
73+ klog .V (5 ).Infof ("[Debug] error searching for nvme path %q: %v" , nvmeName , err )
5974 }
60- if partition != "" {
61- nvmeDevicePath = nvmeDevicePath + nvmeDiskPartitionSuffix + partition
75+
76+ if canonicalDevicePath == "" {
77+ return "" , errNoDevicePathFound (devicePath , volumeID )
6278 }
63- return nvmeDevicePath , nil
79+
80+ return canonicalDevicePath , nil
81+ }
82+
83+ func errNoDevicePathFound (devicePath , volumeID string ) error {
84+ return fmt .Errorf ("no device path for device %q volume %q found!" , devicePath , volumeID )
6485}
6586
6687// findNvmeVolume looks for the nvme volume with the specified name
6788// It follows the symlink (if it exists) and returns the absolute path to the device
68- func findNvmeVolume (findName string ) (device string , err error ) {
89+ func findNvmeVolume (deviceIdentifier DeviceIdentifier , findName string ) (device string , err error ) {
6990 p := filepath .Join ("/dev/disk/by-id/" , findName )
70- stat , err := os .Lstat (p )
91+ stat , err := deviceIdentifier .Lstat (p )
7192 if err != nil {
7293 if os .IsNotExist (err ) {
7394 klog .V (5 ).Infof ("[Debug] nvme path %q not found" , p )
@@ -82,7 +103,7 @@ func findNvmeVolume(findName string) (device string, err error) {
82103 }
83104 // Find the target, resolving to an absolute path
84105 // For example, /dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_vol0fab1d5e3f72a5e23 -> ../../nvme2n1
85- resolved , err := filepath .EvalSymlinks (p )
106+ resolved , err := deviceIdentifier .EvalSymlinks (p )
86107 if err != nil {
87108 return "" , fmt .Errorf ("error reading target of symlink %q: %v" , p , err )
88109 }
0 commit comments