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" qemu_img="cloud-qemu-img"
which $qemu_img which $qemu_img >& /dev/null
if [ $? -gt 0 ] if [ $? -gt 0 ]
then then
which qemu-img which qemu-img >& /dev/null
if [ $? -eq 0 ] if [ $? -eq 0 ]
then then
qemu_img="qemu-img" qemu_img="qemu-img"

View File

@ -1567,15 +1567,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
@Override @Override
public VolumeVO moveVolume(VolumeVO volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType) throws ConcurrentOperationException { 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 // Find a destination storage pool with the specified criteria
DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId()); 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); 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 //permission check
_accountMgr.checkAccess(caller, null, volume); _accountMgr.checkAccess(caller, null, volume);
@ -2622,6 +2618,10 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
boolean transitResult = false; boolean transitResult = false;
try { try {
for (Volume volume : volumes) { 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 { try {
if (!stateTransitTo(volume, Volume.Event.MigrationRequested)) { if (!stateTransitTo(volume, Volume.Event.MigrationRequested)) {
throw new ConcurrentOperationException("Failed to transit volume state"); throw new ConcurrentOperationException("Failed to transit volume state");

View File

@ -21,6 +21,7 @@ package com.cloud.storage.dao;
import java.util.List; import java.util.List;
import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot;
import com.cloud.storage.Snapshot.Status;
import com.cloud.storage.SnapshotVO; import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Snapshot.Type; import com.cloud.storage.Snapshot.Type;
import com.cloud.utils.db.Filter; import com.cloud.utils.db.Filter;
@ -42,4 +43,5 @@ public interface SnapshotDao extends GenericDao<SnapshotVO, Long> {
List<SnapshotVO> listByHostId(long hostId); List<SnapshotVO> listByHostId(long hostId);
public Long countSnapshotsForAccount(long accountId); public Long countSnapshotsForAccount(long accountId);
List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.Status... status); 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> HostIdSearch;
private final SearchBuilder<SnapshotVO> AccountIdSearch; private final SearchBuilder<SnapshotVO> AccountIdSearch;
private final SearchBuilder<SnapshotVO> InstanceIdSearch; private final SearchBuilder<SnapshotVO> InstanceIdSearch;
private final SearchBuilder<SnapshotVO> StatusSearch;
private final GenericSearchBuilder<SnapshotVO, Long> CountSnapshotsByAccount; private final GenericSearchBuilder<SnapshotVO, Long> CountSnapshotsByAccount;
protected final VMInstanceDaoImpl _instanceDao = ComponentLocator.inject(VMInstanceDaoImpl.class); 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.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
AccountIdSearch.done(); 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 = createSearchBuilder(Long.class);
CountSnapshotsByAccount.select(null, Func.COUNT, null); CountSnapshotsByAccount.select(null, Func.COUNT, null);
CountSnapshotsByAccount.and("account", CountSnapshotsByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); 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) { public List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.Status... status) {
SearchCriteria<SnapshotVO> sc = this.InstanceIdSearch.create(); SearchCriteria<SnapshotVO> sc = this.InstanceIdSearch.create();
if (status != null) { if (status != null && status.length != 0) {
sc.setParameters("status", status.toString()); sc.setParameters("status", (Object[])status);
} }
sc.setJoinParameters("instanceSnapshots", "state", Volume.State.Ready); sc.setJoinParameters("instanceSnapshots", "state", Volume.State.Ready);
sc.setJoinParameters("instanceVolumes", "instanceId", instanceId); sc.setJoinParameters("instanceVolumes", "instanceId", instanceId);
return listBy(sc, null); 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 deleteSnapshotsForVolume (String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId );
void deleteSnapshotsDirForVolume(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"); 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; SnapshotVO snapshot = null;
boolean backedUp = false; boolean backedUp = false;
@ -1507,4 +1511,13 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
return false; 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;
}
} }