3535import javax .inject .Inject ;
3636import javax .naming .ConfigurationException ;
3737
38+ import com .cloud .storage .Volume ;
3839import org .apache .cloudstack .api .response .MigrationResponse ;
3940import org .apache .cloudstack .engine .orchestration .service .StorageOrchestrationService ;
4041import org .apache .cloudstack .engine .subsystem .api .storage .DataObject ;
4445import org .apache .cloudstack .engine .subsystem .api .storage .SecondaryStorageService .DataObjectResult ;
4546import org .apache .cloudstack .engine .subsystem .api .storage .SnapshotDataFactory ;
4647import org .apache .cloudstack .engine .subsystem .api .storage .SnapshotInfo ;
48+ import org .apache .cloudstack .engine .subsystem .api .storage .TemplateInfo ;
49+ import org .apache .cloudstack .engine .subsystem .api .storage .VolumeInfo ;
4750import org .apache .cloudstack .framework .async .AsyncCallFuture ;
4851import org .apache .cloudstack .framework .config .ConfigKey ;
4952import org .apache .cloudstack .framework .config .Configurable ;
@@ -147,15 +150,15 @@ public MigrationResponse migrateData(Long srcDataStoreId, List<Long> destDatasto
147150 files = migrationHelper .getSortedValidSourcesList (srcDatastore , snapshotChains );
148151
149152 if (files .isEmpty ()) {
150- return new MigrationResponse ("No files in Image store " + srcDatastore .getId ()+ " to migrate" , migrationPolicy .toString (), true );
153+ return new MigrationResponse (String . format ( "No files in Image store: %s to migrate" , srcDatastore .getId ()) , migrationPolicy .toString (), true );
151154 }
152155 Map <Long , Pair <Long , Long >> storageCapacities = new Hashtable <>();
153156 for (Long storeId : destDatastores ) {
154157 storageCapacities .put (storeId , new Pair <>(null , null ));
155158 }
156159 storageCapacities .put (srcDataStoreId , new Pair <>(null , null ));
157160 if (migrationPolicy == MigrationPolicy .COMPLETE ) {
158- s_logger .debug ("Setting source image store " + srcDatastore . getId ()+ " to read-only" );
161+ s_logger .debug (String . format ( "Setting source image store: %s to read-only" , srcDatastore . getId ()) );
159162 storageService .updateImageStoreStatus (srcDataStoreId , true );
160163 }
161164
@@ -172,6 +175,7 @@ public MigrationResponse migrateData(Long srcDataStoreId, List<Long> destDatasto
172175 return response ;
173176 }
174177
178+ int skipped = 0 ;
175179 List <Future <AsyncCallFuture <DataObjectResult >>> futures = new ArrayList <>();
176180 while (true ) {
177181 DataObject chosenFileForMigration = null ;
@@ -184,7 +188,7 @@ public MigrationResponse migrateData(Long srcDataStoreId, List<Long> destDatasto
184188 Long destDatastoreId = orderedDS .get (0 );
185189
186190 if (chosenFileForMigration == null || destDatastoreId == null || (destDatastoreId == srcDatastore .getId () && migrationPolicy == MigrationPolicy .BALANCE ) ) {
187- Pair <String , Boolean > result = migrateCompleted (destDatastoreId , srcDatastore , files , migrationPolicy );
191+ Pair <String , Boolean > result = migrateCompleted (destDatastoreId , srcDatastore , files , migrationPolicy , skipped );
188192 message = result .first ();
189193 success = result .second ();
190194 break ;
@@ -195,7 +199,8 @@ public MigrationResponse migrateData(Long srcDataStoreId, List<Long> destDatasto
195199 }
196200
197201 if (chosenFileForMigration .getSize () > storageCapacities .get (destDatastoreId ).first ()) {
198- s_logger .debug ("file: " + chosenFileForMigration .getId () + " too large to be migrated to " + destDatastoreId );
202+ s_logger .debug (String .format ("%s: %s too large to be migrated to %s" , getObjectType (chosenFileForMigration ), chosenFileForMigration .getUuid (), destDatastoreId ));
203+ skipped += 1 ;
199204 continue ;
200205 }
201206
@@ -215,7 +220,20 @@ public MigrationResponse migrateData(Long srcDataStoreId, List<Long> destDatasto
215220 return handleResponse (futures , migrationPolicy , message , success );
216221 }
217222
218- protected Pair <String , Boolean > migrateCompleted (Long destDatastoreId , DataStore srcDatastore , List <DataObject > files , MigrationPolicy migrationPolicy ) {
223+ private String getObjectType (DataObject dataObject ) {
224+ if (dataObject instanceof VolumeInfo ) {
225+ return "volume" ;
226+ }
227+ if (dataObject instanceof SnapshotInfo ) {
228+ return "snapshot" ;
229+ }
230+ if (dataObject instanceof TemplateInfo ) {
231+ return "template" ;
232+ }
233+ return "file" ;
234+ }
235+
236+ protected Pair <String , Boolean > migrateCompleted (Long destDatastoreId , DataStore srcDatastore , List <DataObject > files , MigrationPolicy migrationPolicy , int skipped ) {
219237 String message = "" ;
220238 boolean success = true ;
221239 if (destDatastoreId == srcDatastore .getId () && !files .isEmpty ()) {
@@ -233,6 +251,10 @@ protected Pair<String, Boolean> migrateCompleted(Long destDatastoreId, DataStore
233251 }
234252 } else {
235253 message = "Migration completed" ;
254+ if (migrationPolicy == MigrationPolicy .COMPLETE && skipped != 0 ) {
255+ message += ". Not all data objects were migrated. Some were probably skipped due to lack of storage capacity." ;
256+ success = false ;
257+ }
236258 }
237259 return new Pair <String , Boolean >(message , success );
238260 }
@@ -255,7 +277,7 @@ protected Map<Long, Pair<Long, Long>> migrateAway(DataObject chosenFileForMigrat
255277 task .setSnapshotChains (snapshotChains );
256278 }
257279 futures .add ((executor .submit (task )));
258- s_logger .debug ("Migration of file " + chosenFileForMigration .getId () + " is initiated" );
280+ s_logger .debug (String . format ( "Migration of %s: %s is initiated. " , getObjectType ( chosenFileForMigration ), chosenFileForMigration .getUuid ()) );
259281 return storageCapacities ;
260282 }
261283
0 commit comments