5656import org .apache .commons .math3 .stat .descriptive .moment .StandardDeviation ;
5757import org .apache .log4j .Logger ;
5858
59- import com .cloud .configuration .Config ;
6059import com .cloud .server .StatsCollector ;
6160import com .cloud .storage .DataStoreRole ;
6261import com .cloud .storage .SnapshotVO ;
62+ import com .cloud .storage .StorageManager ;
6363import com .cloud .storage .StorageService ;
6464import com .cloud .storage .StorageStats ;
6565import com .cloud .storage .dao .SnapshotDao ;
66- import com .cloud .utils .NumbersUtil ;
6766import com .cloud .utils .Pair ;
6867import com .cloud .utils .StringUtils ;
6968import com .cloud .utils .component .ManagerBase ;
@@ -133,7 +132,7 @@ public boolean offer(T task) {
133132
134133 @ Override
135134 public boolean configure (String name , Map <String , Object > params ) throws ConfigurationException {
136- numConcurrentCopyTasksPerSSVM = NumbersUtil . parseInt ( configDao . getValue ( Config . SecStorageMaxMigrateSessions .key ()), 2 );
135+ numConcurrentCopyTasksPerSSVM = StorageManager . SecStorageMaxMigrateSessions .value ( );
137136 return true ;
138137 }
139138
@@ -144,25 +143,18 @@ public MigrationResponse migrateData(Long srcDataStoreId, List<Long> destDatasto
144143 String message = null ;
145144
146145 migrationHelper .checkIfCompleteMigrationPossible (migrationPolicy , srcDataStoreId );
147-
148146 DataStore srcDatastore = dataStoreManager .getDataStore (srcDataStoreId , DataStoreRole .Image );
149147 Map <DataObject , Pair <List <SnapshotInfo >, Long >> snapshotChains = new HashMap <>();
150148 files = migrationHelper .getSortedValidSourcesList (srcDatastore , snapshotChains );
151149
152150 if (files .isEmpty ()) {
153151 return new MigrationResponse ("No files in Image store " +srcDatastore .getId ()+ " to migrate" , migrationPolicy .toString (), true );
154152 }
155-
156- // Create capacity class with free and total space, maybe id of ds too and use that as the value
157153 Map <Long , Pair <Long , Long >> storageCapacities = new Hashtable <>();
158-
159154 for (Long storeId : destDatastores ) {
160155 storageCapacities .put (storeId , new Pair <>(null , null ));
161156 }
162157 storageCapacities .put (srcDataStoreId , new Pair <>(null , null ));
163-
164- // If the migration policy is to completely migrate data from the given source Image Store, then set it's state
165- // to readonly
166158 if (migrationPolicy == MigrationPolicy .COMPLETE ) {
167159 s_logger .debug ("Setting source image store " +srcDatastore .getId ()+ " to read-only" );
168160 storageService .updateImageStoreStatus (srcDataStoreId , true );
@@ -172,8 +164,8 @@ public MigrationResponse migrateData(Long srcDataStoreId, List<Long> destDatasto
172164 double meanstddev = getStandardDeviation (storageCapacities );
173165 double threshold = ImageStoreImbalanceThreshold .value ();
174166 MigrationResponse response = null ;
175-
176- ThreadPoolExecutor executor = new ThreadPoolExecutor ( numConcurrentCopyTasksPerSSVM , numConcurrentCopyTasksPerSSVM , 30 , TimeUnit .MINUTES , new MigrateBlockingQueue <>(numConcurrentCopyTasksPerSSVM ));
167+ ThreadPoolExecutor executor = new ThreadPoolExecutor ( numConcurrentCopyTasksPerSSVM , numConcurrentCopyTasksPerSSVM , 30 ,
168+ TimeUnit .MINUTES , new MigrateBlockingQueue <>(numConcurrentCopyTasksPerSSVM ));
177169 Date start = new Date ();
178170 if (meanstddev < threshold && migrationPolicy == MigrationPolicy .BALANCE ) {
179171 s_logger .debug ("mean std deviation of the image stores is below threshold, no migration required" );
@@ -188,28 +180,14 @@ public MigrationResponse migrateData(Long srcDataStoreId, List<Long> destDatasto
188180 chosenFileForMigration = files .remove (0 );
189181 }
190182
191- // Choose datastore with maximum free capacity as the destination datastore for migration
192183 storageCapacities = getStorageCapacities (storageCapacities );
193184 List <Long > orderedDS = migrationHelper .sortDataStores (storageCapacities );
194185 Long destDatastoreId = orderedDS .get (0 );
195186
196- // If there aren't anymore files available for migration or no valid Image stores available for migration
197- // end the migration process
198187 if (chosenFileForMigration == null || destDatastoreId == null || destDatastoreId == srcDatastore .getId ()) {
199- if (destDatastoreId == srcDatastore .getId () && !files .isEmpty () ) {
200- if (migrationPolicy == MigrationPolicy .BALANCE ) {
201- s_logger .debug ("Migration completed : data stores have been balanced " );
202- message = "Image stores have been balanced" ;
203- success = true ;
204- } else {
205- message = "Files not completely migrated from " + srcDatastore .getId () +
206- " If you want to continue using the Image Store, please change the read-only status using 'update imagestore' command" ;
207- success = false ;
208- }
209- } else {
210- message = "Migration completed" ;
211- success = true ;
212- }
188+ Pair <String , Boolean > result = migrateCompleted (destDatastoreId , srcDatastore , files , migrationPolicy );
189+ message = result .first ();
190+ success = result .second ();
213191 break ;
214192 }
215193
@@ -218,24 +196,8 @@ public MigrationResponse migrateData(Long srcDataStoreId, List<Long> destDatasto
218196 continue ;
219197 }
220198
221- // If there is a benefit in migration of the chosen file to the destination store, then proceed with migration
222199 if (shouldMigrate (chosenFileForMigration , srcDatastore .getId (), destDatastoreId , storageCapacities , snapshotChains , migrationPolicy )) {
223- Long fileSize = migrationHelper .getFileSize (chosenFileForMigration , snapshotChains );
224- storageCapacities = assumeMigrate (storageCapacities , srcDatastore .getId (), destDatastoreId , fileSize );
225- long activeSsvms = migrationHelper .activeSSVMCount (srcDatastore );
226- long totalJobs = activeSsvms * numConcurrentCopyTasksPerSSVM ;
227- // Increase thread pool size with increase in number of SSVMs
228- if ( totalJobs > executor .getCorePoolSize ()) {
229- executor .setMaximumPoolSize ((int ) (totalJobs ));
230- executor .setCorePoolSize ((int ) (totalJobs ));
231- }
232-
233- MigrateDataTask task = new MigrateDataTask (chosenFileForMigration , srcDatastore , dataStoreManager .getDataStore (destDatastoreId , DataStoreRole .Image ));
234- if (chosenFileForMigration instanceof SnapshotInfo ) {
235- task .setSnapshotChains (snapshotChains );
236- }
237- futures .add ((executor .submit (task )));
238- s_logger .debug ("Migration of file " + chosenFileForMigration .getId () + " is initiated" );
200+ migrateAway (chosenFileForMigration , storageCapacities , snapshotChains , srcDatastore , destDatastoreId , executor , futures );
239201 } else {
240202 if (migrationPolicy == MigrationPolicy .BALANCE ) {
241203 message = "Migration completed and has successfully balanced the data objects among stores: " + StringUtils .join (storageCapacities .keySet (), "," );
@@ -247,11 +209,50 @@ public MigrationResponse migrateData(Long srcDataStoreId, List<Long> destDatasto
247209 }
248210 }
249211 Date end = new Date ();
250- // Migrate snapshots created during the migration process
251212 handleSnapshotMigration (srcDataStoreId , start , end , migrationPolicy , futures , storageCapacities , executor );
252213 return handleResponse (futures , migrationPolicy , message , success );
253214 }
254215
216+ protected Pair <String , Boolean > migrateCompleted (Long destDatastoreId , DataStore srcDatastore , List <DataObject > files , MigrationPolicy migrationPolicy ) {
217+ String message = "" ;
218+ boolean success = true ;
219+ if (destDatastoreId == srcDatastore .getId () && !files .isEmpty () ) {
220+ if (migrationPolicy == MigrationPolicy .BALANCE ) {
221+ s_logger .debug ("Migration completed : data stores have been balanced " );
222+ message = "Image stores have been balanced" ;
223+ success = true ;
224+ } else {
225+ message = "Files not completely migrated from " + srcDatastore .getId () +
226+ " If you want to continue using the Image Store, please change the read-only status using 'update imagestore' command" ;
227+ success = false ;
228+ }
229+ } else {
230+ message = "Migration completed" ;
231+ }
232+ return new Pair <String , Boolean >(message , success );
233+ }
234+
235+ protected void migrateAway (DataObject chosenFileForMigration , Map <Long , Pair <Long , Long >> storageCapacities ,
236+ Map <DataObject , Pair <List <SnapshotInfo >, Long >> snapshotChains , DataStore srcDatastore , Long destDatastoreId , ThreadPoolExecutor executor ,
237+ List <Future <AsyncCallFuture <DataObjectResult >>> futures ) {
238+ Long fileSize = migrationHelper .getFileSize (chosenFileForMigration , snapshotChains );
239+ storageCapacities = assumeMigrate (storageCapacities , srcDatastore .getId (), destDatastoreId , fileSize );
240+ long activeSsvms = migrationHelper .activeSSVMCount (srcDatastore );
241+ long totalJobs = activeSsvms * numConcurrentCopyTasksPerSSVM ;
242+ // Increase thread pool size with increase in number of SSVMs
243+ if ( totalJobs > executor .getCorePoolSize ()) {
244+ executor .setMaximumPoolSize ((int ) (totalJobs ));
245+ executor .setCorePoolSize ((int ) (totalJobs ));
246+ }
247+
248+ MigrateDataTask task = new MigrateDataTask (chosenFileForMigration , srcDatastore , dataStoreManager .getDataStore (destDatastoreId , DataStoreRole .Image ));
249+ if (chosenFileForMigration instanceof SnapshotInfo ) {
250+ task .setSnapshotChains (snapshotChains );
251+ }
252+ futures .add ((executor .submit (task )));
253+ s_logger .debug ("Migration of file " + chosenFileForMigration .getId () + " is initiated" );
254+ }
255+
255256
256257
257258 private MigrationResponse handleResponse (List <Future <AsyncCallFuture <DataObjectResult >>> futures , MigrationPolicy migrationPolicy , String message , boolean success ) {
@@ -271,7 +272,7 @@ private MigrationResponse handleResponse(List<Future<AsyncCallFuture<DataObjectR
271272 return new MigrationResponse (message , migrationPolicy .toString (), success );
272273 }
273274
274- private void handleSnapshotMigration (Long srcDataStoreId , Date start , Date end , MigrationPolicy policy ,
275+ private void handleSnapshotMigration (Long srcDataStoreId , Date start , Date end , MigrationPolicy policy ,
275276 List <Future <AsyncCallFuture <DataObjectResult >>> futures , Map <Long , Pair <Long , Long >> storageCapacities , ThreadPoolExecutor executor ) {
276277 DataStore srcDatastore = dataStoreManager .getDataStore (srcDataStoreId , DataStoreRole .Image );
277278 List <SnapshotDataStoreVO > snaps = snapshotDataStoreDao .findSnapshots (srcDataStoreId , start , end );
0 commit comments