mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
kvm: Add ceph RBD snapshot rollback (#3502)
Add CephSnapshotStrategy to handle RBD revert (rollback) snapshot. In order to support RBD revert (rbd_rollback), this PR adds a CephSnapshotStrategy class to handle Ceph/RBD snapshot actions.
This commit is contained in:
parent
281148d551
commit
6a511fce40
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.storage.snapshot;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.storage.DataStoreRole;
|
||||
import com.cloud.storage.Snapshot;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
|
||||
public class CephSnapshotStrategy extends StorageSystemSnapshotStrategy {
|
||||
@Inject
|
||||
private SnapshotDataStoreDao snapshotStoreDao;
|
||||
@Inject
|
||||
private PrimaryDataStoreDao primaryDataStoreDao;
|
||||
@Inject
|
||||
private VolumeDao volumeDao;
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(CephSnapshotStrategy.class);
|
||||
|
||||
@Override
|
||||
public StrategyPriority canHandle(Snapshot snapshot, SnapshotOperation op) {
|
||||
long volumeId = snapshot.getVolumeId();
|
||||
VolumeVO volumeVO = volumeDao.findByIdIncludingRemoved(volumeId);
|
||||
boolean baseVolumeExists = volumeVO.getRemoved() == null;
|
||||
if (!baseVolumeExists) {
|
||||
return StrategyPriority.CANT_HANDLE;
|
||||
}
|
||||
|
||||
if (SnapshotOperation.REVERT.equals(op) && isSnapshotStoredOnRbdStoragePool(snapshot)) {
|
||||
return StrategyPriority.HIGHEST;
|
||||
}
|
||||
return StrategyPriority.CANT_HANDLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean revertSnapshot(SnapshotInfo snapshotInfo) {
|
||||
VolumeInfo volumeInfo = snapshotInfo.getBaseVolume();
|
||||
ImageFormat imageFormat = volumeInfo.getFormat();
|
||||
if (!ImageFormat.RAW.equals(imageFormat)) {
|
||||
s_logger.error(String.format("Does not support revert snapshot of the image format [%s] on Ceph/RBD. Can only rollback snapshots of format RAW", imageFormat));
|
||||
return false;
|
||||
}
|
||||
|
||||
executeRevertSnapshot(snapshotInfo, volumeInfo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isSnapshotStoredOnRbdStoragePool(Snapshot snapshot) {
|
||||
SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
|
||||
long snapshotStoragePoolId = snapshotStore.getDataStoreId();
|
||||
StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(snapshotStoragePoolId);
|
||||
return storagePoolVO.getPoolType() == StoragePoolType.RBD;
|
||||
}
|
||||
}
|
||||
@ -102,7 +102,6 @@ public class StorageSystemSnapshotStrategy extends SnapshotStrategyBase {
|
||||
@Inject private SnapshotDataFactory snapshotDataFactory;
|
||||
@Inject private SnapshotDetailsDao snapshotDetailsDao;
|
||||
@Inject private SnapshotDataStoreDao snapshotStoreDao;
|
||||
@Inject private VolumeDetailsDao volumeDetailsDao;
|
||||
@Inject private VMInstanceDao vmInstanceDao;
|
||||
@Inject private VMSnapshotDao vmSnapshotDao;
|
||||
@Inject private VMSnapshotService vmSnapshotService;
|
||||
@ -307,8 +306,7 @@ public class StorageSystemSnapshotStrategy extends SnapshotStrategyBase {
|
||||
}
|
||||
}
|
||||
|
||||
boolean storageSystemSupportsCapability = storageSystemSupportsCapability(volumeInfo.getPoolId(),
|
||||
DataStoreCapabilities.CAN_REVERT_VOLUME_TO_SNAPSHOT.toString());
|
||||
boolean storageSystemSupportsCapability = storageSystemSupportsCapability(volumeInfo.getPoolId(), DataStoreCapabilities.CAN_REVERT_VOLUME_TO_SNAPSHOT.toString());
|
||||
|
||||
if (!storageSystemSupportsCapability) {
|
||||
String errMsg = "Storage pool revert capability not supported";
|
||||
@ -318,6 +316,18 @@ public class StorageSystemSnapshotStrategy extends SnapshotStrategyBase {
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
|
||||
executeRevertSnapshot(snapshotInfo, volumeInfo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the SnapshotStrategyBase.revertSnapshot(SnapshotInfo) method, and handles the SnapshotVO table update and the Volume.Event state machine (RevertSnapshotRequested).
|
||||
*/
|
||||
protected void executeRevertSnapshot(SnapshotInfo snapshotInfo, VolumeInfo volumeInfo) {
|
||||
Long hostId = null;
|
||||
boolean success = false;
|
||||
|
||||
SnapshotVO snapshotVO = snapshotDao.acquireInLockTable(snapshotInfo.getId());
|
||||
|
||||
if (snapshotVO == null) {
|
||||
@ -328,9 +338,6 @@ public class StorageSystemSnapshotStrategy extends SnapshotStrategyBase {
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
|
||||
Long hostId = null;
|
||||
boolean success = false;
|
||||
|
||||
try {
|
||||
volumeInfo.stateTransit(Volume.Event.RevertSnapshotRequested);
|
||||
|
||||
@ -350,14 +357,14 @@ public class StorageSystemSnapshotStrategy extends SnapshotStrategyBase {
|
||||
success = snapshotSvr.revertSnapshot(snapshotInfo);
|
||||
|
||||
if (!success) {
|
||||
String errMsg = "Failed to revert a volume to a snapshot state";
|
||||
String errMsg = String.format("Failed to revert volume [name:%s, format:%s] to snapshot [id:%s] state", volumeInfo.getName(), volumeInfo.getFormat(),
|
||||
snapshotInfo.getSnapshotId());
|
||||
|
||||
s_logger.error(errMsg);
|
||||
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
if (getHypervisorRequiresResignature(volumeInfo)) {
|
||||
if (hostId != null) {
|
||||
HostVO hostVO = hostDao.findById(hostId);
|
||||
@ -371,15 +378,12 @@ public class StorageSystemSnapshotStrategy extends SnapshotStrategyBase {
|
||||
|
||||
if (success) {
|
||||
volumeInfo.stateTransit(Volume.Event.OperationSucceeded);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
volumeInfo.stateTransit(Volume.Event.OperationFailed);
|
||||
}
|
||||
|
||||
snapshotDao.releaseFromLockTable(snapshotInfo.getId());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private Long getHostId(VolumeInfo volumeInfo) {
|
||||
|
||||
@ -32,6 +32,9 @@
|
||||
|
||||
<bean id="storageSystemSnapshotStrategy"
|
||||
class="org.apache.cloudstack.storage.snapshot.StorageSystemSnapshotStrategy" />
|
||||
|
||||
<bean id="cephSnapshotStrategy"
|
||||
class="org.apache.cloudstack.storage.snapshot.CephSnapshotStrategy" />
|
||||
|
||||
<bean id="DefaultVMSnapshotStrategy"
|
||||
class="org.apache.cloudstack.storage.vmsnapshot.DefaultVMSnapshotStrategy" />
|
||||
|
||||
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.storage.snapshot;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import com.cloud.storage.Snapshot;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CephSnapshotStrategyTest {
|
||||
|
||||
@Spy
|
||||
@InjectMocks
|
||||
private CephSnapshotStrategy cephSnapshotStrategy;
|
||||
@Mock
|
||||
private SnapshotDataStoreDao snapshotStoreDao;
|
||||
@Mock
|
||||
private PrimaryDataStoreDao primaryDataStoreDao;
|
||||
@Mock
|
||||
private VolumeDao volumeDao;
|
||||
|
||||
@Test
|
||||
public void canHandleTestNotReomvedAndSnapshotStoredOnRbd() {
|
||||
configureAndVerifyCanHandle(null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canHandleTestNotReomvedAndSnapshotNotStoredOnRbd() {
|
||||
configureAndVerifyCanHandle(null, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canHandleTestReomvedAndSnapshotNotStoredOnRbd() {
|
||||
configureAndVerifyCanHandle(null, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canHandleTestReomvedAndSnapshotStoredOnRbd() {
|
||||
configureAndVerifyCanHandle(null, true);
|
||||
}
|
||||
|
||||
private void configureAndVerifyCanHandle(Date removed, boolean isSnapshotStoredOnRbdStoragePool) {
|
||||
Snapshot snapshot = Mockito.mock(Snapshot.class);
|
||||
SnapshotOperation[] snapshotOps = SnapshotOperation.values();
|
||||
|
||||
Mockito.when(snapshot.getVolumeId()).thenReturn(0l);
|
||||
VolumeVO volumeVO = Mockito.mock(VolumeVO.class);
|
||||
Mockito.when(volumeVO.getRemoved()).thenReturn(removed);
|
||||
Mockito.when(volumeDao.findByIdIncludingRemoved(Mockito.anyLong())).thenReturn(volumeVO);
|
||||
Mockito.doReturn(isSnapshotStoredOnRbdStoragePool).when(cephSnapshotStrategy).isSnapshotStoredOnRbdStoragePool(Mockito.any());
|
||||
|
||||
for (int i = 0; i < snapshotOps.length - 1; i++) {
|
||||
StrategyPriority strategyPriority = cephSnapshotStrategy.canHandle(snapshot, snapshotOps[i]);
|
||||
if (snapshotOps[i] == SnapshotOperation.REVERT && isSnapshotStoredOnRbdStoragePool) {
|
||||
Assert.assertEquals(StrategyPriority.HIGHEST, strategyPriority);
|
||||
} else {
|
||||
Assert.assertEquals(StrategyPriority.CANT_HANDLE, strategyPriority);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void revertSnapshotTest() {
|
||||
ImageFormat[] imageFormatValues = ImageFormat.values();
|
||||
|
||||
for (int i = 0; i < imageFormatValues.length - 1; i++) {
|
||||
Mockito.reset(cephSnapshotStrategy);
|
||||
SnapshotInfo snapshotInfo = Mockito.mock(SnapshotInfo.class);
|
||||
VolumeInfo volumeInfo = Mockito.mock(VolumeInfo.class);
|
||||
Mockito.when(snapshotInfo.getBaseVolume()).thenReturn(volumeInfo);
|
||||
Mockito.when(volumeInfo.getFormat()).thenReturn(imageFormatValues[i]);
|
||||
Mockito.doNothing().when(cephSnapshotStrategy).executeRevertSnapshot(Mockito.any(), Mockito.any());
|
||||
|
||||
boolean revertResult = cephSnapshotStrategy.revertSnapshot(snapshotInfo);
|
||||
|
||||
if (imageFormatValues[i] == ImageFormat.RAW) {
|
||||
Assert.assertTrue(revertResult);
|
||||
Mockito.verify(cephSnapshotStrategy).executeRevertSnapshot(Mockito.any(), Mockito.any());
|
||||
} else {
|
||||
Assert.assertFalse(revertResult);
|
||||
Mockito.verify(cephSnapshotStrategy, Mockito.times(0)).executeRevertSnapshot(Mockito.any(), Mockito.any());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -27,6 +27,12 @@ import org.apache.cloudstack.storage.to.SnapshotObjectTO;
|
||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.ceph.rados.IoCTX;
|
||||
import com.ceph.rados.Rados;
|
||||
import com.ceph.rados.exceptions.RadosException;
|
||||
import com.ceph.rbd.Rbd;
|
||||
import com.ceph.rbd.RbdException;
|
||||
import com.ceph.rbd.RbdImage;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
import com.cloud.agent.api.to.NfsTO;
|
||||
@ -40,42 +46,64 @@ import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
|
||||
@ResourceWrapper(handles = RevertSnapshotCommand.class)
|
||||
@ResourceWrapper(handles = RevertSnapshotCommand.class)
|
||||
public final class LibvirtRevertSnapshotCommandWrapper extends CommandWrapper<RevertSnapshotCommand, Answer, LibvirtComputingResource> {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(LibvirtRevertSnapshotCommandWrapper.class);
|
||||
private static final String MON_HOST = "mon_host";
|
||||
private static final String KEY = "key";
|
||||
private static final String CLIENT_MOUNT_TIMEOUT = "client_mount_timeout";
|
||||
private static final String RADOS_CONNECTION_TIMEOUT = "30";
|
||||
|
||||
@Override
|
||||
public Answer execute(final RevertSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
||||
SnapshotObjectTO snapshot = command.getData();
|
||||
VolumeObjectTO volume = snapshot.getVolume();
|
||||
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) volume.getDataStore();
|
||||
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore();
|
||||
DataStoreTO snapshotImageStore = snapshot.getDataStore();
|
||||
if (!(snapshotImageStore instanceof NfsTO)) {
|
||||
return new Answer(command, false, "revert snapshot on object storage is not implemented yet");
|
||||
if (!(snapshotImageStore instanceof NfsTO) && primaryStore.getPoolType() != StoragePoolType.RBD) {
|
||||
return new Answer(command, false,
|
||||
String.format("Revert snapshot does not support storage pool of type [%s]. Revert snapshot is supported by storage pools of type 'NFS' or 'RBD'",
|
||||
primaryStore.getPoolType()));
|
||||
}
|
||||
NfsTO nfsImageStore = (NfsTO) snapshotImageStore;
|
||||
|
||||
String secondaryStoragePoolUrl = nfsImageStore.getUrl();
|
||||
|
||||
String volumePath = volume.getPath();
|
||||
String snapshotPath = null;
|
||||
String snapshotRelPath = null;
|
||||
KVMStoragePool secondaryStoragePool = null;
|
||||
try {
|
||||
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
|
||||
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl);
|
||||
String ssPmountPath = secondaryStoragePool.getLocalPath();
|
||||
snapshotRelPath = snapshot.getPath();
|
||||
snapshotPath = ssPmountPath + File.separator + snapshotRelPath;
|
||||
KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
|
||||
|
||||
KVMPhysicalDisk snapshotDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(),
|
||||
primaryStore.getUuid(), volumePath);
|
||||
KVMPhysicalDisk snapshotDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volumePath);
|
||||
KVMStoragePool primaryPool = snapshotDisk.getPool();
|
||||
|
||||
if (primaryPool.getType() == StoragePoolType.RBD) {
|
||||
return new Answer(command, false, "revert snapshot to RBD is not implemented yet");
|
||||
Rados rados = new Rados(primaryPool.getAuthUserName());
|
||||
rados.confSet(MON_HOST, primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort());
|
||||
rados.confSet(KEY, primaryPool.getAuthSecret());
|
||||
rados.confSet(CLIENT_MOUNT_TIMEOUT, RADOS_CONNECTION_TIMEOUT);
|
||||
rados.connect();
|
||||
|
||||
String[] rbdPoolAndVolumeAndSnapshot = snapshotRelPath.split("/");
|
||||
|
||||
IoCTX io = rados.ioCtxCreate(primaryPool.getSourceDir());
|
||||
Rbd rbd = new Rbd(io);
|
||||
RbdImage image = rbd.open(rbdPoolAndVolumeAndSnapshot[1]);
|
||||
|
||||
s_logger.debug(String.format("Attempting to rollback RBD snapshot [name:%s], [pool:%s], [volumeid:%s], [snapshotid:%s]", snapshot.getName(),
|
||||
rbdPoolAndVolumeAndSnapshot[0], rbdPoolAndVolumeAndSnapshot[1], rbdPoolAndVolumeAndSnapshot[2]));
|
||||
image.snapRollBack(rbdPoolAndVolumeAndSnapshot[2]);
|
||||
|
||||
rbd.close(image);
|
||||
rados.ioCtxDestroy(io);
|
||||
} else {
|
||||
NfsTO nfsImageStore = (NfsTO)snapshotImageStore;
|
||||
String secondaryStoragePoolUrl = nfsImageStore.getUrl();
|
||||
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl);
|
||||
String ssPmountPath = secondaryStoragePool.getLocalPath();
|
||||
snapshotPath = ssPmountPath + File.separator + snapshotRelPath;
|
||||
|
||||
Script cmd = new Script(libvirtComputingResource.manageSnapshotPath(), libvirtComputingResource.getCmdsTimeout(), s_logger);
|
||||
cmd.add("-v", snapshotPath);
|
||||
cmd.add("-n", snapshotDisk.getName());
|
||||
@ -90,6 +118,12 @@ public final class LibvirtRevertSnapshotCommandWrapper extends CommandWrapper<Re
|
||||
return new Answer(command, true, "RevertSnapshotCommand executes successfully");
|
||||
} catch (CloudRuntimeException e) {
|
||||
return new Answer(command, false, e.toString());
|
||||
} catch (RadosException e) {
|
||||
s_logger.error("Failed to connect to Rados pool while trying to revert snapshot. Exception: ", e);
|
||||
return new Answer(command, false, e.toString());
|
||||
} catch (RbdException e) {
|
||||
s_logger.error("Failed to connect to revert snapshot due to RBD exception: ", e);
|
||||
return new Answer(command, false, e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
pom.xml
2
pom.xml
@ -153,7 +153,7 @@
|
||||
<cs.neethi.version>2.0.4</cs.neethi.version>
|
||||
<cs.nitro.version>10.1</cs.nitro.version>
|
||||
<cs.opensaml.version>2.6.4</cs.opensaml.version>
|
||||
<cs.rados-java.version>0.2.0</cs.rados-java.version>
|
||||
<cs.rados-java.version>0.5.0</cs.rados-java.version>
|
||||
<cs.rampart.version>1.5.1</cs.rampart.version>
|
||||
<cs.reflections.version>0.9.11</cs.reflections.version>
|
||||
<cs.servicemix.version>2.5.8_1</cs.servicemix.version>
|
||||
|
||||
@ -98,6 +98,7 @@ import com.cloud.storage.SnapshotScheduleVO;
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
@ -1263,7 +1264,7 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement
|
||||
}
|
||||
}
|
||||
|
||||
private static DataStoreRole getDataStoreRole(Snapshot snapshot, SnapshotDataStoreDao snapshotStoreDao, DataStoreManager dataStoreMgr) {
|
||||
private DataStoreRole getDataStoreRole(Snapshot snapshot, SnapshotDataStoreDao snapshotStoreDao, DataStoreManager dataStoreMgr) {
|
||||
SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
|
||||
|
||||
if (snapshotStore == null) {
|
||||
@ -1284,6 +1285,11 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement
|
||||
}
|
||||
}
|
||||
|
||||
StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId);
|
||||
if (storagePoolVO.getPoolType() == StoragePoolType.RBD && !BackupSnapshotAfterTakingSnapshot.value()) {
|
||||
return DataStoreRole.Primary;
|
||||
}
|
||||
|
||||
return DataStoreRole.Image;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user