@@ -114,26 +114,122 @@ func (m *mounter) GetDevicePath(ctx context.Context, volumeID string) (string, e
114
114
}
115
115
116
116
func (m * mounter ) getDevicePathBySerialID (volumeID string ) (string , error ) {
117
+ // First try XenServer device paths
118
+ for i := 'b' ; i <= 'z' ; i ++ {
119
+ devicePath := fmt .Sprintf ("/dev/xvd%c" , i )
120
+ fmt .Printf ("Checking XenServer device path: %s\n " , devicePath )
121
+
122
+ if _ , err := os .Stat (devicePath ); err == nil {
123
+ isBlock , err := m .IsBlockDevice (devicePath )
124
+ if err == nil && isBlock {
125
+ if m .verifyXenServerDevice (devicePath , volumeID ) {
126
+ fmt .Printf ("Found and verified XenServer device: %s\n " , devicePath )
127
+ return devicePath , nil
128
+ }
129
+ }
130
+ }
131
+ }
132
+
133
+ // Fall back to standard device paths
117
134
sourcePathPrefixes := []string {"virtio-" , "scsi-" , "scsi-0QEMU_QEMU_HARDDISK_" }
118
135
serial := diskUUIDToSerial (volumeID )
119
- fmt .Println ("Searching for device with serial: %s" , serial )
136
+ fmt .Printf ("Searching for device with serial: %s\n " , serial )
120
137
for _ , prefix := range sourcePathPrefixes {
121
138
source := filepath .Join (diskIDPath , prefix + serial )
122
- fmt .Println ("source" , source )
123
- fmt .Println ("Checking path: %s" , source )
139
+ fmt .Printf ("Checking path: %s\n " , source )
124
140
_ , err := os .Stat (source )
125
141
if err == nil {
126
142
return source , nil
127
143
}
128
144
if ! os .IsNotExist (err ) {
129
- fmt .Println ("Not found: %s" , err .Error ())
145
+ fmt .Printf ("Not found: %s\n " , err .Error ())
130
146
return "" , err
131
147
}
132
148
}
133
149
134
150
return "" , nil
135
151
}
136
152
153
+ func (m * mounter ) verifyXenServerDevice (devicePath string , volumeID string ) bool {
154
+ size , err := m .GetBlockSizeBytes (devicePath )
155
+ if err != nil {
156
+ fmt .Printf ("Failed to get device size: %v\n " , err )
157
+ return false
158
+ }
159
+ fmt .Printf ("Device size: %d bytes\n " , size )
160
+
161
+ mounted , err := m .isDeviceMounted (devicePath )
162
+ if err != nil {
163
+ fmt .Printf ("Failed to check if device is mounted: %v\n " , err )
164
+ return false
165
+ }
166
+ if mounted {
167
+ fmt .Printf ("Device is already mounted: %s\n " , devicePath )
168
+ return false
169
+ }
170
+
171
+ inUse , err := m .isDeviceInUse (devicePath )
172
+ if err != nil {
173
+ fmt .Printf ("Failed to check if device is in use: %v\n " , err )
174
+ return false
175
+ }
176
+ if inUse {
177
+ fmt .Printf ("Device is in use: %s\n " , devicePath )
178
+ return false
179
+ }
180
+
181
+ props , err := m .getDeviceProperties (devicePath )
182
+ if err != nil {
183
+ fmt .Printf ("Failed to get device properties: %v\n " , err )
184
+ return false
185
+ }
186
+ fmt .Printf ("Device properties: %v\n " , props )
187
+
188
+ return true
189
+ }
190
+
191
+ func (m * mounter ) isDeviceMounted (devicePath string ) (bool , error ) {
192
+ output , err := m .Exec .Command ("grep" , devicePath , "/proc/mounts" ).Output ()
193
+ if err != nil {
194
+ if strings .Contains (err .Error (), "exit status 1" ) {
195
+ return false , nil
196
+ }
197
+ return false , err
198
+ }
199
+ return len (output ) > 0 , nil
200
+ }
201
+
202
+ func (m * mounter ) isDeviceInUse (devicePath string ) (bool , error ) {
203
+ output , err := m .Exec .Command ("lsof" , devicePath ).Output ()
204
+ if err != nil {
205
+ if strings .Contains (err .Error (), "exit status 1" ) {
206
+ return false , nil
207
+ }
208
+ return false , err
209
+ }
210
+ return len (output ) > 0 , nil
211
+ }
212
+
213
+ func (m * mounter ) getDeviceProperties (devicePath string ) (map [string ]string , error ) {
214
+ output , err := m .Exec .Command ("udevadm" , "info" , "--query=property" , devicePath ).Output ()
215
+ if err != nil {
216
+ return nil , err
217
+ }
218
+
219
+ props := make (map [string ]string )
220
+ for _ , line := range strings .Split (string (output ), "\n " ) {
221
+ if line == "" {
222
+ continue
223
+ }
224
+ parts := strings .Split (line , "=" )
225
+ if len (parts ) == 2 {
226
+ props [parts [0 ]] = parts [1 ]
227
+ }
228
+ }
229
+
230
+ return props , nil
231
+ }
232
+
137
233
func (m * mounter ) probeVolume (ctx context.Context ) {
138
234
logger := klog .FromContext (ctx )
139
235
logger .V (2 ).Info ("Scanning SCSI host" )
0 commit comments