Skip to content

Commit e3443c8

Browse files
committed
Start fix on multiple secondary storages for a single zone
1 parent 89cc8b4 commit e3443c8

File tree

14 files changed

+67
-36
lines changed

14 files changed

+67
-36
lines changed

core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ public VolumeObjectTO(VolumeInfo volume) {
125125
this.passphrase = volume.getPassphrase();
126126
this.encryptFormat = volume.getEncryptFormat();
127127
this.followRedirects = volume.isFollowRedirects();
128+
this.checkpointPaths = volume.getCheckpointPaths();
129+
this.checkpointImageStoreUrls = volume.getCheckpointImageStoreUrls();
128130
}
129131

130132
public String getUuid() {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
import com.cloud.storage.Volume;
2727
import com.cloud.vm.VirtualMachine;
2828

29+
import java.util.List;
30+
import java.util.Set;
31+
2932
public interface VolumeInfo extends DownloadableDataInfo, Volume {
3033

3134
boolean isAttachedVM();
@@ -96,4 +99,8 @@ public interface VolumeInfo extends DownloadableDataInfo, Volume {
9699
public byte[] getPassphrase();
97100

98101
Volume getVolume();
102+
103+
List<String> getCheckpointPaths();
104+
105+
Set<String> getCheckpointImageStoreUrls();
99106
}

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@
8989
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
9090
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
9191
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
92-
import org.apache.cloudstack.storage.to.VolumeObjectTO;
9392
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
9493
import org.apache.commons.collections.CollectionUtils;
9594
import org.apache.commons.collections.MapUtils;
@@ -1985,9 +1984,6 @@ public void prepare(VirtualMachineProfile vm, DeployDestination dest) throws Sto
19851984
_vmCloneSettingDao.persist(vmCloneSettingVO);
19861985
}
19871986
}
1988-
Pair<List<String>, Set<String>> volumeCheckPointPathsAndImageStoreUrls = getVolumeCheckpointPathsAndImageStoreUrls(volumeInfo.getId(), vm.getHypervisorType());
1989-
((VolumeObjectTO) volTO).setCheckpointPaths(volumeCheckPointPathsAndImageStoreUrls.first());
1990-
((VolumeObjectTO) volTO).setCheckpointImageStoreUrls(volumeCheckPointPathsAndImageStoreUrls.second());
19911987
}
19921988
}
19931989

engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, Lo
4747

4848
SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId);
4949

50-
SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId, boolean kvmIncrementalSnapshot, Hypervisor.HypervisorType hypervisorType);
50+
SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long zoneId, Long volumeId, boolean kvmIncrementalSnapshot, Hypervisor.HypervisorType hypervisorType);
5151

5252
SnapshotDataStoreVO findBySnapshotIdAndDataStoreRoleAndState(long snapshotId, DataStoreRole role, ObjectInDataStoreStateMachine.State state);
5353

engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDaoImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,12 +307,12 @@ protected SnapshotDataStoreVO findOldestOrLatestSnapshotForVolume(long volumeId,
307307
@Override
308308
@DB
309309
public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId) {
310-
return findParent(role, storeId, volumeId, false, null);
310+
return findParent(role, storeId, null, volumeId, false, null);
311311
}
312312

313313
@Override
314314
@DB
315-
public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId, boolean kvmIncrementalSnapshot, Hypervisor.HypervisorType hypervisorType) {
315+
public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long zoneId, Long volumeId, boolean kvmIncrementalSnapshot, Hypervisor.HypervisorType hypervisorType) {
316316
if (!isSnapshotChainingRequired(volumeId, kvmIncrementalSnapshot)) {
317317
logger.trace(String.format("Snapshot chaining is not required for snapshots of volume [%s]. Returning null as parent.", volumeId));
318318
return null;
@@ -323,6 +323,7 @@ public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long vol
323323
sc.setParameters(STORE_ROLE, role.toString());
324324
sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Ready.name());
325325
sc.setParametersIfNotNull(STORE_ID, storeId);
326+
sc.setParametersIfNotNull();
326327

327328
List<SnapshotDataStoreVO> snapshotList = listBy(sc, new Filter(SnapshotDataStoreVO.class, CREATED, false, null, null));
328329
if (CollectionUtils.isEmpty(snapshotList)) {
@@ -336,7 +337,6 @@ public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long vol
336337
}
337338

338339
return parent;
339-
340340
}
341341

