Skip to content

Commit f67b738

Browse files
Migrate volume improvements, to bypass secondary storage when copy volume between pools is allowed directly (#11625)
* Migrate volume improvements, to bypass secondary storage when copy volume between pools is allowed directly * Bypass secondary storage for copy volume between zone-wide pools and - local storage on host in the same zone - cluser-wide pools in the same zone * Bypass secondary storage for volumes on ceph/rdb pool when the scope permits * Fix dest disk format while migrating volume from ceph/rbd to nfs, and some code improvements * unit tests * Update suitable disk offering(s) for volume(s) after migrate VM with volumes when change in pool type (shared or local) Currently, Migrate VM with volume(s) bypasses the service and disk offerings of the volumes, as the target pools for migration are specified, which ignores the offerings. Offering change is required when pool type (shared or local) is changed, mainly - when volume on shared pool is migrated to local pool - when volume on local pool is migrated to shared pool * Update with proper message while migrate volume when target pool and offering type mismatches (both are not shared/local) * Consider host scope first during endpoint selection while copying between primary storages * Update disk offering count (for listDiskOfferings api) while removing offerings with tags mismatch with storage tags
1 parent a6ef24d commit f67b738

File tree

36 files changed

+459
-56
lines changed

36 files changed

+459
-56
lines changed

api/src/main/java/com/cloud/offering/DiskOffering.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ public String toString() {
6969

7070
boolean isCustomized();
7171

72+
boolean isShared();
73+
7274
void setDiskSize(long diskSize);
7375

7476
long getDiskSize();
@@ -99,7 +101,6 @@ public String toString() {
99101

100102
Long getBytesReadRateMaxLength();
101103

102-
103104
void setBytesWriteRate(Long bytesWriteRate);
104105

105106
Long getBytesWriteRate();
@@ -112,7 +113,6 @@ public String toString() {
112113

113114
Long getBytesWriteRateMaxLength();
114115

115-
116116
void setIopsReadRate(Long iopsReadRate);
117117

118118
Long getIopsReadRate();
@@ -133,7 +133,6 @@ public String toString() {
133133

134134
Long getIopsWriteRateMax();
135135

136-
137136
void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength);
138137

139138
Long getIopsWriteRateMaxLength();

api/src/main/java/com/cloud/storage/VolumeApiService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ Volume updateVolume(long volumeId, String path, String state, Long storageId,
180180
*/
181181
boolean doesStoragePoolSupportDiskOfferingTags(StoragePool destPool, String diskOfferingTags);
182182

183+
boolean validateConditionsToReplaceDiskOfferingOfVolume(Volume volume, DiskOffering newDiskOffering, StoragePool destPool);
184+
183185
Volume destroyVolume(long volumeId, Account caller, boolean expunge, boolean forceExpunge);
184186

185187
void destroyVolume(long volumeId);

engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Set;
2424

2525
import com.cloud.exception.ResourceAllocationException;
26+
import com.cloud.storage.Storage;
2627
import com.cloud.utils.Pair;
2728
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
2829
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
@@ -182,10 +183,10 @@ List<DiskProfile> allocateTemplatedVolumes(Type type, String name, DiskOffering
182183
*/
183184
DiskProfile importVolume(Type type, String name, DiskOffering offering, Long sizeInBytes, Long minIops, Long maxIops,
184185
Long zoneId, HypervisorType hypervisorType, VirtualMachine vm, VirtualMachineTemplate template,
185-
Account owner, Long deviceId, Long poolId, String path, String chainInfo);
186+
Account owner, Long deviceId, Long poolId, Storage.StoragePoolType poolType, String path, String chainInfo);
186187

187188
DiskProfile updateImportedVolume(Type type, DiskOffering offering, VirtualMachine vm, VirtualMachineTemplate template,
188-
Long deviceId, Long poolId, String path, String chainInfo, DiskProfile diskProfile);
189+
Long deviceId, Long poolId, Storage.StoragePoolType poolType, String path, String chainInfo, DiskProfile diskProfile);
189190

190191
/**
191192
* Unmanage VM volumes

engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.apache.cloudstack.engine.subsystem.api.storage;
2020

2121
import com.cloud.storage.ScopeType;
22+
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
2223

2324
public class ClusterScope extends AbstractScope {
2425
private ScopeType type = ScopeType.CLUSTER;
@@ -51,4 +52,9 @@ public Long getZoneId() {
5152
return this.zoneId;
5253
}
5354

55+
@Override
56+
public String toString() {
57+
return String.format("ClusterScope %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(
58+
this, "zoneId", "clusterId", "podId"));
59+
}
5460
}

engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
package org.apache.cloudstack.engine.subsystem.api.storage;
2020

2121
import com.cloud.storage.ScopeType;
22+
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
2223

2324
public class HostScope extends AbstractScope {
25+
private ScopeType type = ScopeType.HOST;
2426
private Long hostId;
2527
private Long clusterId;
2628
private Long zoneId;
@@ -34,7 +36,7 @@ public HostScope(Long hostId, Long clusterId, Long zoneId) {
3436

3537
@Override
3638
public ScopeType getScopeType() {
37-
return ScopeType.HOST;
39+
return this.type;
3840
}
3941

4042
@Override
@@ -49,4 +51,10 @@ public Long getClusterId() {
4951
public Long getZoneId() {
5052
return zoneId;
5153
}
54+
55+
@Override
56+
public String toString() {
57+
return String.format("HostScope %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(
58+
this, "zoneId", "clusterId", "hostId"));
59+
}
5260
}

engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.apache.cloudstack.engine.subsystem.api.storage;
2020

2121
import com.cloud.storage.ScopeType;
22+
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
2223

2324
public class ZoneScope extends AbstractScope {
2425
private ScopeType type = ScopeType.ZONE;
@@ -39,4 +40,9 @@ public Long getScopeId() {
3940
return this.zoneId;
4041
}
4142

43+
@Override
44+
public String toString() {
45+
return String.format("ZoneScope %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(
46+
this, "zoneId"));
47+
}
4248
}

engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2859,6 +2859,7 @@ private void markVolumesInPool(VMInstanceVO vm, Answer[] hypervisorMigrationResu
28592859
}
28602860
volume.setPath(result.getPath());
28612861
volume.setPoolId(pool.getId());
2862+
volume.setPoolType(pool.getPoolType());
28622863
if (result.getChainInfo() != null) {
28632864
volume.setChainInfo(result.getChainInfo());
28642865
}

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,7 +1423,7 @@ public Volume migrateVolume(Volume volume, StoragePool destPool) throws StorageU
14231423
String volumeToString = getVolumeIdentificationInfos(volume);
14241424

14251425
VolumeInfo vol = volFactory.getVolume(volume.getId());
1426-
if (vol == null){
1426+
if (vol == null) {
14271427
throw new CloudRuntimeException(String.format("Volume migration failed because volume [%s] is null.", volumeToString));
14281428
}
14291429
if (destPool == null) {
@@ -2308,6 +2308,7 @@ public void updateVolumeDiskChain(long volumeId, String path, String chainInfo,
23082308
StoragePoolVO pool = _storagePoolDao.findByUuid(updatedDataStoreUUID);
23092309
if (pool != null) {
23102310
vol.setPoolId(pool.getId());
2311+
vol.setPoolType(pool.getPoolType());
23112312
}
23122313
}
23132314
_volsDao.update(volumeId, vol);
@@ -2317,7 +2318,7 @@ public void updateVolumeDiskChain(long volumeId, String path, String chainInfo,
23172318
@Override
23182319
public DiskProfile importVolume(Type type, String name, DiskOffering offering, Long sizeInBytes, Long minIops, Long maxIops,
23192320
Long zoneId, HypervisorType hypervisorType, VirtualMachine vm, VirtualMachineTemplate template, Account owner,
2320-
Long deviceId, Long poolId, String path, String chainInfo) {
2321+
Long deviceId, Long poolId, Storage.StoragePoolType poolType, String path, String chainInfo) {
23212322
if (sizeInBytes == null) {
23222323
sizeInBytes = offering.getDiskSize();
23232324
}
@@ -2358,6 +2359,7 @@ public DiskProfile importVolume(Type type, String name, DiskOffering offering, L
23582359

23592360
vol.setFormat(getSupportedImageFormatForCluster(hypervisorType));
23602361
vol.setPoolId(poolId);
2362+
vol.setPoolType(poolType);
23612363
vol.setPath(path);
23622364
vol.setChainInfo(chainInfo);
23632365
vol.setState(Volume.State.Ready);
@@ -2367,7 +2369,7 @@ public DiskProfile importVolume(Type type, String name, DiskOffering offering, L
23672369

23682370
@Override
23692371
public DiskProfile updateImportedVolume(Type type, DiskOffering offering, VirtualMachine vm, VirtualMachineTemplate template,
2370-
Long deviceId, Long poolId, String path, String chainInfo, DiskProfile diskProfile) {
2372+
Long deviceId, Long poolId, Storage.StoragePoolType poolType, String path, String chainInfo, DiskProfile diskProfile) {
23712373

23722374
VolumeVO vol = _volsDao.findById(diskProfile.getVolumeId());
23732375
if (vm != null) {
@@ -2401,6 +2403,7 @@ public DiskProfile updateImportedVolume(Type type, DiskOffering offering, Virtua
24012403

24022404
vol.setFormat(getSupportedImageFormatForCluster(vm.getHypervisorType()));
24032405
vol.setPoolId(poolId);
2406+
vol.setPoolType(poolType);
24042407
vol.setPath(path);
24052408
vol.setChainInfo(chainInfo);
24062409
vol.setSize(diskProfile.getSize());

engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestratorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ public void testImportVolume() {
241241

242242
volumeOrchestrator.importVolume(volumeType, name, diskOffering, sizeInBytes, null, null,
243243
zoneId, hypervisorType, null, null, owner,
244-
deviceId, poolId, path, chainInfo);
244+
deviceId, poolId, Storage.StoragePoolType.NetworkFilesystem, path, chainInfo);
245245

246246
VolumeVO volume = volumeVOMockedConstructionConstruction.constructed().get(0);
247247
Mockito.verify(volume, Mockito.never()).setInstanceId(Mockito.anyLong());

engine/schema/src/main/java/com/cloud/storage/DiskOfferingVO.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,11 +577,11 @@ public Integer getHypervisorSnapshotReserve() {
577577
@Override
578578
public void setEncrypt(boolean encrypt) { this.encrypt = encrypt; }
579579

580+
@Override
580581
public boolean isShared() {
581582
return !useLocalStorage;
582583
}
583584

584-
585585
public boolean getDiskSizeStrictness() {
586586
return diskSizeStrictness;
587587
}

0 commit comments

Comments
 (0)