mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	bug 11531: while taking snapshot on volume, if volume is attached to a VM instance and under VMware, check if there are other ongoing snapshot tasks for the VM instance.
This commit is contained in:
		
							parent
							
								
									4557b5d54e
								
							
						
					
					
						commit
						2a6de104e2
					
				| @ -20,6 +20,7 @@ package com.cloud.storage.dao; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| import com.cloud.storage.Snapshot; | ||||
| import com.cloud.storage.SnapshotVO; | ||||
| import com.cloud.storage.Snapshot.Type; | ||||
| import com.cloud.utils.db.Filter; | ||||
| @ -39,5 +40,6 @@ public interface SnapshotDao extends GenericDao<SnapshotVO, Long> { | ||||
|     long updateSnapshotSecHost(long dcId, long secHostId); | ||||
|     List<SnapshotVO> listByHostId(Filter filter, 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); | ||||
| } | ||||
|  | ||||
| @ -26,16 +26,24 @@ import javax.ejb.Local; | ||||
| 
 | ||||
| import org.apache.log4j.Logger; | ||||
| 
 | ||||
| import com.cloud.host.dao.HostDetailsDaoImpl; | ||||
| import com.cloud.storage.Snapshot.Type; | ||||
| import com.cloud.storage.Snapshot; | ||||
| import com.cloud.storage.SnapshotVO; | ||||
| import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; | ||||
| import com.cloud.storage.Volume; | ||||
| import com.cloud.storage.VolumeVO; | ||||
| import com.cloud.utils.component.ComponentLocator; | ||||
| import com.cloud.utils.db.Filter; | ||||
| import com.cloud.utils.db.GenericDaoBase; | ||||
| import com.cloud.utils.db.GenericSearchBuilder; | ||||
| import com.cloud.utils.db.JoinBuilder.JoinType; | ||||
| import com.cloud.utils.db.SearchBuilder; | ||||
| import com.cloud.utils.db.SearchCriteria; | ||||
| import com.cloud.utils.db.SearchCriteria.Func; | ||||
| import com.cloud.utils.db.Transaction; | ||||
| import com.cloud.vm.VMInstanceVO; | ||||
| import com.cloud.vm.dao.VMInstanceDaoImpl; | ||||
| 
 | ||||
