/* * (non-Javadoc) * * @see * com.emc.storageos.volumecontroller.BlockStorageDevice#doWaitForSynchronized * (java.lang.Class, com.emc.storageos.db.client.model.StorageSystem, * java.net.URI, com.emc.storageos.volumecontroller.TaskCompleter) */ @Override public void doWaitForSynchronized( Class<? extends BlockObject> clazz, StorageSystem storageObj, URI target, TaskCompleter completer) { log.info("START waitForSynchronized for {}", target); try { Volume targetObj = dbClient.queryObject(Volume.class, target); // Source could be either Volume or BlockSnapshot BlockObject sourceObj = BlockObject.fetch(dbClient, targetObj.getAssociatedSourceVolume()); // We split the pair which causes the data to be synchronized. // When the split is complete that data is synchronized. HDSApiClient hdsApiClient = hdsApiFactory.getClient( HDSUtils.getHDSServerManagementServerInfo(storageObj), storageObj.getSmisUserName(), storageObj.getSmisPassword()); HDSApiProtectionManager hdsApiProtectionManager = hdsApiClient.getHdsApiProtectionManager(); String replicationGroupObjectID = hdsApiProtectionManager.getReplicationGroupObjectId(); ReplicationInfo replicationInfo = hdsApiProtectionManager.getReplicationInfoFromSystem( sourceObj.getNativeId(), targetObj.getNativeId()) .first; hdsApiProtectionManager.modifyShadowImagePair( replicationGroupObjectID, replicationInfo.getObjectID(), HDSApiProtectionManager.ShadowImageOperationType.split); // Update state in case we are waiting for synchronization // after creation of a new full copy that was not created // inactive. String state = targetObj.getReplicaState(); if (!ReplicationState.SYNCHRONIZED.name().equals(state)) { targetObj.setSyncActive(true); targetObj.setReplicaState(ReplicationState.SYNCHRONIZED.name()); dbClient.persistObject(targetObj); } // Queue job to wait for replication status to move to split. ControllerServiceImpl.enqueueJob( new QueueJob( new HDSReplicationSyncJob( storageObj.getId(), sourceObj.getNativeId(), targetObj.getNativeId(), ReplicationStatus.SPLIT, completer))); } catch (Exception e) { log.error("Exception occurred while waiting for synchronization", e); ServiceError serviceError = DeviceControllerException.errors.jobFailed(e); completer.error(dbClient, serviceError); } log.info("completed doWaitForSynchronized"); }
/** * Prepares the VPLEX volume copies. * * @param name The base name for the volume. * @param copyCount The total number of copies. * @param copyIndex The index for this copy. * @param size The size for the HA volume. * @param srcVPlexVolume The VPLEX volume being copied. * @param srcProject The project for the VPLEX volume being copied. * @param srcVarray The virtual array for the VPLEX volume being copied. * @param srcVpool The virtual pool for the VPLEX volume being copied. * @param srcSystemURI The VPLEX system URI. * @param primaryVolume The primary volume for the copy. * @param haVolume The HA volume for the copy, or null. * @param taskId The task identifier. * @param volumeDescriptors The list of descriptors. * @return A reference to the prepared VPLEX volume copy. */ private Volume prepareFullCopyVPlexVolume( String name, int copyCount, int copyIndex, long size, Volume srcVPlexVolume, Project srcProject, VirtualArray srcVarray, VirtualPool srcVpool, URI srcSystemURI, Volume primaryVolume, Volume haVolume, String taskId, List<VolumeDescriptor> volumeDescriptors) { // Determine the VPLEX volume copy name. StringBuilder nameBuilder = new StringBuilder(name); if (copyCount > 1) { nameBuilder.append("-"); nameBuilder.append(copyIndex + 1); } // Prepare the VPLEX volume copy. Volume vplexCopyVolume = VPlexBlockServiceApiImpl.prepareVolumeForRequest( size, srcProject, srcVarray, srcVpool, srcSystemURI, NullColumnValueGetter.getNullURI(), nameBuilder.toString(), ResourceOperationTypeEnum.CREATE_VOLUME_FULL_COPY, taskId, _dbClient); // Create a volume descriptor and add it to the passed list. VolumeDescriptor vplexCopyVolumeDescr = new VolumeDescriptor( VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, srcSystemURI, vplexCopyVolume.getId(), null, null); volumeDescriptors.add(vplexCopyVolumeDescr); // Set the associated volumes for this new VPLEX volume copy to // the copy of the backend primary and the newly prepared HA // volume if the VPLEX volume being copied is distributed. vplexCopyVolume.setAssociatedVolumes(new StringSet()); StringSet assocVolumes = vplexCopyVolume.getAssociatedVolumes(); assocVolumes.add(primaryVolume.getId().toString()); if (haVolume != null) { assocVolumes.add(haVolume.getId().toString()); } // Set the VPLEX source volume for the copy. vplexCopyVolume.setAssociatedSourceVolume(srcVPlexVolume.getId()); // Copies always created active. vplexCopyVolume.setSyncActive(Boolean.TRUE); // Persist the copy. _dbClient.persistObject(vplexCopyVolume); return vplexCopyVolume; }