diff --git a/api/src/com/cloud/host/Status.java b/api/src/com/cloud/host/Status.java index 63cecb5665f..c9a4d416b72 100644 --- a/api/src/com/cloud/host/Status.java +++ b/api/src/com/cloud/host/Status.java @@ -30,6 +30,7 @@ public enum Status { Updating(true, true, false), PrepareForMaintenance(false, false, false), ErrorInMaintenance(false, false, false), + CancelMaintenance(false, false, false), Maintenance(false, false, false), Alert(true, true, true), Removed(true, false, true); diff --git a/server/src/com/cloud/api/commands/StartSystemVMCmd.java b/server/src/com/cloud/api/commands/StartSystemVMCmd.java index 85647e66794..382e51f550a 100644 --- a/server/src/com/cloud/api/commands/StartSystemVMCmd.java +++ b/server/src/com/cloud/api/commands/StartSystemVMCmd.java @@ -36,6 +36,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.user.Account; import com.cloud.user.UserContext; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VMInstanceVO; @Implementation(responseObject=SystemVmResponse.class, description="Starts a system virtual machine.") @@ -93,8 +94,9 @@ public class StartSystemVMCmd extends BaseAsyncCmd { } @Override - public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException{ - VMInstanceVO instance = BaseCmd._mgr.startSystemVM(this); + + public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException, CloudRuntimeException{ + VMInstanceVO instance = _mgr.startSystemVM(this); SystemVmResponse response = ApiResponseHelper.createSystemVmResponse(instance); response.setResponseName(getName()); this.setResponseObject(response); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 9af932208bc..13e731a23aa 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -4819,29 +4819,9 @@ public class ManagementServerImpl implements ManagementServer { if (systemVm.getType().equals(VirtualMachine.Type.ConsoleProxy)){ long eventId = EventUtils.saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_PROXY_START, "Starting console proxy with Id: "+id); -// try { -// checkIfStoragePoolAvailable(id); -// } catch (StorageUnavailableException e) { -// s_logger.warn(e.getMessage()); -// return null; -// } catch (Exception e){ -// //unforseen exceptions -// s_logger.warn(e.getMessage()); -// return null; -// } return startConsoleProxy(id, eventId); } else { long eventId = EventUtils.saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_SSVM_START, "Starting secondary storage Vm Id: "+id); -// try { -// checkIfStoragePoolAvailable(id); -// } catch (StorageUnavailableException e) { -// s_logger.warn(e.getMessage()); -// return null; -// } catch (Exception e){ -// //unforseen exceptions -// s_logger.warn(e.getMessage()); -// return null; -// } return startSecondaryStorageVm(id, eventId); } } @@ -4862,29 +4842,9 @@ public class ManagementServerImpl implements ManagementServer { if (systemVm.getType() == VirtualMachine.Type.ConsoleProxy) { long eventId = EventUtils.saveScheduledEvent(callerId, callerAccountId, EventTypes.EVENT_PROXY_START, "Starting console proxy with Id: "+id); - try { - checkIfStoragePoolAvailable(id); - } catch (StorageUnavailableException e) { - s_logger.warn(e.getMessage()); - return null; - } catch (Exception e){ - //unforseen exceptions - s_logger.warn(e.getMessage()); - return null; - } return startConsoleProxy(id, eventId); } else if (systemVm.getType() == VirtualMachine.Type.SecondaryStorageVm) { long eventId = EventUtils.saveScheduledEvent(callerId, callerAccountId, EventTypes.EVENT_SSVM_START, "Starting secondary storage Vm Id: "+id); - try { - checkIfStoragePoolAvailable(id); - } catch (StorageUnavailableException e) { - s_logger.warn(e.getMessage()); - return null; - } catch (Exception e){ - //unforseen exceptions - s_logger.warn(e.getMessage()); - return null; - } return startSecondaryStorageVm(id, eventId); } else { throw new InvalidParameterValueException("Unable to find a system vm: " + id); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index f9e0bd404d0..b81f6490a84 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -236,6 +236,15 @@ public class StorageManagerImpl implements StorageManager { @Override public boolean share(VMInstanceVO vm, List vols, HostVO host, boolean cancelPreviousShare) { + //if pool is in maintenance and it is the ONLY pool available; reject + List rootVolForGivenVm = _volsDao.findByInstanceAndType(vm.getId(), VolumeType.ROOT); + if(rootVolForGivenVm != null && rootVolForGivenVm.size() > 0){ + boolean isPoolAvailable = isPoolAvailable(rootVolForGivenVm.get(0).getPoolId()); + if(!isPoolAvailable){ + return false; + } + } + //this check is done for maintenance mode for primary storage //if any one of the volume is unusable, we return false //if we return false, the allocator will try to switch to another PS if available @@ -299,6 +308,17 @@ public class StorageManagerImpl implements StorageManager { return _volsDao.persist(newVol); } + private boolean isPoolAvailable(Long poolId){ + //get list of all pools + List 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) )){ + return false; + }else{ + return true; + } + } @Override public List prepare(VMInstanceVO vm, HostVO host) { @@ -309,9 +329,19 @@ public class StorageManagerImpl implements StorageManager { return vols; } + //if pool is in maintenance and it is the ONLY pool available; reject + List rootVolForGivenVm = _volsDao.findByInstanceAndType(vm.getId(), VolumeType.ROOT); + if(rootVolForGivenVm != null && rootVolForGivenVm.size() > 0){ + boolean isPoolAvailable = isPoolAvailable(rootVolForGivenVm.get(0).getPoolId()); + + if(!isPoolAvailable){ + return new ArrayList(); + } + } + //if we have a system vm //get the storage pool - //if pool is in maintenance + //if pool is in prepareformaintenance //add to recreate vols, and continue if(vm.getType().equals(VirtualMachine.Type.ConsoleProxy) || vm.getType().equals(VirtualMachine.Type.DomainRouter) || vm.getType().equals(VirtualMachine.Type.SecondaryStorageVm)) { @@ -2380,6 +2410,10 @@ public class StorageManagerImpl implements StorageManager { throw new StorageUnavailableException("Primary storage with id " + primaryStorageId + " is not ready to complete migration, as the status is:" + primaryStorage.getStatus().toString()); } + //set state to cancelmaintenance + primaryStorage.setStatus(Status.CancelMaintenance); + _storagePoolDao.persist(primaryStorage); + //2. Get a list of all the volumes within this storage pool List allVolumes = _volsDao.findByPoolId(primaryStorageId); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 3fa99e48a7b..64e10407032 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -817,7 +817,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM return null; } -// checkIfPoolAvailable(vmId);//throws StorageUnavailableException if pool is not UP + checkIfPoolAvailable(vmId);//throws StorageUnavailableException if pool is not UP EventVO event = new EventVO(); event.setType(EventTypes.EVENT_VM_START);