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 java.util.List; | ||||||
| 
 | 
 | ||||||
|  | import com.cloud.storage.Snapshot; | ||||||
| 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; | ||||||
| @ -40,4 +41,5 @@ public interface SnapshotDao extends GenericDao<SnapshotVO, Long> { | |||||||
|     List<SnapshotVO> listByHostId(Filter filter, long hostId); |     List<SnapshotVO> listByHostId(Filter filter, long hostId); | ||||||
|     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); | ||||||
| } | } | ||||||
|  | |||||||
| @ -26,16 +26,24 @@ import javax.ejb.Local; | |||||||
| 
 | 
 | ||||||
| import org.apache.log4j.Logger; | import org.apache.log4j.Logger; | ||||||
| 
 | 
 | ||||||
|  | import com.cloud.host.dao.HostDetailsDaoImpl; | ||||||
| import com.cloud.storage.Snapshot.Type; | import com.cloud.storage.Snapshot.Type; | ||||||
|  | import com.cloud.storage.Snapshot; | ||||||
| import com.cloud.storage.SnapshotVO; | import com.cloud.storage.SnapshotVO; | ||||||
| import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; | 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.Filter; | ||||||
| import com.cloud.utils.db.GenericDaoBase; | import com.cloud.utils.db.GenericDaoBase; | ||||||
| import com.cloud.utils.db.GenericSearchBuilder; | import com.cloud.utils.db.GenericSearchBuilder; | ||||||
|  | import com.cloud.utils.db.JoinBuilder.JoinType; | ||||||
| import com.cloud.utils.db.SearchBuilder; | import com.cloud.utils.db.SearchBuilder; | ||||||
| import com.cloud.utils.db.SearchCriteria; | import com.cloud.utils.db.SearchCriteria; | ||||||
| import com.cloud.utils.db.SearchCriteria.Func; | import com.cloud.utils.db.SearchCriteria.Func; | ||||||
| import com.cloud.utils.db.Transaction; | import com.cloud.utils.db.Transaction; | ||||||
|  | import com.cloud.vm.VMInstanceVO; | ||||||
|  | import com.cloud.vm.dao.VMInstanceDaoImpl; | ||||||
| 
 | 
 | ||||||
