2222import java .util .Collections ;
2323import java .util .Comparator ;
2424import java .util .HashMap ;
25+ import java .util .HashSet ;
2526import java .util .LinkedHashMap ;
2627import java .util .LinkedList ;
2728import java .util .List ;
2829import java .util .Map ;
30+ import java .util .Set ;
2931
3032import javax .inject .Inject ;
3133
@@ -206,12 +208,22 @@ public int compare(DataObject o1, DataObject o2) {
206208
207209 protected List <DataObject > getAllReadyTemplates (DataStore srcDataStore , Map <DataObject , Pair <List <TemplateInfo >, Long >> childTemplates , List <TemplateDataStoreVO > templates ) {
208210 List <TemplateInfo > files = new LinkedList <>();
211+ Set <Long > idsForMigration = new HashSet <>();
212+
209213 for (TemplateDataStoreVO template : templates ) {
210- VMTemplateVO templateVO = templateDao .findById (template .getTemplateId ());
211- if (shouldMigrateTemplate (template , templateVO )) {
212- files .add (templateFactory .getTemplate (template .getTemplateId (), srcDataStore ));
214+ long templateId = template .getTemplateId ();
215+ if (idsForMigration .contains (templateId )) {
216+ logger .warn ("Template store reference [{}] is duplicated; not considering it for migration." , template );
217+ continue ;
218+ }
219+ VMTemplateVO templateVO = templateDao .findById (templateId );
220+ if (!shouldMigrateTemplate (template , templateVO )) {
221+ continue ;
213222 }
223+ files .add (templateFactory .getTemplate (template .getTemplateId (), srcDataStore ));
224+ idsForMigration .add (templateId );
214225 }
226+
215227 for (TemplateInfo template : files ) {
216228 List <VMTemplateVO > children = templateDao .listByParentTemplatetId (template .getId ());
217229 List <TemplateInfo > temps = new ArrayList <>();
@@ -221,6 +233,7 @@ protected List<DataObject> getAllReadyTemplates(DataStore srcDataStore, Map<Data
221233 }
222234 childTemplates .put (template , new Pair <>(temps , getTotalChainSize (temps )));
223235 }
236+
224237 return (List <DataObject >) (List <?>) files ;
225238 }
226239
@@ -263,16 +276,37 @@ protected boolean shouldMigrateTemplate(TemplateDataStoreVO template, VMTemplate
263276 */
264277 protected List <DataObject > getAllReadySnapshotsAndChains (DataStore srcDataStore , Map <DataObject , Pair <List <SnapshotInfo >, Long >> snapshotChains , List <SnapshotDataStoreVO > snapshots ) {
265278 List <SnapshotInfo > files = new LinkedList <>();
279+ Set <Long > idsForMigration = new HashSet <>();
280+
266281 for (SnapshotDataStoreVO snapshot : snapshots ) {
267- SnapshotVO snapshotVO = snapshotDao .findById (snapshot .getSnapshotId ());
268- if (snapshot .getState () == ObjectInDataStoreStateMachine .State .Ready &&
269- snapshotVO != null && snapshotVO .getHypervisorType () != Hypervisor .HypervisorType .Simulator
270- && snapshot .getParentSnapshotId () == 0 ) {
271- SnapshotInfo snap = snapshotFactory .getSnapshot (snapshotVO .getSnapshotId (), snapshot .getDataStoreId (), snapshot .getRole ());
272- if (snap != null ) {
273- files .add (snap );
274- }
282+ long snapshotId = snapshot .getSnapshotId ();
283+ if (idsForMigration .contains (snapshotId )) {
284+ logger .warn ("Snapshot store reference [{}] is duplicated; not considering it for migration." , snapshot );
285+ continue ;
286+ }
287+ if (snapshot .getState () != ObjectInDataStoreStateMachine .State .Ready ) {
288+ logger .warn ("Not migrating snapshot [{}] because its state is not ready." , snapshot );
289+ continue ;
290+ }
291+ SnapshotVO snapshotVO = snapshotDao .findById (snapshotId );
292+ if (snapshotVO == null ) {
293+ logger .debug ("Not migrating snapshot [{}] because we could not find its database entry." , snapshot );
294+ continue ;
295+ }
296+ if (snapshotVO .getHypervisorType () == Hypervisor .HypervisorType .Simulator ) {
297+ logger .debug ("Not migrating snapshot [{}] because its hypervisor type is simulator." , snapshot );
298+ continue ;
275299 }
300+ if (snapshot .getParentSnapshotId () != 0 ) {
301+ continue ; // The child snapshot will be migrated in the for loop below.
302+ }
303+ SnapshotInfo snap = snapshotFactory .getSnapshot (snapshotVO .getSnapshotId (), snapshot .getDataStoreId (), snapshot .getRole ());
304+ if (snap == null ) {
305+ logger .debug ("Not migrating snapshot [{}] because we could not get its information." , snapshot );
306+ continue ;
307+ }
308+ files .add (snap );
309+ idsForMigration .add (snapshotId );
276310 }
277311
278312 for (SnapshotInfo parent : files ) {
@@ -285,7 +319,7 @@ protected List<DataObject> getAllReadySnapshotsAndChains(DataStore srcDataStore,
285319 chain .addAll (children );
286320 }
287321 }
288- snapshotChains .put (parent , new Pair <List < SnapshotInfo >, Long >(chain , getTotalChainSize (chain )));
322+ snapshotChains .put (parent , new Pair <>(chain , getTotalChainSize (chain )));
289323 }
290324
291325 return (List <DataObject >) (List <?>) files ;
@@ -306,14 +340,31 @@ protected Long getTotalChainSize(List<? extends DataObject> chain) {
306340
307341 protected List <DataObject > getAllReadyVolumes (DataStore srcDataStore , List <VolumeDataStoreVO > volumes ) {
308342 List <DataObject > files = new LinkedList <>();
343+ Set <Long > idsForMigration = new HashSet <>();
344+
309345 for (VolumeDataStoreVO volume : volumes ) {
310- if (volume .getState () == ObjectInDataStoreStateMachine .State .Ready ) {
311- VolumeInfo volumeInfo = volumeFactory .getVolume (volume .getVolumeId (), srcDataStore );
312- if (volumeInfo != null && volumeInfo .getHypervisorType () != Hypervisor .HypervisorType .Simulator ) {
313- files .add (volumeInfo );
314- }
346+ long volumeId = volume .getVolumeId ();
347+ if (idsForMigration .contains (volumeId )) {
348+ logger .warn ("Volume store reference [{}] is duplicated; not considering it for migration." , volume );
349+ continue ;
315350 }
351+ if (volume .getState () != ObjectInDataStoreStateMachine .State .Ready ) {
352+ logger .debug ("Not migrating volume [{}] because its state is not ready." , volume );
353+ continue ;
354+ }
355+ VolumeInfo volumeInfo = volumeFactory .getVolume (volume .getVolumeId (), srcDataStore );
356+ if (volumeInfo == null ) {
357+ logger .debug ("Not migrating volume [{}] because we could not get its information." , volume );
358+ continue ;
359+ }
360+ if (volumeInfo .getHypervisorType () == Hypervisor .HypervisorType .Simulator ) {
361+ logger .debug ("Not migrating volume [{}] because its hypervisor type is simulator." , volume );
362+ continue ;
363+ }
364+ files .add (volumeInfo );
365+ idsForMigration .add (volumeId );
316366 }
367+
317368 return files ;
318369 }
319370
@@ -325,10 +376,9 @@ protected List<DataObject> getAllReadyVolumes(DataStore srcDataStore) {
325376 /** Returns the count of active SSVMs - SSVM with agents in connected state, so as to dynamically increase the thread pool
326377 * size when SSVMs scale
327378 */
328- protected int activeSSVMCount (DataStore dataStore ) {
329- long datacenterId = dataStore .getScope ().getScopeId ();
379+ protected int activeSSVMCount (Long zoneId ) {
330380 List <SecondaryStorageVmVO > ssvms =
331- secStorageVmDao .getSecStorageVmListInStates (null , datacenterId , VirtualMachine .State .Running , VirtualMachine .State .Migrating );
381+ secStorageVmDao .getSecStorageVmListInStates (null , zoneId , VirtualMachine .State .Running , VirtualMachine .State .Migrating );
332382 int activeSSVMs = 0 ;
333383 for (SecondaryStorageVmVO vm : ssvms ) {
334384 String name = "s-" +vm .getId ()+"-VM" ;
0 commit comments