Search in sources :

Example 21 with GlobalLock

use of com.cloud.utils.db.GlobalLock in project cloudstack by apache.

the class ExternalFirewallDeviceManagerImpl method manageGuestNetworkWithExternalFirewall.

@Override
public boolean manageGuestNetworkWithExternalFirewall(boolean add, Network network) throws ResourceUnavailableException, InsufficientCapacityException {
    if (network.getTrafficType() != TrafficType.Guest) {
        s_logger.trace("External firewall can only be used for add/remove guest networks.");
        return false;
    }
    long zoneId = network.getDataCenterId();
    DataCenterVO zone = _dcDao.findById(zoneId);
    HostVO externalFirewall = null;
    if (add) {
        GlobalLock deviceMapLock = GlobalLock.getInternLock("NetworkFirewallDeviceMap");
        try {
            if (deviceMapLock.lock(120)) {
                try {
                    ExternalFirewallDeviceVO device = findSuitableFirewallForNetwork(network);
                    long externalFirewallId = device.getId();
                    NetworkExternalFirewallVO networkFW = new NetworkExternalFirewallVO(network.getId(), externalFirewallId);
                    _networkExternalFirewallDao.persist(networkFW);
                    externalFirewall = _hostDao.findById(device.getHostId());
                } finally {
                    deviceMapLock.unlock();
                }
            }
        } finally {
            deviceMapLock.releaseRef();
        }
    } else {
        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
        if (fwDeviceVO == null) {
            s_logger.warn("Network shutdown requested on external firewall element, which did not implement the network." + " Either network implement failed half way through or already network shutdown is completed.");
            return true;
        }
        externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
    }
    Account account = _accountDao.findByIdIncludingRemoved(network.getAccountId());
    NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
    boolean sharedSourceNat = offering.getSharedSourceNat();
    IPAddressVO sourceNatIp = null;
    if (!sharedSourceNat) {
        // Get the source NAT IP address for this network
        List<? extends IpAddress> sourceNatIps = _networkModel.listPublicIpsAssignedToAccount(network.getAccountId(), zoneId, true);
        for (IpAddress ipAddress : sourceNatIps) {
            if (ipAddress.getAssociatedWithNetworkId().longValue() == network.getId()) {
                sourceNatIp = _ipAddressDao.findById(ipAddress.getId());
                break;
            }
        }
        if (sourceNatIp == null) {
            String errorMsg = "External firewall was unable to find the source NAT IP address for network " + network.getName();
            s_logger.error(errorMsg);
            return true;
        }
    }
    // Send a command to the external firewall to implement or shutdown the guest network
    long guestVlanTag = Long.parseLong(BroadcastDomainType.getValue(network.getBroadcastUri()));
    String guestVlanGateway = network.getGateway();
    String guestVlanCidr = network.getCidr();
    String sourceNatIpAddress = null;
    String publicVlanTag = null;
    if (sourceNatIp != null) {
        sourceNatIpAddress = sourceNatIp.getAddress().addr();
        VlanVO publicVlan = _vlanDao.findById(sourceNatIp.getVlanId());
        publicVlanTag = publicVlan.getVlanTag();
    }
    // Get network rate
    Integer networkRate = _networkModel.getNetworkRate(network.getId(), null);
    IpAddressTO ip = new IpAddressTO(account.getAccountId(), sourceNatIpAddress, add, false, !sharedSourceNat, publicVlanTag, null, null, null, networkRate, false);
    IpAddressTO[] ips = new IpAddressTO[1];
    ips[0] = ip;
    IpAssocCommand cmd = new IpAssocCommand(ips);
    cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY, guestVlanGateway);
    cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, guestVlanCidr);
    cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag));
    Answer answer = _agentMgr.easySend(externalFirewall.getId(), cmd);
    List<String> reservedIpAddressesForGuestNetwork = _nicDao.listIpAddressInNetwork(network.getId());
    if (answer == null || !answer.getResult()) {
        String action = add ? "implement" : "shutdown";
        String answerDetails = (answer != null) ? answer.getDetails() : "answer was null";
        String msg = "External firewall was unable to " + action + " the guest network on the external firewall in zone " + zone.getName() + " due to " + answerDetails;
        s_logger.error(msg);
        if (!add && (!reservedIpAddressesForGuestNetwork.contains(network.getGateway()))) {
            // If we failed the implementation as well, then just return, no complain
            s_logger.error("Skip the shutdown of guest network on SRX because it seems we didn't implement it as well");
            return true;
        }
        throw new ResourceUnavailableException(msg, DataCenter.class, zoneId);
    }
    if (add && (!reservedIpAddressesForGuestNetwork.contains(network.getGateway()))) {
        // Insert a new NIC for this guest network to reserve the gateway address
        _networkMgr.savePlaceholderNic(network, network.getGateway(), null, null);
    }
    // Delete any mappings used for inline external load balancers in this network
    List<NicVO> nicsInNetwork = _nicDao.listByNetworkId(network.getId());
    for (NicVO nic : nicsInNetwork) {
        InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByNicId(nic.getId());
        if (mapping != null) {
            _nicDao.expunge(mapping.getNicId());
            _inlineLoadBalancerNicMapDao.expunge(mapping.getId());
        }
    }
    // on network shutdown, delete placeHolder nics used for the firewall device
    if (!add) {
        List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
        for (NicVO nic : nics) {
            if (nic.getVmType() == null && nic.getReservationStrategy().equals(ReservationStrategy.PlaceHolder) && nic.getIPv4Address().equals(network.getGateway())) {
                s_logger.debug("Removing placeholder nic " + nic + " for the network " + network);
                _nicDao.remove(nic.getId());
            }
        }
        freeFirewallForNetwork(network);
    }
    String action = add ? "implemented" : "shut down";
    s_logger.debug("External firewall has " + action + " the guest network for account " + account.getAccountName() + "(id = " + account.getAccountId() + ") with VLAN tag " + guestVlanTag);
    return true;
}
Also used : DataCenterVO(com.cloud.dc.DataCenterVO) Account(com.cloud.user.Account) ExternalFirewallDeviceVO(com.cloud.network.dao.ExternalFirewallDeviceVO) IpAddressTO(com.cloud.agent.api.to.IpAddressTO) NetworkOffering(com.cloud.offering.NetworkOffering) InlineLoadBalancerNicMapVO(com.cloud.network.dao.InlineLoadBalancerNicMapVO) HostVO(com.cloud.host.HostVO) GlobalLock(com.cloud.utils.db.GlobalLock) Answer(com.cloud.agent.api.Answer) NetworkExternalFirewallVO(com.cloud.network.dao.NetworkExternalFirewallVO) IpAssocCommand(com.cloud.agent.api.routing.IpAssocCommand) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) IPAddressVO(com.cloud.network.dao.IPAddressVO) VlanVO(com.cloud.dc.VlanVO) NicVO(com.cloud.vm.NicVO)

