use of org.apache.curator.framework.recipes.locks.InterProcessLock in project coprhd-controller by CoprHD.
the class ControllerLockingServiceImpl method getInterProcessLock.
/**
* Get InterProcessLock object from thread local. We keep single thread
*
* @param lockName
* @return InterProcessLock instance
*/
private InterProcessLock getInterProcessLock(String lockName) {
Map<String, InterProcessLock> lockMap = locks.get();
if (lockMap == null) {
lockMap = new WeakHashMap<String, InterProcessLock>();
locks.set(lockMap);
}
if (lockMap.containsKey(lockName)) {
return lockMap.get(lockName);
}
InterProcessLock lock = _coordinator.getLock(lockName);
lockMap.put(lockName, lock);
return lock;
}
use of org.apache.curator.framework.recipes.locks.InterProcessLock in project coprhd-controller by CoprHD.
the class HostService method provisionBareMetalHosts.
/**
* Provision bare metal hosts by taking compute elements from the compute
* virtual pool.
*
* @param param
* parameter for multiple host creation
* @brief Provision bare metal hosts
* @return TaskResourceRep (asynchronous call)
* @throws DatabaseException
*/
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/provision-bare-metal")
public TaskList provisionBareMetalHosts(ProvisionBareMetalHostsParam param) throws DatabaseException {
ComputeVirtualPool cvp = _dbClient.queryObject(ComputeVirtualPool.class, param.getComputeVpool());
ArgValidator.checkEntity(cvp, param.getComputeVpool(), false);
VirtualArray varray = _dbClient.queryObject(VirtualArray.class, param.getVarray());
ArgValidator.checkEntity(varray, param.getVarray(), false);
TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, param.getTenant());
ArgValidator.checkEntity(tenant, param.getTenant(), false);
if (!NullColumnValueGetter.isNullURI(param.getCluster())) {
Cluster cluster = _dbClient.queryObject(Cluster.class, param.getCluster());
ArgValidator.checkEntity(cluster, param.getCluster(), false);
}
_log.debug("checking if CVP is accessible");
_permissionsHelper.checkTenantHasAccessToComputeVirtualPool(tenant.getId(), cvp);
validateHostNames(param);
InterProcessLock lock = lockBladeReservation();
List<String> ceList = null;
try {
ceList = takeComputeElementsFromPool(cvp, param.getHostNames().size(), varray, param.getCluster());
} catch (Exception e) {
_log.error("unable to takeComputeElementsFromPool", e);
throw e;
} finally {
unlockBladeReservation(lock);
}
Set<Host> hosts = new HashSet<Host>();
for (int i = 0; i < param.getHostNames().size(); i++) {
Host host = populateHost(tenant, param.getHostNames().get(i), ceList.get(i), param.getCluster(), cvp.getId());
hosts.add(host);
_dbClient.createObject(host);
}
return createHostTasks(hosts, param.getComputeVpool(), param.getVarray());
}
use of org.apache.curator.framework.recipes.locks.InterProcessLock in project coprhd-controller by CoprHD.
the class HostService method lockBladeReservation.
private InterProcessLock lockBladeReservation() {
InterProcessLock lock = _coordinator.getLock(BLADE_RESERVATION_LOCK_NAME);
try {
lock.acquire();
_log.info("acquired BladeReservation lock");
} catch (Exception e) {
_log.error("failed to acquire BladeReservation lock", e);
throw BadRequestException.badRequests.unableToLockBladeReservation();
}
return lock;
}
use of org.apache.curator.framework.recipes.locks.InterProcessLock in project coprhd-controller by CoprHD.
the class DisasterRecoveryService method pause.
/**
* Pause data replication to multiple standby sites.
*
* @param idList site uuid list to be removed
* @brief Pause data replication to multiple standby sites.
* @return Response
*/
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@CheckPermission(roles = { Role.SECURITY_ADMIN, Role.RESTRICTED_SECURITY_ADMIN, Role.SYSTEM_ADMIN, Role.RESTRICTED_SYSTEM_ADMIN }, blockProxies = true)
@Path("/pause")
public Response pause(SiteIdListParam idList) {
List<String> siteIdList = idList.getIds();
String siteIdStr = StringUtils.join(siteIdList, ",");
log.info("Begin to pause standby site from local vdc by uuid: {}", siteIdStr);
List<Site> toBePausedSites = new ArrayList<>();
List<String> siteNameList = new ArrayList<>();
for (String siteId : siteIdList) {
Site site;
try {
site = drUtil.getSiteFromLocalVdc(siteId);
} catch (Exception ex) {
log.error("Can't load site {} from ZK", siteId);
throw APIException.badRequests.siteIdNotFound();
}
SiteState state = site.getState();
if (state.equals(SiteState.ACTIVE)) {
log.error("Unable to pause this site {}. It is active", siteId);
throw APIException.badRequests.operationNotAllowedOnActiveSite();
}
if (!state.equals(SiteState.STANDBY_SYNCED)) {
log.error("Unable to pause this site {}. It is in state {}", siteId, state);
throw APIException.badRequests.operationOnlyAllowedOnSyncedSite(site.getName(), state.toString());
}
toBePausedSites.add(site);
siteNameList.add(site.getName());
}
// This String is only used to output human readable message to user when Exception is thrown
String siteNameStr = StringUtils.join(siteNameList, ',');
precheckForPause(siteNameStr);
try {
// the site(s) to be paused must be checked as well
commonPrecheck();
} catch (APIException e) {
throw e;
} catch (Exception e) {
throw APIException.internalServerErrors.pauseStandbyPrecheckFailed(siteNameStr, e.getMessage());
}
InterProcessLock lock = drUtil.getDROperationLock();
// any error is not retry-able beyond this point.
List<String> sitesString = new ArrayList<>();
try {
log.info("Pausing sites");
long vdcTargetVersion = DrUtil.newVdcConfigVersion();
coordinator.startTransaction();
for (Site site : toBePausedSites) {
site.setState(SiteState.STANDBY_PAUSING);
site.setLastStateUpdateTime(System.currentTimeMillis());
coordinator.persistServiceConfiguration(site.toConfiguration());
drUtil.recordDrOperationStatus(site.getUuid(), InterState.PAUSING_STANDBY);
sitesString.add(site.toBriefString());
// notify the to-be-paused sites before others.
drUtil.updateVdcTargetVersion(site.getUuid(), SiteInfo.DR_OP_PAUSE_STANDBY, vdcTargetVersion);
}
log.info("Notify all sites for reconfig");
for (Site site : drUtil.listSites()) {
if (toBePausedSites.contains(site)) {
// already notified
continue;
}
drUtil.updateVdcTargetVersion(site.getUuid(), SiteInfo.DR_OP_PAUSE_STANDBY, vdcTargetVersion);
}
coordinator.commitTransaction();
auditDisasterRecoveryOps(OperationTypeEnum.PAUSE_STANDBY, AuditLogManager.AUDITLOG_SUCCESS, AuditLogManager.AUDITOP_BEGIN, StringUtils.join(sitesString, ','));
return Response.status(Response.Status.ACCEPTED).build();
} catch (Exception e) {
log.error("Failed to pause site {}", siteIdStr, e);
coordinator.discardTransaction();
auditDisasterRecoveryOps(OperationTypeEnum.PAUSE_STANDBY, AuditLogManager.AUDITLOG_FAILURE, null, StringUtils.join(sitesString, ','));
throw APIException.internalServerErrors.pauseStandbyFailed(siteNameStr, e.getMessage());
} finally {
try {
lock.release();
} catch (Exception ignore) {
log.error(String.format("Lock release failed when pausing standby site: %s", siteIdStr));
}
}
}
use of org.apache.curator.framework.recipes.locks.InterProcessLock 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());
}
}
}
Aggregations