use of com.emc.storageos.storagedriver.HostExportInfo in project coprhd-controller by CoprHD.
the class ExternalDeviceUnManagedVolumeDiscoverer method verifyHostExports.
/**
* Verifies that all members of the specified list have the same set of initiators ans the same set
* of storage ports.
*
* @param hostExportInfoList list of HostExportInfo data
* @return If validation is success return VolumeToHostExportInfo with common set of initiators, common set of
* ports, and all volumes from all elements of input list.
* If validation failed, return null.
*/
private HostExportInfo verifyHostExports(List<HostExportInfo> hostExportInfoList) {
HostExportInfo exportInfo = hostExportInfoList.get(0);
// FQDN of a host
String hostName = exportInfo.getHostName();
// storage volumes native Ids
Set<String> volumeNativeIds = new HashSet<>();
// initiators port Ids
Set<String> masterInitiatorNetworkIds = new HashSet<>();
// target native Ids
Set<String> masterTargetNativeIds = new HashSet<>();
// get benchmark set of initiators and targets from first host export info instances
// List of host initiators
List<Initiator> initiators = exportInfo.getInitiators();
// List of storage ports
List<StoragePort> targets = exportInfo.getTargets();
for (Initiator initiator : initiators) {
masterInitiatorNetworkIds.add(initiator.getPort());
}
for (StoragePort port : targets) {
masterTargetNativeIds.add(port.getNativeId());
}
for (HostExportInfo hostExportInfo : hostExportInfoList) {
boolean isValid = verifyHostExports(masterInitiatorNetworkIds, masterTargetNativeIds, hostExportInfo);
if (!isValid) {
return null;
}
// Aggregate all volumes in one set.
volumeNativeIds.addAll(hostExportInfo.getStorageObjectNativeIds());
}
// Create result export info
HostExportInfo hostExportInfo = new HostExportInfo(hostName, new ArrayList<>(volumeNativeIds), initiators, targets);
return hostExportInfo;
}
use of com.emc.storageos.storagedriver.HostExportInfo in project coprhd-controller by CoprHD.
the class ExternalDeviceUnManagedVolumeDiscoverer method determineUnManagedExportMasksForExportInfo.
/**
* This method processes hostToVolumeExportInfoMap to find out which existing unmanaged masks has to be updated,
* and which unmanaged masks have to be created new for this export info. It also identifies hosts with unsupported
* export info data (exported host volumes are not seen through the same set of initiators and the same set of storage
* ports --- which require more than one mask per host) and adds these hosts to invalidExportHosts set.
*
* @param storageSystem
* @param hostToVolumeExportInfoMap [IN] map: key --- host FQDN, value --- list of volume export info instances
* @param invalidExportHosts [IN, OUT] set of invalid hosts, for which we skip export processing for a given array
* @param dbClient reference to db client [IN]
* @param masksToUpdateForVolumes [OUT] map: key --- URI of existing unmanaged export mask, value --- export info to use
* to update the mask.
* @param masksToCreateForVolumes [OUT] list of export info instances for which we need to create new unmanaged masks.
*/
private void determineUnManagedExportMasksForExportInfo(com.emc.storageos.db.client.model.StorageSystem storageSystem, Map<String, List<HostExportInfo>> hostToVolumeExportInfoMap, Set<String> invalidExportHosts, DbClient dbClient, Map<URI, HostExportInfo> masksToUpdateForVolumes, List<HostExportInfo> masksToCreateForVolumes) {
for (Map.Entry<String, List<HostExportInfo>> entry : hostToVolumeExportInfoMap.entrySet()) {
String hostName = entry.getKey();
log.info("Processing export info for host {} .", hostName);
if (invalidExportHosts.contains(hostName)) {
// skip and continue to the next host.
log.info("Found host {} in invalid hosts list. We will not process this host export data.", hostName);
continue;
}
List<HostExportInfo> volumeToHostExportInfoList = entry.getValue();
log.info("Processing export info list {} .", volumeToHostExportInfoList);
String maskName = getUnManagedMaskName(hostName, storageSystem.getNativeGuid());
HostExportInfo hostExportInfo = verifyHostExports(volumeToHostExportInfoList);
if (hostExportInfo == null) {
// invalid, continue to the next host
invalidExportHosts.add(hostName);
log.info("Found export info for host {} invalid. We will not process this host export data.", hostName);
// check existing UnManaged export mask for host/array: the mask could be discovered for volumes on previous
// pages (all unmanaged masks from previous discovery have been deactivated at the begging).
UnManagedExportMask unManagedMask = getUnManagedExportMask(maskName, dbClient, storageSystem.getId());
if (unManagedMask != null) {
log.info("Found existing unmanaged export mask for host {} and array {} --- {} . We will deactivate this mask.", hostName, storageSystem.getNativeId(), unManagedMask);
removeInvalidMaskDataFromVolumes(unManagedMask, dbClient);
unManagedMask.setInactive(true);
dbClient.updateObject(unManagedMask);
}
continue;
}
log.info("The result export info for host {} and array {} : {} .", hostName, storageSystem.getNativeId(), hostExportInfo);
// check existing UnManaged export mask for host/array: the mask could be discovered for volumes on previous
// pages (all unmanaged masks from previous discovery have been deactivated at the begging).
UnManagedExportMask unManagedMask = getUnManagedExportMask(maskName, dbClient, storageSystem.getId());
boolean isValid = true;
if (unManagedMask != null) {
log.info("Found existing unmanaged export mask for host {} and array {} --- {} .", hostName, storageSystem.getNativeId(), unManagedMask);
// check that existing host/array unManaged export mask has the same set of initiators and the same
// set of ports as new discovered hostExportInfo
StringSet storagePortsUris = unManagedMask.getKnownStoragePortUris();
Set<String> storagePortsNativeIds = new HashSet<>();
Set<String> initiatorsNativeIds = new HashSet<>();
for (String portUriString : storagePortsUris) {
URI portUri = URI.create(portUriString);
com.emc.storageos.db.client.model.StoragePort port = dbClient.queryObject(com.emc.storageos.db.client.model.StoragePort.class, portUri);
storagePortsNativeIds.add(port.getNativeId());
}
storagePortsNativeIds.addAll(unManagedMask.getUnmanagedStoragePortNetworkIds());
initiatorsNativeIds.addAll(unManagedMask.getKnownInitiatorNetworkIds());
initiatorsNativeIds.addAll(unManagedMask.getUnmanagedInitiatorNetworkIds());
isValid = verifyHostExports(initiatorsNativeIds, storagePortsNativeIds, hostExportInfo);
if (!isValid) {
// Invalid, we deactivate existing unmanaged mask --- make sure we do not discover invalid export
// masks. We also, remove this mask from "unmanagedExportMasks" set in its unmanaged storage volumes.
log.info("The result export info for host {} and storage array {} does not comply with existing mask.", hostName, storageSystem.getNativeId());
removeInvalidMaskDataFromVolumes(unManagedMask, dbClient);
unManagedMask.setInactive(true);
dbClient.updateObject(unManagedMask);
}
} else {
// Check if export mask for host/array is already managed. If host/array mask is managed, check that hostExportInfo has the same
// storage ports and the same host initiators as in the managed mask. If we have a match for ports/initiators between the mask and hostExportInfo, we will process this
// host export info and create a new UnManagedExportMask for the host.
log.info("There is no existing unmanaged export mask for host {} and array {} .", hostName, storageSystem.getNativeId());
List<String> initiatorPorts = new ArrayList<>();
for (Initiator initiator : hostExportInfo.getInitiators()) {
initiatorPorts.add(initiator.getPort());
}
// We enforce single export mask for host/array for ingested masks, so if only one initiator port match, the mask is a match.
Map<URI, ExportMask> uriToExportMask = ExportMaskUtils.getExportMasksWithInitiatorPorts(dbClient, initiatorPorts);
// Look for export mask for the storage system under processing.
for (ExportMask mask : uriToExportMask.values()) {
if (URIUtil.identical(mask.getStorageDevice(), storageSystem.getId())) {
// found managed export mask for storage system and host initiator
// the mask is already managed.
log.info("Found managed export mask for host {} and array {} --- {}." + " We will process this host export data to see if we can add volumes to this mask.", hostName, storageSystem.getNativeId(), mask.getId());
// check that this managed mask has the same initiators and ports as in the hostExportInfo
StringSet storagePortsUris = mask.getStoragePorts();
StringSet initiatorsUris = mask.getInitiators();
List<com.emc.storageos.db.client.model.StoragePort> ports = dbClient.queryObjectField(com.emc.storageos.db.client.model.StoragePort.class, "nativeId", StringSetUtil.stringSetToUriList(storagePortsUris));
List<com.emc.storageos.db.client.model.Initiator> initiators = dbClient.queryObjectField(com.emc.storageos.db.client.model.Initiator.class, "iniport", StringSetUtil.stringSetToUriList(initiatorsUris));
Set<String> maskStoragePortsNativeIds = new HashSet<>();
Set<String> maskInitiatorPorts = new HashSet<>();
for (com.emc.storageos.db.client.model.StoragePort storagePort : ports) {
maskStoragePortsNativeIds.add(storagePort.getNativeId());
}
for (com.emc.storageos.db.client.model.Initiator initiator : initiators) {
maskInitiatorPorts.add(initiator.getInitiatorPort());
}
log.info("Managed ExportMask {} has the following storage ports {}", mask.getId(), maskStoragePortsNativeIds);
log.info("Managed ExportMask {} has the following initiator ports {}", mask.getId(), maskInitiatorPorts);
// check that hostExportInfo has the same ports and initiators as in the export mask
isValid = verifyHostExports(maskInitiatorPorts, maskStoragePortsNativeIds, hostExportInfo);
if (isValid) {
// we will create unmanaged mask for this hostExportInfo
// we rely on ingestion to add new volumes to the managed mask.
log.info("Managed export mask {} has the same initiators and ports as in hostExportInfo. We will create unmanaged mask for new volumes.", mask.getId());
break;
} else {
log.info("Managed export mask {} has different initiators or ports as those in hostExportInfo.", mask.getId());
}
}
}
}
if (!isValid) {
// invalid, continue to the next host
// add host to invalid hosts list, so we do not process any export volume
// info for this host in the future (for volumes found on next pages).
log.info("Found export info for host {} invalid. Export info: {}." + " We will not process this host export data.", hostName, hostExportInfo);
invalidExportHosts.add(hostName);
continue;
}
if (unManagedMask != null) {
// we will update this mask with additional volumes.
URI maskId = unManagedMask.getId();
masksToUpdateForVolumes.put(maskId, hostExportInfo);
} else {
// we will create new unManaged mask for host/array.
masksToCreateForVolumes.add(hostExportInfo);
}
}
}
use of com.emc.storageos.storagedriver.HostExportInfo in project coprhd-controller by CoprHD.
the class DellSCProvisioning method populateVolumeExportInfo.
/**
* Fills in export information for a specific volume mapping.
*
* @param volumeId The volume instance ID.
* @param map The mapping.
* @param result The export info map.
* @param serverCache The server cache.
* @param serverPortCache The server HBA cache.
* @param portCache The controller port cache.
* @throws StorageCenterAPIException
*/
private void populateVolumeExportInfo(StorageCenterAPI api, String volumeId, ScMapping map, Map<String, HostExportInfo> result, Map<String, ScServer> serverCache, Map<String, Initiator> serverPortCache, Map<String, StoragePort> portCache) throws StorageCenterAPIException {
ScServer server;
Initiator initiator;
StoragePort port;
// Get our server info
if (serverCache.containsKey(map.server.instanceId)) {
server = serverCache.get(map.server.instanceId);
} else {
server = api.getServerDefinition(map.server.instanceId);
serverCache.put(server.instanceId, server);
}
// Find the server HBA
if (serverPortCache.containsKey(map.serverHba.instanceId)) {
initiator = serverPortCache.get(map.serverHba.instanceId);
} else {
ScServerHba hba = api.getServerHba(map.serverHba.instanceId);
initiator = getInitiatorInfo(api, server, hba);
serverPortCache.put(hba.instanceId, initiator);
}
// Get the controller port info
if (portCache.containsKey(map.controllerPort.instanceId)) {
port = portCache.get(map.controllerPort.instanceId);
} else {
ScControllerPort scPort = api.getControllerPort(map.controllerPort.instanceId);
port = util.getStoragePortForControllerPort(api, scPort);
portCache.put(scPort.instanceId, port);
}
String hostName = initiator.getHostName();
if (initiator.getInitiatorType() == Type.Cluster) {
hostName = initiator.getClusterName();
}
HostExportInfo exportInfo;
if (result.containsKey(hostName)) {
exportInfo = result.get(hostName);
} else {
exportInfo = new HostExportInfo(hostName, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
}
// Now populate all the info
if (!exportInfo.getStorageObjectNativeIds().contains(volumeId)) {
exportInfo.getStorageObjectNativeIds().add(volumeId);
}
if (!exportInfo.getTargets().contains(port)) {
exportInfo.getTargets().add(port);
}
if (!exportInfo.getInitiators().contains(initiator)) {
exportInfo.getInitiators().add(initiator);
}
result.put(hostName, exportInfo);
}
use of com.emc.storageos.storagedriver.HostExportInfo in project coprhd-controller by CoprHD.
the class DellSCProvisioning method getVolumeExportInfo.
/**
* Gets the mapping information for a volume to initiators.
*
* @param volumeId The volume instance ID.
* @param systemId The storage system ID.
* @return The mapping details. Map of HostName:HostExportInfo
*/
public Map<String, HostExportInfo> getVolumeExportInfo(String volumeId, String systemId) {
Map<String, HostExportInfo> result = new HashMap<>();
Map<String, ScServer> serverCache = new HashMap<>();
Map<String, Initiator> serverPortCache = new HashMap<>();
Map<String, StoragePort> portCache = new HashMap<>();
try {
StorageCenterAPI api = connectionManager.getConnection(systemId);
ScVolume scVol = api.getVolume(volumeId);
if (scVol == null) {
throw new DellSCDriverException(String.format("Volume %s could not be found.", volumeId));
}
ScMapping[] maps = api.getVolumeMaps(scVol.instanceId);
for (ScMapping map : maps) {
populateVolumeExportInfo(api, volumeId, map, result, serverCache, serverPortCache, portCache);
}
} catch (StorageCenterAPIException | DellSCDriverException dex) {
String message = String.format("Error getting export info for volume %s: %s", volumeId, dex);
LOG.warn(message);
}
return result;
}
use of com.emc.storageos.storagedriver.HostExportInfo in project coprhd-controller by CoprHD.
the class StorageDriverSimulator method generateExportDataForVolume.
private void generateExportDataForVolume(String hostName, String storageSystemId, String volumeId, int volumeIndex, List<StoragePort> ports, int page) {
Map<String, List<HostExportInfo>> volumeToExportInfoMap = arrayToVolumeToVolumeExportInfoMap.get(storageSystemId);
if (volumeToExportInfoMap == null) {
volumeToExportInfoMap = new HashMap<>();
arrayToVolumeToVolumeExportInfoMap.put(storageSystemId, volumeToExportInfoMap);
}
List<HostExportInfo> volumeToHostExportInfoList = volumeToExportInfoMap.get(volumeId);
if (volumeToHostExportInfoList == null) {
volumeToHostExportInfoList = new ArrayList<>();
volumeToExportInfoMap.put(volumeId, volumeToHostExportInfoList);
}
// build volume export info
HostExportInfo exportInfo;
// get volume info
List<String> volumeIds = new ArrayList<>();
volumeIds.add(volumeId);
// for initiators we only know port network id and host name
List<String> hostInitiatorIds = hostToInitiatorPortIdMap.get(hostName);
List<Initiator> initiators = new ArrayList<>();
for (String initiatorId : hostInitiatorIds) {
Initiator initiator = new Initiator();
initiator.setHostName(hostName);
initiator.setPort(initiatorId);
initiators.add(initiator);
}
// decide about ports.
if (page % 2 == 1) {
// for odd pages we generate invalid masks for volumes (to test negative scenarios)
int portIndex = volumeIndex < ports.size() ? volumeIndex : ports.size() - 1;
List<StoragePort> exportPorts = Collections.singletonList(ports.get(portIndex));
exportInfo = new HostExportInfo(hostName, volumeIds, initiators, exportPorts);
} else {
exportInfo = new HostExportInfo(hostName, volumeIds, initiators, ports);
}
volumeToHostExportInfoList.add(exportInfo);
_log.info("VolumeToHostExportInfo: " + volumeToHostExportInfoList);
}
Aggregations