342342
@Override

engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public DataObject create(DataObject obj, DataStore dataStore) {
140140
ss.setPhysicalSize(snapshotInfo.getSize()); // this physical size will get updated with actual size once the snapshot backup is done.
141141
Long clusterId = hostDao.findClusterIdByVolumeInfo(snapshotInfo.getBaseVolume());
142142
boolean kvmIncrementalSnapshot = SnapshotManager.kvmIncrementalSnapshot.valueIn(clusterId);
143-
SnapshotDataStoreVO snapshotDataStoreVO = snapshotDataStoreDao.findParent(dataStore.getRole(), dataStore.getId(), snapshotInfo.getVolumeId(), kvmIncrementalSnapshot, snapshotInfo.getHypervisorType());
143+
SnapshotDataStoreVO snapshotDataStoreVO = snapshotDataStoreDao.findParent(dataStore.getRole(), dataStore.getId(), null, snapshotInfo.getVolumeId(), kvmIncrementalSnapshot, snapshotInfo.getHypervisorType());
144144
snapshotDataStoreVO = tryToGetSnapshotOnSecondaryIfNotOnPrimaryAndIsKVM(dataStore, snapshotInfo, snapshotDataStoreVO, kvmIncrementalSnapshot, snapshotInfo.getHypervisorType());
145145
if (snapshotDataStoreVO != null) {
146146
//Double check the snapshot is removed or not
@@ -193,7 +193,7 @@ public DataObject create(DataObject obj, DataStore dataStore) {
193193
ss.setSize(snapshot.getSize());
194194
ss.setVolumeId(snapshot.getVolumeId());
195195
Long clusterId = hostDao.findClusterIdByVolumeInfo(snapshot.getBaseVolume());
196-
SnapshotDataStoreVO snapshotDataStoreVO = snapshotDataStoreDao.findParent(dataStore.getRole(), dataStore.getId(), snapshot.getVolumeId(), SnapshotManager.kvmIncrementalSnapshot.valueIn(clusterId), snapshot.getHypervisorType());
196+
SnapshotDataStoreVO snapshotDataStoreVO = snapshotDataStoreDao.findParent(dataStore.getRole(), dataStore.getId(), null, snapshot.getVolumeId(), SnapshotManager.kvmIncrementalSnapshot.valueIn(clusterId), snapshot.getHypervisorType());
197197
if (snapshotDataStoreVO != null && !snapshotDataStoreVO.isEndOfChain()) {
198198
ss.setParentSnapshotId(snapshotDataStoreVO.getSnapshotId());
199199
} else {
@@ -220,7 +220,7 @@ public DataObject create(DataObject obj, DataStore dataStore) {
220220
private SnapshotDataStoreVO tryToGetSnapshotOnSecondaryIfNotOnPrimaryAndIsKVM(DataStore dataStore, SnapshotInfo snapshotInfo, SnapshotDataStoreVO snapshotDataStoreVO,
221221
boolean kvmIncrementalSnapshot, Hypervisor.HypervisorType hypervisorType) {
222222
if (snapshotDataStoreVO == null && Hypervisor.HypervisorType.KVM.equals(snapshotInfo.getHypervisorType()) && DataStoreRole.Primary.equals(dataStore.getRole())) {
223-
snapshotDataStoreVO = snapshotDataStoreDao.findParent(DataStoreRole.Image, snapshotInfo.getImageStore().getId(), snapshotInfo.getVolumeId(), kvmIncrementalSnapshot, hypervisorType);
223+
snapshotDataStoreVO = snapshotDataStoreDao.findParent(DataStoreRole.Image, snapshotInfo.getImageStore().getId(), null, snapshotInfo.getVolumeId(), kvmIncrementalSnapshot, hypervisorType);
224224
}
225225
return snapshotDataStoreVO;
226226
}

engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@
2424
import com.cloud.dc.VsphereStoragePolicyVO;
2525
import com.cloud.dc.dao.VsphereStoragePolicyDao;
2626
import com.cloud.storage.StorageManager;
27+
import com.cloud.utils.Pair;
2728
import com.cloud.utils.db.Transaction;
2829
import com.cloud.utils.db.TransactionCallbackNoReturn;
2930
import com.cloud.utils.db.TransactionStatus;
31+
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
3032
import org.apache.cloudstack.secret.dao.PassphraseDao;
3133
import org.apache.cloudstack.secret.PassphraseVO;
3234
import com.cloud.service.dao.ServiceOfferingDetailsDao;
@@ -82,6 +84,7 @@
8284
import java.util.HashMap;
8385
import java.util.List;
8486
import java.util.Map;
87+
import java.util.Set;
8588
import java.util.function.Function;
8689
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
8790

@@ -114,13 +117,19 @@ public class VolumeObject implements VolumeInfo {
114117
VsphereStoragePolicyDao vsphereStoragePolicyDao;
115118
@Inject
116119
PassphraseDao passphraseDao;
120+
@Inject
121+
VolumeOrchestrationService
122+
orchestrationService;
117123

118124
private Object payload;
119125
private MigrationOptions migrationOptions;
120126
private boolean directDownload;
121127
private String vSphereStoragePolicyId;
122128
private boolean followRedirects;
123129

130+
private List<String> checkpointPaths;
131+
private Set<String> checkpointImageStoreUrls;
132+
124133
private final List<Volume.State> volumeStatesThatShouldNotTransitWhenDataStoreRoleIsImage = Arrays.asList(Volume.State.Migrating, Volume.State.Uploaded, Volume.State.Copying,
125134
Volume.State.Expunged);
126135

@@ -136,6 +145,9 @@ public VolumeObject() {
136145
protected void configure(DataStore dataStore, VolumeVO volumeVO) {
137146
this.volumeVO = volumeVO;
138147
this.dataStore = dataStore;
148+
Pair<List<String>, Set<String>> volumeCheckPointPathsAndImageStoreUrls = orchestrationService.getVolumeCheckpointPathsAndImageStoreUrls(volumeVO.getId(), getHypervisorType());
149+
this.checkpointPaths = volumeCheckPointPathsAndImageStoreUrls.first();
150+
this.checkpointImageStoreUrls = volumeCheckPointPathsAndImageStoreUrls.second();
139151
}
140152

141153
public static VolumeObject getVolumeObject(DataStore dataStore, VolumeVO volumeVO) {
@@ -944,4 +956,14 @@ public boolean isDeleteProtection() {
944956
public boolean isFollowRedirects() {
945957
return followRedirects;
946958
}
959+
960+
@Override
961+
public List<String> getCheckpointPaths() {
962+
return checkpointPaths;
963+
}
964+
965+
@Override
966+
public Set<String> getCheckpointImageStoreUrls() {
967+
return checkpointImageStoreUrls;
968+
}
947969
}

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4689,13 +4689,18 @@ public boolean recreateCheckpointsOnVm(List<VolumeObjectTO> volumes, String vmNa
46894689
if (CollectionUtils.isEmpty(volume.getCheckpointPaths())) {
46904690
continue;
46914691
}
4692-
volume.getCheckpointImageStoreUrls().forEach(uri -> getStoragePoolMgr().getStoragePoolByURI(uri));
4692+
connectToAllVolumeSnapshotSecondaryStorages(volume);
46934693
recreateCheckpointsOfDisk(vmName, volume, mapDiskToDiskDef);
46944694
}
46954695
logger.debug("Successfully recreated all checkpoints on VM [{}].", vmName);
46964696
return true;
46974697
}
46984698

4699+
public void connectToAllVolumeSnapshotSecondaryStorages(VolumeObjectTO volumeObjectTO) {
4700+
volumeObjectTO.getCheckpointImageStoreUrls().forEach(uri -> getStoragePoolMgr().getStoragePoolByURI(uri));
4701+
}
4702+
4703+
46994704
protected void recreateCheckpointsOfDisk(String vmName, VolumeObjectTO volume, Map<VolumeObjectTO, DiskDef> mapDiskToDiskDef) {
47004705
for (String path : volume.getCheckpointPaths()) {
47014706
DiskDef diskDef = mapDiskToDiskDef.get(volume);

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConvertSnapshotCommandWrapper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public Answer execute(ConvertSnapshotCommand command, LibvirtComputingResource s
5959

6060
try {
6161
KVMStoragePool secondaryStorage = serverResource.getStoragePoolMgr().getStoragePoolByURI(secondaryStoragePoolUrl);
62+
serverResource.connectToAllVolumeSnapshotSecondaryStorages(snapshotObjectTO.getVolume());
6263

6364
String snapshotRelativePath = snapshotObjectTO.getPath();
6465
String snapshotPath = secondaryStorage.getLocalPathFor(snapshotRelativePath);

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRevertSnapshotCommandWrapper.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public Answer execute(final RevertSnapshotCommand command, final LibvirtComputin
129129
return new Answer(command, false, result);
130130
}
131131
} else {
132-
revertVolumeToSnapshot(snapshotOnPrimaryStorage, snapshot, snapshotImageStore, primaryPool, secondaryStoragePool);
132+
revertVolumeToSnapshot(secondaryStoragePool, snapshotOnPrimaryStorage, snapshot, primaryPool, libvirtComputingResource);
133133
}
134134
}
135135

@@ -156,15 +156,19 @@ protected String getFullPathAccordingToStorage(KVMStoragePool kvmStoragePool, St
156156
/**
157157
* Reverts the volume to the snapshot.
158158
*/
159-
protected void revertVolumeToSnapshot(SnapshotObjectTO snapshotOnPrimaryStorage, SnapshotObjectTO snapshotOnSecondaryStorage, DataStoreTO dataStoreTo,
160-
KVMStoragePool kvmStoragePoolPrimary, KVMStoragePool kvmStoragePoolSecondary) {
159+
protected void revertVolumeToSnapshot(KVMStoragePool kvmStoragePoolSecondary, SnapshotObjectTO snapshotOnPrimaryStorage, SnapshotObjectTO snapshotOnSecondaryStorage,
160+
KVMStoragePool kvmStoragePoolPrimary, LibvirtComputingResource resource) {
161161
VolumeObjectTO volumeObjectTo = snapshotOnSecondaryStorage.getVolume();
162162
String volumePath = getFullPathAccordingToStorage(kvmStoragePoolPrimary, volumeObjectTo.getPath());
163163

164164
Pair<String, SnapshotObjectTO> resultGetSnapshot = getSnapshot(snapshotOnPrimaryStorage, snapshotOnSecondaryStorage, kvmStoragePoolPrimary, kvmStoragePoolSecondary);
165165
String snapshotPath = resultGetSnapshot.first();
166166
SnapshotObjectTO snapshotToPrint = resultGetSnapshot.second();
167167

168+
if (kvmStoragePoolSecondary != null) {
169+
resource.connectToAllVolumeSnapshotSecondaryStorages(volumeObjectTo);
170+
}
171+
168172
logger.debug(String.format("Reverting volume [%s] to snapshot [%s].", volumeObjectTo, snapshotToPrint));
169173

170174
try {

0 commit comments

Comments
 (0)