Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 88CE7C4FF for ; Tue, 23 Jul 2013 08:01:56 +0000 (UTC) Received: (qmail 31100 invoked by uid 500); 23 Jul 2013 08:01:56 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 30906 invoked by uid 500); 23 Jul 2013 08:01:53 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 30899 invoked by uid 99); 23 Jul 2013 08:01:52 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 23 Jul 2013 08:01:52 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 2F20F8B195D; Tue, 23 Jul 2013 08:01:52 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: devdeep@apache.org To: commits@cloudstack.apache.org Message-Id: <09be989d3c404f67addffed3473c262a@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: git commit: updated refs/heads/4.2 to e2f2bc5 Date: Tue, 23 Jul 2013 08:01:52 +0000 (UTC) Updated Branches: refs/heads/4.2 c319ba3ba -> e2f2bc5f0 CLOUDSTACK-3382. Alert should be raised if a vm is migrated from dedicated to non-dedicated resource and vice versa. Alerts are generated for VM migration between: 1) Source host is dedicated and destination host is not. 2) Source host is not dedicated and destination host is dedicated. 3) Both hosts are dedicated to different accounts/domains Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/e2f2bc5f Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e2f2bc5f Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e2f2bc5f Branch: refs/heads/4.2 Commit: e2f2bc5f0bd49401847d5d4681fd7bc167575f9b Parents: c319ba3 Author: Saksham Srivastava Authored: Tue Jul 23 13:19:23 2013 +0530 Committer: Devdeep Singh Committed: Tue Jul 23 13:22:44 2013 +0530 ---------------------------------------------------------------------- .../deploy/dao/PlannerHostReservationDao.java | 2 + .../dao/PlannerHostReservationDaoImpl.java | 15 +- server/src/com/cloud/vm/UserVmManagerImpl.java | 240 +++++++++++++++++-- 3 files changed, 237 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2f2bc5f/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java b/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java index 69118f1..e60254b 100644 --- a/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java +++ b/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java @@ -27,4 +27,6 @@ public interface PlannerHostReservationDao extends GenericDao listAllReservedHosts(); + List listAllDedicatedHosts(); + } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2f2bc5f/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java b/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java index 41e0964..06cdab2 100644 --- a/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java +++ b/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java @@ -20,6 +20,8 @@ import java.util.List; import javax.annotation.PostConstruct; import javax.ejb.Local; + +import com.cloud.deploy.DeploymentPlanner.PlannerResourceUsage; import com.cloud.deploy.PlannerHostReservationVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; @@ -31,6 +33,7 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase _hostIdSearch; private SearchBuilder _reservedHostSearch; + private SearchBuilder _dedicatedHostSearch;; public PlannerHostReservationDaoImpl() { @@ -45,6 +48,10 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase listAllDedicatedHosts() { + SearchCriteria sc = _dedicatedHostSearch.create(); + sc.setParameters("usage", PlannerResourceUsage.Dedicated); + return listBy(sc); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2f2bc5f/server/src/com/cloud/vm/UserVmManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 9968690..0771233 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -33,10 +33,6 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; - -import com.cloud.server.ConfigurationServer; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.affinity.AffinityGroupService; @@ -68,6 +64,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager.OnError; @@ -111,6 +109,8 @@ import com.cloud.dc.dao.HostPodDao; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlanner.ExcludeList; +import com.cloud.deploy.PlannerHostReservationVO; +import com.cloud.deploy.dao.PlannerHostReservationDao; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; @@ -178,9 +178,11 @@ import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.projects.ProjectManager; import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; +import com.cloud.server.ConfigurationServer; import com.cloud.server.Criteria; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.service.dao.ServiceOfferingDetailsDao; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.GuestOSVO; @@ -225,6 +227,7 @@ import com.cloud.user.dao.SSHKeyPairDao; import com.cloud.user.dao.UserDao; import com.cloud.user.dao.VmDiskStatisticsDao; import com.cloud.uservm.UserVm; +import com.cloud.utils.DateUtil; import com.cloud.utils.Journal; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -422,11 +425,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use ConfigurationServer _configServer; @Inject AffinityGroupService _affinityGroupService; + @Inject + PlannerHostReservationDao _plannerHostReservationDao; + @Inject + private ServiceOfferingDetailsDao serviceOfferingDetailsDao; protected ScheduledExecutorService _executor = null; protected int _expungeInterval; protected int _expungeDelay; protected boolean _dailyOrHourly = false; + private int capacityReleaseInterval; protected String _name; protected String _instance; @@ -1428,6 +1436,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use String workers = configs.get("expunge.workers"); int wrks = NumbersUtil.parseInt(workers, 10); + capacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600); String time = configs.get("expunge.interval"); _expungeInterval = NumbersUtil.parseInt(time, 86400); @@ -3868,22 +3877,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use + destinationHost.getResourceState()); } - HostVO srcHost = _hostDao.findById(srcHostId); - HostVO destHost = _hostDao.findById(destinationHost.getId()); - //if srcHost is dedicated and destination Host is not - if (checkIfHostIsDedicated(srcHost) && !checkIfHostIsDedicated(destHost)) { - //raise an alert - String msg = "VM is migrated on a non-dedicated host " + destinationHost.getName(); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); - } - //if srcHost is non dedicated but destination Host is. - if (!checkIfHostIsDedicated(srcHost) && checkIfHostIsDedicated(destHost)) { - //raise an alert - String msg = "VM is migrated on a dedicated host " + destinationHost.getName(); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); - } + checkHostsDedication(vm, srcHostId, destinationHost.getId()); - // call to core process + // call to core process DataCenterVO dcVO = _dcDao.findById(destinationHost.getDataCenterId()); HostPodVO pod = _podDao.findById(destinationHost.getPodId()); Cluster cluster = _clusterDao.findById(destinationHost.getClusterId()); @@ -3926,6 +3922,210 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use } } + private Long accountOfDedicatedHost(HostVO host) { + long hostId = host.getId(); + DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId); + DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId()); + DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId()); + if(dedicatedHost != null) { + return dedicatedHost.getAccountId(); + } + if(dedicatedClusterOfHost != null) { + return dedicatedClusterOfHost.getAccountId(); + } + if(dedicatedPodOfHost != null) { + return dedicatedPodOfHost.getAccountId(); + } + return null; + } + + private Long domainOfDedicatedHost(HostVO host) { + long hostId = host.getId(); + DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId); + DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId()); + DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId()); + if(dedicatedHost != null) { + return dedicatedHost.getDomainId(); + } + if(dedicatedClusterOfHost != null) { + return dedicatedClusterOfHost.getDomainId(); + } + if(dedicatedPodOfHost != null) { + return dedicatedPodOfHost.getDomainId(); + } + return null; + } + + public void checkHostsDedication (VMInstanceVO vm, long srcHostId, long destHostId) { + HostVO srcHost = _hostDao.findById(srcHostId); + HostVO destHost = _hostDao.findById(destHostId); + boolean srcExplDedicated = checkIfHostIsDedicated(srcHost); + boolean destExplDedicated = checkIfHostIsDedicated(destHost); + //if srcHost is explicitly dedicated and destination Host is not + if (srcExplDedicated && !destExplDedicated) { + //raise an alert + String msg = "VM is being migrated from a explicitly dedicated host " + srcHost.getName() +" to non-dedicated host " + destHost.getName(); + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + s_logger.warn(msg); + } + //if srcHost is non dedicated but destination Host is explicitly dedicated + if (!srcExplDedicated && destExplDedicated) { + //raise an alert + String msg = "VM is being migrated from a non dedicated host " + srcHost.getName() + " to a explicitly dedicated host "+ destHost.getName(); + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + s_logger.warn(msg); + } + + //if hosts are dedicated to different account/domains, raise an alert + if (srcExplDedicated && destExplDedicated) { + if((accountOfDedicatedHost(srcHost) != null) && (accountOfDedicatedHost(srcHost)!= accountOfDedicatedHost(destHost))) { + String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(srcHost) + + " to host " + destHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(destHost); + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + s_logger.warn(msg); + } + if((domainOfDedicatedHost(srcHost) != null) && (domainOfDedicatedHost(srcHost)!= domainOfDedicatedHost(destHost))) { + String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(srcHost) + + " to host " + destHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(destHost); + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + s_logger.warn(msg); + } + } + + // Checks for implicitly dedicated hosts + ServiceOfferingVO deployPlanner = _offeringDao.findById(vm.getServiceOfferingId()); + if(deployPlanner.getDeploymentPlanner() != null && deployPlanner.getDeploymentPlanner().equals("ImplicitDedicationPlanner")) { + //VM is deployed using implicit planner + long accountOfVm = vm.getAccountId(); + String msg = "VM of account " + accountOfVm + " with implicit deployment planner being migrated to host " + destHost.getName(); + //Get all vms on destination host + boolean emptyDestination = false; + List vmsOnDest= getVmsOnHost(destHostId); + if (vmsOnDest == null || vmsOnDest.isEmpty()) { + emptyDestination = true; + } + + if (!emptyDestination) { + //Check if vm is deployed using strict implicit planner + if(!isServiceOfferingUsingPlannerInPreferredMode(vm.getServiceOfferingId())) { + //Check if all vms on destination host are created using strict implicit mode + if(!checkIfAllVmsCreatedInStrictMode(accountOfVm, vmsOnDest)) { + msg = "VM of account " + accountOfVm + " with strict implicit deployment planner being migrated to host " + destHost.getName() + + " not having all vms strict implicitly dedicated to account " + accountOfVm; + } + } else { + //If vm is deployed using preferred implicit planner, check if all vms on destination host must be + //using implicit planner and must belong to same account + for (VMInstanceVO vmsDest : vmsOnDest) { + ServiceOfferingVO destPlanner = _offeringDao.findById(vmsDest.getServiceOfferingId()); + if (!((destPlanner.getDeploymentPlanner() != null && destPlanner.getDeploymentPlanner().equals("ImplicitDedicationPlanner")) && + vmsDest.getAccountId()==accountOfVm)) { + msg = "VM of account " + accountOfVm + " with preffered implicit deployment planner being migrated to host " + destHost.getName() + + " not having all vms implicitly dedicated to account " + accountOfVm; + } + } + } + } + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + s_logger.warn(msg); + + } else { + //VM is not deployed using implicit planner, check if it migrated between dedicated hosts + List reservedHosts = _plannerHostReservationDao.listAllDedicatedHosts(); + boolean srcImplDedicated = false; + boolean destImplDedicated = false; + String msg = null; + for (PlannerHostReservationVO reservedHost : reservedHosts) { + if(reservedHost.getHostId() == srcHostId) { + srcImplDedicated = true; + } + if(reservedHost.getHostId() == destHostId) { + destImplDedicated = true; + } + } + if(srcImplDedicated) { + if(destImplDedicated){ + msg = "VM is being migrated from implicitly dedicated host " + srcHost.getName() + " to another implicitly dedicated host " + destHost.getName(); + } else { + msg = "VM is being migrated from implicitly dedicated host " + srcHost.getName() + " to shared host " + destHost.getName(); + } + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + s_logger.warn(msg); + } else { + if (destImplDedicated) { + msg = "VM is being migrated from shared host " + srcHost.getName() + " to implicitly dedicated host " + destHost.getName(); + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + s_logger.warn(msg); + } + } + } + } + + private List getVmsOnHost(long hostId) { + List vms = _vmInstanceDao.listUpByHostId(hostId); + List vmsByLastHostId = _vmInstanceDao.listByLastHostId(hostId); + if (vmsByLastHostId.size() > 0) { + // check if any VMs are within skip.counting.hours, if yes we have to consider the host. + for (VMInstanceVO stoppedVM : vmsByLastHostId) { + long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime() + .getTime()) / 1000; + if (secondsSinceLastUpdate < capacityReleaseInterval) { + vms.add(stoppedVM); + } + } + } + + return vms; + } + private boolean isServiceOfferingUsingPlannerInPreferredMode(long serviceOfferingId) { + boolean preferred = false; + Map details = serviceOfferingDetailsDao.findDetails(serviceOfferingId); + if (details != null && !details.isEmpty()) { + String preferredAttribute = details.get("ImplicitDedicationMode"); + if (preferredAttribute != null && preferredAttribute.equals("Preferred")) { + preferred = true; + } + } + return preferred; + } + + private boolean checkIfAllVmsCreatedInStrictMode(Long accountId, List allVmsOnHost) { + boolean createdByImplicitStrict = true; + if (allVmsOnHost.isEmpty()) + return false; + for (VMInstanceVO vm : allVmsOnHost) { + if (!isImplicitPlannerUsedByOffering(vm.getServiceOfferingId()) || vm.getAccountId()!= accountId) { + s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by a planner other" + + " than implicit, or running vms of other account"); + createdByImplicitStrict = false; + break; + } else if (isServiceOfferingUsingPlannerInPreferredMode(vm.getServiceOfferingId()) || vm.getAccountId()!= accountId) { + s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by an implicit planner" + + " in preferred mode, or running vms of other account"); + createdByImplicitStrict = false; + break; + } + } + return createdByImplicitStrict; + } + + private boolean isImplicitPlannerUsedByOffering(long offeringId) { + boolean implicitPlannerUsed = false; + ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(offeringId); + if (offering == null) { + s_logger.error("Couldn't retrieve the offering by the given id : " + offeringId); + } else { + String plannerName = offering.getDeploymentPlanner(); + if (plannerName != null) { + if(plannerName.equals("ImplicitDedicationPlanner")) { + implicitPlannerUsed = true; + } + } + } + + return implicitPlannerUsed; + } + @Override @ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = "migrating VM", async = true) public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinationHost, @@ -4043,6 +4243,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use " migrate to this host"); } + checkHostsDedication(vm, srcHostId, destinationHost.getId()); + VMInstanceVO migratedVm = _itMgr.migrateWithStorage(vm, srcHostId, destinationHost.getId(), volToPoolObjectMap); return migratedVm; }