Search in sources :

Example 11 with InterProcessLock

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;
}
Also used : InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock)

Example 12 with InterProcessLock

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());
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) TenantOrg(com.emc.storageos.db.client.model.TenantOrg) Cluster(com.emc.storageos.db.client.model.Cluster) InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock) Host(com.emc.storageos.db.client.model.Host) ComputeVirtualPool(com.emc.storageos.db.client.model.ComputeVirtualPool) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) BadRequestException(com.emc.storageos.svcs.errorhandling.resources.BadRequestException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint) HashSet(java.util.HashSet) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces)

Example 13 with InterProcessLock

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;
}
Also used : InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) BadRequestException(com.emc.storageos.svcs.errorhandling.resources.BadRequestException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException)

Example 14 with InterProcessLock

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));
        }
    }
}
Also used : Site(com.emc.storageos.coordinator.client.model.Site) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) SiteState(com.emc.storageos.coordinator.client.model.SiteState) ArrayList(java.util.ArrayList) InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) CoordinatorException(com.emc.storageos.coordinator.exceptions.CoordinatorException) RetryableCoordinatorException(com.emc.storageos.coordinator.exceptions.RetryableCoordinatorException) UnknownHostException(java.net.UnknownHostException) Path(javax.ws.rs.Path) ZkPath(com.emc.storageos.coordinator.common.impl.ZkPath) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 15 with InterProcessLock

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());
        }
    }
}
Also used : UnManagedConsistencyGroup(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedConsistencyGroup) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) StorageVolume(com.emc.storageos.storagedriver.model.StorageVolume) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) HashSet(java.util.HashSet) StorageSystem(com.emc.storageos.storagedriver.model.StorageSystem) StorageVolume(com.emc.storageos.storagedriver.model.StorageVolume) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) Volume(com.emc.storageos.db.client.model.Volume) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) MutableInt(org.apache.commons.lang.mutable.MutableInt) InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock)

Aggregations

InterProcessLock (org.apache.curator.framework.recipes.locks.InterProcessLock)98 APIException (com.emc.storageos.svcs.errorhandling.resources.APIException)25 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)21 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)15 IOException (java.io.IOException)15 ControllerException (com.emc.storageos.volumecontroller.ControllerException)14 Configuration (com.emc.storageos.coordinator.common.Configuration)12 CoordinatorException (com.emc.storageos.coordinator.exceptions.CoordinatorException)12 UnknownHostException (java.net.UnknownHostException)12 Site (com.emc.storageos.coordinator.client.model.Site)11 RetryableCoordinatorException (com.emc.storageos.coordinator.exceptions.RetryableCoordinatorException)11 NetworkDeviceControllerException (com.emc.storageos.networkcontroller.exceptions.NetworkDeviceControllerException)10 CheckPermission (com.emc.storageos.security.authorization.CheckPermission)9 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)9 BiosCommandResult (com.emc.storageos.volumecontroller.impl.BiosCommandResult)9 ArrayList (java.util.ArrayList)9 POST (javax.ws.rs.POST)9 NetworkSystem (com.emc.storageos.db.client.model.NetworkSystem)8 Path (javax.ws.rs.Path)8 ConfigurationImpl (com.emc.storageos.coordinator.common.impl.ConfigurationImpl)6