mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-8302 - Cleanup snapshot on KVM with RBD
Snapshot removing implemented on RBD. 1. On management side: when created new shanpshot we checking if our primary storage is RBD, then do not remove record from cloud.snapshot_store_ref with link to Ceph image via 'install_path' field. 2. On management side: when removing snapshot, also send command to agent 'DeleteCommand'. 3. On agent side: method implemented 'public Answer deleteSnapshot(final DeleteCommand cmd)'
This commit is contained in:
parent
d518b619dd
commit
10ae2aff28
@ -37,6 +37,11 @@
|
|||||||
<type>test-jar</type>
|
<type>test-jar</type>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-engine-storage-volume</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
|||||||
@ -36,6 +36,7 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
|||||||
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
|
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
|
||||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
||||||
|
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl;
|
||||||
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
|
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
|
||||||
|
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
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.dao.VolumeDao;
|
||||||
import com.cloud.storage.snapshot.SnapshotManager;
|
import com.cloud.storage.snapshot.SnapshotManager;
|
||||||
import com.cloud.storage.Storage.ImageFormat;
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
|
import com.cloud.storage.Storage.StoragePoolType;
|
||||||
import com.cloud.utils.NumbersUtil;
|
import com.cloud.utils.NumbersUtil;
|
||||||
import com.cloud.utils.db.DB;
|
import com.cloud.utils.db.DB;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
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
|
//snapshot is deleted on backup storage, need to delete it on primary storage
|
||||||
SnapshotDataStoreVO snapshotOnPrimary = snapshotStoreDao.findBySnapshot(snapshotId, DataStoreRole.Primary);
|
SnapshotDataStoreVO snapshotOnPrimary = snapshotStoreDao.findBySnapshot(snapshotId, DataStoreRole.Primary);
|
||||||
if (snapshotOnPrimary != null) {
|
if (snapshotOnPrimary != null) {
|
||||||
|
SnapshotInfo snapshotOnPrimaryInfo = snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Primary);
|
||||||
|
if (((PrimaryDataStoreImpl)snapshotOnPrimaryInfo.getDataStore()).getPoolType() == StoragePoolType.RBD) {
|
||||||
|
snapshotSvr.deleteSnapshot(snapshotOnPrimaryInfo);
|
||||||
|
}
|
||||||
snapshotOnPrimary.setState(State.Destroyed);
|
snapshotOnPrimary.setState(State.Destroyed);
|
||||||
snapshotStoreDao.update(snapshotOnPrimary.getId(), snapshotOnPrimary);
|
snapshotStoreDao.update(snapshotOnPrimary.getId(), snapshotOnPrimary);
|
||||||
}
|
}
|
||||||
@ -371,15 +377,17 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
SnapshotInfo parent = snapshot.getParent();
|
SnapshotInfo parent = snapshot.getParent();
|
||||||
if (backupedSnapshot != null && parent != null) {
|
if (backupedSnapshot != null && parent != null && primaryStore instanceof PrimaryDataStoreImpl) {
|
||||||
Long parentSnapshotId = parent.getId();
|
if (((PrimaryDataStoreImpl)primaryStore).getPoolType() != StoragePoolType.RBD) {
|
||||||
while (parentSnapshotId != null && parentSnapshotId != 0L) {
|
Long parentSnapshotId = parent.getId();
|
||||||
SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), parentSnapshotId);
|
while (parentSnapshotId != null && parentSnapshotId != 0L) {
|
||||||
if (snapshotDataStoreVO != null) {
|
SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), parentSnapshotId);
|
||||||
parentSnapshotId = snapshotDataStoreVO.getParentSnapshotId();
|
if (snapshotDataStoreVO != null) {
|
||||||
snapshotStoreDao.remove(snapshotDataStoreVO.getId());
|
parentSnapshotId = snapshotDataStoreVO.getParentSnapshotId();
|
||||||
} else {
|
snapshotStoreDao.remove(snapshotDataStoreVO.getId());
|
||||||
parentSnapshotId = null;
|
} else {
|
||||||
|
parentSnapshotId = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), snapshot.getId());
|
SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), snapshot.getId());
|
||||||
|
|||||||
@ -1274,7 +1274,48 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Answer deleteSnapshot(final DeleteCommand cmd) {
|
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
|
@Override
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user