diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 1f5ca0f6827..39976e6c197 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -763,7 +763,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR Map hostMap = Host.getAllRecords(conn); if (hostMap.size() == 1) { s_logger.debug("There's no one to take over as master"); - return new MaintainAnswer(cmd, "Only master in the pool"); + return new MaintainAnswer(cmd,false, "Only master in the pool"); } Host newMaster = null; Host.Record newMasterRecord = null; diff --git a/core/src/com/cloud/server/ManagementServer.java b/core/src/com/cloud/server/ManagementServer.java index a78e68ef140..be62fb62109 100644 --- a/core/src/com/cloud/server/ManagementServer.java +++ b/core/src/com/cloud/server/ManagementServer.java @@ -72,6 +72,7 @@ import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotPolicyVO; import com.cloud.storage.SnapshotScheduleVO; import com.cloud.storage.SnapshotVO; +import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.StorageStats; import com.cloud.storage.VMTemplateHostVO; @@ -2184,4 +2185,7 @@ public interface ManagementServer { boolean addConfig(String instance, String component, String category, String name, String value, String description); boolean validateCustomVolumeSizeRange(long size) throws InvalidParameterValueException; + + boolean checkIfMaintenable(long hostId); + } diff --git a/server/src/com/cloud/api/commands/PrepareForMaintenanceCmd.java b/server/src/com/cloud/api/commands/PrepareForMaintenanceCmd.java index 951997b54a1..02bee1543de 100644 --- a/server/src/com/cloud/api/commands/PrepareForMaintenanceCmd.java +++ b/server/src/com/cloud/api/commands/PrepareForMaintenanceCmd.java @@ -28,6 +28,7 @@ import com.cloud.api.BaseCmd; import com.cloud.api.ServerApiException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.HostVO; +import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.Pair; public class PrepareForMaintenanceCmd extends BaseCmd { @@ -62,6 +63,15 @@ public class PrepareForMaintenanceCmd extends BaseCmd { throw new ServerApiException(BaseCmd.PARAM_ERROR, "Host with id " + hostId.toString() + " doesn't exist"); } + //if this is the only host in the pool, you cannot enable maintenance on this host + boolean maintenable = getManagementServer().checkIfMaintenable(host.getId()); + + if(!maintenable) + { + s_logger.warn("Unable to schedule host maintenance -- there is no host to take over as master in the pool"); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Unable to schedule host maintenance -- there is no host to take over as master in the pool"); + } + long jobId = 0; try { jobId = getManagementServer().prepareForMaintenanceAsync(hostId); @@ -70,7 +80,7 @@ public class PrepareForMaintenanceCmd extends BaseCmd { } if(jobId == 0) { - s_logger.warn("Unable to schedule async-job for PrepareForMaintenance comamnd"); + s_logger.warn("Unable to schedule async-job for PrepareForMaintenance command"); } else { if(s_logger.isDebugEnabled()) s_logger.debug("PrepareForMaintenance command has been accepted, job id: " + jobId); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java old mode 100755 new mode 100644 index 6f8312c6534..25c49f3ba68 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -191,6 +191,7 @@ import com.cloud.storage.SnapshotScheduleVO; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage; import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.StorageStats; import com.cloud.storage.VMTemplateHostVO; @@ -210,6 +211,7 @@ import com.cloud.storage.dao.LaunchPermissionDao; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.SnapshotPolicyDao; import com.cloud.storage.dao.StoragePoolDao; +import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VolumeDao; @@ -319,6 +321,7 @@ public class ManagementServerImpl implements ManagementServer { private final GuestOSDao _guestOSDao; private final GuestOSCategoryDao _guestOSCategoryDao; private final StoragePoolDao _poolDao; + private final StoragePoolHostDao _poolHostDao; private final StorageManager _storageMgr; private final UserVmDao _vmDao; @@ -415,6 +418,7 @@ public class ManagementServerImpl implements ManagementServer { _guestOSDao = locator.getDao(GuestOSDao.class); _guestOSCategoryDao = locator.getDao(GuestOSCategoryDao.class); _poolDao = locator.getDao(StoragePoolDao.class); + _poolHostDao = locator.getDao(StoragePoolHostDao.class); _vmDao = locator.getDao(UserVmDao.class); _configs = _configDao.getConfiguration(); @@ -8544,5 +8548,29 @@ public class ManagementServerImpl implements ManagementServer { return true; } + + @Override + public boolean checkIfMaintenable(long hostId) { + + //get the poolhostref record + List poolHostRecordSet = _poolHostDao.listByHostId(hostId); + + if(poolHostRecordSet!=null) + { + //the above list has only 1 record + StoragePoolHostVO poolHostRecord = poolHostRecordSet.get(0); + + //get the poolId and get hosts associated in that pool + List hostsInPool = _poolHostDao.listByPoolId(poolHostRecord.getPoolId()); + + if(hostsInPool!=null && hostsInPool.size()>1) + { + return true; //since there are other hosts to take over as master in this pool + } + } + return false; + } + + }