mirror of https://github.com/apache/cloudstack.git
bug 8242: introducing the concept of work queue for storage; introducing storage states as opposed to using host states; using row locks as opposed to db table locks
status 8242: resolved fixed
This commit is contained in:
parent
5199167840
commit
5d18c4c527
|
|
@ -22,6 +22,7 @@ import java.util.Date;
|
|||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class StoragePoolResponse extends BaseResponse {
|
||||
|
|
@ -71,7 +72,7 @@ public class StoragePoolResponse extends BaseResponse {
|
|||
private String tags;
|
||||
|
||||
@SerializedName(ApiConstants.STATE) @Param(description="the state of the storage pool")
|
||||
private Status state;
|
||||
private StoragePoolStatus state;
|
||||
|
||||
@SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the storage pool")
|
||||
private Long jobId;
|
||||
|
|
@ -203,11 +204,11 @@ public class StoragePoolResponse extends BaseResponse {
|
|||
this.tags = tags;
|
||||
}
|
||||
|
||||
public Status getState() {
|
||||
public StoragePoolStatus getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(Status state) {
|
||||
public void setState(StoragePoolStatus state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public interface StoragePool {
|
|||
/**
|
||||
* @return the storage pool status
|
||||
*/
|
||||
Status getStatus();
|
||||
StoragePoolStatus getStatus();
|
||||
|
||||
int getPort();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
package com.cloud.storage;
|
||||
|
||||
public enum StoragePoolStatus {
|
||||
Up,
|
||||
PrepareForMaintenance,
|
||||
ErrorInMaintenance,
|
||||
CancelMaintenance,
|
||||
Maintenance,
|
||||
Removed;
|
||||
}
|
||||
|
|
@ -80,7 +80,7 @@ public class StoragePoolVO implements StoragePool {
|
|||
|
||||
@Column(name="status", updatable=true, nullable=false)
|
||||
@Enumerated(value=EnumType.STRING)
|
||||
private Status status;
|
||||
private StoragePoolStatus status;
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
|
|
@ -88,7 +88,7 @@ public class StoragePoolVO implements StoragePool {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Status getStatus() {
|
||||
public StoragePoolStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -193,7 +193,7 @@ public class StoragePoolVO implements StoragePool {
|
|||
this.path = hostPath;
|
||||
this.port = port;
|
||||
this.podId = podId;
|
||||
this.setStatus(Status.Up);
|
||||
this.setStatus(StoragePoolStatus.Up);
|
||||
}
|
||||
|
||||
public StoragePoolVO(StoragePoolVO that) {
|
||||
|
|
@ -205,10 +205,10 @@ public class StoragePoolVO implements StoragePool {
|
|||
this.hostAddress = hostAddress;
|
||||
this.port = port;
|
||||
this.path = path;
|
||||
this.setStatus(Status.Up);
|
||||
this.setStatus(StoragePoolStatus.Up);
|
||||
}
|
||||
|
||||
public void setStatus(Status status)
|
||||
public void setStatus(StoragePoolStatus status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
|
@ -273,7 +273,7 @@ public class StoragePoolVO implements StoragePool {
|
|||
}
|
||||
|
||||
public boolean isInMaintenance() {
|
||||
return status == Status.PrepareForMaintenance || status == Status.Maintenance || status == Status.ErrorInMaintenance || removed != null;
|
||||
return status == StoragePoolStatus.PrepareForMaintenance || status == StoragePoolStatus.Maintenance || status == StoragePoolStatus.ErrorInMaintenance || removed != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
package com.cloud.storage;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name="storage_pool_work")
|
||||
public class StoragePoolWorkVO {
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getPoolId() {
|
||||
return poolId;
|
||||
}
|
||||
|
||||
|
||||
public void setPoolId(Long poolId) {
|
||||
this.poolId = poolId;
|
||||
}
|
||||
|
||||
|
||||
public boolean isStoppedForMaintenance() {
|
||||
return stoppedForMaintenance;
|
||||
}
|
||||
|
||||
|
||||
public void setStoppedForMaintenance(boolean stoppedForMaintenance) {
|
||||
this.stoppedForMaintenance = stoppedForMaintenance;
|
||||
}
|
||||
|
||||
|
||||
public boolean isStartedAfterMaintenance() {
|
||||
return startedAfterMaintenance;
|
||||
}
|
||||
|
||||
public void setStartedAfterMaintenance(boolean startedAfterMaintenance) {
|
||||
this.startedAfterMaintenance = startedAfterMaintenance;
|
||||
}
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public void setVmId(Long vmId) {
|
||||
this.vmId = vmId;
|
||||
}
|
||||
|
||||
public Long getManagementServerId() {
|
||||
return managementServerId;
|
||||
}
|
||||
|
||||
public void setManagementServerId(Long managementServerId) {
|
||||
this.managementServerId = managementServerId;
|
||||
}
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||
@Column(name="id")
|
||||
private Long id;
|
||||
|
||||
@Column(name="pool_id")
|
||||
private Long poolId;
|
||||
|
||||
@Column(name="vm_id")
|
||||
private Long vmId;
|
||||
|
||||
@Column(name="stopped_for_maintenance")
|
||||
private boolean stoppedForMaintenance;
|
||||
|
||||
@Column(name="started_after_maintenance")
|
||||
private boolean startedAfterMaintenance;
|
||||
|
||||
@Column(name="mgmt_server_id")
|
||||
private Long managementServerId;
|
||||
|
||||
|
||||
public StoragePoolWorkVO(long vmId, long poolId, boolean stoppedForMaintenance, boolean startedAfterMaintenance, long mgmtServerId) {
|
||||
super();
|
||||
this.vmId = vmId;
|
||||
this.poolId = poolId;
|
||||
this.stoppedForMaintenance = stoppedForMaintenance;
|
||||
this.startedAfterMaintenance = startedAfterMaintenance;
|
||||
this.managementServerId = mgmtServerId;
|
||||
}
|
||||
|
||||
public StoragePoolWorkVO() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -106,6 +106,7 @@ import com.cloud.storage.dao.SnapshotPolicyDaoImpl;
|
|||
import com.cloud.storage.dao.SnapshotScheduleDaoImpl;
|
||||
import com.cloud.storage.dao.StoragePoolDaoImpl;
|
||||
import com.cloud.storage.dao.StoragePoolHostDaoImpl;
|
||||
import com.cloud.storage.dao.StoragePoolWorkDaoImpl;
|
||||
import com.cloud.storage.dao.UploadDaoImpl;
|
||||
import com.cloud.storage.dao.VMTemplateDaoImpl;
|
||||
import com.cloud.storage.dao.VMTemplateHostDaoImpl;
|
||||
|
|
@ -256,6 +257,7 @@ public class DefaultComponentLibrary implements ComponentLibrary {
|
|||
addDao("GreTunnelDao", GreTunnelDaoImpl.class);
|
||||
addDao("OvsTunnelDao", OvsTunnelDaoImpl.class);
|
||||
addDao("OvsTunnelAccountDao", OvsTunnelAccountDaoImpl.class);
|
||||
addDao("StoragePoolWorkDao", StoragePoolWorkDaoImpl.class);
|
||||
}
|
||||
|
||||
Map<String, ComponentInfo<Manager>> _managers = new HashMap<String, ComponentInfo<Manager>>();
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ import com.cloud.storage.LaunchPermissionVO;
|
|||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePoolHostVO;
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
import com.cloud.storage.StoragePoolVO;
|
||||
import com.cloud.storage.StorageStats;
|
||||
import com.cloud.storage.Upload;
|
||||
|
|
@ -4156,9 +4157,9 @@ public class ManagementServerImpl implements ManagementServer {
|
|||
@Override
|
||||
public long getPsMaintenanceCount(long podId){
|
||||
List<StoragePoolVO> poolsInTransition = new ArrayList<StoragePoolVO>();
|
||||
poolsInTransition.addAll(_poolDao.listPoolsByStatus(Status.Maintenance));
|
||||
poolsInTransition.addAll(_poolDao.listPoolsByStatus(Status.PrepareForMaintenance));
|
||||
poolsInTransition.addAll(_poolDao.listPoolsByStatus(Status.ErrorInMaintenance));
|
||||
poolsInTransition.addAll(_poolDao.listPoolsByStatus(StoragePoolStatus.Maintenance));
|
||||
poolsInTransition.addAll(_poolDao.listPoolsByStatus(StoragePoolStatus.PrepareForMaintenance));
|
||||
poolsInTransition.addAll(_poolDao.listPoolsByStatus(StoragePoolStatus.ErrorInMaintenance));
|
||||
|
||||
return poolsInTransition.size();
|
||||
}
|
||||
|
|
@ -4168,7 +4169,7 @@ public class ManagementServerImpl implements ManagementServer {
|
|||
VolumeVO rootVolume = _volumeDao.findByInstance(instanceId).get(0);
|
||||
|
||||
if(rootVolume!=null){
|
||||
Status poolStatus = _poolDao.findById(rootVolume.getPoolId()).getStatus();
|
||||
StoragePoolStatus poolStatus = _poolDao.findById(rootVolume.getPoolId()).getStatus();
|
||||
|
||||
if(!poolStatus.equals(Status.Up)) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@ import com.cloud.async.AsyncInstanceCreateStatus;
|
|||
import com.cloud.async.AsyncJobManager;
|
||||
import com.cloud.capacity.CapacityVO;
|
||||
import com.cloud.capacity.dao.CapacityDao;
|
||||
import com.cloud.cluster.ClusterManagerListener;
|
||||
import com.cloud.cluster.ManagementServerHostVO;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.configuration.ResourceCount.ResourceType;
|
||||
|
|
@ -115,6 +117,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
|||
import com.cloud.network.NetworkManager;
|
||||
import com.cloud.network.router.VirtualNetworkApplianceManager;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.server.ManagementServer;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
|
|
@ -127,6 +130,7 @@ import com.cloud.storage.dao.DiskOfferingDao;
|
|||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.storage.dao.StoragePoolDao;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.storage.dao.StoragePoolWorkDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VMTemplateHostDao;
|
||||
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||
|
|
@ -138,6 +142,7 @@ import com.cloud.storage.snapshot.SnapshotScheduler;
|
|||
import com.cloud.template.TemplateManager;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
|
|
@ -157,19 +162,26 @@ import com.cloud.utils.db.SearchCriteria;
|
|||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.exception.ExecutionException;
|
||||
import com.cloud.vm.ConsoleProxyVO;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.SecondaryStorageVmVO;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.VirtualMachine.Type;
|
||||
import com.cloud.vm.dao.ConsoleProxyDao;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.SecondaryStorageVmDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@Local(value = { StorageManager.class, StorageService.class })
|
||||
public class StorageManagerImpl implements StorageManager, StorageService, Manager {
|
||||
public class StorageManagerImpl implements StorageManager, StorageService, Manager, ClusterManagerListener {
|
||||
private static final Logger s_logger = Logger.getLogger(StorageManagerImpl.class);
|
||||
|
||||
protected String _name;
|
||||
|
|
@ -212,6 +224,10 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
@Inject protected ClusterDao _clusterDao;
|
||||
@Inject protected VirtualNetworkApplianceManager _routerMgr;
|
||||
@Inject protected UsageEventDao _usageEventDao;
|
||||
@Inject protected VirtualMachineManager _vmMgr;
|
||||
@Inject protected DomainRouterDao _domrDao;
|
||||
@Inject protected SecondaryStorageVmDao _secStrgDao;
|
||||
@Inject protected StoragePoolWorkDao _storagePoolWorkDao;
|
||||
|
||||
|
||||
@Inject(adapter=StoragePoolAllocator.class)
|
||||
|
|
@ -235,6 +251,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
private int _totalRetries;
|
||||
private int _pauseInterval;
|
||||
private final boolean _shouldBeSnapshotCapable = true;
|
||||
private long _serverId;
|
||||
|
||||
public boolean share(VMInstanceVO vm, List<VolumeVO> vols, HostVO host, boolean cancelPreviousShare) throws StorageUnavailableException {
|
||||
|
||||
|
|
@ -305,7 +322,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
List<StoragePoolVO> pools = _storagePoolDao.listAll();
|
||||
|
||||
//if no pools or 1 pool which is in maintenance
|
||||
if(pools == null || pools.size() == 0 || (pools.size() == 1 && pools.get(0).getStatus().equals(Status.Maintenance) )){
|
||||
if(pools == null || pools.size() == 0 || (pools.size() == 1 && pools.get(0).getStatus().equals(StoragePoolStatus.Maintenance) )){
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
|
|
@ -867,6 +884,8 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
HostSearch.done();
|
||||
HostTemplateStatesSearch.done();
|
||||
|
||||
_serverId = ((ManagementServer)ComponentLocator.getComponent(ManagementServer.Name)).getId();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1171,7 +1190,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
pool.setPodId(podId);
|
||||
pool.setName(cmd.getStoragePoolName());
|
||||
pool.setClusterId(clusterId);
|
||||
pool.setStatus(Status.Up);
|
||||
pool.setStatus(StoragePoolStatus.Up);
|
||||
pool = _storagePoolDao.persist(pool, details);
|
||||
if (allHosts.isEmpty()) {
|
||||
return pool;
|
||||
|
|
@ -1297,7 +1316,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
_storagePoolHostDao.deleteStoragePoolHostDetails(host.getHostId(),host.getPoolId());
|
||||
}
|
||||
sPool.setUuid(null);
|
||||
sPool.setStatus(Status.Removed);
|
||||
sPool.setStatus(StoragePoolStatus.Removed);
|
||||
_storagePoolDao.update(id, sPool);
|
||||
_storagePoolDao.remove(id);
|
||||
deleteHostorPoolStats(id);
|
||||
|
|
@ -1905,148 +1924,211 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
}
|
||||
|
||||
@Override @DB
|
||||
public synchronized StoragePoolVO preparePrimaryStorageForMaintenance(PreparePrimaryStorageForMaintenanceCmd cmd) throws ServerApiException{
|
||||
public StoragePoolVO preparePrimaryStorageForMaintenance(PreparePrimaryStorageForMaintenanceCmd cmd) throws ServerApiException{
|
||||
Long primaryStorageId = cmd.getId();
|
||||
Long userId = UserContext.current().getCallerUserId();
|
||||
User user = _userDao.findById(userId);
|
||||
Account account = UserContext.current().getCaller();
|
||||
boolean restart = true;
|
||||
StoragePoolVO primaryStorage = null;
|
||||
try
|
||||
{
|
||||
Transaction.currentTxn();
|
||||
//1. Get the primary storage record and perform validation check
|
||||
primaryStorage = _storagePoolDao.acquireInLockTable(primaryStorageId);
|
||||
|
||||
if(primaryStorage == null){
|
||||
String msg = "Unable to obtain lock on the storage pool in preparePrimaryStorageForMaintenance()";
|
||||
s_logger.error(msg);
|
||||
throw new ExecutionException(msg);
|
||||
}
|
||||
|
||||
if (!primaryStorage.getStatus().equals(Status.Up) && !primaryStorage.getStatus().equals(Status.ErrorInMaintenance)) {
|
||||
throw new InvalidParameterValueException("Primary storage with id " + primaryStorageId + " is not ready for migration, as the status is:" + primaryStorage.getStatus().toString());
|
||||
}
|
||||
//set the pool state to prepare for maintenance
|
||||
primaryStorage.setStatus(Status.PrepareForMaintenance);
|
||||
_storagePoolDao.persist(primaryStorage);
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
//1. Get the primary storage record and perform validation check
|
||||
primaryStorage = _storagePoolDao.lockRow(primaryStorageId, true);
|
||||
|
||||
if(primaryStorage == null){
|
||||
String msg = "Unable to obtain lock on the storage pool record in preparePrimaryStorageForMaintenance()";
|
||||
s_logger.error(msg);
|
||||
throw new ExecutionException(msg);
|
||||
}
|
||||
|
||||
if (!primaryStorage.getStatus().equals(StoragePoolStatus.Up) && !primaryStorage.getStatus().equals(StoragePoolStatus.ErrorInMaintenance)) {
|
||||
throw new InvalidParameterValueException("Primary storage with id " + primaryStorageId + " is not ready for migration, as the status is:" + primaryStorage.getStatus().toString());
|
||||
}
|
||||
|
||||
//set the pool state to prepare for maintenance
|
||||
primaryStorage.setStatus(StoragePoolStatus.PrepareForMaintenance);
|
||||
_storagePoolDao.update(primaryStorageId,primaryStorage);
|
||||
txn.commit();
|
||||
|
||||
//check to see if other ps exist
|
||||
//if they do, then we can migrate over the system vms to them
|
||||
//if they dont, then just stop all vms on this one
|
||||
List<StoragePoolVO> upPools = _storagePoolDao.listPoolsByStatus(Status.Up);
|
||||
List<StoragePoolVO> upPools = _storagePoolDao.listPoolsByStatus(StoragePoolStatus.Up);
|
||||
|
||||
if(upPools == null || upPools.size() == 0) {
|
||||
restart = false;
|
||||
}
|
||||
|
||||
//2. Get a list of all the volumes within this storage pool
|
||||
//2. Get a list of all the ROOT volumes within this storage pool
|
||||
List<VolumeVO> allVolumes = _volsDao.findByPoolId(primaryStorageId);
|
||||
|
||||
//3. Each volume has an instance associated with it, stop the instance if running
|
||||
for(VolumeVO volume : allVolumes)
|
||||
{
|
||||
VMInstanceVO vmInstance = _vmInstanceDao.findById(volume.getInstanceId());
|
||||
|
||||
if(vmInstance == null) {
|
||||
|
||||
//3. Enqueue to the work queue
|
||||
for(VolumeVO volume : allVolumes)
|
||||
{
|
||||
VMInstanceVO vmInstance = _vmInstanceDao.findById(volume.getInstanceId());
|
||||
|
||||
if(vmInstance == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//shut down the running vms
|
||||
if(vmInstance.getState().equals(State.Running) || vmInstance.getState().equals(State.Starting) || vmInstance.getState().equals(State.Stopping))
|
||||
{
|
||||
|
||||
//if the instance is of type consoleproxy, call the console proxy
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.ConsoleProxy))
|
||||
{
|
||||
//make sure it is not restarted again, update config to set flag to false
|
||||
_configMgr.updateConfiguration(userId, "consoleproxy.restart", "false");
|
||||
|
||||
//call the consoleproxymanager
|
||||
if(!_consoleProxyMgr.stopProxy(vmInstance.getId()))
|
||||
{
|
||||
String errorMsg = "There was an error stopping the console proxy id: "+vmInstance.getId()+" ,cannot enable storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
setPoolStateToError(primaryStorage);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
}
|
||||
else if(restart)
|
||||
{
|
||||
//Restore config val for consoleproxy.restart to true
|
||||
_configMgr.updateConfiguration(userId, "consoleproxy.restart", "true");
|
||||
|
||||
if(_consoleProxyMgr.startProxy(vmInstance.getId())==null)
|
||||
{
|
||||
String errorMsg = "There was an error starting the console proxy id: "+vmInstance.getId()+" on another storage pool, cannot enable primary storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
setPoolStateToError(primaryStorage);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if the instance is of type uservm, call the user vm manager
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.User))
|
||||
{
|
||||
//create a dummy event
|
||||
if(!_userVmMgr.stopVirtualMachine(userId, vmInstance.getId()))
|
||||
{
|
||||
String errorMsg = "There was an error stopping the user vm id: "+vmInstance.getId()+" ,cannot enable storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
setPoolStateToError(primaryStorage);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
//if the instance is of type secondary storage vm, call the secondary storage vm manager
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.SecondaryStorageVm))
|
||||
{
|
||||
if(!_secStorageMgr.stopSecStorageVm(vmInstance.getId()))
|
||||
{
|
||||
String errorMsg = "There was an error stopping the ssvm id: "+vmInstance.getId()+" ,cannot enable storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
setPoolStateToError(primaryStorage);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
}
|
||||
else if(restart)
|
||||
{
|
||||
if(_secStorageMgr.startSecStorageVm(vmInstance.getId()) == null)
|
||||
{
|
||||
String errorMsg = "There was an error starting the ssvm id: "+vmInstance.getId()+" on another storage pool, cannot enable primary storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
setPoolStateToError(primaryStorage);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//enqueue sp work
|
||||
if(vmInstance.getState().equals(State.Running) || vmInstance.getState().equals(State.Starting) || vmInstance.getState().equals(State.Stopping)){
|
||||
|
||||
//if the instance is of type domain router vm, call the network manager
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.DomainRouter))
|
||||
{
|
||||
if(_routerMgr.stopRouter(vmInstance.getId()) == null)
|
||||
{
|
||||
String errorMsg = "There was an error stopping the domain router id: "+vmInstance.getId()+" ,cannot enable primary storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
setPoolStateToError(primaryStorage);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
}
|
||||
else if(restart)
|
||||
{
|
||||
if(_routerMgr.startRouter(vmInstance.getId()) == null)
|
||||
{
|
||||
String errorMsg = "There was an error starting the domain router id: "+vmInstance.getId()+" on another storage pool, cannot enable primary storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
setPoolStateToError(primaryStorage);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
}
|
||||
}
|
||||
try {
|
||||
StoragePoolWorkVO work = new StoragePoolWorkVO(vmInstance.getId(),primaryStorageId, false, false, _serverId);
|
||||
_storagePoolWorkDao.persist(work);
|
||||
} catch (Exception e) {
|
||||
if(s_logger.isDebugEnabled())
|
||||
s_logger.debug("Work record already exists, re-using by re-setting values");
|
||||
StoragePoolWorkVO work = _storagePoolWorkDao.findByPoolIdAndVmId(primaryStorageId, vmInstance.getId());
|
||||
work.setStartedAfterMaintenance(false);
|
||||
work.setStoppedForMaintenance(false);
|
||||
work.setManagementServerId(_serverId);
|
||||
_storagePoolWorkDao.update(work.getId(), work);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
txn.commit();
|
||||
txn.close();
|
||||
|
||||
//4. Process the queue
|
||||
List<StoragePoolWorkVO> pendingWork = _storagePoolWorkDao.listPendingWorkForPrepareForMaintenanceByPoolId(primaryStorageId);
|
||||
|
||||
for(StoragePoolWorkVO work : pendingWork)
|
||||
{
|
||||
//shut down the running vms
|
||||
VMInstanceVO vmInstance = _vmInstanceDao.findById(work.getVmId());
|
||||
|
||||
if(vmInstance == null)
|
||||
continue;
|
||||
|
||||
//if the instance is of type consoleproxy, call the console proxy
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.ConsoleProxy))
|
||||
{
|
||||
//make sure it is not restarted again, update config to set flag to false
|
||||
if(!restart) {
|
||||
_configMgr.updateConfiguration(userId, "consoleproxy.restart", "false");
|
||||
}
|
||||
|
||||
//call the consoleproxymanager
|
||||
ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(vmInstance.getId());
|
||||
if(!_vmMgr.advanceStop(consoleProxy, true, user, account))
|
||||
{
|
||||
String errorMsg = "There was an error stopping the console proxy id: "+vmInstance.getId()+" ,cannot enable storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
} else {
|
||||
//update work status
|
||||
work.setStoppedForMaintenance(true);
|
||||
_storagePoolWorkDao.update(work.getId(), work);
|
||||
}
|
||||
}
|
||||
|
||||
if(restart)
|
||||
{
|
||||
//Restore config val for consoleproxy.restart to true
|
||||
_configMgr.updateConfiguration(userId, "consoleproxy.restart", "true");
|
||||
|
||||
if(_vmMgr.advanceStart(consoleProxy, null, user, account) == null)
|
||||
{
|
||||
String errorMsg = "There was an error starting the console proxy id: "+vmInstance.getId()+" on another storage pool, cannot enable primary storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
} else {
|
||||
//update work status
|
||||
work.setStartedAfterMaintenance(true);
|
||||
_storagePoolWorkDao.update(work.getId(), work);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if the instance is of type uservm, call the user vm manager
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.User))
|
||||
{
|
||||
UserVmVO userVm = _userVmDao.findById(vmInstance.getId());
|
||||
if(!_vmMgr.advanceStop(userVm, true, user, account))
|
||||
{
|
||||
String errorMsg = "There was an error stopping the user vm id: "+vmInstance.getId()+" ,cannot enable storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
} else {
|
||||
//update work status
|
||||
work.setStoppedForMaintenance(true);
|
||||
_storagePoolWorkDao.update(work.getId(), work);
|
||||
}
|
||||
}
|
||||
|
||||
//if the instance is of type secondary storage vm, call the secondary storage vm manager
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.SecondaryStorageVm))
|
||||
{
|
||||
SecondaryStorageVmVO secStrgVm = _secStrgDao.findById(vmInstance.getId());
|
||||
if(!_vmMgr.advanceStop(secStrgVm, true, user, account))
|
||||
{
|
||||
String errorMsg = "There was an error stopping the ssvm id: "+vmInstance.getId()+" ,cannot enable storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
} else {
|
||||
//update work status
|
||||
work.setStoppedForMaintenance(true);
|
||||
_storagePoolWorkDao.update(work.getId(), work);
|
||||
}
|
||||
|
||||
if(restart)
|
||||
{
|
||||
if(_vmMgr.advanceStart(secStrgVm, null, user, account) == null)
|
||||
{
|
||||
String errorMsg = "There was an error starting the ssvm id: "+vmInstance.getId()+" on another storage pool, cannot enable primary storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
} else {
|
||||
//update work status
|
||||
work.setStartedAfterMaintenance(true);
|
||||
_storagePoolWorkDao.update(work.getId(), work);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if the instance is of type domain router vm, call the network manager
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.DomainRouter))
|
||||
{
|
||||
DomainRouterVO domR = _domrDao.findById(vmInstance.getId());
|
||||
if(!_vmMgr.advanceStop(domR, true, user, account))
|
||||
{
|
||||
String errorMsg = "There was an error stopping the domain router id: "+vmInstance.getId()+" ,cannot enable primary storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
} else {
|
||||
//update work status
|
||||
work.setStoppedForMaintenance(true);
|
||||
_storagePoolWorkDao.update(work.getId(), work);
|
||||
}
|
||||
|
||||
if(restart)
|
||||
{
|
||||
if(_vmMgr.advanceStart(domR, null, user, account) == null)
|
||||
{
|
||||
String errorMsg = "There was an error starting the domain router id: "+vmInstance.getId()+" on another storage pool, cannot enable primary storage maintenance";
|
||||
s_logger.warn(errorMsg);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
} else {
|
||||
//update work status
|
||||
work.setStartedAfterMaintenance(true);
|
||||
_storagePoolWorkDao.update(work.getId(), work);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//5. Update the status
|
||||
primaryStorage.setStatus(Status.Maintenance);
|
||||
_storagePoolDao.persist(primaryStorage);
|
||||
return _storagePoolDao.findById(primaryStorageId);
|
||||
primaryStorage.setStatus(StoragePoolStatus.Maintenance);
|
||||
_storagePoolDao.update(primaryStorageId,primaryStorage);
|
||||
|
||||
return _storagePoolDao.findById(primaryStorageId);
|
||||
} catch (Exception e) {
|
||||
if(e instanceof ExecutionException || e instanceof ResourceUnavailableException){
|
||||
s_logger.error("Exception in enabling primary storage maintenance:",e);
|
||||
|
|
@ -2068,26 +2150,27 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
setPoolStateToError(primaryStorage);
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, e.getMessage());
|
||||
|
||||
}finally{
|
||||
_storagePoolDao.releaseFromLockTable(primaryStorage.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void setPoolStateToError(StoragePoolVO primaryStorage) {
|
||||
primaryStorage.setStatus(Status.ErrorInMaintenance);
|
||||
_storagePoolDao.persist(primaryStorage);
|
||||
primaryStorage.setStatus(StoragePoolStatus.ErrorInMaintenance);
|
||||
_storagePoolDao.update(primaryStorage.getId(),primaryStorage);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public synchronized StoragePoolVO cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ServerApiException{
|
||||
public StoragePoolVO cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ServerApiException{
|
||||
Long primaryStorageId = cmd.getId();
|
||||
Long userId = UserContext.current().getCallerUserId();
|
||||
User user = _userDao.findById(userId);
|
||||
Account account = UserContext.current().getCaller();
|
||||
StoragePoolVO primaryStorage = null;
|
||||
try {
|
||||
Transaction.currentTxn();
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
//1. Get the primary storage record and perform validation check
|
||||
primaryStorage = _storagePoolDao.acquireInLockTable(primaryStorageId);
|
||||
primaryStorage = _storagePoolDao.lockRow(primaryStorageId, true);
|
||||
|
||||
if(primaryStorage == null){
|
||||
String msg = "Unable to obtain lock on the storage pool in cancelPrimaryStorageForMaintenance()";
|
||||
|
|
@ -2095,82 +2178,111 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
throw new ExecutionException(msg);
|
||||
}
|
||||
|
||||
if (primaryStorage.getStatus().equals(Status.Up) || primaryStorage.getStatus().equals(Status.PrepareForMaintenance)) {
|
||||
if (primaryStorage.getStatus().equals(StoragePoolStatus.Up) || primaryStorage.getStatus().equals(StoragePoolStatus.PrepareForMaintenance)) {
|
||||
throw new StorageUnavailableException("Primary storage with id " + primaryStorageId + " is not ready to complete migration, as the status is:" + primaryStorage.getStatus().toString(), primaryStorageId);
|
||||
}
|
||||
|
||||
//set state to cancelmaintenance
|
||||
primaryStorage.setStatus(Status.CancelMaintenance);
|
||||
_storagePoolDao.persist(primaryStorage);
|
||||
primaryStorage.setStatus(StoragePoolStatus.CancelMaintenance);
|
||||
_storagePoolDao.update(primaryStorageId,primaryStorage);
|
||||
txn.commit();
|
||||
txn.close();
|
||||
|
||||
//2. Get a list of all the volumes within this storage pool
|
||||
List<VolumeVO> allVolumes = _volsDao.findByPoolId(primaryStorageId);
|
||||
//2. Get a list of pending work for this queue
|
||||
List<StoragePoolWorkVO> pendingWork = _storagePoolWorkDao.listPendingWorkForCancelMaintenanceByPoolId(primaryStorageId);
|
||||
|
||||
//3. If the volume is not removed AND not destroyed, start the vm corresponding to it
|
||||
for(VolumeVO volume: allVolumes)
|
||||
//3. work through the queue
|
||||
for(StoragePoolWorkVO work: pendingWork)
|
||||
{
|
||||
if((volume.getState() != Volume.State.Destroy) && (volume.getRemoved() == null))
|
||||
{
|
||||
VMInstanceVO vmInstance = _vmInstanceDao.findById(volume.getInstanceId());
|
||||
|
||||
if(vmInstance.getState().equals(State.Stopping) || vmInstance.getState().equals(State.Stopped))
|
||||
VMInstanceVO vmInstance = _vmInstanceDao.findById(work.getVmId());
|
||||
|
||||
if(vmInstance == null)
|
||||
continue;
|
||||
|
||||
//if the instance is of type consoleproxy, call the console proxy
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.ConsoleProxy))
|
||||
{
|
||||
|
||||
ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(vmInstance.getId());
|
||||
if(_vmMgr.advanceStart(consoleProxy, null, user, account) == null)
|
||||
{
|
||||
//if the instance is of type consoleproxy, call the console proxy
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.ConsoleProxy))
|
||||
{
|
||||
|
||||
if(_consoleProxyMgr.startProxy(vmInstance.getId()) == null)
|
||||
{
|
||||
String msg = "There was an error starting the console proxy id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg);
|
||||
throw new ExecutionException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
//if the instance is of type ssvm, call the ssvm manager
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.SecondaryStorageVm))
|
||||
{
|
||||
|
||||
if(_secStorageMgr.startSecStorageVm(vmInstance.getId()) == null)
|
||||
{
|
||||
String msg = "There was an error starting the ssvm id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg);
|
||||
throw new ExecutionException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
//if the instance is of type user vm, call the user vm manager
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.User))
|
||||
{
|
||||
|
||||
try {
|
||||
if(_userVmMgr.startUserVm(vmInstance.getId()) == null)
|
||||
{
|
||||
String msg = "There was an error starting the user vm id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg);
|
||||
throw new ExecutionException(msg);
|
||||
}
|
||||
} catch (StorageUnavailableException e) {
|
||||
String msg = "There was an error starting the user vm id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg,e);
|
||||
throw new ExecutionException(msg);
|
||||
} catch (InsufficientCapacityException e) {
|
||||
String msg = "There was an error starting the user vm id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg,e);
|
||||
throw new ExecutionException(msg);
|
||||
} catch (ConcurrentOperationException e) {
|
||||
String msg = "There was an error starting the user vm id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg,e);
|
||||
setPoolStateToError(primaryStorage);
|
||||
throw new ExecutionException(msg);
|
||||
} catch (ExecutionException e) {
|
||||
String msg = "There was an error starting the user vm id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg,e);
|
||||
throw new ExecutionException(msg);
|
||||
}
|
||||
}
|
||||
String msg = "There was an error starting the console proxy id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg);
|
||||
throw new ExecutionException(msg);
|
||||
} else {
|
||||
//update work queue
|
||||
work.setStartedAfterMaintenance(true);
|
||||
_storagePoolWorkDao.update(work.getId(), work);
|
||||
}
|
||||
}
|
||||
|
||||
//if the instance is of type ssvm, call the ssvm manager
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.SecondaryStorageVm))
|
||||
{
|
||||
SecondaryStorageVmVO ssVm = _secStrgDao.findById(vmInstance.getId());
|
||||
if(_vmMgr.advanceStart(ssVm, null, user, account) == null)
|
||||
{
|
||||
String msg = "There was an error starting the ssvm id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg);
|
||||
throw new ExecutionException(msg);
|
||||
}else {
|
||||
//update work queue
|
||||
work.setStartedAfterMaintenance(true);
|
||||
_storagePoolWorkDao.update(work.getId(), work);
|
||||
}
|
||||
}
|
||||
|
||||
//if the instance is of type ssvm, call the ssvm manager
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.DomainRouter))
|
||||
{
|
||||
DomainRouterVO domR = _domrDao.findById(vmInstance.getId());
|
||||
if(_vmMgr.advanceStart(domR, null, user, account) == null)
|
||||
{
|
||||
String msg = "There was an error starting the domR id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg);
|
||||
throw new ExecutionException(msg);
|
||||
}else {
|
||||
//update work queue
|
||||
work.setStartedAfterMaintenance(true);
|
||||
_storagePoolWorkDao.update(work.getId(), work);
|
||||
}
|
||||
}
|
||||
|
||||
//if the instance is of type user vm, call the user vm manager
|
||||
if(vmInstance.getType().equals(VirtualMachine.Type.User))
|
||||
{
|
||||
UserVmVO userVm = _userVmDao.findById(vmInstance.getId());
|
||||
try {
|
||||
if(_vmMgr.advanceStart(userVm, null, user, account) == null)
|
||||
{
|
||||
|
||||
String msg = "There was an error starting the user vm id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg);
|
||||
throw new ExecutionException(msg);
|
||||
} else {
|
||||
//update work queue
|
||||
work.setStartedAfterMaintenance(true);
|
||||
_storagePoolWorkDao.update(work.getId(), work);
|
||||
}
|
||||
} catch (StorageUnavailableException e) {
|
||||
String msg = "There was an error starting the user vm id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg,e);
|
||||
throw new ExecutionException(msg);
|
||||
} catch (InsufficientCapacityException e) {
|
||||
String msg = "There was an error starting the user vm id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg,e);
|
||||
throw new ExecutionException(msg);
|
||||
} catch (ConcurrentOperationException e) {
|
||||
String msg = "There was an error starting the user vm id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg,e);
|
||||
throw new ExecutionException(msg);
|
||||
} catch (ExecutionException e) {
|
||||
String msg = "There was an error starting the user vm id: "+vmInstance.getId()+" on storage pool, cannot complete primary storage maintenance";
|
||||
s_logger.warn(msg,e);
|
||||
throw new ExecutionException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Restore config val for consoleproxy.restart to true
|
||||
|
|
@ -2187,8 +2299,8 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
}
|
||||
|
||||
//Change the storage state back to up
|
||||
primaryStorage.setStatus(Status.Up);
|
||||
_storagePoolDao.persist(primaryStorage);
|
||||
primaryStorage.setStatus(StoragePoolStatus.Up);
|
||||
_storagePoolDao.update(primaryStorageId, primaryStorage);
|
||||
|
||||
return primaryStorage;
|
||||
} catch (Exception e) {
|
||||
|
|
@ -2202,8 +2314,6 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
else{//all other exceptions
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}finally{
|
||||
_storagePoolDao.releaseFromLockTable(primaryStorage.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2667,5 +2777,33 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onManagementNodeJoined(List<ManagementServerHostVO> nodeList, long selfNodeId) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onManagementNodeLeft(List<ManagementServerHostVO> nodeList, long selfNodeId) {
|
||||
for (ManagementServerHostVO vo : nodeList) {
|
||||
if(vo.getMsid() == _serverId) {
|
||||
s_logger.info("Cleaning up storage maintenance jobs associated with Management server" + vo.getMsid());
|
||||
List<Long> poolIds = _storagePoolWorkDao.searchForPoolIdsForPendingWorkJobs(vo.getMsid());
|
||||
if(poolIds.size() > 0) {
|
||||
for(Long poolId : poolIds) {
|
||||
StoragePoolVO pool = _storagePoolDao.findById(poolId);
|
||||
//check if pool is in an inconsistent state
|
||||
if(pool != null && (pool.getStatus().equals(StoragePoolStatus.ErrorInMaintenance) || pool.getStatus().equals(StoragePoolStatus.PrepareForMaintenance) || pool.getStatus().equals(StoragePoolStatus.CancelMaintenance))) {
|
||||
_storagePoolWorkDao.removePendingJobsOnMsRestart(vo.getMsid(), poolId);
|
||||
pool.setStatus(StoragePoolStatus.ErrorInMaintenance);
|
||||
_storagePoolDao.update(poolId, pool);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import com.cloud.server.StatsCollector;
|
|||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
import com.cloud.storage.StoragePoolVO;
|
||||
import com.cloud.storage.StorageStats;
|
||||
import com.cloud.storage.VMTemplateHostVO;
|
||||
|
|
@ -139,7 +140,7 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
|
|||
|
||||
//by default, all pools are up when successfully added
|
||||
//don't return the pool if not up (if in maintenance/prepareformaintenance/errorinmaintenance)
|
||||
if(!pool.getStatus().equals(com.cloud.host.Status.Up))
|
||||
if(!pool.getStatus().equals(StoragePoolStatus.Up))
|
||||
return false;
|
||||
|
||||
// Check that the pool type is correct
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
import com.cloud.storage.StoragePoolVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
/**
|
||||
|
|
@ -104,6 +105,5 @@ public interface StoragePoolDao extends GenericDao<StoragePoolVO, Long> {
|
|||
|
||||
List<StoragePoolVO> findIfDuplicatePoolsExistByUUID(String uuid);
|
||||
|
||||
List<StoragePoolVO> listPoolsByStatus(Status status);
|
||||
|
||||
List<StoragePoolVO> listPoolsByStatus(StoragePoolStatus status);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import javax.naming.ConfigurationException;
|
|||
import com.cloud.host.Status;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.StoragePoolDetailVO;
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
import com.cloud.storage.StoragePoolVO;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
import com.cloud.utils.db.DB;
|
||||
|
|
@ -185,7 +186,7 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePoolVO> listPoolsByStatus(Status status){
|
||||
public List<StoragePoolVO> listPoolsByStatus(StoragePoolStatus status){
|
||||
SearchCriteria<StoragePoolVO> sc = StatusSearch.create();
|
||||
sc.setParameters("status", status);
|
||||
return listBy(sc);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.storage.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.storage.StoragePoolWorkVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
/**
|
||||
* Data Access Object for storage_pool table
|
||||
*/
|
||||
public interface StoragePoolWorkDao extends GenericDao<StoragePoolWorkVO, Long> {
|
||||
|
||||
List<StoragePoolWorkVO> listPendingWorkForPrepareForMaintenanceByPoolId(long poolId);
|
||||
|
||||
List<StoragePoolWorkVO> listPendingWorkForCancelMaintenanceByPoolId(long poolId);
|
||||
|
||||
StoragePoolWorkVO findByPoolIdAndVmId(long poolId, long vmId);
|
||||
|
||||
void removePendingJobsOnMsRestart(long msId, long poolId);
|
||||
|
||||
List<Long> searchForPoolIdsForPendingWorkJobs(long msId);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.storage.dao;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import com.cloud.storage.StoragePoolWorkVO;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Local(value={StoragePoolWorkDao.class}) @DB(txn=false)
|
||||
public class StoragePoolWorkDaoImpl extends GenericDaoBase<StoragePoolWorkVO, Long> implements StoragePoolWorkDao {
|
||||
|
||||
protected final SearchBuilder<StoragePoolWorkVO> PendingWorkForPrepareForMaintenanceSearch;
|
||||
protected final SearchBuilder<StoragePoolWorkVO> PendingWorkForCancelMaintenanceSearch;
|
||||
protected final SearchBuilder<StoragePoolWorkVO> PoolAndVmIdSearch;
|
||||
protected final SearchBuilder<StoragePoolWorkVO> PendingJobsForDeadMs;
|
||||
|
||||
private final String FindPoolIds = "SELECT distinct storage_pool_work.pool_id FROM storage_pool_work WHERE mgmt_server_id = ?";
|
||||
|
||||
protected StoragePoolWorkDaoImpl() {
|
||||
PendingWorkForPrepareForMaintenanceSearch = createSearchBuilder();
|
||||
PendingWorkForPrepareForMaintenanceSearch.and("poolId", PendingWorkForPrepareForMaintenanceSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
|
||||
PendingWorkForPrepareForMaintenanceSearch.and("stoppedForMaintenance", PendingWorkForPrepareForMaintenanceSearch.entity().isStoppedForMaintenance(), SearchCriteria.Op.EQ);
|
||||
PendingWorkForPrepareForMaintenanceSearch.and("startedAfterMaintenance", PendingWorkForPrepareForMaintenanceSearch.entity().isStartedAfterMaintenance(), SearchCriteria.Op.EQ);
|
||||
PendingWorkForPrepareForMaintenanceSearch.done();
|
||||
|
||||
PendingWorkForCancelMaintenanceSearch = createSearchBuilder();
|
||||
PendingWorkForCancelMaintenanceSearch.and("poolId", PendingWorkForCancelMaintenanceSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
|
||||
PendingWorkForCancelMaintenanceSearch.and("stoppedForMaintenance", PendingWorkForCancelMaintenanceSearch.entity().isStoppedForMaintenance(), SearchCriteria.Op.EQ);
|
||||
PendingWorkForCancelMaintenanceSearch.and("startedAfterMaintenance", PendingWorkForCancelMaintenanceSearch.entity().isStartedAfterMaintenance(), SearchCriteria.Op.EQ);
|
||||
PendingWorkForCancelMaintenanceSearch.done();
|
||||
|
||||
PoolAndVmIdSearch = createSearchBuilder();
|
||||
PoolAndVmIdSearch.and("poolId", PoolAndVmIdSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
|
||||
PoolAndVmIdSearch.and("vmId", PoolAndVmIdSearch.entity().getVmId(), SearchCriteria.Op.EQ);
|
||||
PoolAndVmIdSearch.done();
|
||||
|
||||
PendingJobsForDeadMs = createSearchBuilder();
|
||||
PendingJobsForDeadMs.and("managementServerId", PendingJobsForDeadMs.entity().getManagementServerId(), SearchCriteria.Op.EQ);
|
||||
PendingJobsForDeadMs.and("poolId", PendingJobsForDeadMs.entity().getPoolId(), SearchCriteria.Op.EQ);
|
||||
PendingJobsForDeadMs.and("stoppedForMaintenance", PendingJobsForDeadMs.entity().isStoppedForMaintenance(), SearchCriteria.Op.EQ);
|
||||
PendingJobsForDeadMs.and("startedAfterMaintenance", PendingJobsForDeadMs.entity().isStartedAfterMaintenance(), SearchCriteria.Op.EQ);
|
||||
PendingJobsForDeadMs.done();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePoolWorkVO> listPendingWorkForPrepareForMaintenanceByPoolId(long poolId) {
|
||||
SearchCriteria<StoragePoolWorkVO> sc = PendingWorkForPrepareForMaintenanceSearch.create();
|
||||
sc.setParameters("poolId", poolId);
|
||||
sc.setParameters("stoppedForMaintenance", false);
|
||||
sc.setParameters("startedAfterMaintenance", false);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePoolWorkVO> listPendingWorkForCancelMaintenanceByPoolId(long poolId) {
|
||||
SearchCriteria<StoragePoolWorkVO> sc = PendingWorkForCancelMaintenanceSearch.create();
|
||||
sc.setParameters("poolId", poolId);
|
||||
sc.setParameters("stoppedForMaintenance", true);
|
||||
sc.setParameters("startedAfterMaintenance", false);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StoragePoolWorkVO findByPoolIdAndVmId(long poolId, long vmId) {
|
||||
SearchCriteria<StoragePoolWorkVO> sc = PoolAndVmIdSearch.create();
|
||||
sc.setParameters("poolId", poolId);
|
||||
sc.setParameters("vmId", vmId);
|
||||
return listBy(sc).get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePendingJobsOnMsRestart(long msId, long poolId) {
|
||||
//hung jobs are those which are stopped, but never started
|
||||
SearchCriteria<StoragePoolWorkVO> sc = PendingJobsForDeadMs.create();
|
||||
sc.setParameters("managementServerId", msId);
|
||||
sc.setParameters("poolId", poolId);
|
||||
sc.setParameters("stoppedForMaintenance", true);
|
||||
sc.setParameters("startedAfterMaintenance", false);
|
||||
remove(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public List<Long> searchForPoolIdsForPendingWorkJobs(long msId){
|
||||
|
||||
StringBuilder sql = new StringBuilder(FindPoolIds);
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
PreparedStatement pstmt = null;
|
||||
try {
|
||||
pstmt = txn.prepareAutoCloseStatement(sql.toString());
|
||||
pstmt.setLong(1, msId);
|
||||
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
List<Long> poolIds = new ArrayList<Long>();
|
||||
|
||||
while (rs.next()) {
|
||||
poolIds.add(rs.getLong("pool_id"));
|
||||
}
|
||||
return poolIds;
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -122,6 +122,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("poolId", poolId);
|
||||
sc.setParameters("notDestroyed", Volume.State.Destroy);
|
||||
sc.setParameters("vType", Volume.VolumeType.ROOT.toString());
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,6 +133,11 @@ import com.cloud.storage.DiskOfferingVO;
|
|||
import com.cloud.storage.GuestOSVO;
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.Storage.StorageResourceType;
|
||||
import com.cloud.storage.Storage.TemplateType;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePoolVO;
|
||||
import com.cloud.storage.VMTemplateHostVO;
|
||||
|
|
@ -1906,7 +1911,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
|||
_accountMgr.checkAccess(owner, domain);
|
||||
}
|
||||
//check if we have available pools for vm deployment
|
||||
List<StoragePoolVO> availablePools = _storagePoolDao.listPoolsByStatus(com.cloud.host.Status.Up);
|
||||
List<StoragePoolVO> availablePools = _storagePoolDao.listPoolsByStatus(StoragePoolStatus.Up);
|
||||
|
||||
if( availablePools == null || availablePools.size() < 1) {
|
||||
throw new StorageUnavailableException("There are no available pools in the UP state for vm deployment",-1);
|
||||
|
|
|
|||
|
|
@ -559,7 +559,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, StateLi
|
|||
long vmId = vm.getId();
|
||||
|
||||
VirtualMachineGuru<T> vmGuru = getVmGuru(vm);
|
||||
|
||||
vm = vmGuru.findById(vm.getId());
|
||||
Ternary<T, ReservationContext, ItWorkVO> start = changeToStartState(vmGuru, vm, caller, account);
|
||||
if (start == null) {
|
||||
return vmGuru.findById(vmId);
|
||||
|
|
|
|||
|
|
@ -1385,4 +1385,15 @@ CREATE TABLE `cloud`.`ovs_work` (
|
|||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`storage_pool_work` (
|
||||
`id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`pool_id` bigint unsigned NOT NULL COMMENT 'storage pool associated with the vm',
|
||||
`vm_id` bigint unsigned NOT NULL COMMENT 'vm identifier',
|
||||
`stopped_for_maintenance` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'this flag denoted whether the vm was stopped during maintenance',
|
||||
`started_after_maintenance` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'this flag denoted whether the vm was started after maintenance',
|
||||
`mgmt_server_id` bigint unsigned NOT NULL COMMENT 'management server id',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (pool_id,vm_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
SET foreign_key_checks = 1;
|
||||
|
|
|
|||
Loading…
Reference in New Issue