blob: 40e4a0f3dfc4d6b70728fc65d908cfbd04e5b22c [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.storage;
import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.commons.collections.CollectionUtils;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.VMInstanceDao;
import org.apache.logging.log4j.Logger;
public class StorageUtil {
@Inject private ClusterDao clusterDao;
@Inject private HostDao hostDao;
@Inject private PrimaryDataStoreDao storagePoolDao;
@Inject private VMInstanceDao vmInstanceDao;
@Inject private VolumeDao volumeDao;
public static void traceLogStoragePools(List<StoragePool> poolList, Logger logger, String initialMessage) {
if (logger.isTraceEnabled()) {
StringBuilder pooltable = new StringBuilder();
pooltable.append(initialMessage);
int i = 1;
for (StoragePool pool : poolList) {
pooltable.append("\nno ").append(i).append(": ").append(pool.getName()).append("/").append(pool.getUuid());
}
logger.trace(pooltable.toString());
}
}
private Long getClusterId(Long hostId) {
if (hostId == null) {
return null;
}
HostVO hostVO = hostDao.findById(hostId);
if (hostVO == null) {
return null;
}
return hostVO.getClusterId();
}
/**
* This method relates to managed storage only. CloudStack currently supports managed storage with XenServer, vSphere, and KVM.
* With managed storage on XenServer and vSphere, CloudStack needs to use an iSCSI SR (XenServer) or datastore (vSphere) per CloudStack
* volume. Since XenServer and vSphere are limited to the hundreds with regards to how many SRs or datastores can be leveraged per
* compute cluster, this method is used to check a Global Setting (that specifies the maximum number of SRs or datastores per compute cluster)
* against what is being requested. KVM does not apply here because it does not suffer from the same scalability limits as XenServer and
* vSphere do. With XenServer and vSphere, each host is configured to see all the SRs/datastores of the cluster. With KVM, each host typically
* is only configured to see the managed volumes of the VMs that are currently running on that host.
*
* If the clusterId is passed in, we use it. Otherwise, we use the hostId. If neither leads to a cluster, we just return true.
*/
public boolean managedStoragePoolCanScale(StoragePool storagePool, Long clusterId, Long hostId) {
if (clusterId == null) {
clusterId = getClusterId(hostId);
if (clusterId == null) {
return true;
}
}
ClusterVO clusterVO = clusterDao.findById(clusterId);
if (clusterVO == null) {
return true;
}
Hypervisor.HypervisorType hypervisorType = clusterVO.getHypervisorType();
if (hypervisorType == null) {
return true;
}
if (Hypervisor.HypervisorType.XenServer.equals(hypervisorType) || Hypervisor.HypervisorType.VMware.equals(hypervisorType)) {
int maxValue = StorageManager.MaxNumberOfManagedClusteredFileSystems.valueIn(clusterId);
return getNumberOfManagedClusteredFileSystemsInComputeCluster(storagePool.getDataCenterId(), clusterId) < maxValue;
}
return true;
}
private int getNumberOfManagedClusteredFileSystemsInComputeCluster(long zoneId, long clusterId) {
int numberOfManagedClusteredFileSystemsInComputeCluster = 0;
List<VolumeVO> volumes = volumeDao.findByDc(zoneId);
if (CollectionUtils.isEmpty(volumes)) {
return numberOfManagedClusteredFileSystemsInComputeCluster;
}
for (VolumeVO volume : volumes) {
Long instanceId = volume.getInstanceId();
if (instanceId == null) {
continue;
}
VMInstanceVO vmInstanceVO = vmInstanceDao.findById(instanceId);
if (vmInstanceVO == null) {
continue;
}
Long vmHostId = vmInstanceVO.getHostId();
if (vmHostId == null) {
vmHostId = vmInstanceVO.getLastHostId();
}
if (vmHostId == null) {
continue;
}
HostVO vmHostVO = hostDao.findById(vmHostId);
if (vmHostVO == null) {
continue;
}
Long vmHostClusterId = vmHostVO.getClusterId();
if (vmHostClusterId != null && vmHostClusterId == clusterId) {
StoragePoolVO storagePoolVO = storagePoolDao.findById(volume.getPoolId());
if (storagePoolVO != null && storagePoolVO.isManaged()) {
numberOfManagedClusteredFileSystemsInComputeCluster++;
}
}
}
return numberOfManagedClusteredFileSystemsInComputeCluster;
}
}