mirror of https://github.com/apache/cloudstack.git
Merge from 4.3: CLOUDSTACK-4810: Enable hypervisor snapshots for CloudStack-managed storage (for XenServer and VMware)
This commit is contained in:
parent
09da5153df
commit
03118c2969
|
|
@ -189,7 +189,5 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
|
|||
|
||||
Long getVmSnapshotChainSize();
|
||||
|
||||
void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve);
|
||||
|
||||
Integer getHypervisorSnapshotReserve();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,14 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
|
|||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
import org.apache.cloudstack.storage.command.CommandResult;
|
||||
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.Volume;
|
||||
|
||||
public interface PrimaryDataStoreDriver extends DataStoreDriver {
|
||||
public ChapInfo getChapInfo(VolumeInfo volumeInfo);
|
||||
|
||||
public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool);
|
||||
|
||||
public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback);
|
||||
|
||||
public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CommandResult> callback);
|
||||
|
|
|
|||
|
|
@ -404,6 +404,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
@DB
|
||||
public VolumeInfo createVolume(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering,
|
||||
DiskOffering diskOffering, List<StoragePool> avoids, long size, HypervisorType hyperType) {
|
||||
volume = updateHypervisorSnapshotReserveForVolume(diskOffering, volume, hyperType);
|
||||
|
||||
StoragePool pool = null;
|
||||
|
||||
DiskProfile dskCh = null;
|
||||
|
|
@ -423,8 +425,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
|
||||
pool = findStoragePool(dskCh, dc, pod, clusterId, vm.getHostId(), vm, avoidPools);
|
||||
if (pool == null) {
|
||||
s_logger.warn("Unable to find storage pool when create volume " + volume.getName());
|
||||
throw new CloudRuntimeException("Unable to find storage pool when create volume" + volume.getName());
|
||||
s_logger.warn("Unable to find suitable primary storage when creating volume " + volume.getName());
|
||||
throw new CloudRuntimeException("Unable to find suitable primary storage when creating volume " + volume.getName());
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
|
|
@ -436,7 +438,6 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
AsyncCallFuture<VolumeApiResult> future = null;
|
||||
boolean isNotCreatedFromTemplate = volume.getTemplateId() == null ? true : false;
|
||||
if (isNotCreatedFromTemplate) {
|
||||
volume = updateHypervisorSnapshotReserveForVolume(diskOffering, volume, hyperType);
|
||||
future = volService.createVolumeAsync(volume, store);
|
||||
} else {
|
||||
TemplateInfo templ = tmplFactory.getTemplate(template.getId(), DataStoreRole.Image);
|
||||
|
|
|
|||
|
|
@ -587,7 +587,6 @@ public class VolumeVO implements Volume {
|
|||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve) {
|
||||
this.hypervisorSnapshotReserve = hypervisorSnapshotReserve;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ import org.apache.cloudstack.storage.to.SnapshotObjectTO;
|
|||
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
import com.cloud.agent.api.to.DataTO;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.Volume;
|
||||
|
||||
public class FakePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
||||
boolean snapshotResult = true;
|
||||
|
|
@ -45,6 +47,11 @@ public class FakePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) {
|
||||
return volume.getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {
|
||||
CreateCmdResult result = new CreateCmdResult(null, null);
|
||||
|
|
|
|||
|
|
@ -153,7 +153,6 @@ public class VolumeObject implements VolumeInfo {
|
|||
return volumeVO.getMaxIops();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve) {
|
||||
volumeVO.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ import com.cloud.storage.ResizeVolumePayload;
|
|||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
|
|
@ -148,6 +149,11 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) {
|
||||
return volume.getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
|
||||
String errMsg = null;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ import org.apache.cloudstack.storage.datastore.DataObjectManager;
|
|||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
import com.cloud.agent.api.to.DataTO;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
|
|
@ -78,6 +80,11 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) {
|
||||
return volume.getSize();
|
||||
}
|
||||
|
||||
private class CreateVolumeContext<T> extends AsyncRpcContext<T> {
|
||||
private final DataObject volume;
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ import com.cloud.agent.api.to.DataStoreTO;
|
|||
import com.cloud.agent.api.to.DataTO;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.dao.VolumeDetailsDao;
|
||||
|
|
@ -284,8 +286,20 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
iops = new Iops(volumeInfo.getMinIops(), volumeInfo.getMaxIops(), getDefaultBurstIops(storagePoolId, volumeInfo.getMaxIops()));
|
||||
}
|
||||
|
||||
long volumeSize = volumeInfo.getSize();
|
||||
Integer hypervisorSnapshotReserve = volumeInfo.getHypervisorSnapshotReserve();
|
||||
long volumeSize = getVolumeSizeIncludingHypervisorSnapshotReserve(volumeInfo, _storagePoolDao.findById(storagePoolId));
|
||||
|
||||
long sfVolumeId = SolidFireUtil.createSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword,
|
||||
getSolidFireVolumeName(volumeInfo.getName()), sfAccountId, volumeSize, true,
|
||||
NumberFormat.getInstance().format(volumeInfo.getSize()),
|
||||
iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
|
||||
|
||||
return SolidFireUtil.getSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolumeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) {
|
||||
long volumeSize = volume.getSize();
|
||||
Integer hypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve();
|
||||
|
||||
if (hypervisorSnapshotReserve != null) {
|
||||
if (hypervisorSnapshotReserve < 25) {
|
||||
|
|
@ -295,11 +309,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
volumeSize += volumeSize * (hypervisorSnapshotReserve / 100f);
|
||||
}
|
||||
|
||||
long sfVolumeId =
|
||||
SolidFireUtil.createSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, getSolidFireVolumeName(volumeInfo.getName()), sfAccountId,
|
||||
volumeSize, true, NumberFormat.getNumberInstance().format(volumeInfo.getSize().toString()), iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
|
||||
|
||||
return SolidFireUtil.getSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolumeId);
|
||||
return volumeSize;
|
||||
}
|
||||
|
||||
private String getSolidFireVolumeName(String strCloudStackVolumeName) {
|
||||
|
|
@ -356,11 +366,12 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
}
|
||||
}
|
||||
|
||||
private void deleteSolidFireVolume(VolumeInfo volumeInfo, SolidFireConnection sfConnection) {
|
||||
private SolidFireUtil.SolidFireVolume deleteSolidFireVolume(VolumeInfo volumeInfo, SolidFireConnection sfConnection)
|
||||
{
|
||||
Long storagePoolId = volumeInfo.getPoolId();
|
||||
|
||||
if (storagePoolId == null) {
|
||||
return; // this volume was never assigned to a storage pool, so no SAN volume should exist for it
|
||||
return null; // this volume was never assigned to a storage pool, so no SAN volume should exist for it
|
||||
}
|
||||
|
||||
String mVip = sfConnection.getManagementVip();
|
||||
|
|
@ -370,7 +381,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
|
||||
long sfVolumeId = Long.parseLong(volumeInfo.getFolder());
|
||||
|
||||
SolidFireUtil.deleteSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolumeId);
|
||||
return SolidFireUtil.deleteSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolumeId);
|
||||
}
|
||||
|
||||
private String getSfAccountName(String csAccountUuid, long csAccountId) {
|
||||
|
|
@ -429,7 +440,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
long capacityBytes = storagePool.getCapacityBytes();
|
||||
long usedBytes = storagePool.getUsedBytes();
|
||||
|
||||
usedBytes += volumeInfo.getSize();
|
||||
usedBytes += sfVolume.getTotalSize();
|
||||
|
||||
storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);
|
||||
|
||||
|
|
@ -493,31 +504,31 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
|
||||
if (dataObject.getType() == DataObjectType.VOLUME) {
|
||||
VolumeInfo volumeInfo = (VolumeInfo)dataObject;
|
||||
AccountVO account = _accountDao.findById(volumeInfo.getAccountId());
|
||||
AccountDetailVO accountDetails = _accountDetailsDao.findDetail(account.getAccountId(), SolidFireUtil.ACCOUNT_ID);
|
||||
long sfAccountId = Long.parseLong(accountDetails.getValue());
|
||||
// AccountVO account = _accountDao.findById(volumeInfo.getAccountId());
|
||||
// AccountDetailVO accountDetails = _accountDetailsDao.findDetail(account.getAccountId(), SolidFireUtil.ACCOUNT_ID);
|
||||
// long sfAccountId = Long.parseLong(accountDetails.getValue());
|
||||
|
||||
long storagePoolId = dataStore.getId();
|
||||
SolidFireConnection sfConnection = getSolidFireConnection(storagePoolId);
|
||||
|
||||
deleteSolidFireVolume(volumeInfo, sfConnection);
|
||||
SolidFireUtil.SolidFireVolume sfVolume = deleteSolidFireVolume(volumeInfo, sfConnection);
|
||||
|
||||
_volumeDao.deleteVolumesByInstance(volumeInfo.getId());
|
||||
|
||||
// if (!sfAccountHasVolume(sfAccountId, sfConnection)) {
|
||||
// // delete the account from the SolidFire SAN
|
||||
// deleteSolidFireAccount(sfAccountId, sfConnection);
|
||||
// if (!sfAccountHasVolume(sfAccountId, sfConnection)) {
|
||||
// // delete the account from the SolidFire SAN
|
||||
// deleteSolidFireAccount(sfAccountId, sfConnection);
|
||||
//
|
||||
// // delete the info in the account_details table
|
||||
// // that's related to the SolidFire account
|
||||
// _accountDetailsDao.deleteDetails(account.getAccountId());
|
||||
// }
|
||||
// // delete the info in the account_details table
|
||||
// // that's related to the SolidFire account
|
||||
// _accountDetailsDao.deleteDetails(account.getAccountId());
|
||||
// }
|
||||
|
||||
StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
|
||||
|
||||
long usedBytes = storagePool.getUsedBytes();
|
||||
|
||||
usedBytes -= volumeInfo.getSize();
|
||||
usedBytes -= sfVolume != null ? sfVolume.getTotalSize() : 0;
|
||||
|
||||
storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes);
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,10 @@ public class SolidFireUtil {
|
|||
return volumeCreateResult.result.volumeID;
|
||||
}
|
||||
|
||||
public static void deleteSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVolumeId) {
|
||||
public static SolidFireVolume deleteSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVolumeId)
|
||||
{
|
||||
SolidFireVolume sfVolume = getSolidFireVolume(strSfMvip, iSfPort, strSfAdmin, strSfPassword, lVolumeId);
|
||||
|
||||
final Gson gson = new GsonBuilder().create();
|
||||
|
||||
VolumeToDelete volumeToDelete = new VolumeToDelete(lVolumeId);
|
||||
|
|
@ -103,6 +106,8 @@ public class SolidFireUtil {
|
|||
String strVolumeToDeleteJson = gson.toJson(volumeToDelete);
|
||||
|
||||
executeJsonRpc(strVolumeToDeleteJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword);
|
||||
|
||||
return sfVolume;
|
||||
}
|
||||
|
||||
public static void purgeSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVolumeId) {
|
||||
|
|
@ -132,8 +137,9 @@ public class SolidFireUtil {
|
|||
String strVolumeIqn = getVolumeIqn(volumeGetResult, lVolumeId);
|
||||
long lAccountId = getVolumeAccountId(volumeGetResult, lVolumeId);
|
||||
String strVolumeStatus = getVolumeStatus(volumeGetResult, lVolumeId);
|
||||
long lTotalSize = getVolumeTotalSize(volumeGetResult, lVolumeId);
|
||||
|
||||
return new SolidFireVolume(lVolumeId, strVolumeName, strVolumeIqn, lAccountId, strVolumeStatus);
|
||||
return new SolidFireVolume(lVolumeId, strVolumeName, strVolumeIqn, lAccountId, strVolumeStatus, lTotalSize);
|
||||
}
|
||||
|
||||
public static List<SolidFireVolume> getSolidFireVolumesForAccountId(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lAccountId) {
|
||||
|
|
@ -152,7 +158,7 @@ public class SolidFireUtil {
|
|||
List<SolidFireVolume> sfVolumes = new ArrayList<SolidFireVolume>();
|
||||
|
||||
for (VolumeGetResult.Result.Volume volume : volumeGetResult.result.volumes) {
|
||||
sfVolumes.add(new SolidFireVolume(volume.volumeID, volume.name, volume.iqn, volume.accountID, volume.status));
|
||||
sfVolumes.add(new SolidFireVolume(volume.volumeID, volume.name, volume.iqn, volume.accountID, volume.status, volume.totalSize));
|
||||
}
|
||||
|
||||
return sfVolumes;
|
||||
|
|
@ -166,13 +172,17 @@ public class SolidFireUtil {
|
|||
private final String _iqn;
|
||||
private final long _accountId;
|
||||
private final String _status;
|
||||
private final long _totalSize;
|
||||
|
||||
public SolidFireVolume(long id, String name, String iqn, long accountId, String status) {
|
||||
public SolidFireVolume(long id, String name, String iqn,
|
||||
long accountId, String status, long totalSize)
|
||||
{
|
||||
_id = id;
|
||||
_name = name;
|
||||
_iqn = "/" + iqn + "/0";
|
||||
_accountId = accountId;
|
||||
_status = status;
|
||||
_totalSize = totalSize;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
|
|
@ -195,6 +205,10 @@ public class SolidFireUtil {
|
|||
return ACTIVE.equalsIgnoreCase(_status);
|
||||
}
|
||||
|
||||
public long getTotalSize() {
|
||||
return _totalSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return _iqn.hashCode();
|
||||
|
|
@ -217,7 +231,9 @@ public class SolidFireUtil {
|
|||
|
||||
SolidFireVolume sfv = (SolidFireVolume)obj;
|
||||
|
||||
if (_id == sfv._id && _name.equals(sfv._name) && _iqn.equals(sfv._iqn) && _accountId == sfv._accountId && isActive() == sfv.isActive()) {
|
||||
if (_id == sfv._id && _name.equals(sfv._name) &&
|
||||
_iqn.equals(sfv._iqn) && _accountId == sfv._accountId &&
|
||||
isActive() == sfv.isActive() && getTotalSize() == sfv.getTotalSize()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -366,7 +382,7 @@ public class SolidFireUtil {
|
|||
List<SolidFireVolume> deletedVolumes = new ArrayList<SolidFireVolume>();
|
||||
|
||||
for (VolumeGetResult.Result.Volume volume : volumeGetResult.result.volumes) {
|
||||
deletedVolumes.add(new SolidFireVolume(volume.volumeID, volume.name, volume.iqn, volume.accountID, volume.status));
|
||||
deletedVolumes.add(new SolidFireVolume(volume.volumeID, volume.name, volume.iqn, volume.accountID, volume.status, volume.totalSize));
|
||||
}
|
||||
|
||||
return deletedVolumes;
|
||||
|
|
@ -655,6 +671,7 @@ public class SolidFireUtil {
|
|||
private String iqn;
|
||||
private long accountID;
|
||||
private String status;
|
||||
private long totalSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -811,7 +828,7 @@ public class SolidFireUtil {
|
|||
return volumeGetResult.result.volumes[0].name;
|
||||
}
|
||||
|
||||
throw new CloudRuntimeException("Could not determine the name of the volume, " + "but the volume was created with an ID of " + lVolumeId + ".");
|
||||
throw new CloudRuntimeException("Could not determine the name of the volume for volume ID of " + lVolumeId + ".");
|
||||
}
|
||||
|
||||
private static String getVolumeIqn(VolumeGetResult volumeGetResult, long lVolumeId) {
|
||||
|
|
@ -819,7 +836,7 @@ public class SolidFireUtil {
|
|||
return volumeGetResult.result.volumes[0].iqn;
|
||||
}
|
||||
|
||||
throw new CloudRuntimeException("Could not determine the IQN of the volume, " + "but the volume was created with an ID of " + lVolumeId + ".");
|
||||
throw new CloudRuntimeException("Could not determine the IQN of the volume for volume ID of " + lVolumeId + ".");
|
||||
}
|
||||
|
||||
private static long getVolumeAccountId(VolumeGetResult volumeGetResult, long lVolumeId) {
|
||||
|
|
@ -827,7 +844,7 @@ public class SolidFireUtil {
|
|||
return volumeGetResult.result.volumes[0].accountID;
|
||||
}
|
||||
|
||||
throw new CloudRuntimeException("Could not determine the volume's account ID, " + "but the volume was created with an ID of " + lVolumeId + ".");
|
||||
throw new CloudRuntimeException("Could not determine the account ID of the volume for volume ID of " + lVolumeId + ".");
|
||||
}
|
||||
|
||||
private static String getVolumeStatus(VolumeGetResult volumeGetResult, long lVolumeId) {
|
||||
|
|
@ -835,6 +852,17 @@ public class SolidFireUtil {
|
|||
return volumeGetResult.result.volumes[0].status;
|
||||
}
|
||||
|
||||
throw new CloudRuntimeException("Could not determine the status of the volume, " + "but the volume was created with an ID of " + lVolumeId + ".");
|
||||
throw new CloudRuntimeException("Could not determine the status of the volume for volume ID of " + lVolumeId + ".");
|
||||
}
|
||||
|
||||
private static long getVolumeTotalSize(VolumeGetResult volumeGetResult, long lVolumeId)
|
||||
{
|
||||
if (volumeGetResult.result.volumes != null && volumeGetResult.result.volumes.length == 1 &&
|
||||
volumeGetResult.result.volumes[0].volumeID == lVolumeId)
|
||||
{
|
||||
return volumeGetResult.result.volumes[0].totalSize;
|
||||
}
|
||||
|
||||
throw new CloudRuntimeException("Could not determine the total size of the volume for volume ID of " + lVolumeId + ".");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -500,10 +500,19 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
|
|||
|
||||
@Override
|
||||
public long getAllocatedPoolCapacity(StoragePoolVO pool, VMTemplateVO templateForVmCreation) {
|
||||
long totalAllocatedSize = 0;
|
||||
|
||||
// Get size for all the non-destroyed volumes
|
||||
Pair<Long, Long> sizes = _volumeDao.getNonDestroyedCountAndTotalByPool(pool.getId());
|
||||
long totalAllocatedSize = sizes.second() + sizes.first() * _extraBytesPerVolume;
|
||||
// if the storage pool is managed, the used bytes can be larger than the sum of the sizes of all of the non-destroyed volumes
|
||||
// in this case, just get the used bytes from the storage pool object
|
||||
if (pool.isManaged()) {
|
||||
totalAllocatedSize = pool.getUsedBytes();
|
||||
}
|
||||
else {
|
||||
// Get size for all the non-destroyed volumes
|
||||
Pair<Long, Long> sizes = _volumeDao.getNonDestroyedCountAndTotalByPool(pool.getId());
|
||||
|
||||
totalAllocatedSize = sizes.second() + sizes.first() * _extraBytesPerVolume;
|
||||
}
|
||||
|
||||
// Get size for VM Snapshots
|
||||
totalAllocatedSize = totalAllocatedSize + _volumeDao.getVMSnapshotSizeByPool(pool.getId());
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
|
|||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
|
||||
|
|
@ -62,6 +63,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
|
|||
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
||||
|
|
@ -1542,7 +1544,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
}
|
||||
}
|
||||
if (volume.getState() != Volume.State.Ready) {
|
||||
totalAskingSize = totalAskingSize + volume.getSize();
|
||||
totalAskingSize = totalAskingSize + getVolumeSizeIncludingHvSsReserve(volume, pool);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1581,6 +1583,19 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
return true;
|
||||
}
|
||||
|
||||
private long getVolumeSizeIncludingHvSsReserve(Volume volume, StoragePool pool) {
|
||||
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
|
||||
DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
|
||||
|
||||
if (storeDriver instanceof PrimaryDataStoreDriver) {
|
||||
PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver;
|
||||
|
||||
return primaryStoreDriver.getVolumeSizeIncludingHypervisorSnapshotReserve(volume, pool);
|
||||
}
|
||||
|
||||
return volume.getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createCapacityEntry(long poolId) {
|
||||
StoragePoolVO storage = _storagePoolDao.findById(poolId);
|
||||
|
|
|
|||
Loading…
Reference in New Issue