use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class ExternalDeviceExportOperations method removeVolumes.
@Override
public void removeVolumes(StorageSystem storage, URI exportMaskUri, List<URI> volumeUris, List<com.emc.storageos.db.client.model.Initiator> initiatorList, TaskCompleter taskCompleter) throws DeviceControllerException {
log.info("{} removeVolumes START...", storage.getSerialNumber());
try {
log.info("removeVolumes: Export mask id: {}", exportMaskUri);
log.info("removeVolumes: volumes: {}", Joiner.on(',').join(volumeUris));
if (initiatorList != null) {
log.info("removeVolumes: impacted 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));
// Prepare volumes. We send to driver only new volumes for the export mask.
List<StorageVolume> driverVolumes = new ArrayList<>();
prepareVolumes(storage, volumeUris, driverVolumes);
// Prepare initiators
Set<com.emc.storageos.db.client.model.Initiator> initiators = ExportMaskUtils.getInitiatorsForExportMask(dbClient, exportMask, null);
List<Initiator> driverInitiators = new ArrayList<>();
// Get export group uri from task completer
URI exportGroupUri = taskCompleter.getId();
ExportGroup exportGroup = (ExportGroup) dbClient.queryObject(exportGroupUri);
prepareInitiators(initiators, exportGroup.forCluster(), driverInitiators);
// Ready to call driver
DriverTask task = driver.unexportVolumesFromInitiators(driverInitiators, driverVolumes);
// todo: need to implement support for async case.
if (task.getStatus() == DriverTask.TaskStatus.READY) {
String msg = String.format("Removed volumes from export: %s.", task.getMessage());
log.info(msg);
taskCompleter.ready(dbClient);
} else {
String errorMsg = String.format("Failed to remove volumes from export mask: %s .", task.getMessage());
log.error(errorMsg);
ServiceError serviceError = ExternalDeviceException.errors.deleteVolumesFromExportMaskFailed("removeVolumes", errorMsg);
taskCompleter.error(dbClient, serviceError);
}
} catch (Exception ex) {
log.error("Problem in removeVolumes: ", ex);
String errorMsg = String.format("Failed to remove volumes from export mask: %s .", ex.getMessage());
log.error(errorMsg);
ServiceError serviceError = ExternalDeviceException.errors.deleteVolumesFromExportMaskFailed("removeVolumes", errorMsg);
taskCompleter.error(dbClient, serviceError);
}
log.info("{} removeVolumes END...", storage.getSerialNumber());
}
use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class ExternalDeviceExportOperations method prepareVolumes.
/**
* Prepare new driver volumes for driver export request (Ex. in context of create a new export mask,
* or add new volumes to the existing mask).
*
* @param storage
* storage sytem
* @param volumeURIHLUs
* mapping of volume uri to volume hlu
* @param driverVolumes
* driver volumes (output)
* @param driverVolumeToHLUMap
* map of driver volumes to hlu values
* @param volumeNativeIdToUriMap
* map of volume native id to uri
*/
private void prepareVolumes(StorageSystem storage, VolumeURIHLU[] volumeURIHLUs, List<StorageVolume> driverVolumes, Map<String, String> driverVolumeToHLUMap, Map<String, URI> volumeNativeIdToUriMap) {
for (VolumeURIHLU volumeURIHLU : volumeURIHLUs) {
URI volumeURI = volumeURIHLU.getVolumeURI();
BlockObject volume = (BlockObject) dbClient.queryObject(volumeURI);
StorageVolume driverVolume = createDriverVolume(storage, volume);
driverVolumes.add(driverVolume);
// We send volume lun number to driver in decimal format.
Integer decimalHLU;
if (volumeURIHLU.getHLU().equals(ExportGroup.LUN_UNASSIGNED_STR)) {
// cannot parse "ffffffff" with
// Integer.parseInt(volumeURIHLU.getHLU(),
// 16),
// got "NumberFormatException". Looks as
// Java error ???
decimalHLU = ExportGroup.LUN_UNASSIGNED;
} else {
decimalHLU = Integer.parseInt(volumeURIHLU.getHLU(), 16);
}
driverVolumeToHLUMap.put(driverVolume.getNativeId(), decimalHLU.toString());
volumeNativeIdToUriMap.put(driverVolume.getNativeId(), volumeURI);
}
log.info("prepareVolumes: volume-HLU pairs for driver: {}", driverVolumeToHLUMap);
}
use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class ExternalDeviceExportOperations method createDriverVolume.
/**
* Create driver block object
*
* @param storage
* @param volume
* @return
*/
private StorageVolume createDriverVolume(StorageSystem storage, BlockObject volume) {
StorageVolume driverVolume = new StorageVolume();
driverVolume.setStorageSystemId(storage.getNativeId());
driverVolume.setNativeId(volume.getNativeId());
driverVolume.setDeviceLabel(volume.getDeviceLabel());
if (!NullColumnValueGetter.isNullURI(volume.getConsistencyGroup())) {
BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, volume.getConsistencyGroup());
driverVolume.setConsistencyGroup(cg.getLabel());
}
return driverVolume;
}
use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class ExternalDeviceUnManagedVolumeDiscoverer method discoverUnManagedBlockObjects.
/**
* Discovers unmanaged block objects: volumes, snaps, clones, their CG information and their exports.
* @param driver storage driver reference [IN]
* @param storageSystem storage system [IN]
* @param dbClient reference to db client [IN]
* @param partitionManager partition manager [IN]
*/
public void discoverUnManagedBlockObjects(BlockStorageDriver driver, com.emc.storageos.db.client.model.StorageSystem storageSystem, DbClient dbClient, PartitionManager partitionManager) {
Set<URI> allCurrentUnManagedVolumeUris = new HashSet<>();
Set<URI> allCurrentUnManagedCgURIs = new HashSet<>();
MutableInt lastPage = new MutableInt(0);
MutableInt nextPage = new MutableInt(0);
List<UnManagedVolume> unManagedVolumesToCreate = new ArrayList<>();
List<UnManagedVolume> unManagedVolumesToUpdate = new ArrayList<>();
List<UnManagedConsistencyGroup> unManagedCGToUpdate;
Map<String, UnManagedConsistencyGroup> unManagedCGToUpdateMap = new HashMap<>();
// We support only single export mask concept for host-array combination for external devices.
// If we find that storage system has volumes which are exported to the same host through
// different initiators or different array ports (we cannot create single UnManaged export
// mask for the host and the array in this case), we won't discover exports to this
// host on the array; we discover only volumes.
// The result of this limitation is that it could happen that for some volumes we are able to
// discover all their host exports;
// for some volumes we will be able to discover their exports to subset of hosts;
// for some volumes we may not be able to discover their exports to hosts.
// This limits management scope for pre-existing exports initially, but this does not
// not present a management issue for exports going forward, since driver implementation should handle export requests based
// on provided initiators and volumes in the requests and the current state of device.
// set of hosts for which we cannot build single export mask
Set<String> invalidExportHosts = new HashSet<>();
// for exported array volumes
// get inter-process lock for exclusive discovery of unmanaged objects for a given system
// lock is backed by curator's InterProcessMutex.
InterProcessLock lock = null;
String lockName = UNMANAGED_DISCOVERY_LOCK + storageSystem.getSystemType() + "-" + storageSystem.getNativeId();
try {
lock = coordinator.getLock(lockName);
boolean lockAcquired = lock.acquire(UNMANAGED_DISCOVERY_LOCK_TIMEOUT, TimeUnit.SECONDS);
if (lockAcquired) {
log.info("Acquired lock {} for storage system {} .", lockName, storageSystem.getNativeId());
} else {
log.info("Failed to acquire lock {} for storage system {} .", lockName, storageSystem.getNativeId());
return;
}
} catch (Exception ex) {
// check that lock was not acquired. if lock was acquired for this thread, proceed.
if (lock == null || !lock.isAcquiredInThisProcess()) {
log.error("Error processing unmanaged discovery for storage system: {}. Failed to get lock {} for this operation.", storageSystem.getNativeId(), lockName, ex);
return;
}
}
log.info("Started discovery of UnManagedVolumes for system {}", storageSystem.getId());
try {
// We need to deactivate all old unManaged export masks for this array. Each export discovery starts a new.
// Otherwise, we cannot distinguish between stale host masks and host mask discovered for volumes on the previous pages.
DiscoveryUtils.markInActiveUnManagedExportMask(storageSystem.getId(), new HashSet<URI>(), dbClient, partitionManager);
// prepare storage system
StorageSystem driverStorageSystem = ExternalDeviceCommunicationInterface.initStorageSystem(storageSystem);
do {
Map<String, List<HostExportInfo>> hostToVolumeExportInfoMap = new HashMap<>();
List<StorageVolume> driverVolumes = new ArrayList<>();
Map<String, URI> unManagedVolumeNativeIdToUriMap = new HashMap<>();
Map<String, URI> managedVolumeNativeIdToUriMap = new HashMap<>();
log.info("Processing page {} ", nextPage);
driver.getStorageVolumes(driverStorageSystem, driverVolumes, nextPage);
log.info("Volume count on this page {} ", driverVolumes.size());
for (StorageVolume driverVolume : driverVolumes) {
UnManagedVolume unManagedVolume = null;
try {
com.emc.storageos.db.client.model.StoragePool storagePool = getStoragePoolOfUnManagedVolume(storageSystem, driverVolume, dbClient);
if (null == storagePool) {
log.error("Skipping unManaged volume discovery as the volume {} storage pool doesn't exist in controller", driverVolume.getNativeId());
continue;
}
String managedVolumeNativeGuid = NativeGUIDGenerator.generateNativeGuidForVolumeOrBlockSnapShot(storageSystem.getNativeGuid(), driverVolume.getNativeId());
Volume systemVolume = DiscoveryUtils.checkStorageVolumeExistsInDB(dbClient, managedVolumeNativeGuid);
if (null != systemVolume) {
log.info("Skipping volume {} as it is already managed by the system. Id: {}", managedVolumeNativeGuid, systemVolume.getId());
// get export data for managed volume to process later --- we need to collect export data for
// managed volume
managedVolumeNativeIdToUriMap.put(driverVolume.getNativeId(), systemVolume.getId());
getVolumeExportInfo(driver, driverVolume, hostToVolumeExportInfoMap);
getExportInfoForManagedVolumeReplicas(managedVolumeNativeIdToUriMap, hostToVolumeExportInfoMap, dbClient, storageSystem, systemVolume, driverVolume, driver);
continue;
}
unManagedVolume = createUnManagedVolume(driverVolume, storageSystem, storagePool, unManagedVolumesToCreate, unManagedVolumesToUpdate, dbClient);
unManagedVolumeNativeIdToUriMap.put(driverVolume.getNativeId(), unManagedVolume.getId());
// if the volume is associated with a CG, set up the unManaged CG
if (driverVolume.getConsistencyGroup() != null && !driverVolume.getConsistencyGroup().isEmpty()) {
addObjectToUnManagedConsistencyGroup(storageSystem, driverVolume.getConsistencyGroup(), unManagedVolume, allCurrentUnManagedCgURIs, unManagedCGToUpdateMap, driver, dbClient);
} else {
// Make sure the unManagedVolume object does not contain CG information from previous discovery
unManagedVolume.getVolumeCharacterstics().put(UnManagedVolume.SupportedVolumeCharacterstics.IS_VOLUME_ADDED_TO_CONSISTENCYGROUP.toString(), Boolean.FALSE.toString());
// remove uri of the unManaged CG in the unManaged volume object
unManagedVolume.getVolumeInformation().remove(UnManagedVolume.SupportedVolumeInformation.UNMANAGED_CONSISTENCY_GROUP_URI.toString());
}
allCurrentUnManagedVolumeUris.add(unManagedVolume.getId());
getVolumeExportInfo(driver, driverVolume, hostToVolumeExportInfoMap);
Set<URI> unManagedSnaphotUris = processUnManagedSnapshots(driverVolume, unManagedVolume, storageSystem, storagePool, unManagedVolumesToCreate, unManagedVolumesToUpdate, allCurrentUnManagedCgURIs, unManagedCGToUpdateMap, unManagedVolumeNativeIdToUriMap, hostToVolumeExportInfoMap, driver, dbClient);
allCurrentUnManagedVolumeUris.addAll(unManagedSnaphotUris);
Set<URI> unManagedCloneUris = processUnManagedClones(driverVolume, unManagedVolume, storageSystem, storagePool, unManagedVolumesToCreate, unManagedVolumesToUpdate, allCurrentUnManagedCgURIs, unManagedCGToUpdateMap, unManagedVolumeNativeIdToUriMap, hostToVolumeExportInfoMap, driver, dbClient);
allCurrentUnManagedVolumeUris.addAll(unManagedCloneUris);
} catch (Exception ex) {
log.error("Error processing {} volume {}", storageSystem.getNativeId(), driverVolume.getNativeId(), ex);
}
}
if (!unManagedVolumesToCreate.isEmpty()) {
log.info("Unmanaged volumes to create: {}", unManagedVolumesToCreate);
partitionManager.insertInBatches(unManagedVolumesToCreate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_VOLUME);
unManagedVolumesToCreate.clear();
}
if (!unManagedVolumesToUpdate.isEmpty()) {
log.info("Unmanaged volumes to update: {}", unManagedVolumesToUpdate);
partitionManager.updateAndReIndexInBatches(unManagedVolumesToUpdate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_VOLUME);
unManagedVolumesToUpdate.clear();
}
// Process export data for volumes
processExportData(driver, storageSystem, unManagedVolumeNativeIdToUriMap, managedVolumeNativeIdToUriMap, hostToVolumeExportInfoMap, invalidExportHosts, dbClient, partitionManager);
} while (!nextPage.equals(lastPage));
if (!unManagedCGToUpdateMap.isEmpty()) {
unManagedCGToUpdate = new ArrayList<>(unManagedCGToUpdateMap.values());
partitionManager.updateAndReIndexInBatches(unManagedCGToUpdate, unManagedCGToUpdate.size(), dbClient, UNMANAGED_CONSISTENCY_GROUP);
unManagedCGToUpdate.clear();
}
log.info("Processed {} unmanged objects.", allCurrentUnManagedVolumeUris.size());
// Process those active unManaged volume objects available in database but not in newly discovered items, to mark them inactive.
DiscoveryUtils.markInActiveUnManagedVolumes(storageSystem, allCurrentUnManagedVolumeUris, dbClient, partitionManager);
// Process those active unManaged consistency group objects available in database but not in newly discovered items, to mark them
// inactive.
DiscoveryUtils.performUnManagedConsistencyGroupsBookKeeping(storageSystem, allCurrentUnManagedCgURIs, dbClient, partitionManager);
} catch (Exception ex) {
log.error("Error processing unmanaged discovery for storage system: {}. Error on page: {}.", storageSystem.getNativeId(), nextPage.toString(), ex);
} finally {
// release lock
try {
lock.release();
log.info("Released lock for storage system {}", storageSystem.getNativeId());
} catch (Exception e) {
log.error("Failed to release Lock {} : {}", lockName, e.getMessage());
}
}
}
use of com.emc.storageos.storagedriver.model.StorageVolume in project coprhd-controller by CoprHD.
the class ExternalDeviceUnManagedVolumeDiscoverer method getExportInfoForManagedVolumeReplicas.
/**
* Get export info for replicas (snaps and clones) of managed volume.
* We expect that all replicas of managed volume should be managed (known to the system) ---
* enforced by ingest framework, plus we do not support coexistence .
* Warning log message is generated for each replica which is unmanaged.
*
* @param managedVolumeNativeIdToUriMap [OUT], map: key --- managed volume native id, value: volume uri.
* @param hostToManagedVolumeExportInfoMap [OUT], map: key --- host name, value: list of export infos for volumes exported
* to this host.
* @param dbClient reference to db client [IN]
* @param storageSystem storage system [IN]
* @param systemVolume system volume [IN]
* @param driverVolume native volume [IN]
* @param driver reference to driver [IN]
* @throws Exception
*/
private void getExportInfoForManagedVolumeReplicas(Map<String, URI> managedVolumeNativeIdToUriMap, Map<String, List<HostExportInfo>> hostToManagedVolumeExportInfoMap, DbClient dbClient, com.emc.storageos.db.client.model.StorageSystem storageSystem, Volume systemVolume, StorageVolume driverVolume, BlockStorageDriver driver) throws Exception {
// get export info for managed volume snapshots
log.info("Processing snapshots for managed volume {} ", systemVolume.getNativeGuid());
List<VolumeSnapshot> driverSnapshots = driver.getVolumeSnapshots(driverVolume);
if (driverSnapshots == null || driverSnapshots.isEmpty()) {
log.info("There are no snapshots for volume {} ", systemVolume.getNativeGuid());
} else {
log.info("Snapshots for managed volume {}:" + Joiner.on("\t").join(driverSnapshots), systemVolume.getNativeGuid());
for (VolumeSnapshot driverSnapshot : driverSnapshots) {
String managedSnapNativeGuid = NativeGUIDGenerator.generateNativeGuidForVolumeOrBlockSnapShot(storageSystem.getNativeGuid(), driverSnapshot.getNativeId());
BlockSnapshot systemSnap = DiscoveryUtils.checkBlockSnapshotExistsInDB(dbClient, managedSnapNativeGuid);
if (systemSnap == null) {
log.warn("Found unmanaged snapshot of managed volume --- this is unexpected! Skipping this snapshot {}.", driverSnapshot.getNativeId());
continue;
} else {
log.info("Processing managed {} snapshot of managed volume ().", systemSnap.getNativeId(), systemVolume.getNativeGuid());
}
// get export data for the snapshot
managedVolumeNativeIdToUriMap.put(driverSnapshot.getNativeId(), systemSnap.getId());
getSnapshotExportInfo(driver, driverSnapshot, hostToManagedVolumeExportInfoMap);
}
}
// get export info for managed volume clones
log.info("Processing clones for managed volume {} ", systemVolume.getNativeGuid());
List<VolumeClone> driverClones = driver.getVolumeClones(driverVolume);
if (driverClones == null || driverClones.isEmpty()) {
log.info("There are no clones for volume {} ", systemVolume.getNativeGuid());
} else {
log.info("Clones for managed volume {}:" + Joiner.on("\t").join(driverClones), systemVolume.getNativeGuid());
for (VolumeClone driverClone : driverClones) {
String managedCloneNativeGuid = NativeGUIDGenerator.generateNativeGuidForVolumeOrBlockSnapShot(storageSystem.getNativeGuid(), driverClone.getNativeId());
Volume systemClone = DiscoveryUtils.checkStorageVolumeExistsInDB(dbClient, managedCloneNativeGuid);
if (systemClone == null) {
log.warn("Found unmanaged clone of managed volume --- this is unexpected! Skipping this clone {}.", driverClone.getNativeId());
continue;
} else {
log.info("Processing managed {} clone of managed volume ().", systemClone.getNativeId(), systemVolume.getNativeGuid());
}
// get export data for the clone
managedVolumeNativeIdToUriMap.put(driverClone.getNativeId(), systemClone.getId());
getCloneExportInfo(driver, driverClone, hostToManagedVolumeExportInfoMap);
}
}
}
Aggregations