@@ -114,26 +114,122 @@ func (m *mounter) GetDevicePath(ctx context.Context, volumeID string) (string, e
114114}
115115
116116func (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
117134 sourcePathPrefixes := []string {"virtio-" , "scsi-" , "scsi-0QEMU_QEMU_HARDDISK_" }
118135 serial := diskUUIDToSerial (volumeID )
119- fmt .Println ("Searching for device with serial: %s" , serial )
136+ fmt .Printf ("Searching for device with serial: %s\n " , serial )
120137 for _ , prefix := range sourcePathPrefixes {
121138 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 )
124140 _ , err := os .Stat (source )
125141 if err == nil {
126142 return source , nil
127143 }
128144 if ! os .IsNotExist (err ) {
129- fmt .Println ("Not found: %s" , err .Error ())
145+ fmt .Printf ("Not found: %s\n " , err .Error ())
130146 return "" , err
131147 }
132148 }
133149
134150 return "" , nil
135151}
136152
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+
137233func (m * mounter ) probeVolume (ctx context.Context ) {
138234 logger := klog .FromContext (ctx )
139235 logger .V (2 ).Info ("Scanning SCSI host" )
0 commit comments