@@ -1088,6 +1088,8 @@ private Answer backupSnapshotFromManagedStorage(final CopyCommand cmd) {
10881088
10891089 logger .info ("backupSnapshotFromManagedStorage: Device available at {}" , deviceByPath );
10901090
1091+ verifyDeviceReadable (deviceByPath , 30 );
1092+
10911093 secondaryStorage = storagePoolMgr .getStoragePoolByURI (nfsImageStore .getUrl ());
10921094
10931095 final String snapshotRelPath = destSnapshot .getPath ();
@@ -1130,6 +1132,37 @@ private Answer backupSnapshotFromManagedStorage(final CopyCommand cmd) {
11301132 }
11311133 }
11321134
1135+ private void verifyDeviceReadable (String devicePath , int timeoutSeconds ) {
1136+ logger .info ("verifyDeviceReadable: Testing read access to device {}" , devicePath );
1137+
1138+ Script script = new Script ("/bin/dd" , timeoutSeconds * 1000L , logger );
1139+ script .add ("if=" + devicePath );
1140+ script .add ("bs=64k" );
1141+ script .add ("count=16" ); // Read 1MB
1142+ script .add ("iflag=direct" );
1143+ script .add ("of=/dev/null" );
1144+
1145+ long startTime = System .currentTimeMillis ();
1146+ String result = script .execute ();
1147+ long elapsed = System .currentTimeMillis () - startTime ;
1148+
1149+ if (result != null ) {
1150+ throw new CloudRuntimeException ("verifyDeviceReadable: Device " + devicePath +
1151+ " is not readable (error: " + result + "). The iSCSI LUN may be offline, " +
1152+ "unmapped, or experiencing I/O errors." );
1153+ }
1154+
1155+ // If 1MB read took more than 10 seconds, warn about slow throughput
1156+ if (elapsed > 10000 ) {
1157+ long throughputKBps = (1024 * 1000 ) / elapsed ;
1158+ logger .warn ("verifyDeviceReadable: Device {} has very slow throughput: {} kB/s " +
1159+ "(1MB read took {}ms). The qemu-img convert will be extremely slow." ,
1160+ devicePath , throughputKBps , elapsed );
1161+ } else {
1162+ logger .info ("verifyDeviceReadable: Device {} is readable (1MB read completed in {}ms)" , devicePath , elapsed );
1163+ }
1164+ }
1165+
11331166 /**
11341167 * Ensures an iSCSI session is active and rescanned so that the target LUN is visible.
11351168 * Handles three scenarios:
0 commit comments