@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
55you may not use this file except in compliance with the License.
66You may obtain a copy of the License at
77
8- http://www.apache.org/licenses/LICENSE-2.0
8+ http://www.apache.org/licenses/LICENSE-2.0
99
1010Unless required by applicable law or agreed to in writing, software
1111distributed under the License is distributed on an "AS IS" BASIS,
@@ -22,6 +22,7 @@ import (
2222 "io/ioutil"
2323 "os"
2424 "os/exec"
25+ "time"
2526
2627 "path"
2728 "path/filepath"
@@ -30,6 +31,13 @@ import (
3031 "k8s.io/klog/v2"
3132)
3233
34+ // Number of times to retry device discovery
35+ const discoveryRetries = 5
36+
37+ // sleep time in milliseconds between device discovery iterations.
38+ // May need to be adjusted to be longer if multipath discovery is not occuring quickly enough
39+ const discoverySleepTime = 500
40+
3341type ioHandler interface {
3442 ReadDir (dirname string ) ([]os.FileInfo , error )
3543 Lstat (name string ) (os.FileInfo , error )
@@ -160,22 +168,22 @@ func ResizeMultipathDevice(ctx context.Context, devicePath string) error {
160168
161169// PRIVATE
162170
163- //ReadDir calls the ReadDir function from ioutil package
171+ // ReadDir calls the ReadDir function from ioutil package
164172func (handler * OSioHandler ) ReadDir (dirname string ) ([]os.FileInfo , error ) {
165173 return ioutil .ReadDir (dirname )
166174}
167175
168- //Lstat calls the Lstat function from os package
176+ // Lstat calls the Lstat function from os package
169177func (handler * OSioHandler ) Lstat (name string ) (os.FileInfo , error ) {
170178 return os .Lstat (name )
171179}
172180
173- //EvalSymlinks calls EvalSymlinks from filepath package
181+ // EvalSymlinks calls EvalSymlinks from filepath package
174182func (handler * OSioHandler ) EvalSymlinks (path string ) (string , error ) {
175183 return filepath .EvalSymlinks (path )
176184}
177185
178- //WriteFile calls WriteFile from ioutil package
186+ // WriteFile calls WriteFile from ioutil package
179187func (handler * OSioHandler ) WriteFile (filename string , data []byte , perm os.FileMode ) error {
180188 return ioutil .WriteFile (filename , data , perm )
181189}
@@ -201,15 +209,17 @@ func discoverDevices(logger klog.Logger, c *Connector, io ioHandler) error {
201209
202210 c .Multipath = false
203211 c .OSPathName = ""
204- rescaned := false
212+ retries := 0
205213
206214 // two-phase search:
207215 // first phase, search existing device paths, if a multipath dm is found, exit loop
208216 // otherwise, in second phase, rescan scsi bus and search again, return with any findings
209- for true {
217+ for retries < discoveryRetries {
210218
211219 // Find the multipath device using WWN
212- dm , devices = findDiskById (logger , c .VolumeWWN , io )
220+ logger .V (5 ).Info ("Sleeping 0.5 seconds before device discovery" )
221+ time .Sleep (discoverySleepTime * time .Millisecond )
222+ dm , devices = FindDiskById (logger , c .VolumeWWN , io )
213223 logger .V (1 ).Info ("find disk by id returned" , "dm" , dm , "devices" , devices )
214224
215225 for _ , device := range devices {
@@ -227,15 +237,9 @@ func discoverDevices(logger klog.Logger, c *Connector, io ioHandler) error {
227237 break
228238 }
229239
230- // if a dm is found, exit loop
231- if rescaned || dm != "" {
232- break
233- }
234-
235- // rescan scsi hosts and search again
236240 logger .V (2 ).Info ("scsi rescan host" )
237241 scsiHostRescan (logger , io )
238- rescaned = true
242+ retries ++
239243 }
240244
241245 // if no disk matches input wwn, return error
@@ -249,8 +253,8 @@ func discoverDevices(logger klog.Logger, c *Connector, io ioHandler) error {
249253 return nil
250254}
251255
252- // findDiskById : given a wwn of the storage volume, find the multipath device and associated scsi devices
253- func findDiskById (logger klog.Logger , wwn string , io ioHandler ) (string , []string ) {
256+ // FindDiskById : given a wwn of the storage volume, find the multipath device and associated scsi devices
257+ func FindDiskById (logger klog.Logger , wwn string , io ioHandler ) (string , []string ) {
254258
255259 // Example multipath device naming:
256260 // Under /dev/disk/by-id:
@@ -260,21 +264,14 @@ func findDiskById(logger klog.Logger, wwn string, io ioHandler) (string, []strin
260264 // wwn-0x600c0ff0005460670a4ae16201000000 -> ../../dm-5
261265
262266 var devices []string
263- wwnPath := "wwn-0x" + wwn
264- devPath := "/dev/disk/by-id/"
265- logger .V (2 ).Info ("find disk by id" , "wwnPath" , wwnPath , "devPath" , devPath )
266-
267- if dirs , err := io .ReadDir (devPath ); err == nil {
268- for _ , f := range dirs {
269- name := f .Name ()
270- logger .V (4 ).Info ("checking" , "contains" , strings .Contains (name , wwnPath ), "name" , name )
271- if strings .Contains (name , wwnPath ) {
272- logger .V (2 ).Info ("found device, evaluate symbolic links" , "devPath" , devPath , "name" , name )
273- if dm , err1 := io .EvalSymlinks (devPath + name ); err1 == nil {
274- devices = FindLinkedDevicesOnMultipath (logger , dm , io )
275- return dm , devices
276- }
277- }
267+ devPath := "/dev/disk/by-id/wwn-0x" + wwn
268+ logger .V (2 ).Info ("find disk by id" , "devPath" , devPath )
269+
270+ if _ , err := os .Stat (devPath ); err == nil {
271+ logger .V (2 ).Info ("found device, evaluate symbolic links" , "devPath" , devPath )
272+ if dm , err1 := io .EvalSymlinks (devPath ); err1 == nil {
273+ devices = FindLinkedDevicesOnMultipath (logger , dm , io )
274+ return dm , devices
278275 }
279276 }
280277 return "" , devices
0 commit comments