Search in sources :

Example 1 with VPlexScheduler

use of com.emc.storageos.api.service.impl.placement.VPlexScheduler in project coprhd-controller by CoprHD.

the class MigrationService method migrateVolume.

/**
 * Performs a non-disruptive migration for the passed VPLEX virtual volume.
 * The backend volume of the VPLEX volume that is migrated is the backend
 * volume on the passed source storage system. The volume is migrated to the
 * passed target storage system, which must be connected to the same VPLEX
 * cluster as the source storage system.
 *
 * @prereq none
 *
 * @param migrateParam A reference to the migration parameters.
 * @deprecated Use the Change Virtual Pool API instead
 * @brief Perform a non-disruptive migration for a VPLEX volume.
 * @return A TaskResourceRep for the volume being migrated.
 * @throws InternalException
 */
@Deprecated
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@CheckPermission(roles = { Role.SYSTEM_ADMIN, Role.SYSTEM_ADMIN })
public TaskResourceRep migrateVolume(MigrationParam migrateParam) throws InternalException {
    // Create a unique task id.
    String taskId = UUID.randomUUID().toString();
    s_logger.info("Migrate volume {} from storage system {} to storage system {}", new Object[] { migrateParam.getVolume(), migrateParam.getSrcStorageSystem(), migrateParam.getTgtStorageSystem() });
    // Verify the requested volume supports migration.
    Volume vplexVolume = verifyRequestedVolumeSupportsMigration(migrateParam.getVolume());
    s_logger.debug("Verfified requested volume");
    // Make sure that we don't have some pending
    // operation against the volume
    checkForPendingTasks(Arrays.asList(vplexVolume.getTenant().getURI()), Arrays.asList(vplexVolume));
    // Determine the backend volume of the requested VPlex volume that
    // is to be migrated. It is the volume on the passed source storage
    // system.
    Volume migrationSrc = getMigrationSource(vplexVolume, migrateParam.getSrcStorageSystem());
    s_logger.debug("Migration source is {}", migrationSrc.getId());
    // The project for the migration target will be the same as that
    // of the source.
    Project migrationTgtProject = _permissionsHelper.getObjectById(migrationSrc.getProject().getURI(), Project.class);
    s_logger.debug("Migration target project is {}", migrationTgtProject.getId());
    // The VirtualArray for the migration target will be the same as
    // that of the source.
    VirtualArray migrationTargetVarray = _permissionsHelper.getObjectById(migrationSrc.getVirtualArray(), VirtualArray.class);
    s_logger.debug("Migration target VirtualArray is {}", migrationTargetVarray.getId());
    // Verify the requested target storage system exists and
    // is a system to which the migration source volume can
    // be migrated.
    verifyTargetStorageSystemForMigration(migrateParam.getVolume(), vplexVolume.getStorageController(), migrateParam.getSrcStorageSystem(), migrateParam.getTgtStorageSystem());
    s_logger.debug("Verified target storage system {}", migrateParam.getTgtStorageSystem());
    // Get the VirtualPool for the migration target.
    VirtualPool migrationTgtCos = getVirtualPoolForMigrationTarget(migrateParam.getVirtualPool(), vplexVolume, migrationSrc);
    s_logger.debug("Migration target VirtualPool is {}", migrationTgtCos.getId());
    // Get the VPlex storage system for the virtual volume.
    URI vplexSystemURI = vplexVolume.getStorageController();
    Set<URI> requestedVPlexSystems = new HashSet<URI>();
    requestedVPlexSystems.add(vplexSystemURI);
    // Get a placement recommendation on the requested target storage
    // system connected to the VPlex storage system of the VPlex volume.
    VPlexScheduler vplexScheduler = _vplexBlockServiceApi.getBlockScheduler();
    VirtualPoolCapabilityValuesWrapper cosWrapper = new VirtualPoolCapabilityValuesWrapper();
    cosWrapper.put(VirtualPoolCapabilityValuesWrapper.SIZE, migrationSrc.getCapacity());
    cosWrapper.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, new Integer(1));
    List<Recommendation> recommendations = vplexScheduler.scheduleStorage(migrationTargetVarray, requestedVPlexSystems, migrateParam.getTgtStorageSystem(), migrationTgtCos, false, null, null, cosWrapper, migrationTgtProject, VpoolUse.ROOT, new HashMap<VpoolUse, List<Recommendation>>());
    if (recommendations.isEmpty()) {
        throw APIException.badRequests.noStorageFoundForVolumeMigration(migrationTgtCos.getLabel(), migrationTargetVarray.getLabel(), vplexVolume.getId());
    }
    s_logger.debug("Got recommendation for migration target");
    // There should be a single recommendation.
    Recommendation recommendation = recommendations.get(0);
    URI recommendedSystem = recommendation.getSourceStorageSystem();
    URI recommendedPool = recommendation.getSourceStoragePool();
    s_logger.debug("Recommendation storage system is {}", recommendedSystem);
    s_logger.debug("Recommendation storage pool is {}", recommendedPool);
    // Prepare the migration target.
    List<URI> migrationTgts = new ArrayList<URI>();
    Map<URI, URI> poolTgtMap = new HashMap<URI, URI>();
    Long size = _vplexBlockServiceApi.getVolumeCapacity(migrationSrc);
    Volume migrationTgt = VPlexBlockServiceApiImpl.prepareVolumeForRequest(size, migrationTgtProject, migrationTargetVarray, migrationTgtCos, recommendedSystem, recommendedPool, migrationSrc.getLabel(), ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME, taskId, _dbClient);
    URI migrationTgtURI = migrationTgt.getId();
    migrationTgts.add(migrationTgtURI);
    poolTgtMap.put(recommendedPool, migrationTgtURI);
    s_logger.debug("Prepared migration target volume {}", migrationTgtURI);
    // Prepare the migration.
    Map<URI, URI> migrationsMap = new HashMap<URI, URI>();
    Migration migration = _vplexBlockServiceApi.prepareMigration(migrateParam.getVolume(), migrationSrc.getId(), migrationTgt.getId(), taskId);
    migrationsMap.put(migrationTgtURI, migration.getId());
    s_logger.debug("Prepared migration {}", migration.getId());
    // Create a task for the virtual volume being migrated and set the
    // initial task state to pending.
    Operation op = _dbClient.createTaskOpStatus(Volume.class, vplexVolume.getId(), taskId, ResourceOperationTypeEnum.MIGRATE_BLOCK_VOLUME);
    TaskResourceRep task = toTask(vplexVolume, taskId, op);
    s_logger.debug("Created task for volume {}", migrateParam.getVolume());
    try {
        VPlexController controller = _vplexBlockServiceApi.getController();
        String successMsg = String.format("Migration succeeded for volume %s", migrateParam.getVolume());
        String failMsg = String.format("Migration failed for volume %s", migrateParam.getVolume());
        controller.migrateVolumes(vplexSystemURI, migrateParam.getVolume(), migrationTgts, migrationsMap, poolTgtMap, (migrateParam.getVirtualPool() != null ? migrateParam.getVirtualPool() : null), null, successMsg, failMsg, null, taskId, null);
        s_logger.debug("Got VPlex controller and created migration workflow");
    } catch (InternalException e) {
        s_logger.error("Controller Error", e);
        String errMsg = String.format("Controller Error: %s", e.getMessage());
        task.setState(Operation.Status.error.name());
        task.setMessage(errMsg);
        Operation opStatus = new Operation(Operation.Status.error.name(), errMsg);
        _dbClient.updateTaskOpStatus(Volume.class, task.getResource().getId(), taskId, opStatus);
        migrationTgt.setInactive(true);
        _dbClient.persistObject(migrationTgt);
        migration.setInactive(true);
        _dbClient.persistObject(migration);
        throw e;
    }
    return task;
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VPlexController(com.emc.storageos.vplexcontroller.VPlexController) HashMap(java.util.HashMap) Migration(com.emc.storageos.db.client.model.Migration) ArrayList(java.util.ArrayList) Operation(com.emc.storageos.db.client.model.Operation) URI(java.net.URI) List(java.util.List) ArrayList(java.util.ArrayList) BulkList(com.emc.storageos.api.service.impl.response.BulkList) MigrationList(com.emc.storageos.model.block.MigrationList) HashSet(java.util.HashSet) VpoolUse(com.emc.storageos.api.service.impl.placement.VpoolUse) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) Recommendation(com.emc.storageos.volumecontroller.Recommendation) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) Project(com.emc.storageos.db.client.model.Project) Volume(com.emc.storageos.db.client.model.Volume) VPlexScheduler(com.emc.storageos.api.service.impl.placement.VPlexScheduler) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 2 with VPlexScheduler

