use of com.emc.storageos.storagedriver.BlockStorageDriver in project coprhd-controller by CoprHD.
the class ExternalDeviceExportOperations method deleteExportMask.
@Override
public void deleteExportMask(StorageSystem storage, URI exportMaskUri, List<URI> volumeUrisList, List<URI> targetUris, List<com.emc.storageos.db.client.model.Initiator> initiators, TaskCompleter taskCompleter) throws DeviceControllerException {
// Unexport export mask volumes from export mask initiators.
log.info("{} deleteExportMask START...", storage.getSerialNumber());
try {
log.info("deleteExportMask: Export mask id: {}", exportMaskUri);
if (volumeUrisList != null) {
log.info("deleteExportMask: volumes: {}", Joiner.on(',').join(volumeUrisList));
}
if (targetUris != null) {
log.info("deleteExportMask: assignments: {}", Joiner.on(',').join(targetUris));
}
if (initiators != null) {
log.info("deleteExportMask: initiators: {}", Joiner.on(',').join(initiators));
}
BlockStorageDriver driver = externalDevice.getDriver(storage.getSystemType());
ExportMask exportMask = (ExportMask) dbClient.queryObject(exportMaskUri);
List<URI> volumeUris = new ArrayList<>();
StringMap maskVolumes = exportMask.getVolumes();
if (maskVolumes != null) {
for (String vol : maskVolumes.keySet()) {
URI volumeURI = URI.create(vol);
volumeUris.add(volumeURI);
}
}
StringSet maskInitiatorUris = exportMask.getInitiators();
List<String> initiatorUris = new ArrayList<>();
for (String initiatorUri : maskInitiatorUris) {
initiatorUris.add(initiatorUri);
}
log.info("Export mask existing initiators: {} ", Joiner.on(',').join(initiatorUris));
StringMap volumes = exportMask.getVolumes();
log.info("Export mask existing volumes: {} ", volumes != null ? Joiner.on(',').join(volumes.keySet()) : null);
// Prepare volumes.
List<StorageVolume> driverVolumes = new ArrayList<>();
prepareVolumes(storage, volumeUris, driverVolumes);
// Prepare initiators
List<Initiator> driverInitiators = new ArrayList<>();
Set<com.emc.storageos.db.client.model.Initiator> maskInitiators = ExportMaskUtils.getInitiatorsForExportMask(dbClient, exportMask, null);
// Get export group uri from task completer
URI exportGroupUri = taskCompleter.getId();
ExportGroup exportGroup = (ExportGroup) dbClient.queryObject(exportGroupUri);
prepareInitiators(maskInitiators, exportGroup.forCluster(), driverInitiators);
// Ready to call driver
log.info("Initiators to call driver: {} ", maskInitiators);
log.info("Volumes to call driver: {} ", volumeUris);
DriverTask task = driver.unexportVolumesFromInitiators(driverInitiators, driverVolumes);
// todo: need to implement support for async case.
if (task.getStatus() == DriverTask.TaskStatus.READY) {
String msg = String.format("Deleted export mask: %s.", task.getMessage());
log.info(msg);
taskCompleter.ready(dbClient);
} else {
String errorMsg = String.format("Failed to delete export mask: %s .", task.getMessage());
log.error(errorMsg);
ServiceError serviceError = ExternalDeviceException.errors.deleteExportMaskFailed("deleteExportMask", errorMsg);
taskCompleter.error(dbClient, serviceError);
}
} catch (Exception ex) {
log.error("Problem in deleteExportMask: ", ex);
String errorMsg = String.format("Failed to delete export mask: %s .", ex.getMessage());
log.error(errorMsg);
ServiceError serviceError = ExternalDeviceException.errors.deleteExportMaskFailed("deleteExportMask", errorMsg);
taskCompleter.error(dbClient, serviceError);
}
log.info("{} deleteExportMask END...", storage.getSerialNumber());
}
use of com.emc.storageos.storagedriver.BlockStorageDriver 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.BlockStorageDriver in project coprhd-controller by CoprHD.
the class ExternalBlockStorageDevice method doDetachClone.
@Override
public void doDetachClone(StorageSystem storageSystem, URI cloneVolume, TaskCompleter taskCompleter) {
BlockStorageDriver driver = getDriver(storageSystem.getSystemType());
DriverTask task = null;
Volume clone = dbClient.queryObject(Volume.class, cloneVolume);
_log.info("Detaching volume clone on storage system {}, clone: {} .", storageSystem.getNativeId(), clone.toString());
try {
BlockObject sourceVolume = BlockObject.fetch(dbClient, clone.getAssociatedSourceVolume());
VolumeClone driverClone = new VolumeClone();
driverClone.setStorageSystemId(storageSystem.getNativeId());
driverClone.setNativeId(clone.getNativeId());
driverClone.setParentId(sourceVolume.getNativeId());
driverClone.setConsistencyGroup(clone.getReplicationGroupInstance());
// Call driver
task = driver.detachVolumeClone(Collections.unmodifiableList(Collections.singletonList(driverClone)));
// todo: need to implement support for async case.
if (task.getStatus() == DriverTask.TaskStatus.READY) {
ReplicationUtils.removeDetachedFullCopyFromSourceFullCopiesList(clone, dbClient);
clone.setAssociatedSourceVolume(NullColumnValueGetter.getNullURI());
clone.setReplicaState(Volume.ReplicationState.DETACHED.name());
String msg = String.format("doDetachClone -- Detached volume clone: %s .", task.getMessage());
_log.info(msg);
dbClient.updateObject(clone);
taskCompleter.ready(dbClient);
} else {
String msg = String.format("Failed to detach volume clone on storage system %s, clone: %s .", storageSystem.getNativeId(), clone.toString());
_log.error(msg);
// todo: add error
ServiceError serviceError = ExternalDeviceException.errors.detachVolumeCloneFailed("doDetachClone", msg);
taskCompleter.error(dbClient, serviceError);
}
} catch (Exception e) {
String msg = String.format("Failed to detach volume clone on storage system %s, clone: %s .", storageSystem.getNativeId(), clone.toString());
_log.error(msg, e);
ServiceError serviceError = ExternalDeviceException.errors.detachVolumeCloneFailed("doDetachClone", msg);
taskCompleter.error(dbClient, serviceError);
}
}
use of com.emc.storageos.storagedriver.BlockStorageDriver in project coprhd-controller by CoprHD.
the class ExternalBlockStorageDevice method doExpandVolume.
@Override
public void doExpandVolume(StorageSystem storageSystem, StoragePool storagePool, Volume volume, Long size, TaskCompleter taskCompleter) throws DeviceControllerException {
_log.info("Volume expand ..... Started");
BlockStorageDriver driver = getDriver(storageSystem.getSystemType());
DriverTask task = null;
try {
// Prepare driver volume
StorageVolume driverVolume = new StorageVolume();
driverVolume.setNativeId(volume.getNativeId());
driverVolume.setDeviceLabel(volume.getDeviceLabel());
driverVolume.setStorageSystemId(storageSystem.getNativeId());
driverVolume.setStoragePoolId(storagePool.getNativeId());
driverVolume.setRequestedCapacity(volume.getCapacity());
driverVolume.setThinlyProvisioned(volume.getThinlyProvisioned());
driverVolume.setDisplayName(volume.getLabel());
driverVolume.setAllocatedCapacity(volume.getAllocatedCapacity());
driverVolume.setProvisionedCapacity(volume.getProvisionedCapacity());
driverVolume.setWwn(volume.getWWN());
// call driver
task = driver.expandVolume(driverVolume, size);
if (!isTaskInTerminalState(task.getStatus())) {
// If the task is not in a terminal state and will be completed asynchronously
// create a job to monitor the progress of the request and update the volume and
// call the completer as appropriate based on the result of the request.
ExpandVolumeExternalDeviceJob job = new ExpandVolumeExternalDeviceJob(storageSystem.getId(), volume.getId(), task.getTaskId(), taskCompleter);
ControllerServiceImpl.enqueueJob(new QueueJob(job));
} else if (task.getStatus() == DriverTask.TaskStatus.READY) {
String msg = String.format("doExpandVolume -- Expanded volume: %s .", task.getMessage());
_log.info(msg);
ExternalDeviceUtils.updateExpandedVolume(volume, driverVolume, dbClient);
taskCompleter.ready(dbClient);
} else {
// operation failed
String errorMsg = String.format("doExpandVolume -- Failed to expand volume: %s .", task.getMessage());
_log.error(errorMsg);
ServiceError serviceError = ExternalDeviceException.errors.expandVolumeFailed("doExpandVolume", errorMsg);
taskCompleter.error(dbClient, serviceError);
}
} catch (Exception e) {
_log.error("doExpandVolume -- Failed to expand volume. ", e);
ServiceError serviceError = ExternalDeviceException.errors.expandVolumeFailed("doExpandVolume", e.getMessage());
taskCompleter.error(dbClient, serviceError);
} finally {
try {
if (task == null || isTaskInTerminalState(task.getStatus())) {
updateStoragePoolCapacity(storagePool, storageSystem, URIUtil.toUris(Collections.singletonList(volume)), dbClient);
}
} catch (Exception ex) {
_log.error("Failed to update storage pool {} after expand volume operation completion.", storagePool.getId(), ex);
}
}
}
use of com.emc.storageos.storagedriver.BlockStorageDriver in project coprhd-controller by CoprHD.
the class ExternalBlockStorageDevice method doCreateConsistencyGroup.
@Override
public void doCreateConsistencyGroup(StorageSystem storageSystem, URI consistencyGroup, String replicationGroupName, TaskCompleter taskCompleter) throws DeviceControllerException {
_log.info("Creating consistency group for volumes START.....");
BlockConsistencyGroup cg = null;
try {
VolumeConsistencyGroup driverCG = new VolumeConsistencyGroup();
cg = dbClient.queryObject(BlockConsistencyGroup.class, consistencyGroup);
driverCG.setDisplayName(cg.getLabel());
driverCG.setStorageSystemId(storageSystem.getNativeId());
// call driver
BlockStorageDriver driver = getDriver(storageSystem.getSystemType());
DriverTask task = driver.createConsistencyGroup(driverCG);
// todo: need to implement support for async case.
if (task.getStatus() == DriverTask.TaskStatus.READY) {
cg.setNativeId(driverCG.getNativeId());
cg.addSystemConsistencyGroup(storageSystem.getId().toString(), cg.getLabel());
cg.addConsistencyGroupTypes(BlockConsistencyGroup.Types.LOCAL.name());
if (NullColumnValueGetter.isNullURI(cg.getStorageController())) {
cg.setStorageController(storageSystem.getId());
}
dbClient.updateObject(cg);
String msg = String.format("doCreateConsistencyGroup -- Created consistency group: %s .", task.getMessage());
_log.info(msg);
taskCompleter.ready(dbClient);
} else {
cg.setInactive(true);
dbClient.updateObject(cg);
String errorMsg = String.format("doCreateConsistencyGroup -- Failed to create Consistency Group: %s .", task.getMessage());
_log.error(errorMsg);
ServiceError serviceError = ExternalDeviceException.errors.createConsistencyGroupFailed("doCreateConsistencyGroup", errorMsg);
taskCompleter.error(dbClient, serviceError);
}
} catch (Exception e) {
if (cg != null) {
cg.setInactive(true);
dbClient.updateObject(cg);
}
String errorMsg = String.format("doCreateConsistencyGroup -- Failed to create Consistency Group: %s .", e.getMessage());
_log.error(errorMsg, e);
ServiceError serviceError = ExternalDeviceException.errors.createConsistencyGroupFailed("doCreateConsistencyGroup", errorMsg);
taskCompleter.error(dbClient, serviceError);
} finally {
_log.info("Creating consistency group for volumes END.....");
}
}
Aggregations