@@ -80,9 +80,9 @@ func (m *mounter) GetBlockSizeBytes(devicePath string) (int64, error) {
8080
8181func (m * mounter ) GetDevicePath (ctx context.Context , volumeID string ) (string , error ) {
8282 backoff := wait.Backoff {
83- Duration : 1 * time .Second ,
84- Factor : 1.1 ,
85- Steps : 15 ,
83+ Duration : 2 * time .Second ,
84+ Factor : 1.5 ,
85+ Steps : 20 ,
8686 }
8787
8888 var devicePath string
@@ -111,6 +111,24 @@ func (m *mounter) GetDevicePath(ctx context.Context, volumeID string) (string, e
111111}
112112
113113func (m * mounter ) getDevicePathBySerialID (volumeID string ) (string , error ) {
114+ // First try XenServer device paths
115+ xenDevicePath , err := m .getDevicePathForXenServer (volumeID )
116+ if err != nil {
117+ fmt .Printf ("Failed to get XenServer device path: %v\n " , err )
118+ }
119+ if xenDevicePath != "" {
120+ return xenDevicePath , nil
121+ }
122+
123+ // Try VMware device paths
124+ vmwareDevicePath , err := m .getDevicePathForVMware (volumeID )
125+ if err != nil {
126+ fmt .Printf ("Failed to get VMware device path: %v\n " , err )
127+ }
128+ if vmwareDevicePath != "" {
129+ return vmwareDevicePath , nil
130+ }
131+ // Fall back to standard device paths (for KVM)
114132 sourcePathPrefixes := []string {"virtio-" , "scsi-" , "scsi-0QEMU_QEMU_HARDDISK_" }
115133 serial := diskUUIDToSerial (volumeID )
116134 for _ , prefix := range sourcePathPrefixes {
@@ -120,13 +138,150 @@ func (m *mounter) getDevicePathBySerialID(volumeID string) (string, error) {
120138 return source , nil
121139 }
122140 if ! os .IsNotExist (err ) {
141+ fmt .Printf ("Not found: %s\n " , err .Error ())
123142 return "" , err
124143 }
125144 }
126145
127146 return "" , nil
128147}
129148
149+ func (m * mounter ) getDevicePathForXenServer (volumeID string ) (string , error ) {
150+ for i := 'b' ; i <= 'z' ; i ++ {
151+ devicePath := fmt .Sprintf ("/dev/xvd%c" , i )
152+ fmt .Printf ("Checking XenServer device path: %s\n " , devicePath )
153+
154+ if _ , err := os .Stat (devicePath ); err == nil {
155+ isBlock , err := m .IsBlockDevice (devicePath )
156+ if err == nil && isBlock {
157+ if m .verifyXenServerDevice (devicePath , volumeID ) {
158+ fmt .Printf ("Found and verified XenServer device: %s\n " , devicePath )
159+ return devicePath , nil
160+ }
161+ }
162+ }
163+ }
164+ return "" , fmt .Errorf ("device not found for volume %s" , volumeID )
165+ }
166+
167+ func (m * mounter ) verifyXenServerDevice (devicePath string , volumeID string ) bool {
168+ size , err := m .GetBlockSizeBytes (devicePath )
169+ if err != nil {
170+ fmt .Printf ("Failed to get device size: %v\n " , err )
171+ return false
172+ }
173+ fmt .Printf ("Device size: %d bytes\n " , size )
174+
175+ mounted , err := m .isDeviceMounted (devicePath )
176+ if err != nil {
177+ fmt .Printf ("Failed to check if device is mounted: %v\n " , err )
178+ return false
179+ }
180+ if mounted {
181+ fmt .Printf ("Device is already mounted: %s\n " , devicePath )
182+ return false
183+ }
184+
185+ props , err := m .getDeviceProperties (devicePath )
186+ if err != nil {
187+ fmt .Printf ("Failed to get device properties: %v\n " , err )
188+ return false
189+ }
190+ fmt .Printf ("Device properties: %v\n " , props )
191+
192+ return true
193+ }
194+
195+ func (m * mounter ) getDevicePathForVMware (volumeID string ) (string , error ) {
196+ // Loop through /dev/sdb to /dev/sdz (/dev/sda -> the root disk)
197+ for i := 'b' ; i <= 'z' ; i ++ {
198+ devicePath := fmt .Sprintf ("/dev/sd%c" , i )
199+ fmt .Printf ("Checking VMware device path: %s\n " , devicePath )
200+
201+ if _ , err := os .Stat (devicePath ); err == nil {
202+ isBlock , err := m .IsBlockDevice (devicePath )
203+ if err == nil && isBlock {
204+ // Use the same verification as for XenServer
205+ if m .verifyVMwareDevice (devicePath , volumeID ) {
206+ fmt .Printf ("Found and verified VMware device: %s\n " , devicePath )
207+ return devicePath , nil
208+ }
209+ }
210+ }
211+ }
212+ return "" , fmt .Errorf ("device not found for volume %s" , volumeID )
213+ }
214+
215+ func (m * mounter ) verifyVMwareDevice (devicePath string , volumeID string ) bool {
216+ size , err := m .GetBlockSizeBytes (devicePath )
217+ if err != nil {
218+ fmt .Printf ("Failed to get device size: %v\n " , err )
219+ return false
220+ }
221+ fmt .Printf ("Device size: %d bytes\n " , size )
222+
223+ mounted , err := m .isDeviceMounted (devicePath )
224+ if err != nil {
225+ fmt .Printf ("Failed to check if device is mounted: %v\n " , err )
226+ return false
227+ }
228+ if mounted {
229+ fmt .Printf ("Device is already mounted: %s\n " , devicePath )
230+ return false
231+ }
232+
233+ props , err := m .getDeviceProperties (devicePath )
234+ if err != nil {
235+ fmt .Printf ("Failed to get device properties: %v\n " , err )
236+ return false
237+ }
238+ fmt .Printf ("Device properties: %v\n " , props )
239+
240+ return true
241+ }
242+
243+ func (m * mounter ) isDeviceMounted (devicePath string ) (bool , error ) {
244+ output , err := m .Exec .Command ("grep" , devicePath , "/proc/mounts" ).Output ()
245+ if err != nil {
246+ if strings .Contains (err .Error (), "exit status 1" ) {
247+ return false , nil
248+ }
249+ return false , err
250+ }
251+ return len (output ) > 0 , nil
252+ }
253+
254+ func (m * mounter ) isDeviceInUse (devicePath string ) (bool , error ) {
255+ output , err := m .Exec .Command ("lsof" , devicePath ).Output ()
256+ if err != nil {
257+ if strings .Contains (err .Error (), "exit status 1" ) {
258+ return false , nil
259+ }
260+ return false , err
261+ }
262+ return len (output ) > 0 , nil
263+ }
264+
265+ func (m * mounter ) getDeviceProperties (devicePath string ) (map [string ]string , error ) {
266+ output , err := m .Exec .Command ("udevadm" , "info" , "--query=property" , devicePath ).Output ()
267+ if err != nil {
268+ return nil , err
269+ }
270+
271+ props := make (map [string ]string )
272+ for _ , line := range strings .Split (string (output ), "\n " ) {
273+ if line == "" {
274+ continue
275+ }
276+ parts := strings .Split (line , "=" )
277+ if len (parts ) == 2 {
278+ props [parts [0 ]] = parts [1 ]
279+ }
280+ }
281+
282+ return props , nil
283+ }
284+
130285func (m * mounter ) probeVolume (ctx context.Context ) {
131286 logger := klog .FromContext (ctx )
132287 logger .V (2 ).Info ("Scanning SCSI host" )
0 commit comments