Example 22 with GlobalLock

use of com.cloud.utils.db.GlobalLock in project cloudstack by apache.

the class ExternalLoadBalancerDeviceManagerImpl method freeLoadBalancerForNetwork.

@DB
protected boolean freeLoadBalancerForNetwork(final Network guestConfig) {
    GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock");
    try {
        if (deviceMapLock.lock(120)) {
            ExternalLoadBalancerDeviceVO lbDevice = Transaction.execute(new TransactionCallback<ExternalLoadBalancerDeviceVO>() {

                @Override
                public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) {
                    // since network is shutdown remove the network mapping to the load balancer device
                    NetworkExternalLoadBalancerVO networkLBDevice = _networkExternalLBDao.findByNetworkId(guestConfig.getId());
                    long lbDeviceId = networkLBDevice.getExternalLBDeviceId();
                    _networkExternalLBDao.remove(networkLBDevice.getId());
                    List<NetworkExternalLoadBalancerVO> ntwksMapped = _networkExternalLBDao.listByLoadBalancerDeviceId(networkLBDevice.getExternalLBDeviceId());
                    ExternalLoadBalancerDeviceVO lbDevice = _externalLoadBalancerDeviceDao.findById(lbDeviceId);
                    boolean lbInUse = !(ntwksMapped == null || ntwksMapped.isEmpty());
                    boolean lbCloudManaged = lbDevice.getIsManagedDevice();
                    if (!lbInUse && !lbCloudManaged) {
                        // this is the last network mapped to the load balancer device so set device allocation state to be free
                        lbDevice.setAllocationState(LBDeviceAllocationState.Free);
                        _externalLoadBalancerDeviceDao.update(lbDevice.getId(), lbDevice);
                    }
                    // commit the changes before sending agent command to destroy cloudstack managed LB
                    if (!lbInUse && lbCloudManaged) {
                        return lbDevice;
                    } else {
                        return null;
                    }
                }
            });
            if (lbDevice != null) {
                // send DestroyLoadBalancerApplianceCommand to the host where load balancer appliance is provisioned
                Host lbHost = _hostDao.findById(lbDevice.getHostId());
                String lbIP = lbHost.getPrivateIpAddress();
                DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP);
                DestroyLoadBalancerApplianceAnswer answer = null;
                try {
                    answer = (DestroyLoadBalancerApplianceAnswer) _agentMgr.easySend(lbDevice.getParentHostId(), lbDeleteCmd);
                    if (answer == null || !answer.getResult()) {
                        s_logger.warn("Failed to destoy load balancer appliance used by the network" + guestConfig.getId() + " due to " + answer == null ? "communication error with agent" : answer.getDetails());
                    }
                } catch (Exception e) {
                    s_logger.warn("Failed to destroy load balancer appliance used by the network" + guestConfig.getId() + " due to " + e.getMessage());
                }
                if (s_logger.isDebugEnabled()) {
                    s_logger.debug("Successfully destroyed load balancer appliance used for the network" + guestConfig.getId());
                }
                deviceMapLock.unlock();
                // remove the provisioned load balancer appliance from cloudstack
                deleteExternalLoadBalancer(lbHost.getId());
                // release the private IP back to dc pool, as the load balancer appliance is now destroyed
                _dcDao.releasePrivateIpAddress(lbHost.getPrivateIpAddress(), guestConfig.getDataCenterId(), null);
                // release the public IP allocated for this LB appliance
                DetailVO publicIpDetail = _hostDetailDao.findDetail(lbHost.getId(), "publicip");
                IPAddressVO ipVo = _ipAddressDao.findByIpAndDcId(guestConfig.getDataCenterId(), publicIpDetail.toString());
                _ipAddrMgr.disassociatePublicIpAddress(ipVo.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
            } else {
                deviceMapLock.unlock();
            }
            return true;
        } else {
            s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + "as failed to acquire lock ");
            return false;
        }
    } catch (Exception exception) {
        s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + " due to " + exception.getMessage());
    } finally {
        deviceMapLock.releaseRef();
    }
    return false;
}
Also used : TransactionStatus(com.cloud.utils.db.TransactionStatus) Host(com.cloud.host.Host) NetworkExternalLoadBalancerVO(com.cloud.network.dao.NetworkExternalLoadBalancerVO) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InsufficientNetworkCapacityException(com.cloud.exception.InsufficientNetworkCapacityException) URISyntaxException(java.net.URISyntaxException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ConfigurationException(javax.naming.ConfigurationException) UnableDeleteHostException(com.cloud.resource.UnableDeleteHostException) GlobalLock(com.cloud.utils.db.GlobalLock) ExternalLoadBalancerDeviceVO(com.cloud.network.dao.ExternalLoadBalancerDeviceVO) DestroyLoadBalancerApplianceCommand(com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand) DetailVO(com.cloud.host.DetailVO) DestroyLoadBalancerApplianceAnswer(com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer) ArrayList(java.util.ArrayList) List(java.util.List) IPAddressVO(com.cloud.network.dao.IPAddressVO) DB(com.cloud.utils.db.DB)

Example 23 with GlobalLock

use of com.cloud.utils.db.GlobalLock in project cloudstack by apache.

the class ExternalLoadBalancerDeviceManagerImpl method allocateLoadBalancerForNetwork.

@DB
protected ExternalLoadBalancerDeviceVO allocateLoadBalancerForNetwork(final Network guestConfig) throws InsufficientCapacityException {
    boolean retry = true;
    boolean tryLbProvisioning = false;
    ExternalLoadBalancerDeviceVO lbDevice = null;
    long physicalNetworkId = guestConfig.getPhysicalNetworkId();
    NetworkOfferingVO offering = _networkOfferingDao.findById(guestConfig.getNetworkOfferingId());
    String provider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(guestConfig.getId(), Service.Lb);
    while (retry) {
        GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock");
        try {
            if (deviceMapLock.lock(120)) {
                try {
                    // does network offering supports a dedicated load balancer?
                    final boolean dedicatedLB = offering.getDedicatedLB();
                    try {
                        lbDevice = Transaction.execute(new TransactionCallbackWithException<ExternalLoadBalancerDeviceVO, InsufficientCapacityException>() {

                            @Override
                            public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException {
                                // FIXME: should the device allocation be done during network implement phase or do a
                                // lazy allocation when first rule for the network is configured??
                                // find a load balancer device for this network as per the network offering
                                ExternalLoadBalancerDeviceVO lbDevice = findSuitableLoadBalancerForNetwork(guestConfig, dedicatedLB);
                                long lbDeviceId = lbDevice.getId();
                                // persist the load balancer device id that will be used for this network. Once a network
                                // is implemented on a LB device then later on all rules will be programmed on to same device
                                NetworkExternalLoadBalancerVO networkLB = new NetworkExternalLoadBalancerVO(guestConfig.getId(), lbDeviceId);
                                _networkExternalLBDao.persist(networkLB);
                                // mark device to be either dedicated or shared use
                                lbDevice.setAllocationState(dedicatedLB ? LBDeviceAllocationState.Dedicated : LBDeviceAllocationState.Shared);
                                _externalLoadBalancerDeviceDao.update(lbDeviceId, lbDevice);
                                return lbDevice;
                            }
                        });
                        // allocated load balancer for the network, so skip retry
                        tryLbProvisioning = false;
                        retry = false;
                    } catch (InsufficientCapacityException exception) {
                        // if already attempted to provision load balancer then throw out of capacity exception,
                        if (tryLbProvisioning) {
                            retry = false;
                            // TODO: throwing warning instead of error for now as its possible another provider can service this network
                            s_logger.warn("There are no load balancer device with the capacity for implementing this network");
                            throw exception;
                        } else {
                            // if possible provision a LB appliance in to the physical network
                            tryLbProvisioning = true;
                        }
                    }
                } finally {
                    deviceMapLock.unlock();
                }
            }
        } finally {
            deviceMapLock.releaseRef();
        }
        // there are no LB devices or there is no free capacity on the devices in the physical network so provision a new LB appliance
        if (tryLbProvisioning) {
            // check if LB appliance can be dynamically provisioned
            List<ExternalLoadBalancerDeviceVO> providerLbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Provider);
            if ((providerLbDevices != null) && (!providerLbDevices.isEmpty())) {
                for (ExternalLoadBalancerDeviceVO lbProviderDevice : providerLbDevices) {
                    if (lbProviderDevice.getState() == LBDeviceState.Enabled) {
                        // acquire a private IP from the data center which will be used as management IP of provisioned LB appliance,
                        DataCenterIpAddressVO dcPrivateIp = _dcDao.allocatePrivateIpAddress(guestConfig.getDataCenterId(), lbProviderDevice.getUuid());
                        if (dcPrivateIp == null) {
                            throw new InsufficientNetworkCapacityException("failed to acquire a priavate IP in the zone " + guestConfig.getDataCenterId() + " needed for management IP of the load balancer appliance", DataCenter.class, guestConfig.getDataCenterId());
                        }
                        Pod pod = _podDao.findById(dcPrivateIp.getPodId());
                        String lbIP = dcPrivateIp.getIpAddress();
                        String netmask = NetUtils.getCidrNetmask(pod.getCidrSize());
                        String gateway = pod.getGateway();
                        // send CreateLoadBalancerApplianceCommand to the host capable of provisioning
                        CreateLoadBalancerApplianceCommand lbProvisionCmd = new CreateLoadBalancerApplianceCommand(lbIP, netmask, gateway);
                        CreateLoadBalancerApplianceAnswer createLbAnswer = null;
                        try {
                            createLbAnswer = (CreateLoadBalancerApplianceAnswer) _agentMgr.easySend(lbProviderDevice.getHostId(), lbProvisionCmd);
                            if (createLbAnswer == null || !createLbAnswer.getResult()) {
                                s_logger.error("Could not provision load balancer instance on the load balancer device " + lbProviderDevice.getId());
                                continue;
                            }
                        } catch (Exception agentException) {
                            s_logger.error("Could not provision load balancer instance on the load balancer device " + lbProviderDevice.getId() + " due to " + agentException.getMessage());
                            continue;
                        }
                        String username = createLbAnswer.getUsername();
                        String password = createLbAnswer.getPassword();
                        String publicIf = createLbAnswer.getPublicInterface();
                        String privateIf = createLbAnswer.getPrivateInterface();
                        // we have provisioned load balancer so add the appliance as cloudstack provisioned external load balancer
                        String dedicatedLb = offering.getDedicatedLB() ? "true" : "false";
                        String capacity = Long.toString(lbProviderDevice.getCapacity());
                        // acquire a public IP to associate with lb appliance (used as subnet IP to make the appliance part of private network)
                        PublicIp publicIp = _ipAddrMgr.assignPublicIpAddress(guestConfig.getDataCenterId(), null, _accountMgr.getSystemAccount(), VlanType.VirtualNetwork, null, null, false);
                        String publicIPNetmask = publicIp.getVlanNetmask();
                        String publicIPgateway = publicIp.getVlanGateway();
                        String publicIP = publicIp.getAddress().toString();
                        String publicIPVlanTag = "";
                        try {
                            publicIPVlanTag = BroadcastDomainType.getValue(publicIp.getVlanTag());
                        } catch (URISyntaxException e) {
                            s_logger.error("Failed to parse public ip vlan tag" + e.getMessage());
                        }
                        String url = "https://" + lbIP + "?publicinterface=" + publicIf + "&privateinterface=" + privateIf + "&lbdevicededicated=" + dedicatedLb + "&cloudmanaged=true" + "&publicip=" + publicIP + "&publicipnetmask=" + publicIPNetmask + "&lbdevicecapacity=" + capacity + "&publicipvlan=" + publicIPVlanTag + "&publicipgateway=" + publicIPgateway;
                        ExternalLoadBalancerDeviceVO lbAppliance = null;
                        try {
                            lbAppliance = addExternalLoadBalancer(physicalNetworkId, url, username, password, createLbAnswer.getDeviceName(), createLbAnswer.getServerResource(), false, false, null, null);
                        } catch (Exception e) {
                            s_logger.error("Failed to add load balancer appliance in to cloudstack due to " + e.getMessage() + ". So provisioned load balancer appliance will be destroyed.");
                        }
                        if (lbAppliance != null) {
                            // mark the load balancer as cloudstack managed and set parent host id on which lb appliance is provisioned
                            ExternalLoadBalancerDeviceVO managedLb = _externalLoadBalancerDeviceDao.findById(lbAppliance.getId());
                            managedLb.setIsManagedDevice(true);
                            managedLb.setParentHostId(lbProviderDevice.getHostId());
                            _externalLoadBalancerDeviceDao.update(lbAppliance.getId(), managedLb);
                        } else {
                            // failed to add the provisioned load balancer into cloudstack so destroy the appliance
                            DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP);
                            DestroyLoadBalancerApplianceAnswer answer = null;
                            try {
                                answer = (DestroyLoadBalancerApplianceAnswer) _agentMgr.easySend(lbProviderDevice.getHostId(), lbDeleteCmd);
                                if (answer == null || !answer.getResult()) {
                                    s_logger.warn("Failed to destroy load balancer appliance created");
                                } else {
                                    // release the public & private IP back to dc pool, as the load balancer appliance is now destroyed
                                    _dcDao.releasePrivateIpAddress(lbIP, guestConfig.getDataCenterId(), null);
                                    _ipAddrMgr.disassociatePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
                                }
                            } catch (Exception e) {
                                s_logger.warn("Failed to destroy load balancer appliance created for the network" + guestConfig.getId() + " due to " + e.getMessage());
                            }
                        }
                    }
                }
            }
        }
    }
    return lbDevice;
}
Also used : CreateLoadBalancerApplianceCommand(com.cloud.agent.api.routing.CreateLoadBalancerApplianceCommand) Pod(com.cloud.dc.Pod) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) PublicIp(com.cloud.network.addr.PublicIp) DataCenterIpAddressVO(com.cloud.dc.DataCenterIpAddressVO) TransactionStatus(com.cloud.utils.db.TransactionStatus) URISyntaxException(java.net.URISyntaxException) NetworkExternalLoadBalancerVO(com.cloud.network.dao.NetworkExternalLoadBalancerVO) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InsufficientNetworkCapacityException(com.cloud.exception.InsufficientNetworkCapacityException) URISyntaxException(java.net.URISyntaxException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ConfigurationException(javax.naming.ConfigurationException) UnableDeleteHostException(com.cloud.resource.UnableDeleteHostException) ExternalLoadBalancerDeviceVO(com.cloud.network.dao.ExternalLoadBalancerDeviceVO) GlobalLock(com.cloud.utils.db.GlobalLock) InsufficientNetworkCapacityException(com.cloud.exception.InsufficientNetworkCapacityException) DestroyLoadBalancerApplianceCommand(com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand) CreateLoadBalancerApplianceAnswer(com.cloud.network.resource.CreateLoadBalancerApplianceAnswer) NetworkOfferingVO(com.cloud.offerings.NetworkOfferingVO) DestroyLoadBalancerApplianceAnswer(com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) DB(com.cloud.utils.db.DB)

Example 24 with GlobalLock

use of com.cloud.utils.db.GlobalLock in project cloudstack by apache.

the class SecondaryStorageManagerImpl method allocCapacity.

private void allocCapacity(long dataCenterId, SecondaryStorageVm.Role role) {
    if (s_logger.isTraceEnabled()) {
        s_logger.trace("Allocate secondary storage vm standby capacity for data center : " + dataCenterId);
    }
    if (!isSecondaryStorageVmRequired(dataCenterId)) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " according to zone config");
        }
        return;
    }
    SecondaryStorageVmVO secStorageVm = null;
    String errorString = null;
    try {
        boolean secStorageVmFromStoppedPool = false;
        secStorageVm = assignSecStorageVmFromStoppedPool(dataCenterId, role);
        if (secStorageVm == null) {
            if (s_logger.isInfoEnabled()) {
                s_logger.info("No stopped secondary storage vm is available, need to allocate a new secondary storage vm");
            }
            if (_allocLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
                try {
                    secStorageVm = startNew(dataCenterId, role);
                    for (UploadVO upload : _uploadDao.listAll()) {
                        _uploadDao.expunge(upload.getId());
                    }
                } finally {
                    _allocLock.unlock();
                }
            } else {
                if (s_logger.isInfoEnabled()) {
                    s_logger.info("Unable to acquire synchronization lock for secondary storage vm allocation, wait for next scan");
                }
                return;
            }
        } else {
            if (s_logger.isInfoEnabled()) {
                s_logger.info("Found a stopped secondary storage vm, starting it. Vm id : " + secStorageVm.getId());
            }
            secStorageVmFromStoppedPool = true;
        }
        if (secStorageVm != null) {
            long secStorageVmId = secStorageVm.getId();
            GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVmId));
            try {
                if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
                    try {
                        secStorageVm = startSecStorageVm(secStorageVmId);
                    } finally {
                        secStorageVmLock.unlock();
                    }
                } else {
                    if (s_logger.isInfoEnabled()) {
                        s_logger.info("Unable to acquire synchronization lock for starting secondary storage vm id : " + secStorageVm.getId());
                    }
                    return;
                }
            } finally {
                secStorageVmLock.releaseRef();
            }
            if (secStorageVm == null) {
                if (s_logger.isInfoEnabled()) {
                    s_logger.info("Unable to start secondary storage vm for standby capacity, vm id : " + secStorageVmId + ", will recycle it and start a new one");
                }
                if (secStorageVmFromStoppedPool) {
                    destroySecStorageVm(secStorageVmId);
                }
            } else {
                SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this, new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_UP, dataCenterId, secStorageVmId, secStorageVm, null));
                if (s_logger.isInfoEnabled()) {
                    s_logger.info("Secondary storage vm " + secStorageVm.getHostName() + " is started");
                }
            }
        }
    } catch (Exception e) {
        errorString = e.getMessage();
        throw e;
    } finally {
        // Also add failure reason since startvm masks some of them.
        if (secStorageVm == null || secStorageVm.getState() != State.Running)
            SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this, new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATE_FAILURE, dataCenterId, 0l, null, errorString));
    }
}
Also used : GlobalLock(com.cloud.utils.db.GlobalLock) SecondaryStorageVmVO(com.cloud.vm.SecondaryStorageVmVO) UploadVO(com.cloud.storage.UploadVO) SecStorageVmAlertEventArgs(com.cloud.storage.secondary.SecStorageVmAlertEventArgs) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) URISyntaxException(java.net.URISyntaxException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) ConfigurationException(javax.naming.ConfigurationException) UnableDeleteHostException(com.cloud.resource.UnableDeleteHostException)

