Skip to content

Commit 38f97c6

Browse files
nvazquezyadvr
authored andcommitted
server: Fix hardcoded max data volumes when VM has been created but not started before (#3494)
When VM is created but not started on any host, attaching a volume on it causes the maximum number of allowed volumes to be 6 (hardcoded).
1 parent e1fa270 commit 38f97c6

4 files changed

Lines changed: 29 additions & 1 deletion

File tree

engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,6 @@ public interface HypervisorCapabilitiesDao extends GenericDao<HypervisorCapabili
3535
Integer getMaxHostsPerCluster(HypervisorType hypervisorType, String hypervisorVersion);
3636

3737
Boolean isVmSnapshotEnabled(HypervisorType hypervisorType, String hypervisorVersion);
38+
39+
List<HypervisorType> getHypervisorsWithDefaultEntries();
3840
}

engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// under the License.
1717
package com.cloud.hypervisor.dao;
1818

19+
import java.util.ArrayList;
1920
import java.util.List;
2021

2122
import org.apache.commons.lang3.StringUtils;
@@ -106,4 +107,16 @@ public Boolean isVmSnapshotEnabled(HypervisorType hypervisorType, String hypervi
106107
HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion);
107108
return result.getVmSnapshotEnabled();
108109
}
110+
111+
@Override
112+
public List<HypervisorType> getHypervisorsWithDefaultEntries() {
113+
SearchCriteria<HypervisorCapabilitiesVO> sc = HypervisorTypeAndVersionSearch.create();
114+
sc.setParameters("hypervisorVersion", DEFAULT_VERSION);
115+
List<HypervisorCapabilitiesVO> hypervisorCapabilitiesVOS = listBy(sc);
116+
List<HypervisorType> hvs = new ArrayList<>();
117+
for (HypervisorCapabilitiesVO capabilitiesVO : hypervisorCapabilitiesVOS) {
118+
hvs.add(capabilitiesVO.getHypervisorType());
119+
}
120+
return hvs;
121+
}
109122
}

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
266266

267267
private List<StoragePoolAllocator> _storagePoolAllocators;
268268

269+
private List<HypervisorType> supportingDefaultHV;
270+
269271
VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this);
270272

271273
static final ConfigKey<Long> VmJobCheckInterval = new ConfigKey<Long>("Advanced", Long.class, "vm.job.check.interval", "3000", "Interval in milliseconds to check if the job is complete", false);
@@ -2857,7 +2859,9 @@ private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, L
28572859
}
28582860
}
28592861

2860-
verifyManagedStorage(volumeToAttachStoragePool.getId(), hostId);
2862+
if (volumeToAttachStoragePool != null) {
2863+
verifyManagedStorage(volumeToAttachStoragePool.getId(), hostId);
2864+
}
28612865

28622866
// volumeToAttachStoragePool should be null if the VM we are attaching the disk to has never been started before
28632867
DataStore dataStore = volumeToAttachStoragePool != null ? dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary) : null;
@@ -3003,6 +3007,11 @@ private int getMaxDataVolumesSupported(UserVmVO vm) {
30033007
if (host != null) {
30043008
_hostDao.loadDetails(host);
30053009
maxDataVolumesSupported = _hypervisorCapabilitiesDao.getMaxDataVolumesLimit(host.getHypervisorType(), host.getDetail("product_version"));
3010+
} else {
3011+
HypervisorType hypervisorType = vm.getHypervisorType();
3012+
if (hypervisorType != null && CollectionUtils.isNotEmpty(supportingDefaultHV) && supportingDefaultHV.contains(hypervisorType)) {
3013+
maxDataVolumesSupported = _hypervisorCapabilitiesDao.getMaxDataVolumesLimit(hypervisorType, "default");
3014+
}
30063015
}
30073016
if (maxDataVolumesSupported == null || maxDataVolumesSupported.intValue() <= 0) {
30083017
maxDataVolumesSupported = 6; // 6 data disks by default if nothing
@@ -3050,6 +3059,7 @@ private Long getDeviceId(UserVmVO vm, Long deviceId) {
30503059
public boolean configure(String name, Map<String, Object> params) {
30513060
String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.toString());
30523061
_maxVolumeSizeInGb = NumbersUtil.parseLong(maxVolumeSizeInGbString, 2000);
3062+
supportingDefaultHV = _hypervisorCapabilitiesDao.getHypervisorsWithDefaultEntries();
30533063
return true;
30543064
}
30553065

server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.UUID;
3434
import java.util.concurrent.ExecutionException;
3535

36+
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
3637
import org.apache.cloudstack.acl.ControlledEntity;
3738
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
3839
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
@@ -149,6 +150,8 @@ public class VolumeApiServiceImplTest {
149150
private HostDao _hostDao;
150151
@Mock
151152
private StoragePoolTagsDao storagePoolTagsDao;
153+
@Mock
154+
private HypervisorCapabilitiesDao hypervisorCapabilitiesDao;
152155

153156
private DetachVolumeCmd detachCmd = new DetachVolumeCmd();
154157
private Class<?> _detachCmdClass = detachCmd.getClass();

0 commit comments

Comments
 (0)