public static void processMaxSubscriptionPercent( Integer newMaxSubscriptionPercentFromArray, StoragePool pool, DbClient dbClient, RecordableEventManager eventManager) { // get limits in vipr int poolSubscriptionPercent = pool.getMaxThinPoolSubscriptionPercentage() == null ? 0 : pool.getMaxThinPoolSubscriptionPercentage(); int poolUtilizationPercent = pool.getMaxPoolUtilizationPercentage() == null ? 0 : pool.getMaxPoolUtilizationPercentage(); _logger.info( String.format( "StoragePool %s subscription/utilization percent limits in vipr: %s / %s", pool.getPoolName(), poolSubscriptionPercent, poolUtilizationPercent)); Integer currentMaxSubscriptionPercentFromArray = pool.getMaxThinPoolSubscriptionPercentageFromArray(); _logger.info( String.format( "Current maximum subscription percent of storage pool %s from array in vipr : %s ", pool.getPoolName(), currentMaxSubscriptionPercentFromArray)); // Currently smis uses value of 0 as indication that MaxSubscriptionPercent is not available. // Some array clients explicitly set this array limit to 0 to indicate that the value is 0%. // The OPT was filed 448553 and it targeted for 4.6.2 // The plan is to use null to show that this property is not available, and 0 will show 0%. // Until the fix for OPT is in, we will use 0 and null as indication for the property is not // available. // TODO!! Remove check for 0 when the OPT is in. if (newMaxSubscriptionPercentFromArray != null && newMaxSubscriptionPercentFromArray != 0 && newMaxSubscriptionPercentFromArray < poolSubscriptionPercent) { // reset vipr limit and send alert pool.setMaxThinPoolSubscriptionPercentage(newMaxSubscriptionPercentFromArray); recordBourneStoragePoolEvent( RecordableEventManager.EventType.StoragePoolUpdated, pool, "Discovered pool max subscription percent is below current pool subscription limit. The limit will be reset.", RecordType.Alert, dbClient, eventManager); // check if we need to reset max utilization percent in vipr // pool max utilization percent is always less or equal to pool max subscription percent, // so we do this check in this 'if' statement if (newMaxSubscriptionPercentFromArray < poolUtilizationPercent) { // reset vipr utilization limit and send alert pool.setMaxPoolUtilizationPercentage(newMaxSubscriptionPercentFromArray); recordBourneStoragePoolEvent( RecordableEventManager.EventType.StoragePoolUpdated, pool, "Discovered pool max subscription percent is below current pool utilization limit. The limit will be reset.", RecordType.Alert, dbClient, eventManager); } } else if (currentMaxSubscriptionPercentFromArray != null && currentMaxSubscriptionPercentFromArray == poolSubscriptionPercent && (newMaxSubscriptionPercentFromArray == null || currentMaxSubscriptionPercentFromArray < newMaxSubscriptionPercentFromArray)) { // In this case array limit went up from previous value and vipr max pool subscription percent // is using old array value --- // send event that array value was increased so client may increase vipr limits if needed. recordBourneStoragePoolEvent( RecordableEventManager.EventType.StoragePoolUpdated, pool, "Discovered pool max subscription percent is above current pool subscription limit", RecordType.Event, dbClient, eventManager); } // set array subscription percent in the pool pool.setMaxThinPoolSubscriptionPercentageFromArray(newMaxSubscriptionPercentFromArray); // TODO!! Remove the "if" below when fix for OPT 448553 is in. // Use 0 as not available until then. if (newMaxSubscriptionPercentFromArray != null && newMaxSubscriptionPercentFromArray == 0) { pool.setMaxThinPoolSubscriptionPercentageFromArray(null); } }
/** * Create StoragePool Record, if not present already, else update only the properties. * * @param pool * @param poolInstance * @param profile * @param poolClassName * @param supportedVolumeTypes * @param protocols * @param poolsToMatchWithVpool * @throws URISyntaxException * @throws IOException */ private void createStoragePool( StoragePool pool, CIMInstance poolInstance, AccessProfile profile, String poolClassName, String supportedVolumeTypes, Set<String> protocols, Map<URI, StoragePool> poolsToMatchWithVpool, StorageSystem device) throws URISyntaxException, IOException { boolean newPool = false; boolean modifiedPool = false; // indicates whether to add to modified pools list or not if (null == pool) { String instanceID = getCIMPropertyValue(poolInstance, Constants.INSTANCEID); String nativeIdFromInstance = getNativeIDFromInstance(instanceID); newPool = true; pool = new StoragePool(); pool.setId(URIUtil.createId(StoragePool.class)); pool.setPoolName(getCIMPropertyValue(poolInstance, POOL_ID)); pool.setNativeId(nativeIdFromInstance); pool.setStorageDevice(profile.getSystemId()); pool.setPoolServiceType(PoolServiceType.block.toString()); String poolNativeGuid = NativeGUIDGenerator.generateNativeGuid(_dbClient, pool); pool.setNativeGuid(poolNativeGuid); pool.setLabel(poolNativeGuid); // setting default values on Pool Creation for VMAX and VNX pool.setMaximumThickVolumeSize(0L); pool.setMinimumThickVolumeSize(0L); pool.setMaximumThinVolumeSize(0L); pool.setMinimumThinVolumeSize(0L); if (device.getAutoTieringEnabled()) { pool.setAutoTieringEnabled(Boolean.TRUE); } else { pool.setAutoTieringEnabled(Boolean.FALSE); } _logger.info( String.format( "Maximum default limits for volume capacity in storage pool %s / %s : \n " + "max thin volume capacity: %s, max thick volume capacity: %s ", pool.getPoolName(), pool.getId(), pool.getMaximumThinVolumeSize(), pool.getMaximumThickVolumeSize())); // set default utilization/subscription limits double poolSubscriptionPercent = CapacityMatcher.getMaxPoolSubscriptionPercentage(pool, _coordinator); double poolUtilizationPercent = CapacityMatcher.getMaxPoolUtilizationPercentage(pool, _coordinator); pool.setMaxThinPoolSubscriptionPercentage((int) poolSubscriptionPercent); pool.setMaxPoolUtilizationPercentage((int) poolUtilizationPercent); } String maxSubscriptionPercent = getCIMPropertyValue(poolInstance, SmisConstants.CP_EMCMAXSUBSCRIPTIONPERCENT); _logger.info( String.format( "Discovered maximum subscription percent of storage pool %s from array : %s ", pool.getPoolName(), maxSubscriptionPercent)); // null value indicates "not available". Integer newMaxSubscriptionPercentFromArray = maxSubscriptionPercent == null ? null : new Integer(maxSubscriptionPercent); _logger.info( String.format( "New maximum subscription percent of storage pool %s from array : %s ", pool.getPoolName(), newMaxSubscriptionPercentFromArray)); processMaxSubscriptionPercent( newMaxSubscriptionPercentFromArray, pool, _dbClient, _eventManager); String subscribedCapacity = getCIMPropertyValue(poolInstance, SmisConstants.CP_SUBSCRIBEDCAPACITY); if (null != subscribedCapacity) { pool.setSubscribedCapacity(ControllerUtils.convertBytesToKBytes(subscribedCapacity)); } pool.setFreeCapacity(SmisUtils.getFreeCapacity(poolInstance)); pool.setTotalCapacity(SmisUtils.getTotalCapacity(poolInstance)); pool.setPoolClassName(poolClassName); pool.setSupportedResourceTypes(supportedVolumeTypes); String operationalStatus = determineOperationalStatus(poolInstance); if (!newPool && (ImplicitPoolMatcher.checkPoolPropertiesChanged( pool.getOperationalStatus(), operationalStatus) || ImplicitPoolMatcher.checkPoolPropertiesChanged(pool.getProtocols(), protocols) || ImplicitPoolMatcher.checkPoolPropertiesChanged( pool.getCompatibilityStatus(), DiscoveredDataObject.CompatibilityStatus.COMPATIBLE.name()) || ImplicitPoolMatcher.checkPoolPropertiesChanged( pool.getDiscoveryStatus(), DiscoveredDataObject.DiscoveryStatus.VISIBLE.name()))) { modifiedPool = true; } pool.addProtocols(protocols); pool.setOperationalStatus(operationalStatus); pool.setCompatibilityStatus(DiscoveredDataObject.CompatibilityStatus.COMPATIBLE.name()); pool.setDiscoveryStatus(DiscoveredDataObject.DiscoveryStatus.VISIBLE.name()); Set<String> diskDrives = new HashSet<String>(); String driveTypes = getCIMPropertyValue(poolInstance, EMC_DRIVE_TYPE); if (null != driveTypes) { String driveTypesArr[] = driveTypes.split(SPACE_STR_DELIM); if (device.checkIfVmax3() && driveTypesArr.length == 1 && driveTypesArr[0].equals(MIXED_DRIVE_TYPE)) { driveTypesArr = getVMAX3PoolDriveTypes(device, poolInstance); } for (String driveType : driveTypesArr) { String driveDisplayName = SupportedDriveTypeValues.getDiskDriveDisplayName(driveType); if (null == driveDisplayName) { _logger.warn( "UnSupported DiskDrive Type : {} resulting in drives not getting discovered for this pool: {}", driveType, getCIMPropertyValue(poolInstance, Constants.INSTANCEID)); continue; } diskDrives.add(driveDisplayName); } if (!newPool && !modifiedPool && ImplicitPoolMatcher.checkPoolPropertiesChanged( pool.getSupportedDriveTypes(), diskDrives)) { modifiedPool = true; } pool.addDriveTypes(diskDrives); } _logger.info("Discovered disk drives:[{}] for pool id:{}", driveTypes, pool.getId()); if (newPool) { _newPoolList.add(pool); // add new pools to modified pools list to consider them for implicit pool matching. if (!poolsToMatchWithVpool.containsKey(pool.getId())) { poolsToMatchWithVpool.put(pool.getId(), pool); } } else { _updatePoolList.add(pool); // add to modified pool list if pool's property which is required for vPool matcher, has // changed. // No need to check whether the pool is already there in the list here // because this processor is the first to discover pools. if (modifiedPool && !poolsToMatchWithVpool.containsKey(pool.getId())) { poolsToMatchWithVpool.put(pool.getId(), pool); } } }