use of com.emc.storageos.api.service.impl.placement.VPlexScheduler in project coprhd-controller by CoprHD.

the class VPlexBlockFullCopyApiImpl method prepareFullCopyHAVolumes.

/**
 * Places and prepares the HA volumes when copying a distributed VPLEX
 * volume.
 *
 * @param name The base name for the volume.
 * @param copyCount The number of copies to be made.
 * @param size The size for the HA volume.
 * @param vplexSystem A reference to the VPLEX storage system.
 * @param vplexSystemProject A reference to the VPLEX system project.
 * @param srcVarray The virtual array for the VPLEX volume being copied.
 * @param srcHAVolume The HA volume of the VPLEX volume being copied.
 * @param taskId The task identifier.
 * @param volumeDescriptors The list of descriptors.
 *
 * @return A list of the prepared HA volumes for the VPLEX volume copy.
 */
private List<Volume> prepareFullCopyHAVolumes(String name, int copyCount, Long size, StorageSystem vplexSystem, Project vplexSystemProject, VirtualArray srcVarray, Volume srcHAVolume, String taskId, List<VolumeDescriptor> volumeDescriptors) {
    List<Volume> copyHAVolumes = new ArrayList<>();
    // Get the storage placement recommendations for the volumes.
    // Placement must occur on the same VPLEX system
    Set<URI> vplexSystemURIS = new HashSet<>();
    vplexSystemURIS.add(vplexSystem.getId());
    VirtualArray haVarray = _dbClient.queryObject(VirtualArray.class, srcHAVolume.getVirtualArray());
    VirtualPool haVpool = _dbClient.queryObject(VirtualPool.class, srcHAVolume.getVirtualPool());
    VirtualPoolCapabilityValuesWrapper haCapabilities = new VirtualPoolCapabilityValuesWrapper();
    haCapabilities.put(VirtualPoolCapabilityValuesWrapper.SIZE, size);
    haCapabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, copyCount);
    VirtualPool vpool = BlockFullCopyUtils.queryFullCopySourceVPool(srcHAVolume, _dbClient);
    if (VirtualPool.ProvisioningType.Thin.toString().equalsIgnoreCase(vpool.getSupportedProvisioningType())) {
        haCapabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, Boolean.TRUE);
        // To guarantee that storage pool for a copy has enough physical
        // space to contain current allocated capacity of thin source volume
        haCapabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_VOLUME_PRE_ALLOCATE_SIZE, BlockFullCopyUtils.getAllocatedCapacityForFullCopySource(srcHAVolume, _dbClient));
    }
    List<Recommendation> recommendations = ((VPlexScheduler) _scheduler).scheduleStorageForImport(srcVarray, vplexSystemURIS, haVarray, haVpool, haCapabilities);
    if (recommendations.isEmpty()) {
        throw APIException.badRequests.noStorageForHaVolumesForVplexVolumeCopies();
    }
    // Prepare the HA volumes for the VPLEX volume copy.
    int copyIndex = 1;
    for (Recommendation recommendation : recommendations) {
        VPlexRecommendation haRecommendation = (VPlexRecommendation) recommendation;
        for (int i = 0; i < haRecommendation.getResourceCount(); i++) {
            // Determine the name for the HA volume copy.
            StringBuilder nameBuilder = new StringBuilder(name);
            nameBuilder.append("-1");
            if (copyCount > 1) {
                nameBuilder.append("-");
                nameBuilder.append(copyIndex++);
            }
            // Prepare the volume.
            Volume volume = VPlexBlockServiceApiImpl.prepareVolumeForRequest(size, vplexSystemProject, haVarray, haVpool, haRecommendation.getSourceStorageSystem(), haRecommendation.getSourceStoragePool(), nameBuilder.toString(), null, taskId, _dbClient);
            volume.addInternalFlags(Flag.INTERNAL_OBJECT);
            _dbClient.persistObject(volume);
            copyHAVolumes.add(volume);
            // Create the volume descriptor and add it to the passed list.
            VolumeDescriptor volumeDescriptor = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, volume.getStorageController(), volume.getId(), volume.getPool(), haCapabilities);
            volumeDescriptors.add(volumeDescriptor);
        }
    }
    return copyHAVolumes;
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) VolumeRecommendation(com.emc.storageos.api.service.impl.placement.VolumeRecommendation) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) Volume(com.emc.storageos.db.client.model.Volume) VPlexScheduler(com.emc.storageos.api.service.impl.placement.VPlexScheduler) HashSet(java.util.HashSet)

Aggregations

VPlexScheduler (com.emc.storageos.api.service.impl.placement.VPlexScheduler)2 VirtualArray (com.emc.storageos.db.client.model.VirtualArray)2 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)2 Volume (com.emc.storageos.db.client.model.Volume)2 Recommendation (com.emc.storageos.volumecontroller.Recommendation)2 VirtualPoolCapabilityValuesWrapper (com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper)2 URI (java.net.URI)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 VolumeRecommendation (com.emc.storageos.api.service.impl.placement.VolumeRecommendation)1 VpoolUse (com.emc.storageos.api.service.impl.placement.VpoolUse)1 BulkList (com.emc.storageos.api.service.impl.response.BulkList)1 VolumeDescriptor (com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor)1 AlternateIdConstraint (com.emc.storageos.db.client.constraint.AlternateIdConstraint)1 Migration (com.emc.storageos.db.client.model.Migration)1 Operation (com.emc.storageos.db.client.model.Operation)1 Project (com.emc.storageos.db.client.model.Project)1 TaskResourceRep (com.emc.storageos.model.TaskResourceRep)1 MigrationList (com.emc.storageos.model.block.MigrationList)1 CheckPermission (com.emc.storageos.security.authorization.CheckPermission)1