use of com.emc.storageos.volumecontroller.impl.smis.job.SmisBlockSnapshotSessionUnlinkTargetJob in project coprhd-controller by CoprHD.
the class VmaxSnapshotOperations method unlinkSnapshotSessionTarget.
/**
* {@inheritDoc}
*/
@SuppressWarnings("rawtypes")
@Override
public void unlinkSnapshotSessionTarget(StorageSystem system, URI snapSessionURI, URI snapshotURI, Boolean deleteTarget, TaskCompleter completer) throws DeviceControllerException {
// Only supported for VMAX3 storage systems.
if (!system.checkIfVmax3()) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
try {
_log.info("Unlink target {} from snapshot session {} START", snapshotURI, snapSessionURI);
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotURI);
String targetDeviceId = snapshot.getNativeId();
if (isNullOrEmpty(targetDeviceId)) {
// The snapshot has no target device id. This means we must
// have failed creating the target device for a link target
// request and unlink target is being called in rollback.
// Since the target was never created, we just return
// success.
_log.info("Snapshot target {} was never created.", snapshotURI);
completer.ready(_dbClient);
return;
}
// If the snapshot has a native id, then we at least
// know the target device was created. Now we try and get
// the sync object path representing the linked target so
// that it can be detached.
boolean syncObjectFound = false;
List<BlockSnapshot> snapshots = null;
BlockObject sourceObj = BlockObject.fetch(_dbClient, snapshot.getParent().getURI());
CIMObjectPath syncObjectPath = SmisConstants.NULL_CIM_OBJECT_PATH;
if (snapshot.hasConsistencyGroup() && NullColumnValueGetter.isNotNullValue(snapshot.getReplicationGroupInstance())) {
String replicationGroupName = snapshot.getReplicationGroupInstance();
String sourceReplicationGroupName = sourceObj.getReplicationGroupInstance();
List<CIMObjectPath> groupSyncs = getAllGroupSyncObjects(system, snapshot);
if (groupSyncs != null && !groupSyncs.isEmpty()) {
// the passed snapshot is the sync'd element.
for (CIMObjectPath groupSynchronized : groupSyncs) {
String syncElementPath = groupSynchronized.getKeyValue(SmisConstants.CP_SYNCED_ELEMENT).toString();
String systemElementPath = groupSynchronized.getKeyValue(SmisConstants.CP_SYSTEM_ELEMENT).toString();
if (syncElementPath.contains(replicationGroupName) && systemElementPath.contains(sourceReplicationGroupName)) {
syncObjectPath = groupSynchronized;
break;
}
}
}
snapshots = ControllerUtils.getSnapshotsPartOfReplicationGroup(snapshot, _dbClient);
} else {
syncObjectPath = getSyncObject(system, snapshot, sourceObj);
snapshots = Lists.newArrayList(snapshot);
}
if (!SmisConstants.NULL_CIM_OBJECT_PATH.equals(syncObjectPath)) {
syncObjectFound = true;
CIMArgument[] inArgs = _helper.getUnlinkBlockSnapshotSessionTargetInputArguments(syncObjectPath);
CIMArgument[] outArgs = new CIMArgument[5];
CIMObjectPath replicationSvcPath = _cimPath.getControllerReplicationSvcPath(system);
SmisBlockSnapshotSessionUnlinkTargetJob job = new SmisBlockSnapshotSessionUnlinkTargetJob(null, system.getId(), completer);
_helper.invokeMethodSynchronously(system, replicationSvcPath, SmisConstants.MODIFY_REPLICA_SYNCHRONIZATION, inArgs, outArgs, job);
// Succeeded in unlinking the target from the snapshot.
for (BlockSnapshot snapshotToUpdate : snapshots) {
snapshotToUpdate.setSettingsInstance(NullColumnValueGetter.getNullStr());
}
_dbClient.updateObject(snapshots);
} else {
// For some reason we could not find the path for the
// CIM_StorageSychronized instance for the linked target.
// If the settingsInstance for the snapshot is not set,
// this may mean we just failed a link target request
// and unlink target is being called in rollback. In this
// case we successfully created the target volume, but
// failed to link the target to the snapshot, in which
// case the settingsInstance would be null. Otherwise,
// we could be retrying a failed unlink request. In this
// case, we must have succeeded in unlinking the target
// from the array snapshot, but failed attempting to
// delete the target volume. If the unlink is successful,
// the settingsInstance is reset to null. So, if the
// settingsInstance is null, we move on without failing.
// Otherwise, we should throw an exception.
String settingsInstance = snapshot.getSettingsInstance();
if (NullColumnValueGetter.isNotNullValue(settingsInstance)) {
throw DeviceControllerException.exceptions.couldNotFindSyncObjectToUnlinkTarget(targetDeviceId);
}
}
if (deleteTarget) {
_log.info("Delete target device {} :{}", targetDeviceId, snapshotURI);
Collection<String> nativeIds = transform(snapshots, fctnBlockObjectToNativeID());
if (snapshot.hasConsistencyGroup() && NullColumnValueGetter.isNotNullValue(snapshot.getReplicationGroupInstance())) {
try {
checkReplicationGroupAccessibleOrFail(system, snapshot, _dbClient, _helper, _cimPath);
deleteTargetGroup(system, snapshot.getReplicationGroupInstance());
} catch (DeviceControllerException | WBEMException e) {
_log.info("Failed to delete the target group. It may have already been deleted.");
}
}
// remove snapshot from them before deleting it.
for (BlockSnapshot snap : snapshots) {
try {
_helper.removeVolumeFromStorageGroupsIfVolumeIsNotInAnyMV(system, snap);
} catch (Exception e) {
_log.info("Failed to remove snap {} from storage groups. It may have already been removed.", snap.getNativeGuid());
}
}
callEMCRefresh(_helper, system, true);
deleteTargetDevices(system, nativeIds.toArray(new String[] {}), completer);
_log.info("Delete target device complete");
} else if (!syncObjectFound) {
// Need to be sure the completer is called.
completer.ready(_dbClient);
}
} catch (Exception e) {
_log.error("Exception unlinking snapshot session target", e);
ServiceError error = DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
completer.error(_dbClient, error);
}
}
Aggregations