use of javax.cim.CIMArgument in project coprhd-controller by CoprHD.
the class VmaxSnapshotOperations method deleteTargetDevices.
/**
* Method will invoke the SMI-S operation to return the Volumes represented by the native ids to the storage pool
*
* @param storageSystem - StorageSystem where the pool and volume exist
* @param deviceIds - List of native Ids representing the elements to be returned to the pool
* @param taskCompleter - Completer object used for task status update
*
* @throws DeviceControllerException
*/
private void deleteTargetDevices(final StorageSystem storageSystem, final String[] deviceIds, final TaskCompleter taskCompleter) {
_log.info(format("Removing target devices {0} from storage system {1}", Joiner.on("\t").join(deviceIds), storageSystem.getId()));
try {
if (storageSystem.checkIfVmax3()) {
_helper.removeVolumeFromParkingSLOStorageGroup(storageSystem, deviceIds, false);
_log.info("Done invoking remove volumes from parking SLO storage group");
}
final CIMObjectPath configSvcPath = _cimPath.getConfigSvcPath(storageSystem);
final CIMObjectPath[] theElements = _cimPath.getVolumePaths(storageSystem, deviceIds);
final CIMArgument[] inArgs = _helper.getReturnElementsToStoragePoolArguments(theElements, SmisConstants.CONTINUE_ON_NONEXISTENT_ELEMENT);
final CIMArgument[] outArgs = new CIMArgument[5];
final SmisDeleteVmaxCGTargetVolumesJob job = new SmisDeleteVmaxCGTargetVolumesJob(null, storageSystem.getId(), deviceIds, taskCompleter);
_helper.invokeMethodSynchronously(storageSystem, configSvcPath, RETURN_ELEMENTS_TO_STORAGE_POOL, inArgs, outArgs, job);
} catch (Exception e) {
_log.error(format("An error occurred when removing target devices {0} from storage system {1}", Joiner.on("\t").join(deviceIds), storageSystem.getId()), e);
}
}
use of javax.cim.CIMArgument 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);
}
}
use of javax.cim.CIMArgument in project coprhd-controller by CoprHD.
the class VmaxSnapshotOperations method establishVolumeSnapshotGroupRelation.
@Override
public void establishVolumeSnapshotGroupRelation(StorageSystem storage, URI sourceVolume, URI snapshot, TaskCompleter taskCompleter) throws DeviceControllerException {
_log.info("establishVolumeSnapshotGroupRelation operation START");
try {
/**
* get groupPath for source volume
* get groupPath for snapshot
* get snapshots belonging to the same Replication Group
* get Element synchronizations between volumes and snapshots
* call CreateGroupReplicaFromElementSynchronizations
*/
BlockSnapshot snapshotObj = _dbClient.queryObject(BlockSnapshot.class, snapshot);
Volume volumeObj = _dbClient.queryObject(Volume.class, sourceVolume);
CIMObjectPath srcRepSvcPath = _cimPath.getControllerReplicationSvcPath(storage);
String volumeGroupName = ConsistencyGroupUtils.getSourceConsistencyGroupName(volumeObj, _dbClient);
CIMObjectPath volumeGroupPath = _cimPath.getReplicationGroupPath(storage, volumeGroupName);
CIMObjectPath snapshotGroupPath = _cimPath.getReplicationGroupPath(storage, snapshotObj.getReplicationGroupInstance());
// Check if snapshot is referenced by a BlockSnapshotSession
// if so, we must pass in the RelationshipName with the value of the session name.
// NB. a SourceGroup aspect must exist
List<BlockSnapshotSession> snapshotSessions = queryActiveResourcesByConstraint(_dbClient, BlockSnapshotSession.class, getLinkedTargetSnapshotSessionConstraint(snapshot));
String relationshipName = null;
if (!snapshotSessions.isEmpty()) {
relationshipName = snapshotSessions.get(0).getSessionLabel();
_log.info("Found snapshot session relationship: {}", relationshipName);
}
CIMObjectPath groupSynchronizedPath = _cimPath.getGroupSynchronized(volumeGroupPath, snapshotGroupPath);
CIMInstance syncInstance = _helper.checkExists(storage, groupSynchronizedPath, false, false);
if (syncInstance == null) {
// get all snapshots belonging to a Replication Group. There may be multiple snapshots available for a Volume
List<BlockSnapshot> snapshots = ControllerUtils.getSnapshotsPartOfReplicationGroup(snapshotObj, _dbClient);
List<CIMObjectPath> elementSynchronizations = new ArrayList<CIMObjectPath>();
for (BlockSnapshot snapshotObject : snapshots) {
Volume volume = _dbClient.queryObject(Volume.class, snapshotObject.getParent());
elementSynchronizations.add(_cimPath.getStorageSynchronized(storage, volume, storage, snapshotObject));
}
_log.info("Creating Group synchronization between volume group and snapshot group");
CIMArgument[] inArgs = _helper.getCreateGroupReplicaFromElementSynchronizationsForSRDFInputArguments(volumeGroupPath, snapshotGroupPath, elementSynchronizations, relationshipName);
CIMArgument[] outArgs = new CIMArgument[5];
_helper.invokeMethod(storage, srcRepSvcPath, SmisConstants.CREATE_GROUP_REPLICA_FROM_ELEMENT_SYNCHRONIZATIONS, inArgs, outArgs);
// No Job returned
} else {
_log.info("Link already established..");
}
taskCompleter.ready(_dbClient);
} catch (Exception e) {
String msg = String.format("Failed to establish group relation between volume group and snapshot group. Volume: %s, Snapshot: %s", sourceVolume, snapshot);
_log.error(msg, e);
ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
taskCompleter.error(_dbClient, serviceError);
}
}
use of javax.cim.CIMArgument in project coprhd-controller by CoprHD.
the class VmaxSnapshotOperations method restoreGroupSnapshots.
/**
* Implementation should restore the set of snapshots that were taken for a set of
* volumes in a consistency group. That is, at some time there was a consistency
* group of volumes created and snapshot was taken of these; these snapshots would
* belong to a "snap-set". This restore operation, will restore the volumes in the
* consistency group from this snap-set. Any snapshot from the snap-set can be
* provided to restore the whole snap-set.
*
* @param storage [required] - StorageSystem object representing the array
* @param snapshot [required] - BlockSnapshot URI representing the previously created
* snap for the volume
* @param taskCompleter - TaskCompleter object used for the updating operation status.
*/
@Override
public void restoreGroupSnapshots(StorageSystem storage, URI volume, URI snapshot, TaskCompleter taskCompleter) throws DeviceControllerException {
try {
callEMCRefreshIfRequired(_dbClient, _helper, storage, Arrays.asList(snapshot));
BlockSnapshot snapshotObj = _dbClient.queryObject(BlockSnapshot.class, snapshot);
// Check if the consistency group exists
String consistencyGroupName = ConsistencyGroupUtils.getSourceConsistencyGroupName(snapshotObj, _dbClient);
storage = findProviderFactory.withGroup(storage, consistencyGroupName).find();
if (storage == null) {
ServiceError error = DeviceControllerErrors.smis.noConsistencyGroupWithGivenName();
taskCompleter.error(_dbClient, error);
return;
}
String snapshotGroupName = snapshotObj.getReplicationGroupInstance();
CIMObjectPath groupSynchronized = _cimPath.getGroupSynchronizedPath(storage, consistencyGroupName, snapshotGroupName);
if (_helper.checkExists(storage, groupSynchronized, false, false) != null) {
CIMObjectPath cimJob = null;
if (storage.checkIfVmax3()) {
if (snapshotObj.getSettingsInstance() == null) {
throw DeviceControllerException.exceptions.snapSettingsInstanceNull(snapshotObj.getSnapsetLabel(), snapshotObj.getId().toString());
}
// there could only be one restored snapshot per device at a time
// terminate any pre-existing one in favor of the new one
terminateAnyRestoreSessions(storage, snapshotObj, snapshot, taskCompleter);
CIMObjectPath settingsPath = _cimPath.getGroupSynchronizedSettingsPath(storage, consistencyGroupName, snapshotObj.getSettingsInstance());
cimJob = _helper.callModifySettingsDefineState(storage, _helper.getRestoreFromSettingsStateInputArguments(settingsPath, false));
} else {
CIMArgument[] restoreCGSnapInput = _helper.getRestoreFromReplicaInputArguments(groupSynchronized);
cimJob = _helper.callModifyReplica(storage, restoreCGSnapInput);
}
ControllerServiceImpl.enqueueJob(new QueueJob(new SmisBlockRestoreSnapshotJob(cimJob, storage.getId(), taskCompleter)));
} else {
ServiceError error = DeviceControllerErrors.smis.unableToFindSynchPath(consistencyGroupName);
taskCompleter.error(_dbClient, error);
}
} catch (Exception e) {
String message = String.format("Generic exception when trying to restoring snapshots from consistency group on array %s", storage.getSerialNumber());
_log.error(message, e);
ServiceError error = DeviceControllerErrors.smis.methodFailed("restoreGroupSnapshots", e.getMessage());
taskCompleter.error(_dbClient, error);
}
}
use of javax.cim.CIMArgument in project coprhd-controller by CoprHD.
the class VmaxSnapshotOperations method createStorageSetting.
/**
* In order to create VDEV targets for snapshots, we need to have a StorageSetting
* with a parameter set to enable it. This method will create an instance of this.
* We will try to maintain a single StorageSetting for this purpose, per pool. To
* that end, we'll first check for the existence of the setting (based on a
* special name).
*
* @param storage - StorageSystem where the pool exists
* @param poolPath - CIMObject representing the pool to allocate targets from
* @return CIMInstance - null => error. Otherwise, will be the StorageSetting
* instance for creating VDEVs against the pool.
* @throws DeviceControllerException
*/
private CIMInstance createStorageSetting(StorageSystem storage, CIMObjectPath poolPath) throws Exception {
CloseableIterator<CIMObjectPath> capabilities = null;
CloseableIterator<CIMObjectPath> poolSettings = null;
CIMInstance instance = null;
try {
// From the storage pool, get its capability (assuming there is only
// one per pool). Get associated storage settings from the capability,
// loop through each and find one that has the special name. If it
// doesn't exist, create it and modify the StorageExtentInitialUsage
// and ElementName.
capabilities = _helper.getAssociatorNames(storage, poolPath, null, SYMM_STORAGE_POOL_CAPABILITIES, null, null);
if (capabilities != null && capabilities.hasNext()) {
CIMObjectPath poolCapabilities = capabilities.next();
poolSettings = _helper.getAssociatorNames(storage, poolCapabilities, null, SYMM_STORAGE_POOL_SETTING, null, null);
CIMInstance foundVdevSettingForThisPool = null;
while (poolSettings != null && poolSettings.hasNext()) {
CIMInstance it = _helper.getInstance(storage, poolSettings.next(), false, false, PL_STORAGE_EXTENT_INITIAL_USAGE);
int storageExtentInitialUsage = Integer.valueOf(CIMPropertyFactory.getPropertyValue(it, CP_STORAGE_EXTENT_INITIAL_USAGE));
if (storageExtentInitialUsage == DELTA_REPLICA_TARGET_VALUE) {
// We found a setting that has the "Delta Replica Target" value
// for the StorageExtentInitialUsage attribute
foundVdevSettingForThisPool = it;
break;
}
}
if (foundVdevSettingForThisPool != null) {
instance = foundVdevSettingForThisPool;
_log.info(String.format("Found existing StorageSetting for VDEV %s", instance.toString()));
} else {
// It wasn't found ==> create it
// TODO: How do we prevent concurrent operations from creating duplicates?
_log.info("Could not find existing StorageSetting for VDEV, going to create it and modify it...");
CIMArgument[] inArgs = _helper.getCreateDefaultStoragePoolSettingsArguments();
CIMArgument[] outArgs = new CIMArgument[5];
_helper.invokeMethod(storage, poolCapabilities, CREATE_SETTING, inArgs, outArgs);
CIMObjectPath newSetting = _cimPath.getCimObjectPathFromOutputArgs(outArgs, NEW_SETTING);
instance = _cimPath.getStoragePoolVdevSettings(newSetting);
_helper.modifyInstance(storage, instance, PL_STORAGE_EXTENT_INITIAL_USAGE);
// Get the unique ID for display
CIMInstance newSettingInstance = _helper.getInstance(storage, newSetting, false, false, PL_ONLY_EMC_UNIQUE_ID);
String emcUniqueId = CIMPropertyFactory.getPropertyValue(newSettingInstance, CP_EMC_UNIQUE_ID);
_log.info(String.format("Created StorageSetting for VDEV %s (EMCUniqueID = %s)", instance.toString(), emcUniqueId));
}
} else {
String message = String.format("Could not find any %s instances for StoragePool %s. Will not be able to create a StorageSetting.", SYMM_STORAGE_POOL_CAPABILITIES, poolPath.toString());
_log.error(message);
throw DeviceControllerExceptions.smis.noStoragePoolInstances(message, null);
}
} finally {
if (capabilities != null) {
capabilities.close();
}
if (poolSettings != null) {
poolSettings.close();
}
}
return instance;
}
Aggregations