diff --git a/engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java b/engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java index 029a8fa273cf..83c32b1c2efd 100644 --- a/engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java +++ b/engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java @@ -35,4 +35,6 @@ public interface HypervisorCapabilitiesDao extends GenericDao getHypervisorsWithDefaultEntries(); } diff --git a/engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java b/engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java index a4341380ddc4..5cecff2af95f 100644 --- a/engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.hypervisor.dao; +import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.StringUtils; @@ -106,4 +107,16 @@ public Boolean isVmSnapshotEnabled(HypervisorType hypervisorType, String hypervi HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion); return result.getVmSnapshotEnabled(); } + + @Override + public List getHypervisorsWithDefaultEntries() { + SearchCriteria sc = HypervisorTypeAndVersionSearch.create(); + sc.setParameters("hypervisorVersion", DEFAULT_VERSION); + List hypervisorCapabilitiesVOS = listBy(sc); + List hvs = new ArrayList<>(); + for (HypervisorCapabilitiesVO capabilitiesVO : hypervisorCapabilitiesVOS) { + hvs.add(capabilitiesVO.getHypervisorType()); + } + return hvs; + } } diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index 2022d5b5be13..aa3c8522dc71 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -266,6 +266,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic private List _storagePoolAllocators; + private List supportingDefaultHV; + VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this); static final ConfigKey VmJobCheckInterval = new ConfigKey("Advanced", Long.class, "vm.job.check.interval", "3000", "Interval in milliseconds to check if the job is complete", false); @@ -2861,7 +2863,9 @@ private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, L } } - verifyManagedStorage(volumeToAttachStoragePool.getId(), hostId); + if (volumeToAttachStoragePool != null) { + verifyManagedStorage(volumeToAttachStoragePool.getId(), hostId); + } // volumeToAttachStoragePool should be null if the VM we are attaching the disk to has never been started before DataStore dataStore = volumeToAttachStoragePool != null ? dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary) : null; @@ -3007,6 +3011,11 @@ private int getMaxDataVolumesSupported(UserVmVO vm) { if (host != null) { _hostDao.loadDetails(host); maxDataVolumesSupported = _hypervisorCapabilitiesDao.getMaxDataVolumesLimit(host.getHypervisorType(), host.getDetail("product_version")); + } else { + HypervisorType hypervisorType = vm.getHypervisorType(); + if (hypervisorType != null && CollectionUtils.isNotEmpty(supportingDefaultHV) && supportingDefaultHV.contains(hypervisorType)) { + maxDataVolumesSupported = _hypervisorCapabilitiesDao.getMaxDataVolumesLimit(hypervisorType, "default"); + } } if (maxDataVolumesSupported == null || maxDataVolumesSupported.intValue() <= 0) { maxDataVolumesSupported = 6; // 6 data disks by default if nothing @@ -3054,6 +3063,7 @@ private Long getDeviceId(UserVmVO vm, Long deviceId) { public boolean configure(String name, Map params) { String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.toString()); _maxVolumeSizeInGb = NumbersUtil.parseLong(maxVolumeSizeInGbString, 2000); + supportingDefaultHV = _hypervisorCapabilitiesDao.getHypervisorsWithDefaultEntries(); return true; } diff --git a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java index 9d1426ce9f15..da346536d5a3 100644 --- a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java +++ b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java @@ -33,6 +33,7 @@ import java.util.UUID; import java.util.concurrent.ExecutionException; +import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; @@ -149,6 +150,8 @@ public class VolumeApiServiceImplTest { private HostDao _hostDao; @Mock private StoragePoolTagsDao storagePoolTagsDao; + @Mock + private HypervisorCapabilitiesDao hypervisorCapabilitiesDao; private DetachVolumeCmd detachCmd = new DetachVolumeCmd(); private Class _detachCmdClass = detachCmd.getClass();