| @Local (value={SnapshotDao.class}) | @Local (value={SnapshotDao.class}) | ||||||
| public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements SnapshotDao { | public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements SnapshotDao { | ||||||
| @ -52,8 +60,12 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements | |||||||
|     private final SearchBuilder<SnapshotVO> VolumeIdVersionSearch; |     private final SearchBuilder<SnapshotVO> VolumeIdVersionSearch; | ||||||
|     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 GenericSearchBuilder<SnapshotVO, Long> CountSnapshotsByAccount; |     private final GenericSearchBuilder<SnapshotVO, Long> CountSnapshotsByAccount; | ||||||
|      |      | ||||||
|  |     protected final VMInstanceDaoImpl _instanceDao = ComponentLocator.inject(VMInstanceDaoImpl.class); | ||||||
|  |     protected final VolumeDaoImpl _volumeDao = ComponentLocator.inject(VolumeDaoImpl.class); | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     public SnapshotVO findNextSnapshot(long snapshotId) { |     public SnapshotVO findNextSnapshot(long snapshotId) { | ||||||
|         SearchCriteria<SnapshotVO> sc = ParentIdSearch.create(); |         SearchCriteria<SnapshotVO> sc = ParentIdSearch.create(); | ||||||
| @ -162,6 +174,19 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements | |||||||
|         CountSnapshotsByAccount.and("account", CountSnapshotsByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); |         CountSnapshotsByAccount.and("account", CountSnapshotsByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); | ||||||
|         CountSnapshotsByAccount.and("removed", CountSnapshotsByAccount.entity().getRemoved(), SearchCriteria.Op.NULL); |         CountSnapshotsByAccount.and("removed", CountSnapshotsByAccount.entity().getRemoved(), SearchCriteria.Op.NULL); | ||||||
|         CountSnapshotsByAccount.done(); |         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  |     @Override  | ||||||
| @ -241,4 +266,13 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements | |||||||
|         sc.setParameters("account", accountId); |         sc.setParameters("account", accountId); | ||||||
|         return customSearch(sc, null).get(0); |         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 " |                         throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volumeId + " is associated with vm:" + userVm.getInstanceName() + " is in " | ||||||
|                                 + userVm.getState().toString() + " state"); |                                 + 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 { |                 } else { | ||||||
|                     _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.snapshot); |                     _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.snapshot); | ||||||
|                 } |                 } | ||||||
|  |             } else { | ||||||
|  |             	snapshot = _snapshotDao.findById(snapshotId); | ||||||
|  |                 snapshot.setStatus(Status.Error); | ||||||
|  |                 _snapshotDao.update(snapshotId, snapshot); | ||||||
|             } |             } | ||||||
|              |              | ||||||
|             if ( volume != null ) { |             if ( volume != null ) { | ||||||
|  | |||||||
| @ -208,8 +208,26 @@ public class SearchCriteria<K> { | |||||||
|         return _selects == null || _selects.size() == 0; |         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) { |     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; |         assert (join != null) : "Incorrect join name specified: " + joinName; | ||||||
|         join.getT().setParameters(conditionName, params); |         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 --> |    <!-- 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"> | <!--   <appender name="FILE" class="org.apache.log4j.rolling.RollingFileAppender"> | ||||||
|       <param name="Append" value="true"/> |       <param name="Append" value="true"/> | ||||||
|       <param name="Threshold" value="DEBUG"/> |       <param name="Threshold" value="TRACE"/> | ||||||
|       <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy"> |       <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy"> | ||||||
|         <param name="FileNamePattern" value="@MSLOG@.%d{yyyy-MM-dd}.gz"/> |         <param name="FileNamePattern" value="@MSLOG@.%d{yyyy-MM-dd}.gz"/> | ||||||
|         <param name="ActiveFileName" value="@MSLOG@"/> |         <param name="ActiveFileName" value="@MSLOG@"/> | ||||||
| @ -24,7 +24,7 @@ | |||||||
|   <!--  |   <!--  | ||||||
|    <appender name="APISERVER" class="org.apache.log4j.rolling.RollingFileAppender"> |    <appender name="APISERVER" class="org.apache.log4j.rolling.RollingFileAppender"> | ||||||
|       <param name="Append" value="true"/> |       <param name="Append" value="true"/> | ||||||
|       <param name="Threshold" value="DEBUG"/> |       <param name="Threshold" value="TRACE"/> | ||||||
|       <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy"> |       <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy"> | ||||||
|         <param name="FileNamePattern" value="@APISERVERLOG@.%d{yyyy-MM-dd}.gz"/> |         <param name="FileNamePattern" value="@APISERVERLOG@.%d{yyyy-MM-dd}.gz"/> | ||||||
|         <param name="ActiveFileName" value="@APISERVERLOG@"/> |         <param name="ActiveFileName" value="@APISERVERLOG@"/> | ||||||
| @ -55,7 +55,7 @@ | |||||||
| 
 | 
 | ||||||
|    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> |    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> | ||||||
|       <param name="Target" value="System.out"/> |       <param name="Target" value="System.out"/> | ||||||
|       <param name="Threshold" value="DEBUG"/> |       <param name="Threshold" value="TRACE"/> | ||||||
|       <layout class="org.apache.log4j.PatternLayout"> |       <layout class="org.apache.log4j.PatternLayout"> | ||||||
|          <param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{3}] (%t:%x) %m%n"/> |          <param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{3}] (%t:%x) %m%n"/> | ||||||
|       </layout> |       </layout> | ||||||
| @ -66,7 +66,7 @@ | |||||||
|    <!-- ================ --> |    <!-- ================ --> | ||||||
| 
 | 
 | ||||||
|    <category name="com.cloud"> |    <category name="com.cloud"> | ||||||
|      <priority value="DEBUG"/> |      <priority value="TRACE"/> | ||||||
|    </category> |    </category> | ||||||
|     |     | ||||||
|    <!-- Limit the org.apache category to INFO as its DEBUG is verbose --> |    <!-- Limit the org.apache category to INFO as its DEBUG is verbose --> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user