mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	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:
		
							parent
							
								
									a4d4d9d6bb
								
							
						
					
					
						commit
						c067763075
					
				| @ -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" | ||||||
|  | |||||||
| @ -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"); | ||||||
|  | |||||||
| @ -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); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user