/*
* Copyright (c) 2012 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.api.service.impl.resource.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.db.client.DbClient;
import com.emc.storageos.db.client.model.DiscoveredDataObject;
import com.emc.storageos.db.client.model.StoragePool;
import com.emc.storageos.db.client.model.StorageSystem;
import com.emc.storageos.db.client.model.VirtualPool;
import com.emc.storageos.db.client.model.Volume;
import com.emc.storageos.volumecontroller.impl.smis.MetaVolumeRecommendation;
import com.emc.storageos.volumecontroller.impl.utils.MetaVolumeUtils;
public class VmaxCapacityCalculator implements CapacityCalculator {
private static final Logger logger = LoggerFactory.getLogger(VmaxCapacityCalculator.class);
private static final long tracksPerCylinder = 15;
private static final long blocksPerTrack = 128;
private static final long blocksPerTrackVMAX3 = 256;
private static final long bytesPerBlock = 512;
/**
* {@inheritDoc}
*/
@Override
public Long calculateAllocatedCapacity(Long requestedCapacity, Volume volume, DbClient dbClient) {
StorageSystem storageSystem = dbClient.queryObject(StorageSystem.class, volume.getStorageController());
if (requestedCapacity != null) {
long bytesPerCylinder = 0L;
if (storageSystem != null &&
storageSystem.checkIfVmax3()) {
bytesPerCylinder = (tracksPerCylinder * blocksPerTrackVMAX3 * bytesPerBlock);
} else {
bytesPerCylinder = (tracksPerCylinder * blocksPerTrack * bytesPerBlock);
VirtualPool vPool = dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
StoragePool storagePool = dbClient.queryObject(StoragePool.class, volume.getPool());
// Determine if we are provisioning meta volumes. Meta volume provisioning only applies to non-VMAX3.
MetaVolumeRecommendation metaRecommendation = MetaVolumeUtils.getCreateRecommendation(storageSystem, storagePool,
requestedCapacity, volume.getThinlyProvisioned(), vPool.getFastExpansion(), null);
if (metaRecommendation.isCreateMetaVolumes()) {
long metaCount = metaRecommendation.getMetaMemberCount();
long metaSize = metaRecommendation.getMetaMemberSize();
long metaCylinderCount = getCylinderCount(metaSize, bytesPerCylinder);
long allocatedSingleMetaCapacity = (metaCylinderCount * bytesPerCylinder);
// Return the total meta allocation size
long allocatedMetaCapacity = (metaCount * allocatedSingleMetaCapacity);
logger.info(String
.format(
"Determined that volume %s is being provisioned as meta volumes. Allocated capacity per meta will be %d. Total volume allocation (%d metas) will be %d.",
volume.getLabel(), allocatedSingleMetaCapacity, metaCount, allocatedMetaCapacity));
return allocatedMetaCapacity;
}
}
long cyls = getCylinderCount(requestedCapacity, bytesPerCylinder);
return (cyls * bytesPerCylinder);
}
return requestedCapacity;
}
/**
* Computes the provisioned cylinder count for a given requested capacity size
* and bytes-per-cylinder value.
*
* @param requestedCapacity the requested capacity size
* @param bytesPerCylinder the bytes per cylinder
* @return the cylinder count
*/
private long getCylinderCount(long requestedCapacity, long bytesPerCylinder) {
return (long) Math.ceil((double) requestedCapacity / bytesPerCylinder);
}
/**
* {@inheritDoc}
*/
@Override
public Boolean capacitiesCanMatch(String storageSystemType) {
if (storageSystemType.equalsIgnoreCase(DiscoveredDataObject.Type.xtremio.name())) {
return false;
}
return true;
}
}