diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml
index 97ca7f21e33..eda47be41e2 100644
--- a/engine/storage/snapshot/pom.xml
+++ b/engine/storage/snapshot/pom.xml
@@ -37,6 +37,11 @@
test-jar
test
+
+ org.apache.cloudstack
+ cloud-engine-storage-volume
+ ${project.version}
+
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
index edd194e605b..99fc1612faa 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
@@ -36,6 +36,7 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl;
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
import com.cloud.exception.InvalidParameterValueException;
@@ -53,6 +54,7 @@ import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
@@ -263,6 +265,10 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
//snapshot is deleted on backup storage, need to delete it on primary storage
SnapshotDataStoreVO snapshotOnPrimary = snapshotStoreDao.findBySnapshot(snapshotId, DataStoreRole.Primary);
if (snapshotOnPrimary != null) {
+ SnapshotInfo snapshotOnPrimaryInfo = snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Primary);
+ if (((PrimaryDataStoreImpl)snapshotOnPrimaryInfo.getDataStore()).getPoolType() == StoragePoolType.RBD) {
+ snapshotSvr.deleteSnapshot(snapshotOnPrimaryInfo);
+ }
snapshotOnPrimary.setState(State.Destroyed);
snapshotStoreDao.update(snapshotOnPrimary.getId(), snapshotOnPrimary);
}
@@ -371,15 +377,17 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
try {
SnapshotInfo parent = snapshot.getParent();
- if (backupedSnapshot != null && parent != null) {
- Long parentSnapshotId = parent.getId();
- while (parentSnapshotId != null && parentSnapshotId != 0L) {
- SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), parentSnapshotId);
- if (snapshotDataStoreVO != null) {
- parentSnapshotId = snapshotDataStoreVO.getParentSnapshotId();
- snapshotStoreDao.remove(snapshotDataStoreVO.getId());
- } else {
- parentSnapshotId = null;
+ if (backupedSnapshot != null && parent != null && primaryStore instanceof PrimaryDataStoreImpl) {
+ if (((PrimaryDataStoreImpl)primaryStore).getPoolType() != StoragePoolType.RBD) {
+ Long parentSnapshotId = parent.getId();
+ while (parentSnapshotId != null && parentSnapshotId != 0L) {
+ SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), parentSnapshotId);
+ if (snapshotDataStoreVO != null) {
+ parentSnapshotId = snapshotDataStoreVO.getParentSnapshotId();
+ snapshotStoreDao.remove(snapshotDataStoreVO.getId());
+ } else {
+ parentSnapshotId = null;
+ }
}
}
SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), snapshot.getId());
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
index 51931dbb9af..92e985e023e 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@ -1274,7 +1274,48 @@ public class KVMStorageProcessor implements StorageProcessor {
@Override
public Answer deleteSnapshot(final DeleteCommand cmd) {
- return new Answer(cmd);
+ String snap_full_name = "";
+ try {
+ SnapshotObjectTO snapshotTO = (SnapshotObjectTO) cmd.getData();
+ PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) snapshotTO.getDataStore();
+ VolumeObjectTO volume = snapshotTO.getVolume();
+ KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
+ KVMPhysicalDisk disk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volume.getPath());
+ String snapshotFullPath = snapshotTO.getPath();
+ String snapshotName = snapshotFullPath.substring(snapshotFullPath.lastIndexOf("/") + 1);
+ snap_full_name = disk.getName() + "@" + snapshotName;
+ if (primaryPool.getType() == StoragePoolType.RBD) {
+ Rados r = new Rados(primaryPool.getAuthUserName());
+ r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort());
+ r.confSet("key", primaryPool.getAuthSecret());
+ r.confSet("client_mount_timeout", "30");
+ r.connect();
+ s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
+ IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir());
+ Rbd rbd = new Rbd(io);
+ RbdImage image = rbd.open(disk.getName());
+ try {
+ s_logger.info("Attempting to remove RBD snapshot " + snap_full_name);
+ if (image.snapIsProtected(snapshotName)) {
+ s_logger.debug("Unprotecting RBD snapshot " + snap_full_name);
+ image.snapUnprotect(snapshotName);
+ }
+ image.snapRemove(snapshotName);
+ s_logger.info("Snapshot " + snap_full_name + " successfully removed from " +
+ primaryPool.getType().toString() + " pool.");
+ } finally {
+ rbd.close(image);
+ r.ioCtxDestroy(io);
+ }
+ } else {
+ s_logger.warn("Operation not implemented for storage pool type of " + primaryPool.getType().toString());
+ throw new InternalErrorException("Operation not implemented for storage pool type of " + primaryPool.getType().toString());
+ }
+ return new Answer(cmd, true, "Snapshot " + snap_full_name + " removed successfully.");
+ } catch (Exception e) {
+ s_logger.error(e.getMessage());
+ return new Answer(cmd, false, "Failed to remove snapshot " + snap_full_name);
+ }
}
@Override