/* * (non-Javadoc) * * @see com.emc.storageos.volumecontroller.BlockStorageDevice#doExpandAsMetaVolume(com.emc.storageos.db.client.model.StorageSystem, * com.emc.storageos.db.client.model.StoragePool, com.emc.storageos.db.client.model.Volume, long, * com.emc.storageos.volumecontroller.impl.smis.MetaVolumeRecommendation, com.emc.storageos.volumecontroller.TaskCompleter) */ @Override public void doExpandAsMetaVolume( StorageSystem storageSystem, StoragePool storagePool, Volume metaHead, long size, MetaVolumeRecommendation recommendation, VolumeExpandCompleter volumeCompleter) throws DeviceControllerException { StringBuilder logMsgBuilder = new StringBuilder( String.format( "Expand Meta Volume Start - Array:%s, Pool:%s %n Volume: %s, id: %s", storageSystem.getSerialNumber(), storagePool.getNativeId(), metaHead.getLabel(), metaHead.getId())); log.info(logMsgBuilder.toString()); long metaMemberCapacity = recommendation.getMetaMemberSize(); int metaMemberCount = (int) recommendation.getMetaMemberCount(); MetaVolumeTaskCompleter metaVolumeTaskCompleter = new MetaVolumeTaskCompleter(volumeCompleter); try { // Step 1: create meta members. List<String> newMetaMembers = metaVolumeOperations.createMetaVolumeMembers( storageSystem, storagePool, metaHead, metaMemberCount, metaMemberCapacity, metaVolumeTaskCompleter); log.info("ldevMetaMembers created successfully: {}", newMetaMembers); if (metaVolumeTaskCompleter.getLastStepStatus() == Job.JobStatus.SUCCESS) { metaVolumeOperations.expandMetaVolume( storageSystem, storagePool, metaHead, newMetaMembers, metaVolumeTaskCompleter); } else { ServiceError serviceError = DeviceControllerErrors.hds.jobFailed("LDEV Meta Member creation failed"); volumeCompleter.error(dbClient, serviceError); } } catch (final InternalException e) { log.error("Problem in doExpandAsMetaVolume: ", e); volumeCompleter.error(dbClient, e); } catch (final Exception e) { log.error("Problem in doExpandAsMetaVolume: ", e); ServiceError serviceError = DeviceControllerErrors.hds.methodFailed("doExpandAsMetaVolume", e.getMessage()); volumeCompleter.error(dbClient, serviceError); } }
/** * Called to update the job status when the volume expand job completes. * * @param jobContext The job context. */ public void updateStatus(JobContext jobContext) throws Exception { CloseableIterator<CIMObjectPath> associatorIterator = null; CloseableIterator<CIMInstance> instanceIterator = null; JobStatus jobStatus = getJobStatus(); try { if (jobStatus == JobStatus.IN_PROGRESS) { return; } DbClient dbClient = jobContext.getDbClient(); CIMConnectionFactory cimConnectionFactory = jobContext.getCimConnectionFactory(); WBEMClient client = getWBEMClient(dbClient, cimConnectionFactory); // If terminal state update storage pool capacity and remove reservation for volume capacity // from pool's reserved capacity map. if (jobStatus == JobStatus.SUCCESS || jobStatus == JobStatus.FAILED || jobStatus == JobStatus.FATAL_ERROR) { SmisUtils.updateStoragePoolCapacity(dbClient, client, _storagePoolURI); StoragePool pool = dbClient.queryObject(StoragePool.class, _storagePoolURI); StringMap reservationMap = pool.getReservedCapacityMap(); URI volumeId = getTaskCompleter().getId(); // remove from reservation map reservationMap.remove(volumeId.toString()); dbClient.persistObject(pool); } String opId = getTaskCompleter().getOpId(); StringBuilder logMsgBuilder = new StringBuilder( String.format( "Updating status of job %s to %s, task: %s", this.getJobName(), jobStatus.name(), opId)); if (jobStatus == JobStatus.SUCCESS) { VolumeExpandCompleter taskCompleter = (VolumeExpandCompleter) getTaskCompleter(); Volume volume = dbClient.queryObject(Volume.class, taskCompleter.getId()); // set requested capacity volume.setCapacity(taskCompleter.getSize()); // set meta related properties volume.setTotalMetaMemberCapacity(taskCompleter.getTotalMetaMembersSize()); volume.setMetaMemberCount(taskCompleter.getMetaMemberCount()); volume.setMetaMemberSize(taskCompleter.getMetaMemberSize()); volume.setIsComposite(taskCompleter.isComposite()); volume.setCompositionType(taskCompleter.getMetaVolumeType()); // set provisioned capacity associatorIterator = client.associatorNames(getCimJob(), null, SmisConstants.CIM_STORAGE_VOLUME, null, null); if (associatorIterator.hasNext()) { CIMObjectPath volumePath = associatorIterator.next(); CIMInstance volumeInstance = client.getInstance(volumePath, true, false, null); if (volumeInstance != null) { CIMProperty consumableBlocks = volumeInstance.getProperty(SmisConstants.CP_CONSUMABLE_BLOCKS); CIMProperty blockSize = volumeInstance.getProperty(SmisConstants.CP_BLOCK_SIZE); // calculate provisionedCapacity = consumableBlocks * block size Long provisionedCapacity = Long.valueOf(consumableBlocks.getValue().toString()) * Long.valueOf(blockSize.getValue().toString()); volume.setProvisionedCapacity(provisionedCapacity); } // set allocated capacity instanceIterator = client.referenceInstances( volumePath, SmisConstants.CIM_ALLOCATED_FROM_STORAGEPOOL, null, false, SmisConstants.PS_SPACE_CONSUMED); if (instanceIterator.hasNext()) { CIMInstance allocatedFromStoragePoolPath = instanceIterator.next(); CIMProperty spaceConsumed = allocatedFromStoragePoolPath.getProperty(SmisConstants.CP_SPACE_CONSUMED); if (null != spaceConsumed) { volume.setAllocatedCapacity(Long.valueOf(spaceConsumed.getValue().toString())); } } } logMsgBuilder.append( String.format( "%n Capacity: %s, Provisioned capacity: %s, Allocated Capacity: %s", volume.getCapacity(), volume.getProvisionedCapacity(), volume.getAllocatedCapacity())); if (volume.getIsComposite()) { logMsgBuilder.append( String.format( "%n Is Meta: %s, Total meta member capacity: %s, Meta member count %s, Meta member size: %s", volume.getIsComposite(), volume.getTotalMetaMemberCapacity(), volume.getMetaMemberCount(), volume.getMetaMemberSize())); } _log.info(logMsgBuilder.toString()); // Reset list of meta member volumes in the volume if (volume.getMetaVolumeMembers() != null) { volume.getMetaVolumeMembers().clear(); } StorageSystem storageSystem = dbClient.queryObject(StorageSystem.class, volume.getStorageController()); // set the RP tag on the volume if the volume is RP protected if (volume.checkForRp() && storageSystem.getSystemType() != null && storageSystem .getSystemType() .equalsIgnoreCase(DiscoveredDataObject.Type.vmax.toString())) { SmisCommandHelper helper = jobContext.getSmisCommandHelper(); List<CIMObjectPath> volumePathList = new ArrayList<CIMObjectPath>(); volumePathList.add(helper.getVolumeMember(storageSystem, volume)); helper.setRecoverPointTag(storageSystem, volumePathList, true); } dbClient.persistObject(volume); // Reset list of meta members native ids in WF data (when meta is created meta members are // removed from array) WorkflowService.getInstance().storeStepData(opId, new ArrayList<String>()); } } catch (Exception e) { _log.error("Caught an exception while trying to updateStatus for SmisVolumeExpandJob", e); setPostProcessingErrorStatus( "Encountered an internal error during volume expand job status processing : " + e.getMessage()); } finally { _metaVolumeTaskCompleter.setLastStepStatus(jobStatus); if (associatorIterator != null) { associatorIterator.close(); } if (instanceIterator != null) { instanceIterator.close(); } super.updateStatus(jobContext); } }