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