use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class HP3PARExpUnexpHelper method exportVolumesToInitiators.
/**
*******USE CASES**********
*
* EXCLUSIVE EXPORT: Will include port number of host
*
* 1 Export volume to existing host
* 2 Export volume to non-existing host
* 3 Add initiator to existing host
* 4 Remove initiator from host
* 5 Unexport volume
*
* A 1-5 can be done with single/multiple volumes,initiators as applicable
* B Does not depend on host name
* C Adding an initiator in matched-set will not do anything further.
* All volumes have to be exported to new initiator explicitly.
* In host-sees 3PAR will automatically export the volumes to newly added initiator.
* -------------------------------------------
* SHARED EXPORT: Will not include port number, exported to all ports, the cluster can see
*
* 1 Export volume to existing cluster
* 2 Export volume to non-existing cluster
* 3 Add initiator to existing host in cluster
* 4 Remove initiator from host in cluster
* 5 Unexport volume from cluster
* 6 Export a private volume to a host in a cluster
* 7 Unexport a private volume from a host in a cluster
* 8 Add a host to cluster
* 9 Remove a host from a cluster
* 10 Add a host having private export
* 11 Remove a host having private export
* 12 Move a host from one cluster to another
*
* A 1-12 can be done with single/multiple volumes,initiators,hosts as applicable
* B Cluster name in ViPR and 3PAR has to be identical with case
* C Adding a new host to host-set will automatically export all volumes to the new host(initial export must have been host-set)
*/
/*
* All volumes in the list will be exported to all initiators using recommended ports. If a volume can not be exported to 'n'
* initiators the same will be tried with available ports
*/
public DriverTask exportVolumesToInitiators(List<Initiator> initiators, List<StorageVolume> volumes, Map<String, String> volumeToHLUMap, List<StoragePort> recommendedPorts, List<StoragePort> availablePorts, StorageCapabilities capabilities, MutableBoolean usedRecommendedPorts, List<StoragePort> selectedPorts, DriverTask task, Registry driverRegistry, LockManager driverLockManager) {
_log.info("3PARDriver:exportVolumesToInitiators enter");
String host = null;
host = doHostProcessing(initiators, volumes, driverRegistry, driverLockManager);
if (host == null) {
task.setMessage("exportVolumesToInitiators error: Processing hosts, Unable to export");
task.setStatus(DriverTask.TaskStatus.FAILED);
return task;
}
/*
Export will be done keeping volumes as the starting point
*/
Integer totalExport = recommendedPorts.size();
for (StorageVolume vol : volumes) {
Integer currExport = 0;
Integer hlu = Integer.parseInt(volumeToHLUMap.get(vol.getNativeId()));
try {
// volume could belong to different storage system; get specific api client;
HP3PARApi hp3parApi = hp3parUtil.getHP3PARDeviceFromNativeId(vol.getStorageSystemId(), driverRegistry);
/*
export for INDIVIDUAL HOST=exclusive
Some code is repeated with cluster for simplicity
*/
if (!host.startsWith("set:")) {
// try with recommended ports
for (StoragePort port : recommendedPorts) {
// volume and port belong to same storage system
String message = String.format("3PARDriver:exportVolumesToInitiators using recommendedPorts for " + "storage system %s, volume %s host %s hlu %s port %s", port.getStorageSystemId(), vol.getNativeId(), host, hlu.toString(), port.getNativeId());
_log.info(message);
VlunResult vlunRes = hp3parApi.createVlun(vol.getNativeId(), hlu, host, port.getNativeId());
if (vlunRes != null && vlunRes.getStatus()) {
currExport++;
usedRecommendedPorts.setValue(true);
// update hlu obtained as lun from 3apr & add the selected port if required
volumeToHLUMap.put(vol.getNativeId(), vlunRes.getAssignedLun());
if (!selectedPorts.contains(port)) {
selectedPorts.add(port);
}
} else {
task.setStatus(DriverTask.TaskStatus.PARTIALLY_FAILED);
_log.warn("3PARDriver: Could not export " + message);
}
}
// now try with available ports
for (StoragePort port : availablePorts) {
if (currExport == totalExport) {
task.setStatus(DriverTask.TaskStatus.READY);
break;
}
// Make sure this port is not used for earlier export
if (selectedPorts.contains(port)) {
continue;
}
// verify volume and port belong to same storage
if (!vol.getStorageSystemId().equalsIgnoreCase(port.getStorageSystemId())) {
continue;
}
String message = String.format("3PARDriver:exportVolumesToInitiators using availablePorts for " + "storage system %s, volume %s host %s hlu %s port %s", port.getStorageSystemId(), vol.getNativeId(), host, hlu.toString(), port.getNativeId());
_log.info(message);
VlunResult vlunRes = hp3parApi.createVlun(vol.getNativeId(), hlu, host, port.getNativeId());
if (vlunRes != null && vlunRes.getStatus()) {
currExport++;
usedRecommendedPorts.setValue(false);
// update hlu obtained as lun from 3apr & add the selected port if required
volumeToHLUMap.put(vol.getNativeId(), vlunRes.getAssignedLun());
if (!selectedPorts.contains(port)) {
selectedPorts.add(port);
}
} else {
task.setStatus(DriverTask.TaskStatus.PARTIALLY_FAILED);
_log.warn("3PARDriver: Could not export " + message);
}
}
// for available ports
} else {
/*
export for CLUSTER=shared
Some code is repeated with cluster for simplicity
Cluster export will be done as host-set in 3APR for entire cluster in one go.
Hence requests coming for rest of the individual host exports should gracefully exit
*/
String lockName = volumes.get(0).getStorageSystemId() + vol.getNativeId() + host;
if (driverLockManager.acquireLock(lockName, 10, TimeUnit.MINUTES)) {
_log.info("3PARDriver: Acquired lock {} to examine vlun creation", lockName);
/*
If this is the first request key gets created with export operation.
other requests will gracefully exit. key will be removed in unexport.
*/
String message = String.format("3PARDriver:exportVolumesToInitiators " + "storage system %s, volume %s Cluster %s hlu %s ", vol.getStorageSystemId(), vol.getNativeId(), host, hlu.toString());
_log.info(message);
String exportPath = vol.getStorageSystemId() + vol.getNativeId() + host;
_log.info("3PARDriver:exportPath {} for registry entry", exportPath);
Map<String, List<String>> attributes = new HashMap<>();
List<String> expValue = new ArrayList<>();
List<String> lunValue = new ArrayList<>();
boolean doExport = true;
attributes = driverRegistry.getDriverAttributesForKey(HP3PARConstants.DRIVER_NAME, exportPath);
if (attributes != null) {
expValue = attributes.get("EXPORT_PATH");
if (expValue != null && expValue.get(0).compareTo(exportPath) == 0) {
doExport = false;
// Already exported, make hlu, port details; gracefully exit
lunValue = attributes.get(vol.getNativeId());
volumeToHLUMap.put(vol.getNativeId(), lunValue.get(0));
HP3PARHostNameResult hostNameResult = get3parHostname(initiators, vol.getStorageSystemId(), driverRegistry);
HostMember hostRes = hp3parApi.getHostDetails(hostNameResult.getHostName());
// get storage array ports for this host ports
List<StoragePort> clusterStoragePorts = new ArrayList<>();
getClusterStoragePorts(hostRes, availablePorts, vol.getStorageSystemId(), clusterStoragePorts);
for (StoragePort sp : clusterStoragePorts) {
// assign all these ports as selected ports
if (!selectedPorts.contains(sp)) {
selectedPorts.add(sp);
}
}
// go thru all slectedports.
// if anyone is not part of the recommendedPorts set usedRecommendedPorts to false
usedRecommendedPorts.setValue(true);
for (StoragePort sp : selectedPorts) {
if (!recommendedPorts.contains(sp)) {
usedRecommendedPorts.setValue(false);
break;
}
}
task.setStatus(DriverTask.TaskStatus.READY);
_log.info("3PARDriver: Already exported, exiting " + message);
}
}
if (doExport) {
_log.info("3PARDriver: exporting volume {} as exportPath {} is not present in registry", vol.getNativeId(), exportPath);
/*
for cluster use host set method, We cannot specify port;
determine the individual host ports used
*/
VlunResult vlunRes = hp3parApi.createVlun(vol.getNativeId(), hlu, host, null);
if (vlunRes != null && vlunRes.getStatus()) {
// update hlu obtained as lun from 3apr & add the selected port if required
volumeToHLUMap.put(vol.getNativeId(), vlunRes.getAssignedLun());
HP3PARHostNameResult hostNameResult = get3parHostname(initiators, vol.getStorageSystemId(), driverRegistry);
HostMember hostRes = hp3parApi.getHostDetails(hostNameResult.getHostName());
// get storage array ports for this host ports
List<StoragePort> clusterStoragePorts = new ArrayList<>();
getClusterStoragePorts(hostRes, availablePorts, vol.getStorageSystemId(), clusterStoragePorts);
for (StoragePort sp : clusterStoragePorts) {
// assign all these ports as selected ports
if (!selectedPorts.contains(sp)) {
selectedPorts.add(sp);
}
}
usedRecommendedPorts.setValue(true);
for (StoragePort sp : selectedPorts) {
if (!recommendedPorts.contains(sp)) {
usedRecommendedPorts.setValue(false);
break;
}
}
// Everything is successful, Set as exported in registry
attributes = new HashMap<>();
expValue = new ArrayList<>();
lunValue = new ArrayList<>();
expValue.add(exportPath);
attributes.put("EXPORT_PATH", expValue);
lunValue.add(vlunRes.getAssignedLun());
attributes.put(vol.getNativeId(), lunValue);
attributes.put(vol.getNativeId(), lunValue);
driverRegistry.setDriverAttributesForKey(HP3PARConstants.DRIVER_NAME, exportPath, attributes);
task.setMessage("Successful");
task.setStatus(DriverTask.TaskStatus.READY);
} else {
// end createVlun
task.setStatus(DriverTask.TaskStatus.PARTIALLY_FAILED);
_log.warn("3PARDriver: Could not export " + message);
}
}
// doExport
_log.info("3PARDriver: Releasing lock {} after examining vlun creation", lockName);
driverLockManager.releaseLock(lockName);
} else {
_log.error("3PARDriver:exportVolumesToInitiators error: could not acquire thread lock");
throw new HP3PARException("3PARDriver:exportVolumesToInitiators error: could not acquire thread lock");
}
}
// end cluster export
} catch (Exception e) {
String msg = String.format("3PARDriver: Unable to export few volumes, error: %s", e);
_log.error(CompleteError.getStackTrace(e));
_log.error(msg);
task.setMessage(msg);
task.setStatus(DriverTask.TaskStatus.PARTIALLY_FAILED);
e.printStackTrace();
}
}
// for each volume
_log.info("3PARDriver:exportVolumesToInitiators leave");
return task;
}
use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class HP3PARProvisioningHelper method createVolumes.
public DriverTask createVolumes(List<StorageVolume> volumes, StorageCapabilities capabilities, DriverTask task, Registry driverRegistry) {
int volumesCreated = 0;
boolean IsDeDupEnabled = false;
// get deduplicationCapability
CommonStorageCapabilities commonCapabilities = capabilities.getCommonCapabilitis();
if (commonCapabilities != null) {
List<DataStorageServiceOption> dataService = commonCapabilities.getDataStorage();
if (dataService != null) {
for (DataStorageServiceOption dataServiceOption : dataService) {
List<CapabilityInstance> capabilityList = dataServiceOption.getCapabilities();
if (capabilityList != null) {
for (CapabilityInstance ci : capabilityList) {
String provTypeValue = ci.getPropertyValue(DeduplicationCapabilityDefinition.PROPERTY_NAME.ENABLED.name());
if (provTypeValue != null && provTypeValue.equalsIgnoreCase(Boolean.TRUE.toString())) {
IsDeDupEnabled = true;
}
}
}
}
}
}
// For each requested volume
for (StorageVolume volume : volumes) {
try {
_log.info("3PARDriver:createVolumes for storage system native id {}, volume name {} - start", volume.getStorageSystemId(), volume.getDisplayName());
// get Api client
HP3PARApi hp3parApi = hp3parUtil.getHP3PARDeviceFromNativeId(volume.getStorageSystemId(), driverRegistry);
// Create volume
VolumeDetailsCommandResult volResult = null;
Boolean isThin = volume.getThinlyProvisioned();
if (IsDeDupEnabled) {
isThin = false;
}
hp3parApi.createVolume(volume.getDisplayName(), volume.getStoragePoolId(), isThin, IsDeDupEnabled, volume.getRequestedCapacity() / HP3PARConstants.MEGA_BYTE);
volResult = hp3parApi.getVolumeDetails(volume.getDisplayName());
// Attributes of the volume in array
volume.setProvisionedCapacity(volResult.getSizeMiB() * HP3PARConstants.MEGA_BYTE);
// Allocated capacity is the sum of user, snapshot and admin reserved space
Long allocatedCapacity = volResult.getUserSpace().getReservedMiB();
allocatedCapacity += volResult.getSnapshotSpace().getReservedMiB();
allocatedCapacity += volResult.getAdminSpace().getReservedMiB();
volume.setAllocatedCapacity(allocatedCapacity * HP3PARConstants.MEGA_BYTE);
volume.setWwn(volResult.getWwn());
// required for volume delete
volume.setNativeId(volume.getDisplayName());
volume.setDeviceLabel(volume.getDisplayName());
volume.setAccessStatus(AccessStatus.READ_WRITE);
// Update Consistency Group
String volumeCGName = volume.getConsistencyGroup();
if (volumeCGName != null && !volumeCGName.isEmpty()) {
_log.info("3PARDriver:createVolumes Adding volume {} to consistency group {} ", volume.getDisplayName(), volumeCGName);
int addMember = 1;
hp3parApi.updateVVset(volumeCGName, volume.getNativeId(), addMember);
}
volumesCreated++;
_log.info("3PARDriver:createVolumes for storage system native id {}, volume name {} - end", volume.getStorageSystemId(), volume.getDisplayName());
} catch (Exception e) {
String msg = String.format("3PARDriver: Unable to create volume name %s with pool id %s for storage system native id %s; Error: %s.\n", volume.getDisplayName(), volume.getStoragePoolId(), volume.getStorageSystemId(), e);
_log.error(msg);
_log.error(CompleteError.getStackTrace(e));
task.setMessage(msg);
e.printStackTrace();
}
}
if (volumes.size() != 0) {
if (volumesCreated == volumes.size()) {
task.setMessage("Successful");
task.setStatus(DriverTask.TaskStatus.READY);
} else if (volumesCreated == 0) {
task.setStatus(DriverTask.TaskStatus.FAILED);
} else {
task.setStatus(DriverTask.TaskStatus.PARTIALLY_FAILED);
}
}
return task;
}
use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class DellSCUtil method getStorageVolumeFromScVolume.
/**
* Populates a StorageVolume instance with Storage Center volume data.
*
* @param api The API connection.
* @param volume The Storage Center volume.
* @param cgInfo Consistency group information or null.
* @return The StorageVolume.
* @throws StorageCenterAPIException
*/
public StorageVolume getStorageVolumeFromScVolume(StorageCenterAPI api, ScVolume volume, Map<ScReplayProfile, List<String>> cgInfo) throws StorageCenterAPIException {
ScVolumeStorageUsage storageUsage = api.getVolumeStorageUsage(volume.instanceId);
StorageVolume driverVol = new StorageVolume();
driverVol.setStorageSystemId(volume.scSerialNumber);
driverVol.setStoragePoolId(volume.storageType.instanceId);
driverVol.setNativeId(volume.instanceId);
driverVol.setThinlyProvisioned(true);
driverVol.setProvisionedCapacity(SizeUtil.sizeStrToBytes(volume.configuredSize));
driverVol.setAllocatedCapacity(SizeUtil.sizeStrToBytes(storageUsage.totalDiskSpace));
driverVol.setWwn(volume.deviceId);
driverVol.setDeviceLabel(volume.name);
// Check consistency group membership
if (cgInfo != null) {
for (ScReplayProfile cg : cgInfo.keySet()) {
if (cgInfo.get(cg).contains(volume.instanceId)) {
// Found our volume in a consistency group
driverVol.setConsistencyGroup(cg.instanceId);
break;
}
}
}
return driverVol;
}
use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class DellSCConsistencyGroups method removeVolumesFromConsistencyGroup.
/**
* Remove volumes from consistency groups.
*
* @param volumes The volumes.
* @param capabilities The requested capabilities.
* @return The driver task.
*/
public DriverTask removeVolumesFromConsistencyGroup(List<StorageVolume> volumes, StorageCapabilities capabilities) {
DellSCDriverTask task = new DellSCDriverTask("removeVolumeFromCG");
StringBuilder errBuffer = new StringBuilder();
int removeCount = 0;
for (StorageVolume volume : volumes) {
String ssn = volume.getStorageSystemId();
try {
StorageCenterAPI api = connectionManager.getConnection(ssn);
api.removeVolumeFromConsistencyGroup(volume.getNativeId(), volume.getConsistencyGroup());
removeCount++;
} 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 (removeCount == volumes.size()) {
task.setStatus(TaskStatus.READY);
} else if (removeCount == 0) {
task.setStatus(TaskStatus.FAILED);
} else {
task.setStatus(TaskStatus.PARTIALLY_FAILED);
}
return task;
}
use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class DellSCProvisioning method unexportVolumesFromInitiators.
/**
* Remove volume exports to initiators.
*
* @param initiators The initiators to remove from.
* @param volumes The volumes to remove.
* @return The unexport task.
*/
public DriverTask unexportVolumesFromInitiators(List<Initiator> initiators, List<StorageVolume> volumes) {
LOG.info("Unexporting volumes from initiators");
DriverTask task = new DellSCDriverTask("unexportVolumes");
ScServer server = null;
StringBuilder errBuffer = new StringBuilder();
int volumesUnmapped = 0;
for (StorageVolume volume : volumes) {
String ssn = volume.getStorageSystemId();
boolean isSnapshot = StringUtils.countMatches(volume.getNativeId(), ".") == 2;
try {
StorageCenterAPI api = connectionManager.getConnection(ssn);
// Find our actual volume
ScVolume scVol = null;
if (isSnapshot) {
scVol = api.findReplayView(volume.getNativeId());
// For snapshot views we can just delete the view
if (scVol != null) {
api.deleteVolume(scVol.instanceId);
volumesUnmapped++;
continue;
}
} else {
scVol = api.getVolume(volume.getNativeId());
}
if (scVol == null) {
throw new DellSCDriverException(String.format("Unable to find volume %s", volume.getNativeId()));
}
// Look up the server if needed
if (server == null) {
server = findScServer(api, ssn, initiators);
}
if (server == null) {
// Unable to find the server, can't continue
throw new DellSCDriverException(SERVER_CREATE_FAIL_MSG);
}
ScMappingProfile[] mappingProfiles = api.findMappingProfiles(server.instanceId, scVol.instanceId);
for (ScMappingProfile mappingProfile : mappingProfiles) {
api.deleteMappingProfile(mappingProfile.instanceId);
}
volumesUnmapped++;
LOG.info("Volume '{}' unexported from server '{}'", scVol.name, server.name);
} catch (StorageCenterAPIException | DellSCDriverException dex) {
String error = String.format("Error unmapping volume %s: %s", volume.getDisplayName(), dex);
LOG.error(error);
errBuffer.append(String.format("%s%n", error));
if (SERVER_CREATE_FAIL_MSG.equals(dex.getMessage())) {
// Game over
break;
}
}
}
task.setMessage(errBuffer.toString());
if (volumesUnmapped == volumes.size()) {
task.setStatus(TaskStatus.READY);
} else if (volumesUnmapped == 0) {
task.setStatus(TaskStatus.FAILED);
} else {
task.setStatus(TaskStatus.PARTIALLY_FAILED);
}
return task;
}
Aggregations