bug 12604: if there are actually snapshots creating on the volume, then don't move the snapshot

status 12604: resolved fixed
This commit is contained in:
Edison Su 2011-12-20 15:10:37 -08:00
parent a4d4d9d6bb
commit c067763075
6 changed files with 44 additions and 13 deletions

View File

@ -33,10 +33,10 @@ usage() {
}
qemu_img="cloud-qemu-img"
which $qemu_img
which $qemu_img >& /dev/null
if [ $? -gt 0 ]
then
which qemu-img
which qemu-img >& /dev/null
if [ $? -eq 0 ]
then
qemu_img="qemu-img"

View File

@ -1567,15 +1567,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
@Override
public VolumeVO moveVolume(VolumeVO volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType) throws ConcurrentOperationException {
List<SnapshotVO> snapshots = _snapshotDao.listByVolumeId(volume.getId());
if (snapshots != null && snapshots.size() > 0) {
throw new CloudRuntimeException("Unable to move volume " + volume.getId() + " due to there are snapshots for this volume");
}
List<SnapshotPolicyVO> snapshotPolicys = _snapshotPolicyDao.listByVolumeId(volume.getId());
if (snapshotPolicys != null && snapshotPolicys.size() > 0) {
throw new CloudRuntimeException("Unable to move volume " + volume.getId() + " due to there are snapshot policyes for this volume");
}
// Find a destination storage pool with the specified criteria
DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
@ -2440,6 +2432,10 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
throw new InvalidParameterValueException("Unable to aquire volume with ID: " + volumeId);
}
if (!_snapshotMgr.canOperateOnVolume(volume)) {
throw new InvalidParameterValueException("There are snapshot creating on it, Unable to delete the volume");
}
//permission check
_accountMgr.checkAccess(caller, null, volume);
@ -2622,6 +2618,10 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
boolean transitResult = false;
try {
for (Volume volume : volumes) {
if (!_snapshotMgr.canOperateOnVolume((VolumeVO)volume)) {
throw new CloudRuntimeException("There are snapshots creating on this volume, can not move this volume");
}
try {
if (!stateTransitTo(volume, Volume.Event.MigrationRequested)) {
throw new ConcurrentOperationException("Failed to transit volume state");

View File

@ -21,6 +21,7 @@ package com.cloud.storage.dao;
import java.util.List;
import com.cloud.storage.Snapshot;
import com.cloud.storage.Snapshot.Status;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Snapshot.Type;
import com.cloud.utils.db.Filter;
@ -42,4 +43,5 @@ public interface SnapshotDao extends GenericDao<SnapshotVO, Long> {
List<SnapshotVO> listByHostId(long hostId);
public Long countSnapshotsForAccount(long accountId);
List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.Status... status);
List<SnapshotVO> listByStatus(long volumeId, Snapshot.Status... status);
}

View File

@ -60,6 +60,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
private final SearchBuilder<SnapshotVO> HostIdSearch;
private final SearchBuilder<SnapshotVO> AccountIdSearch;
private final SearchBuilder<SnapshotVO> InstanceIdSearch;
private final SearchBuilder<SnapshotVO> StatusSearch;
private final GenericSearchBuilder<SnapshotVO, Long> CountSnapshotsByAccount;
protected final VMInstanceDaoImpl _instanceDao = ComponentLocator.inject(VMInstanceDaoImpl.class);
@ -168,6 +169,11 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
AccountIdSearch.done();
StatusSearch = createSearchBuilder();
StatusSearch.and("volumeId", StatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
StatusSearch.and("status", StatusSearch.entity().getStatus(), SearchCriteria.Op.IN);
StatusSearch.done();
CountSnapshotsByAccount = createSearchBuilder(Long.class);
CountSnapshotsByAccount.select(null, Func.COUNT, null);
CountSnapshotsByAccount.and("account", CountSnapshotsByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
@ -270,12 +276,20 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
public List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.Status... status) {
SearchCriteria<SnapshotVO> sc = this.InstanceIdSearch.create();
if (status != null) {
sc.setParameters("status", status.toString());
if (status != null && status.length != 0) {
sc.setParameters("status", (Object[])status);
}
sc.setJoinParameters("instanceSnapshots", "state", Volume.State.Ready);
sc.setJoinParameters("instanceVolumes", "instanceId", instanceId);
return listBy(sc, null);
}
@Override
public List<SnapshotVO> listByStatus(long volumeId, Snapshot.Status... status) {
SearchCriteria<SnapshotVO> sc = this.StatusSearch.create();
sc.setParameters("volumeId", volumeId);
sc.setParameters("status", (Object[])status);
return listBy(sc, null);
}
}

View File

@ -137,4 +137,6 @@ public interface SnapshotManager {
void deleteSnapshotsForVolume (String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId );
void deleteSnapshotsDirForVolume(String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId);
boolean canOperateOnVolume(VolumeVO volume);
}

View File

@ -372,6 +372,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
throw new InvalidParameterValueException("No such volume exist");
}
if (volume.getState() != Volume.State.Ready) {
throw new InvalidParameterValueException("Volume is not in ready state");
}
SnapshotVO snapshot = null;
boolean backedUp = false;
@ -1506,5 +1510,14 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
}
return false;
}
@Override
public boolean canOperateOnVolume(VolumeVO volume) {
List<SnapshotVO> snapshots = _snapshotDao.listByStatus(volume.getId(), Status.Creating, Status.CreatedOnPrimary, Status.BackingUp);
if (snapshots.size() > 0) {
return false;
}
return true;
}
}