use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class ExternalDeviceExportOperations method addVolumes.
@Override
public void addVolumes(StorageSystem storage, URI exportMaskUri, VolumeURIHLU[] volumeURIHLUs, List<com.emc.storageos.db.client.model.Initiator> initiatorList, TaskCompleter taskCompleter) throws DeviceControllerException {
log.info("{} addVolumes START...", storage.getSerialNumber());
try {
log.info("addVolumes: Export mask id: {}", exportMaskUri);
log.info("addVolumes: New volumes to add: volume-HLU pairs: {}", Joiner.on(',').join(volumeURIHLUs));
if (initiatorList != null) {
log.info("addVolumes: initiators: {}", Joiner.on(',').join(initiatorList));
}
BlockStorageDriver driver = externalDevice.getDriver(storage.getSystemType());
ExportMask exportMask = (ExportMask) dbClient.queryObject(exportMaskUri);
StringSet maskInitiators = exportMask.getInitiators();
List<String> maskInitiatorList = new ArrayList<>();
for (String initiatorUri : maskInitiators) {
maskInitiatorList.add(initiatorUri);
}
log.info("Export mask existing initiators: {} ", Joiner.on(',').join(maskInitiatorList));
StringSet storagePorts = exportMask.getStoragePorts();
List<URI> portList = new ArrayList<>();
for (String portUri : storagePorts) {
portList.add(URI.create(portUri));
}
log.info("Export mask existing storage ports: {} ", Joiner.on(',').join(portList));
// Get export group uri from task completer
URI exportGroupUri = taskCompleter.getId();
ExportGroup exportGroup = (ExportGroup) dbClient.queryObject(exportGroupUri);
Set<URI> volumeUris = new HashSet<>();
for (VolumeURIHLU volumeURIHLU : volumeURIHLUs) {
URI volumeURI = volumeURIHLU.getVolumeURI();
volumeUris.add(volumeURI);
}
// Prepare volumes. We send to driver only new volumes for the export mask.
List<StorageVolume> driverVolumes = new ArrayList<>();
Map<String, String> driverVolumeToHLUMap = new HashMap<>();
Map<String, URI> volumeNativeIdToUriMap = new HashMap<>();
prepareVolumes(storage, volumeURIHLUs, driverVolumes, driverVolumeToHLUMap, volumeNativeIdToUriMap);
// Prepare initiators
Set<com.emc.storageos.db.client.model.Initiator> initiators = ExportMaskUtils.getInitiatorsForExportMask(dbClient, exportMask, null);
List<Initiator> driverInitiators = new ArrayList<>();
prepareInitiators(initiators, exportGroup.forCluster(), driverInitiators);
// Prepare target storage ports
List<StoragePort> recommendedPorts = new ArrayList<>();
List<StoragePort> availablePorts = new ArrayList<>();
List<StoragePort> selectedPorts = new ArrayList<>();
// Prepare ports for driver call. Populate lists of recommended and available ports.
Map<String, com.emc.storageos.db.client.model.StoragePort> nativeIdToAvailablePortMap = new HashMap<>();
// We use existing ports in the mask as recommended ports.
preparePorts(storage, exportMaskUri, portList, recommendedPorts, availablePorts, nativeIdToAvailablePortMap);
log.info("varray ports: {}", nativeIdToAvailablePortMap);
// For add volumes to existing export mask, we do not allow storage port change in the mask.
// Only ports in the mask are available for driver call.
availablePorts = recommendedPorts;
ExportPathParams pathParams = blockScheduler.calculateExportPathParamForVolumes(volumeUris, exportGroup.getNumPaths(), storage.getId(), exportGroupUri);
StorageCapabilities capabilities = new StorageCapabilities();
// Prepare num paths to send to driver
prepareCapabilities(pathParams, capabilities);
MutableBoolean usedRecommendedPorts = new MutableBoolean(true);
// Ready to call driver
DriverTask task = driver.exportVolumesToInitiators(driverInitiators, driverVolumes, driverVolumeToHLUMap, recommendedPorts, availablePorts, capabilities, usedRecommendedPorts, selectedPorts);
// todo: need to implement support for async case.
if (task.getStatus() == DriverTask.TaskStatus.READY) {
String msg = String.format("Created export for volumes: %s . Used recommended ports: %s .", task.getMessage(), usedRecommendedPorts);
log.info(msg);
log.info("Driver selected storage ports: {} ", Joiner.on(',').join(selectedPorts));
// auto san zoning is enabled, we will fail the request.
if (usedRecommendedPorts.isFalse() && !selectedPorts.containsAll(recommendedPorts)) {
// for auto san zoning enabled we can not support case when selected ports do not include ports which are already in the mask
VirtualArray varray = dbClient.queryObject(VirtualArray.class, exportGroup.getVirtualArray());
log.info("AutoSanZoning for varray {} is {} ", varray.getLabel(), varray.getAutoSanZoning());
if (varray.getAutoSanZoning()) {
String errorMsg = String.format("AutoSanZoning is enabled and driver selected ports do not contain ports from the export mask: %s .", task.getMessage());
log.error(errorMsg);
ServiceError serviceError = ExternalDeviceException.errors.addVolumesToExportMaskFailed("addVolumes", errorMsg);
taskCompleter.error(dbClient, serviceError);
} else {
// auto san zoning is disabled --- add new selected ports to the mask
// we do not care about zoning map in this case
List<com.emc.storageos.db.client.model.StoragePort> selectedPortsForMask = new ArrayList<>();
for (StoragePort driverPort : selectedPorts) {
log.info("Driver selected port: {}", driverPort);
com.emc.storageos.db.client.model.StoragePort port = nativeIdToAvailablePortMap.get(driverPort.getNativeId());
if (port != null) {
// add all ports, StringSet in the mask will ignore duplicates
log.info("System port: {}", port);
selectedPortsForMask.add(port);
}
}
for (com.emc.storageos.db.client.model.StoragePort port : selectedPortsForMask) {
exportMask.addTarget(port.getId());
}
dbClient.updateObject(exportMask);
taskCompleter.ready(dbClient);
}
} else {
// Update volumes Lun Ids in export mask based on driver selection
for (String volumeNativeId : driverVolumeToHLUMap.keySet()) {
String targetLunId = driverVolumeToHLUMap.get(volumeNativeId);
URI volumeUri = volumeNativeIdToUriMap.get(volumeNativeId);
exportMask.getVolumes().put(volumeUri.toString(), targetLunId);
}
dbClient.updateObject(exportMask);
taskCompleter.ready(dbClient);
}
} else {
String errorMsg = String.format("Failed to add volumes to export mask: %s .", task.getMessage());
log.error(errorMsg);
ServiceError serviceError = ExternalDeviceException.errors.addVolumesToExportMaskFailed("addVolumes", errorMsg);
taskCompleter.error(dbClient, serviceError);
}
} catch (Exception ex) {
log.error("Problem in addVolumes: ", ex);
String errorMsg = String.format("Failed to add volumes to export mask: %s .", ex.getMessage());
log.error(errorMsg);
ServiceError serviceError = ExternalDeviceException.errors.addVolumesToExportMaskFailed("addVolumes", errorMsg);
taskCompleter.error(dbClient, serviceError);
}
log.info("{} addVolumes END...", storage.getSerialNumber());
}
use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class ExternalDeviceUnManagedVolumeDiscoverer method processUnManagedClones.
/**
* Process clones of unManaged volume.
* Check if unManaged clone should be created and create unManaged volume instance for a clone in such a case.
* Add unManaged clone to parent volume CG if needed and update the clone with parent volume CG information.
* Gets export information for clones and stores it in the provided map.
*
* @param driverVolume driver volume for clone parent volume. [IN]
* @param unManagedParentVolume unManaged parent volume [IN/OUT]
* @param storageSystem storage system [IN]
* @param storagePool storage pool [IN]
* @param unManagedVolumesToCreate list of unmanaged volumes to create [OUT]
* @param unManagedVolumesToUpdate list of unmanaged volumes to update [OUT]
* @param allCurrentUnManagedCgURIs set of unManaged CG uris found in the current discovery [OUT]
* @param unManagedCGToUpdateMap map of unManaged CG GUID to unManaged CG instance [IN/OUT]
* @param unManagedVolumeNativeIdToUriMap map of unmanaged volumes nativeId to their uri [OUT]
* @param hostToUnManagedVolumeExportInfoMap map with export data for unmanaged volumes (including snaps and clones)
* @param driver storage driver [IN]
* @param dbClient reference to db client [IN]
* @return set of URIs for unmanaged clones
* @throws Exception
*/
private Set<URI> processUnManagedClones(StorageVolume driverVolume, UnManagedVolume unManagedParentVolume, com.emc.storageos.db.client.model.StorageSystem storageSystem, com.emc.storageos.db.client.model.StoragePool storagePool, List<UnManagedVolume> unManagedVolumesToCreate, List<UnManagedVolume> unManagedVolumesToUpdate, Set<URI> allCurrentUnManagedCgURIs, Map<String, UnManagedConsistencyGroup> unManagedCGToUpdateMap, Map<String, URI> unManagedVolumeNativeIdToUriMap, Map<String, List<HostExportInfo>> hostToUnManagedVolumeExportInfoMap, BlockStorageDriver driver, DbClient dbClient) throws Exception {
log.info("Processing clones for volume {} ", unManagedParentVolume.getNativeGuid());
Set<URI> cloneUris = new HashSet<>();
List<VolumeClone> driverClones = driver.getVolumeClones(driverVolume);
if (driverClones == null || driverClones.isEmpty()) {
log.info("There are no clones for volume {} ", unManagedParentVolume.getNativeGuid());
} else {
log.info("Clones for unManaged volume {}:" + Joiner.on("\t").join(driverClones), unManagedParentVolume.getNativeGuid());
StringSet unManagedClones = new StringSet();
for (VolumeClone driverClone : driverClones) {
String managedCloneNativeGuid = NativeGUIDGenerator.generateNativeGuidForVolumeOrBlockSnapShot(storageSystem.getNativeGuid(), driverClone.getNativeId());
Volume systemClone = DiscoveryUtils.checkStorageVolumeExistsInDB(dbClient, managedCloneNativeGuid);
if (null != systemClone) {
log.info("Skipping clone {} as it is already managed by the system.", managedCloneNativeGuid);
continue;
}
String unManagedCloneNatvieGuid = NativeGUIDGenerator.generateNativeGuidForPreExistingVolume(storageSystem.getNativeGuid(), driverClone.getNativeId());
UnManagedVolume unManagedClone = createUnManagedClone(driverClone, unManagedParentVolume, storageSystem, storagePool, unManagedVolumesToCreate, unManagedVolumesToUpdate, dbClient);
cloneUris.add(unManagedClone.getId());
unManagedClones.add(unManagedCloneNatvieGuid);
// Check if this clone is for a volume in consistency group on device.
String isParentVolumeInCG = unManagedParentVolume.getVolumeCharacterstics().get(UnManagedVolume.SupportedVolumeCharacterstics.IS_VOLUME_ADDED_TO_CONSISTENCYGROUP.toString());
if (isParentVolumeInCG.equals(Boolean.TRUE.toString())) {
log.info("Clone {} is for volume in CG. ", managedCloneNativeGuid);
// add clone to parent volume unManaged consistency group, update clone with parent volume CG information.
addObjectToUnManagedConsistencyGroup(storageSystem, driverVolume.getConsistencyGroup(), unManagedClone, allCurrentUnManagedCgURIs, unManagedCGToUpdateMap, driver, dbClient);
}
// get export data for the clone
unManagedVolumeNativeIdToUriMap.put(driverClone.getNativeId(), unManagedClone.getId());
getCloneExportInfo(driver, driverClone, hostToUnManagedVolumeExportInfoMap);
}
if (!unManagedClones.isEmpty()) {
// set the HAS_REPLICAS property
unManagedParentVolume.getVolumeCharacterstics().put(UnManagedVolume.SupportedVolumeCharacterstics.HAS_REPLICAS.toString(), TRUE);
StringSetMap unManagedVolumeInformation = unManagedParentVolume.getVolumeInformation();
log.info("New unManaged clones for unManaged volume {}:" + Joiner.on("\t").join(unManagedClones), unManagedParentVolume.getNativeGuid());
if (unManagedVolumeInformation.containsKey(UnManagedVolume.SupportedVolumeInformation.FULL_COPIES.toString())) {
log.info("Old unManaged clones for unManaged volume {}:" + Joiner.on("\t").join(unManagedVolumeInformation.get(UnManagedVolume.SupportedVolumeInformation.FULL_COPIES.toString())), unManagedParentVolume.getNativeGuid());
// replace with new StringSet
unManagedVolumeInformation.get(UnManagedVolume.SupportedVolumeInformation.FULL_COPIES.toString()).replace(unManagedClones);
log.info("Replaced clones :" + Joiner.on("\t").join(unManagedVolumeInformation.get(UnManagedVolume.SupportedVolumeInformation.FULL_COPIES.toString())));
} else {
unManagedVolumeInformation.put(UnManagedVolume.SupportedVolumeInformation.FULL_COPIES.toString(), unManagedClones);
}
} else {
log.info("All clones for volume {} are already managed.", unManagedParentVolume.getNativeGuid());
}
}
return cloneUris;
}
use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class ExpandVolumeExternalDeviceJob method doTaskSucceeded.
/**
* {@inheritDoc}
*/
@Override
protected void doTaskSucceeded(DriverTask driverTask, DbClient dbClient) throws Exception {
// Get the ViPR volume.
s_logger.info(String.format("Successfully expanded volume %s:%s", _volumeURI, driverTask.getMessage()));
Volume volume = dbClient.queryObject(Volume.class, _volumeURI);
if (volume == null) {
s_logger.error(String.format("Failed to find volume %s", _volumeURI));
throw DeviceControllerException.exceptions.objectNotFound(_volumeURI);
}
// Update the ViPR volume with the driver volume information.
ExpandVolumeDriverTask expandVolumeDriverTask = (ExpandVolumeDriverTask) driverTask;
StorageVolume updatedDeviceVolume = expandVolumeDriverTask.getStorageVolume();
ExternalDeviceUtils.updateExpandedVolume(volume, updatedDeviceVolume, dbClient);
try {
// Update storage pool capacity in database.
ExternalDeviceUtils.updateStoragePoolCapacityAfterOperationComplete(volume.getPool(), _storageSystemURI, Collections.singletonList(_volumeURI), dbClient);
} catch (Exception ex) {
s_logger.error("Failed to update storage pool {} after volume expand operation completion.", volume.getPool(), ex);
}
}
use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class HP3PARIngestHelper method getStorageVolumes.
public DriverTask getStorageVolumes(StorageSystem storageSystem, List<StorageVolume> storageVolumes, MutableInt token, DriverTask task, Registry driverRegistry) {
_log.info("3PARDriver: getStorageVolumes Running ");
Map<String, List<String>> vvolAssociations = new HashMap<String, List<String>>();
Map<String, List<String>> vvolAncestryMap = new HashMap<String, List<String>>();
HashMap<Long, String> vvolNamesMap = new HashMap<Long, String>();
try {
HashMap<String, ArrayList<String>> volumesToVolSetsMap = generateVolumeSetToVolumeMap(storageSystem, driverRegistry);
// get Api client
HP3PARApi hp3parApi = hp3parUtil.getHP3PARDeviceFromNativeId(storageSystem.getNativeId(), driverRegistry);
VolumesCommandResult objStorageVolumes = hp3parApi.getStorageVolumes();
// first we build HashMap of volume id , volume name
for (VolumeDetailsCommandResult objVolMember : objStorageVolumes.getMembers()) {
vvolNamesMap.put(new Long(objVolMember.getId()), objVolMember.getName());
}
_log.info("vvolNamesMap is {}", vvolNamesMap);
// We build a hashmap of volume names and their respective ancestors.
for (VolumeDetailsCommandResult objVolMember : objStorageVolumes.getMembers()) {
if (objVolMember.getCopyType() == HP3PARConstants.copyType.VIRTUAL_COPY.getValue()) {
ArrayList<String> arrLst = new ArrayList<String>();
arrLst.add(vvolNamesMap.get(objVolMember.getBaseId()));
vvolAncestryMap.put(new String(objVolMember.getId()), arrLst);
} else if (objVolMember.getCopyType() == HP3PARConstants.copyType.PHYSICAL_COPY.getValue()) {
ArrayList<String> arrLst = new ArrayList<String>();
arrLst.add(vvolNamesMap.get(objVolMember.getPhysParentId()));
vvolAncestryMap.put(new String(objVolMember.getId()), arrLst);
}
}
_log.info("vvolAncestryMap is {}", vvolAncestryMap);
_log.info("Total Volumes returned by API call {}", objStorageVolumes.getTotal());
for (VolumeDetailsCommandResult objVolMember : objStorageVolumes.getMembers()) {
_log.info("objVolMember is {}", objVolMember.getAllValues());
StorageVolume driverVolume = new StorageVolume();
driverVolume.setStorageSystemId(storageSystem.getNativeId());
driverVolume.setStoragePoolId(objVolMember.getUserCPG());
driverVolume.setNativeId(objVolMember.getName());
driverVolume.setProvisionedCapacity(objVolMember.getSizeMiB() * HP3PARConstants.MEGA_BYTE);
// Allocated capacity is the sum of user, snapshot and admin reserved space
Long allocatedCapacity = objVolMember.getUserSpace().getReservedMiB();
allocatedCapacity += objVolMember.getSnapshotSpace().getReservedMiB();
allocatedCapacity += objVolMember.getAdminSpace().getReservedMiB();
driverVolume.setAllocatedCapacity(allocatedCapacity * HP3PARConstants.MEGA_BYTE);
driverVolume.setWwn(objVolMember.getWwn());
driverVolume.setNativeId(objVolMember.getName());
driverVolume.setDeviceLabel(objVolMember.getName());
// teminology)
if (volumesToVolSetsMap.containsKey(objVolMember.getName())) {
driverVolume.setConsistencyGroup(volumesToVolSetsMap.get(objVolMember.getName()).get(0));
} else {
_log.debug("Unmanaged volume volume {} not part of any consistency group", driverVolume);
}
if (objVolMember.isReadOnly()) {
driverVolume.setAccessStatus(StorageVolume.AccessStatus.READ_ONLY);
} else {
driverVolume.setAccessStatus(StorageVolume.AccessStatus.READ_WRITE);
}
if (objVolMember.getProvisioningType() == HP3PARConstants.provisioningType.TPVV.getValue()) {
driverVolume.setThinlyProvisioned(true);
} else {
driverVolume.setThinlyProvisioned(false);
}
// TODO: how much should the thin volume preallocation size be.
driverVolume.setThinVolumePreAllocationSize(3000L);
if (objVolMember.getCopyOf() != null) {
_log.info("skipping adding the volume {} to storagevolumes array", objVolMember.getName());
} else {
_log.info("Adding to storagevolumes array the volume {}", objVolMember.getName());
storageVolumes.add(driverVolume);
}
_log.info("Unmanaged volume info: pool {}, volume {}", driverVolume.getStoragePoolId(), driverVolume);
if (objVolMember.getCopyOf() != null) {
String ancestorId = null;
String ancestorName = null;
if (objVolMember.getCopyType() == copyType.VIRTUAL_COPY.getValue()) {
ancestorName = vvolAncestryMap.get(objVolMember.getId()).get(0);
} else if (objVolMember.getCopyType() == copyType.PHYSICAL_COPY.getValue()) {
ancestorName = vvolAncestryMap.get(objVolMember.getId()).get(0);
}
// ancestorName = vvolNamesMap.get(ancestorId);
if (vvolAssociations.containsKey(ancestorName)) {
ArrayList<String> listOfChildren = (ArrayList<String>) vvolAssociations.get(ancestorName);
listOfChildren.add(objVolMember.getName());
} else {
ArrayList<String> listOfChildren = new ArrayList<String>();
listOfChildren.add(objVolMember.getName());
vvolAssociations.put(ancestorName, listOfChildren);
}
_log.debug("objAncestor name is {}", ancestorName);
_log.debug("objVolMember being added is {} ", objVolMember.getName());
}
}
_log.info("The vvolAssociations being returned by GetStorageVolumes is {}", vvolAssociations);
task.setStatus(DriverTask.TaskStatus.READY);
driverRegistry.setDriverAttributesForKey(HP3PARConstants.DRIVER_NAME, storageSystem.getNativeId() + "____VVOL_ASSOCIATIONS", vvolAssociations);
driverRegistry.setDriverAttributesForKey(HP3PARConstants.DRIVER_NAME, storageSystem.getNativeId() + "____VVOL_ANCESTORS", vvolAncestryMap);
} catch (Exception e) {
String msg = String.format("3PARDriver: Unable to get storagevolumes for storage system %s native id %s; Error: %s.\n", storageSystem.getSystemName(), storageSystem.getNativeId(), e.getMessage());
task.setMessage(msg);
task.setStatus(DriverTask.TaskStatus.FAILED);
e.printStackTrace();
}
_log.info("3PARDriver: getStorageVolumes Leaving");
return task;
}
use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class DellSCConsistencyGroups method addVolumesToConsistencyGroup.
/**
* Add volumes to consistency groups.
*
* @param volumes The volumes to add.
* @param capabilities The requested capabilities.
* @return The driver task.
*/
public DriverTask addVolumesToConsistencyGroup(List<StorageVolume> volumes, StorageCapabilities capabilities) {
DellSCDriverTask task = new DellSCDriverTask("addVolumesToCG");
StringBuilder errBuffer = new StringBuilder();
int addCount = 0;
for (StorageVolume volume : volumes) {
String ssn = volume.getStorageSystemId();
try {
StorageCenterAPI api = connectionManager.getConnection(ssn);
api.addVolumeToConsistencyGroup(volume.getNativeId(), volume.getConsistencyGroup());
addCount++;
} catch (StorageCenterAPIException | DellSCDriverException dex) {
String error = String.format("Error adding volume %s to consistency group: %s", volume.getNativeId(), dex);
LOG.warn(error);
errBuffer.append(String.format("%s%n", error));
}
}
task.setMessage(errBuffer.toString());
if (addCount == volumes.size()) {
task.setStatus(TaskStatus.READY);
} else if (addCount == 0) {
task.setStatus(TaskStatus.FAILED);
} else {
task.setStatus(TaskStatus.PARTIALLY_FAILED);
}
return task;
}
Aggregations