/* * Copyright (c) 2016 EMC Corporation * All Rights Reserved */ package com.emc.storageos.db.client.upgrade.callbacks; import java.net.URI; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.constraint.ContainmentConstraint; import com.emc.storageos.db.client.constraint.URIQueryResultList; import com.emc.storageos.db.client.model.DiscoveredDataObject; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.model.Volume; import com.emc.storageos.db.client.upgrade.BaseCustomMigrationCallback; import com.emc.storageos.db.client.util.NullColumnValueGetter; import com.emc.storageos.svcs.errorhandling.resources.MigrationCallbackException; /** * If we are upgrading from any version before 3.5, the thinlyProvisioned * property should be set to false on any ViPR-managed volumes. * * Before 3.5, the flag on VPLEX virtual volumes would just have been set * however the owning VirtualPool's thin provisioning property was set, * even though VPLEX didn't use this flag. Support for thin provisioning * was added to VPLEX version supported at the same time as ViPR 3.5. So, * any volumes created before that would need to be thinlyProvisioned=false. * * @author beachn * @since 3.5 */ public class VplexVolumeThinlyProvisionedMigration extends BaseCustomMigrationCallback { private static final Logger logger = LoggerFactory.getLogger(VplexVolumeThinlyProvisionedMigration.class); @Override public void process() throws MigrationCallbackException { DbClient dbClient = getDbClient(); int volumeUpdatedCount = 0; // cache a list of vplex URIs for performance reasons List<URI> vplexUris = new ArrayList<URI>(); List<StorageSystem> vplexes = getAllVplexStorageSystems(dbClient); for (StorageSystem vplex : vplexes) { if (null != vplex) { vplexUris.add(vplex.getId()); } } logger.info("found {} vplex storage systems in the database", vplexUris.size()); for (URI vplexUri : vplexUris) { URIQueryResultList result = new URIQueryResultList(); dbClient.queryByConstraint( ContainmentConstraint.Factory.getStorageDeviceVolumeConstraint(vplexUri), result); Iterator<Volume> volumesIter = dbClient.queryIterativeObjects(Volume.class, result); while (volumesIter.hasNext()) { Volume volume = volumesIter.next(); URI systemURI = volume.getStorageController(); if (!NullColumnValueGetter.isNullURI(systemURI)) { if (vplexUris.contains(systemURI)) { // This is a VPLEX volume. If we are upgrading from any version // before 3.5, if the thinlyProvisioned property is true, it should // be set to false on any ViPR-managed volumes. if (volume.getThinlyProvisioned()) { logger.info("updating thinlyProvisioned property on volume {} to false", volume.forDisplay()); volume.setThinlyProvisioned(false); dbClient.updateObject(volume); volumeUpdatedCount++; } } } } } logger.info("VplexVolumeThinlyProvisionedMigration completed, updated thinlyProvisioned to false on {} volumes", volumeUpdatedCount); } /** * Returns all VPLEX storage systems in ViPR. * * @param dbClient a database client reference * @return a List of StorageSystems that are "vplex" type */ private List<StorageSystem> getAllVplexStorageSystems(DbClient dbClient) { List<StorageSystem> vplexStorageSystems = new ArrayList<StorageSystem>(); List<URI> allStorageSystemUris = dbClient.queryByType(StorageSystem.class, true); List<StorageSystem> allStorageSystems = dbClient.queryObject(StorageSystem.class, allStorageSystemUris); for (StorageSystem storageSystem : allStorageSystems) { if ((storageSystem != null) && (DiscoveredDataObject.Type.vplex.name().equals(storageSystem.getSystemType()))) { vplexStorageSystems.add(storageSystem); } } return vplexStorageSystems; } }