Example 25 with GlobalLock

use of com.cloud.utils.db.GlobalLock in project cloudstack by apache.

the class PrimaryDataStoreImpl method create.

/**
     * Please read the comment for the create(DataObject) method if you are planning on passing in "false" for createEntryInTempSpoolRef.
     */
@Override
public DataObject create(DataObject obj, boolean createEntryInTempSpoolRef) {
    // create template on primary storage
    if (obj.getType() == DataObjectType.TEMPLATE && (!isManaged() || (createEntryInTempSpoolRef && canCloneVolume()))) {
        try {
            String templateIdPoolIdString = "templateId:" + obj.getId() + "poolId:" + getId();
            VMTemplateStoragePoolVO templateStoragePoolRef;
            GlobalLock lock = GlobalLock.getInternLock(templateIdPoolIdString);
            if (!lock.lock(5)) {
                s_logger.debug("Couldn't lock the db on the string " + templateIdPoolIdString);
                return null;
            }
            try {
                templateStoragePoolRef = templatePoolDao.findByPoolTemplate(getId(), obj.getId());
                if (templateStoragePoolRef == null) {
                    if (s_logger.isDebugEnabled()) {
                        s_logger.debug("Not found (" + templateIdPoolIdString + ") in template_spool_ref, persisting it");
                    }
                    templateStoragePoolRef = new VMTemplateStoragePoolVO(getId(), obj.getId());
                    templateStoragePoolRef = templatePoolDao.persist(templateStoragePoolRef);
                }
            } catch (Throwable t) {
                if (s_logger.isDebugEnabled()) {
                    s_logger.debug("Failed to insert (" + templateIdPoolIdString + ") to template_spool_ref", t);
                }
                templateStoragePoolRef = templatePoolDao.findByPoolTemplate(getId(), obj.getId());
                if (templateStoragePoolRef == null) {
                    throw new CloudRuntimeException("Failed to create template storage pool entry");
                } else {
                    if (s_logger.isDebugEnabled()) {
                        s_logger.debug("Another thread already inserts " + templateStoragePoolRef.getId() + " to template_spool_ref", t);
                    }
                }
            } finally {
                lock.unlock();
                lock.releaseRef();
            }
        } catch (Exception e) {
            s_logger.debug("Caught exception ", e);
        }
    } else if (obj.getType() == DataObjectType.SNAPSHOT) {
        return objectInStoreMgr.create(obj, this);
    } else if (obj.getType() == DataObjectType.VOLUME) {
        VolumeVO vol = volumeDao.findById(obj.getId());
        if (vol != null) {
            vol.setPoolId(getId());
            volumeDao.update(vol.getId(), vol);
        }
    }
    return objectInStoreMgr.get(obj, this);
}
Also used : VMTemplateStoragePoolVO(com.cloud.storage.VMTemplateStoragePoolVO) GlobalLock(com.cloud.utils.db.GlobalLock) VolumeVO(com.cloud.storage.VolumeVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException)

Aggregations

GlobalLock (com.cloud.utils.db.GlobalLock)28 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)19 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)8 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)7 HostVO (com.cloud.host.HostVO)6 URISyntaxException (java.net.URISyntaxException)6 ConfigurationException (javax.naming.ConfigurationException)6 ClusterVO (com.cloud.dc.ClusterVO)5 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)5 DB (com.cloud.utils.db.DB)5 Date (java.util.Date)5 Answer (com.cloud.agent.api.Answer)4 TransactionCallbackWithException (com.cloud.utils.db.TransactionCallbackWithException)4 TransactionStatus (com.cloud.utils.db.TransactionStatus)4 AgentUnavailableException (com.cloud.exception.AgentUnavailableException)3 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)3 PermissionDeniedException (com.cloud.exception.PermissionDeniedException)3 StorageUnavailableException (com.cloud.exception.StorageUnavailableException)3 HypervisorType (com.cloud.hypervisor.Hypervisor.HypervisorType)3 IPAddressVO (com.cloud.network.dao.IPAddressVO)3