use of com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo in project coprhd-controller by CoprHD.
the class VPlexDeviceController method updateThinProperty.
/**
* Updates the thinlyProvisioned property on the given VPLEX virtual volume by checking
* the VPLEX REST API for a change to the thin-enabled property on the virtual-volume.
*
* @param client
* a reference to the VPlexApiClient
* @param vplexSystem
* the StorageSystem object for the VPLEX
* @param vplexVolume
* the VPLEX virtual Volume object
*/
private void updateThinProperty(VPlexApiClient client, StorageSystem vplexSystem, Volume vplexVolume) {
if (vplexVolume != null && verifyVplexSupportsThinProvisioning(vplexSystem)) {
_log.info("Checking if thinly provisioned property changed after mirror operation...");
VPlexVirtualVolumeInfo virtualVolumeInfo = client.findVirtualVolume(vplexVolume.getDeviceLabel(), vplexVolume.getNativeId());
if (virtualVolumeInfo != null) {
if (VPlexApiConstants.TRUE.equalsIgnoreCase(virtualVolumeInfo.getThinCapable())) {
VirtualPool vpool = getDataObject(VirtualPool.class, vplexVolume.getVirtualPool(), _dbClient);
if (vpool != null) {
boolean doEnableThin = VirtualPool.ProvisioningType.Thin.toString().equalsIgnoreCase(vpool.getSupportedProvisioningType());
if (doEnableThin) {
// api client call will update thin-enabled on virtualVolumeInfo object, if it succeeds
client.setVirtualVolumeThinEnabled(virtualVolumeInfo);
}
}
}
if (virtualVolumeInfo.isThinEnabled() != vplexVolume.getThinlyProvisioned()) {
_log.info("Thin provisioned setting changed after mirror operation to " + virtualVolumeInfo.isThinEnabled());
vplexVolume.setThinlyProvisioned(virtualVolumeInfo.isThinEnabled());
_dbClient.updateObject(vplexVolume);
}
}
}
}
use of com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo in project coprhd-controller by CoprHD.
the class VPlexDeviceController method detachMirror.
/**
* Called to detach the remote mirror for a distributed VPLEX volume prior
* to restoring a native snapshot of the backend source volume.
*
* @param vplexURI
* The URI of the VPLEX system.
* @param vplexVolumeURI
* The URI of the distributed VPLEX volume.
* @param cgURI
* The URI of the volume's CG or null.
* @param stepId
* The workflow step identifier.
*/
public void detachMirror(URI vplexURI, URI vplexVolumeURI, URI cgURI, String stepId) {
_log.info("Executing detach mirror of VPLEX volume {} on VPLEX {}", new Object[] { vplexVolumeURI, vplexURI });
String detachedDeviceName = "";
try {
// Initialize the data that will tell RB what to do in
// case of failure.
Map<String, String> stepData = new HashMap<String, String>();
stepData.put(REATTACH_MIRROR, Boolean.FALSE.toString());
stepData.put(ADD_BACK_TO_CG, Boolean.FALSE.toString());
_workflowService.storeStepData(stepId, stepData);
// Update workflow step.
WorkflowStepCompleter.stepExecuting(stepId);
// Get the API client.
StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplexURI, _dbClient);
VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplexSystem, _dbClient);
_log.info("Got VPLEX API client");
// Get the VPLEX volume.
Volume vplexVolume = getDataObject(Volume.class, vplexVolumeURI, _dbClient);
String vplexVolumeName = vplexVolume.getDeviceLabel();
_log.info("Got VPLEX volume");
// COP-17337 : If device length is greater than 47 character then VPLEX does
// not allow reattaching mirror. This is mostly going to be the case for the
// distributed volume with XIO back-end on both legs. Temporarily rename the
// device to 47 characters and then detach the mirror. Now when we reattach
// the device name will not exceed the limit. We must do this before we detach
// so that the device name is the same for the detach/attach operations. If
// we try to rename prior to reattaching the mirror, COP-25581 will result.
VPlexVirtualVolumeInfo vvInfo = client.findVirtualVolume(vplexVolumeName, vplexVolume.getNativeId());
if (vvInfo != null) {
String distDeviceName = vvInfo.getSupportingDevice();
if (distDeviceName.length() > VPlexApiConstants.MAX_DEVICE_NAME_LENGTH_FOR_ATTACH_MIRROR) {
String modifiedName = distDeviceName.substring(0, VPlexApiConstants.MAX_DEVICE_NAME_LENGTH_FOR_ATTACH_MIRROR);
_log.info("Temporarily renaming the distributed device from {} to {} as VPLEX expects the name " + " to be 47 characters or less when we reattach the mirror.", distDeviceName, modifiedName);
client.renameDistributedDevice(distDeviceName, modifiedName);
stepData.put(RESTORE_DEVICE_NAME, distDeviceName);
}
} else {
_log.error("Can't find volume {}:{} to detach mirror.", vplexVolumeName, vplexVolumeURI);
throw VPlexApiException.exceptions.cantFindVolumeForDeatchMirror(vplexVolume.forDisplay());
}
// detaching the remote mirror.
if (cgURI != null) {
ConsistencyGroupManager consistencyGroupManager = getConsistencyGroupManager(vplexVolume);
consistencyGroupManager.removeVolumeFromCg(cgURI, vplexVolume, client, false);
stepData.put(ADD_BACK_TO_CG, Boolean.TRUE.toString());
_workflowService.storeStepData(stepId, stepData);
_log.info("Removed volumes from consistency group.");
}
// Detach the mirror.
detachedDeviceName = client.detachMirrorFromDistributedVolume(vplexVolumeName, null);
stepData.put(DETACHED_DEVICE, detachedDeviceName);
stepData.put(REATTACH_MIRROR, Boolean.TRUE.toString());
_workflowService.storeStepData(stepId, stepData);
_log.info("Detached the mirror");
updateThinProperty(client, vplexSystem, vplexVolume);
// Update workflow step state to success.
WorkflowStepCompleter.stepSucceded(stepId);
_log.info("Updated workflow step state to success");
} catch (VPlexApiException vae) {
_log.error("Exception detaching mirror for VPLEX distributed volume: " + vae.getMessage(), vae);
WorkflowStepCompleter.stepFailed(stepId, vae);
} catch (Exception e) {
_log.error("Exception detaching mirror for VPLEX distributed volume: " + e.getMessage(), e);
WorkflowStepCompleter.stepFailed(stepId, VPlexApiException.exceptions.failedDetachingVPlexVolumeMirror(detachedDeviceName, vplexVolumeURI.toString(), e));
}
}
Aggregations