| @Local (value={SnapshotDao.class}) | ||||
| public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements SnapshotDao { | ||||
| @ -52,7 +60,11 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements | ||||
|     private final SearchBuilder<SnapshotVO> VolumeIdVersionSearch; | ||||
|     private final SearchBuilder<SnapshotVO> HostIdSearch; | ||||
|     private final SearchBuilder<SnapshotVO> AccountIdSearch; | ||||
|     private final SearchBuilder<SnapshotVO> InstanceIdSearch; | ||||
|     private final GenericSearchBuilder<SnapshotVO, Long> CountSnapshotsByAccount; | ||||
|      | ||||
|     protected final VMInstanceDaoImpl _instanceDao = ComponentLocator.inject(VMInstanceDaoImpl.class); | ||||
|     protected final VolumeDaoImpl _volumeDao = ComponentLocator.inject(VolumeDaoImpl.class); | ||||
| 
 | ||||
|     @Override | ||||
|     public SnapshotVO findNextSnapshot(long snapshotId) { | ||||
| @ -162,6 +174,19 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements | ||||
|         CountSnapshotsByAccount.and("account", CountSnapshotsByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); | ||||
|         CountSnapshotsByAccount.and("removed", CountSnapshotsByAccount.entity().getRemoved(), SearchCriteria.Op.NULL); | ||||
|         CountSnapshotsByAccount.done(); | ||||
|          | ||||
|     	InstanceIdSearch = createSearchBuilder(); | ||||
|     	InstanceIdSearch.and("status", InstanceIdSearch.entity().getStatus(), SearchCriteria.Op.IN); | ||||
|     	 | ||||
|     	SearchBuilder<VMInstanceVO> instanceSearch = _instanceDao.createSearchBuilder(); | ||||
|     	instanceSearch.and("instanceId", instanceSearch.entity().getId(), SearchCriteria.Op.EQ); | ||||
|     	 | ||||
|     	SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder(); | ||||
|     	volumeSearch.and("state", volumeSearch.entity().getState(), SearchCriteria.Op.EQ); | ||||
|     	volumeSearch.join("instanceVolumes", instanceSearch, instanceSearch.entity().getId(), volumeSearch.entity().getInstanceId(), JoinType.INNER); | ||||
|     	 | ||||
|     	InstanceIdSearch.join("instanceSnapshots", volumeSearch, volumeSearch.entity().getId(), InstanceIdSearch.entity().getVolumeId(), JoinType.INNER); | ||||
|     	InstanceIdSearch.done(); | ||||
|     } | ||||
|      | ||||
|     @Override  | ||||
| @ -241,4 +266,13 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements | ||||
|         sc.setParameters("account", accountId); | ||||
|         return customSearch(sc, null).get(0); | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
| 	public List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.Status... status) { | ||||
|     	SearchCriteria<SnapshotVO> sc = this.InstanceIdSearch.create(); | ||||
|     	sc.setParameters("status", status); | ||||
|     	sc.setJoinParameters("instanceSnapshots", "state", Volume.State.Ready); | ||||
|     	sc.setJoinParameters("instanceVolumes", "instanceId", instanceId); | ||||
|         return listBy(sc, null); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -389,6 +389,12 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma | ||||
|                         throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volumeId + " is associated with vm:" + userVm.getInstanceName() + " is in " | ||||
|                                 + userVm.getState().toString() + " state"); | ||||
|                     } | ||||
|                      | ||||
|                     if(userVm.getHypervisorType() == HypervisorType.VMware) { | ||||
|                     	List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(v.getInstanceId(), Snapshot.Status.Creating,  Snapshot.Status.CreatedOnPrimary,  Snapshot.Status.BackingUp); | ||||
|                     	if(activeSnapshots.size() > 1) | ||||
|                             throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later"); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
| @ -442,6 +448,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma | ||||
|                 } else { | ||||
|                     _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.snapshot); | ||||
|                 } | ||||
|             } else { | ||||
|             	snapshot = _snapshotDao.findById(snapshotId); | ||||
|                 snapshot.setStatus(Status.Error); | ||||
|                 _snapshotDao.update(snapshotId, snapshot); | ||||
|             } | ||||
|              | ||||
|             if ( volume != null ) { | ||||
|  | ||||
| @ -208,8 +208,26 @@ public class SearchCriteria<K> { | ||||
|         return _selects == null || _selects.size() == 0; | ||||
|     } | ||||
|      | ||||
|     protected JoinBuilder<SearchCriteria<?>> findJoin(Map<String, JoinBuilder<SearchCriteria<?>>> jbmap, String joinName) { | ||||
|     	JoinBuilder<SearchCriteria<?>> jb = jbmap.get(joinName); | ||||
|     	if (jb != null) { | ||||
|     		return jb; | ||||
|     	} | ||||
|     	 | ||||
|     	for (JoinBuilder<SearchCriteria<?>> j2 : _joins.values()) { | ||||
|     		SearchCriteria<?> sc = j2.getT(); | ||||
|     		jb = findJoin(sc._joins, joinName); | ||||
|     		if (jb != null) { | ||||
|     			return jb; | ||||
|     		} | ||||
|     	} | ||||
|     	 | ||||
|     	assert (false) : "Unable to find a join by the name " + joinName; | ||||
|     	return null; | ||||
|     } | ||||
|      | ||||
|     public void setJoinParameters(String joinName, String conditionName, Object... params) { | ||||
|     	JoinBuilder<SearchCriteria<?>> join = _joins.get(joinName); | ||||
|     	JoinBuilder<SearchCriteria<?>> join = findJoin(_joins, joinName); | ||||
|         assert (join != null) : "Incorrect join name specified: " + joinName; | ||||
|         join.getT().setParameters(conditionName, params); | ||||
| 
 | ||||
|  | ||||
| @ -11,7 +11,7 @@ | ||||
|    <!-- A regular appender FIXME implement code that will close/reopen logs on SIGHUP by logrotate FIXME make the paths configurable using the build system --> | ||||
| <!--   <appender name="FILE" class="org.apache.log4j.rolling.RollingFileAppender"> | ||||
|       <param name="Append" value="true"/> | ||||
|       <param name="Threshold" value="DEBUG"/> | ||||
|       <param name="Threshold" value="TRACE"/> | ||||
|       <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy"> | ||||
|         <param name="FileNamePattern" value="@MSLOG@.%d{yyyy-MM-dd}.gz"/> | ||||
|         <param name="ActiveFileName" value="@MSLOG@"/> | ||||
| @ -24,7 +24,7 @@ | ||||
|   <!--  | ||||
|    <appender name="APISERVER" class="org.apache.log4j.rolling.RollingFileAppender"> | ||||
|       <param name="Append" value="true"/> | ||||
|       <param name="Threshold" value="DEBUG"/> | ||||
|       <param name="Threshold" value="TRACE"/> | ||||
|       <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy"> | ||||
|         <param name="FileNamePattern" value="@APISERVERLOG@.%d{yyyy-MM-dd}.gz"/> | ||||
|         <param name="ActiveFileName" value="@APISERVERLOG@"/> | ||||
| @ -55,7 +55,7 @@ | ||||
| 
 | ||||
|    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> | ||||
|       <param name="Target" value="System.out"/> | ||||
|       <param name="Threshold" value="DEBUG"/> | ||||
|       <param name="Threshold" value="TRACE"/> | ||||
|       <layout class="org.apache.log4j.PatternLayout"> | ||||
|          <param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{3}] (%t:%x) %m%n"/> | ||||
|       </layout> | ||||
| @ -66,7 +66,7 @@ | ||||
|    <!-- ================ --> | ||||
| 
 | ||||
|    <category name="com.cloud"> | ||||
|      <priority value="DEBUG"/> | ||||
|      <priority value="TRACE"/> | ||||
|    </category> | ||||
|     | ||||
|    <!-- Limit the org.apache category to INFO as its DEBUG is verbose --> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user