cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From prachida...@apache.org
Subject git commit: updated refs/heads/planner_reserve to 0e792eb
Date Wed, 08 May 2013 23:42:56 GMT
Updated Branches:
  refs/heads/planner_reserve 81d6da5ad -> 0e792eb93


- Host reservation release process

- Make deployment_planner optional field in service offering, global config vm.deployment.planner
- Admin API to release host reservation


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/0e792eb9
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/0e792eb9
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/0e792eb9

Branch: refs/heads/planner_reserve
Commit: 0e792eb938d6e5af7a3d0324ba61fc11f4011a46
Parents: 81d6da5
Author: Prachi Damle <prachi@cloud.com>
Authored: Wed May 8 16:38:01 2013 -0700
Committer: Prachi Damle <prachi@cloud.com>
Committed: Wed May 8 16:38:01 2013 -0700

----------------------------------------------------------------------
 api/src/com/cloud/event/EventTypes.java            |    3 +
 api/src/com/cloud/resource/ResourceService.java    |    4 +-
 .../admin/host/ReleaseHostReservationCmd.java      |  105 +++++++
 .../admin/offering/CreateServiceOfferingCmd.java   |    2 +-
 client/tomcatconf/commands.properties.in           |    1 +
 .../com/cloud/capacity/CapacityManagerImpl.java    |   33 ++-
 server/src/com/cloud/configuration/Config.java     |    3 +
 .../deploy/DeploymentPlanningManagerImpl.java      |  239 +++++++++++----
 server/src/com/cloud/deploy/FirstFitPlanner.java   |    8 +-
 .../deploy/dao/PlannerHostReservationDao.java      |    4 +
 .../deploy/dao/PlannerHostReservationDaoImpl.java  |   13 +
 .../com/cloud/resource/ResourceManagerImpl.java    |   43 +++
 .../src/com/cloud/server/ManagementServerImpl.java |    1 +
 .../src/com/cloud/service/ServiceOfferingVO.java   |   11 +-
 .../src/com/cloud/upgrade/dao/Upgrade410to420.java |   10 +-
 server/src/com/cloud/vm/UserVmManagerImpl.java     |    3 +
 server/src/com/cloud/vm/dao/VMInstanceDao.java     |   28 +-
 server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java |  147 ++++++----
 .../cloud/resource/MockResourceManagerImpl.java    |    6 +
 setup/db/db/schema-410to420.sql                    |    5 +-
 20 files changed, 510 insertions(+), 159 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/api/src/com/cloud/event/EventTypes.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index 0ee7f40..f9a0c04 100755
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -390,6 +390,8 @@ public class EventTypes {
     public static final String EVENT_AFFINITY_GROUP_REMOVE = "AG.REMOVE";
     public static final String EVENT_VM_AFFINITY_GROUP_UPDATE = "VM.AG.UPDATE";
 
+    public static final String EVENT_HOST_RESERVATION_RELEASE = "HOST.RESERVATION.RELEASE";
+
     static {
 
         // TODO: need a way to force author adding event types to declare the entity details as well, with out braking
@@ -690,6 +692,7 @@ public class EventTypes {
         entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_UPDATE, AutoScaleVmGroup.class.getName());
         entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_ENABLE, AutoScaleVmGroup.class.getName());
         entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DISABLE, AutoScaleVmGroup.class.getName());
+
     }
 
     public static String getEntityForEvent (String eventName) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/api/src/com/cloud/resource/ResourceService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/resource/ResourceService.java b/api/src/com/cloud/resource/ResourceService.java
index 08e2585..ce0df63 100755
--- a/api/src/com/cloud/resource/ResourceService.java
+++ b/api/src/com/cloud/resource/ResourceService.java
@@ -100,11 +100,13 @@ public interface ResourceService {
     Swift discoverSwift(AddSwiftCmd addSwiftCmd) throws DiscoveryException;
 
     S3 discoverS3(AddS3Cmd cmd) throws DiscoveryException;
-    
+
     List<HypervisorType> getSupportedHypervisorTypes(long zoneId, boolean forVirtualRouter, Long podId);
 
     Pair<List<? extends Swift>, Integer> listSwifts(ListSwiftsCmd cmd);
 
     List<? extends S3> listS3s(ListS3sCmd cmd);
 
+    boolean releaseHostReservation(Long hostId);
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/api/src/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java
new file mode 100644
index 0000000..d09cf38
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java
@@ -0,0 +1,105 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.host;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.async.AsyncJob;
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+
+@APICommand(name = "releaseHostReservation", description = "Releases host reservation.", responseObject = SuccessResponse.class)
+public class ReleaseHostReservationCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(ReleaseHostReservationCmd.class.getName());
+
+    private static final String s_name = "releasehostreservationresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=HostResponse.class,
+            required=true, description="the host ID")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = UserContext.current().getCaller();
+        if (account != null) {
+            return account.getId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_HOST_RESERVATION_RELEASE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "releasing reservation for host: " + getId();
+    }
+
+    @Override
+    public AsyncJob.Type getInstanceType() {
+        return AsyncJob.Type.Host;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute(){
+        boolean result = _resourceService.releaseHostReservation(getId());
+        if (result) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release host reservation");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
index 74392cd..c155b70 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
@@ -84,7 +84,7 @@ public class CreateServiceOfferingCmd extends BaseCmd {
     @Parameter(name=ApiConstants.NETWORKRATE, type=CommandType.INTEGER, description="data transfer rate in megabits per second allowed. Supported only for non-System offering and system offerings having \"domainrouter\" systemvmtype")
     private Integer networkRate;
 
-    @Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "The deployment planner heuristics used to deploy a VM of this offering, default \"FirstFitPlanner\".")
+    @Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "The deployment planner heuristics used to deploy a VM of this offering. If null, value of global config vm.deployment.planner is used")
     private String deploymentPlanner;
 
     /////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index bd9b897..7f62603 100644
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -259,6 +259,7 @@ listHosts=3
 findHostsForMigration=1
 addSecondaryStorage=1
 updateHostPassword=1
+releaseHostReservation=1
 
 #### volume commands
 attachVolume=15

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/server/src/com/cloud/capacity/CapacityManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java
index 9a1e972..9e4bb22 100755
--- a/server/src/com/cloud/capacity/CapacityManagerImpl.java
+++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java
@@ -82,11 +82,14 @@ import com.cloud.utils.db.DB;
 import com.cloud.utils.db.SearchCriteria;
 import com.cloud.utils.db.Transaction;
 import com.cloud.utils.fsm.StateListener;
+import com.cloud.vm.UserVmDetailVO;
+import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachine.Event;
 import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
 import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.snapshot.VMSnapshot;
 import com.cloud.vm.snapshot.VMSnapshotVO;
@@ -126,6 +129,8 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
     protected VMSnapshotDao _vmSnapshotDao;
     @Inject
     protected UserVmDao _userVMDao;
+    @Inject
+    protected UserVmDetailsDao _userVmDetailsDao;
 
     @Inject
     ClusterDetailsDao _clusterDetailsDao;
@@ -140,6 +145,8 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
     @Inject
     MessageBus _messageBus;
 
+    private static final String MESSAGE_RESERVED_CAPACITY_FREED_FLAG = "Message.ReservedCapacityFreed.Flag";
+
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
         _vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
@@ -561,9 +568,19 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
                 reservedMemory += so.getRamSize() * 1024L * 1024L;
                 reservedCpu += so.getCpu() * so.getSpeed();
             } else {
-                // signal that the VM has been stopped for skip.counting.hours,
+                // signal if not done already, that the VM has been stopped for skip.counting.hours,
                 // hence capacity will not be reserved anymore.
-                _messageBus.publish(_name, "VM_ReservedCapacity_Free", PublishScope.LOCAL, vm);
+                UserVmDetailVO messageSentFlag = _userVmDetailsDao.findDetail(vm.getId(), MESSAGE_RESERVED_CAPACITY_FREED_FLAG);
+                if (messageSentFlag == null || !Boolean.valueOf(messageSentFlag.getValue())) {
+                    _messageBus.publish(_name, "VM_ReservedCapacity_Free", PublishScope.LOCAL, vm);
+
+                    if (vm.getType() == VirtualMachine.Type.User) {
+                        UserVmVO userVM = _userVMDao.findById(vm.getId());
+                        _userVMDao.loadDetails(userVM);
+                        userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "true");
+                        _userVMDao.saveDetails(userVM);
+                    }
+                }
             }
         }
 
@@ -700,6 +717,18 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
             allocateVmCapacity(vm, fromLastHost);
         }
 
+        if (newState == State.Stopped) {
+            if (vm.getType() == VirtualMachine.Type.User) {
+
+                UserVmVO userVM = _userVMDao.findById(vm.getId());
+                _userVMDao.loadDetails(userVM);
+                // free the message sent flag if it exists
+                userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "false");
+                _userVMDao.saveDetails(userVM);
+
+            }
+        }
+
         return true;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 1f0a1a9..dea8807 100755
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -214,6 +214,8 @@ public enum Config {
 	SecStorageProxy("Advanced", AgentManager.class, String.class, "secstorage.proxy", null, "http proxy used by ssvm, in http://username:password@proxyserver:port format", null),
     AlertPurgeInterval("Advanced", ManagementServer.class, Integer.class, "alert.purge.interval", "86400", "The interval (in seconds) to wait before running the alert purge thread", null),
     AlertPurgeDelay("Advanced", ManagementServer.class, Integer.class, "alert.purge.delay", "0", "Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts", null),
+    HostReservationReleasePeriod("Advanced", ManagementServer.class, Integer.class, "host.reservation.release.period", "300000", "The interval in milliseconds between host reservation release checks", null),
+    
 
     // LB HealthCheck Interval.
     LBHealthCheck("Advanced", ManagementServer.class, String.class, "healthcheck.update.interval", "600",
@@ -235,6 +237,7 @@ public enum Config {
 	ApplyAllocationAlgorithmToPods("Advanced", ManagementServer.class, Boolean.class, "apply.allocation.algorithm.to.pods", "false", "If true, deployment planner applies the allocation heuristics at pods first in the given datacenter during VM resource allocation", "true,false"),
 	VmUserDispersionWeight("Advanced", ManagementServer.class, Float.class, "vm.user.dispersion.weight", "1", "Weight for user dispersion heuristic (as a value between 0 and 1) applied to resource allocation during vm deployment. Weight for capacity heuristic will be (1 - weight of user dispersion)", null),
     VmAllocationAlgorithm("Advanced", ManagementServer.class, String.class, "vm.allocation.algorithm", "random", "'random', 'firstfit', 'userdispersing', 'userconcentratedpod_random', 'userconcentratedpod_firstfit' : Order in which hosts within a cluster will be considered for VM/volume allocation.", null),
+    VmDeploymentPlanner("Advanced", ManagementServer.class, String.class, "vm.deployment.planner", "FirstFitPlanner", "'FirstFitPlanner', 'UserDispersingPlanner', 'UserConcentratedPodPlanner': DeploymentPlanner heuristic that will be used for VM deployment.", null),
 	EndpointeUrl("Advanced", ManagementServer.class, String.class, "endpointe.url", "http://localhost:8080/client/api", "Endpointe Url", null),
 	ElasticLoadBalancerEnabled("Advanced", ManagementServer.class, String.class, "network.loadbalancer.basiczone.elb.enabled", "false", "Whether the load balancing service is enabled for basic zones", "true,false"),
 	ElasticLoadBalancerNetwork("Advanced", ManagementServer.class, String.class, "network.loadbalancer.basiczone.elb.network", "guest", "Whether the elastic load balancing service public ips are taken from the public or guest network", "guest,public"),

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
index b05d065..5af17d2 100644
--- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
+++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
@@ -21,7 +21,8 @@ import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
 import java.util.TreeSet;
 
 import javax.ejb.Local;
@@ -29,7 +30,7 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 import org.apache.cloudstack.affinity.AffinityGroupProcessor;
-import org.apache.cloudstack.affinity.AffinityGroupVMMapVO;
+
 import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
 import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
@@ -41,9 +42,10 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
 
-import com.cloud.capacity.Capacity;
+
 import com.cloud.capacity.CapacityManager;
 import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.cluster.ManagementServerNode;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.dao.ConfigurationDao;
 import com.cloud.dc.ClusterDetailsDao;
@@ -65,7 +67,6 @@ import com.cloud.host.HostVO;
 import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.security.SecurityGroupVO;
 import com.cloud.offering.ServiceOffering;
 import com.cloud.org.Cluster;
 import com.cloud.org.Grouping;
@@ -82,6 +83,7 @@ import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.storage.dao.StoragePoolHostDao;
 import com.cloud.storage.dao.VolumeDao;
 import com.cloud.user.AccountManager;
+import com.cloud.utils.DateUtil;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.ComponentContext;
@@ -94,6 +96,7 @@ import com.cloud.vm.ReservationContext;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.dao.UserVmDao;
 import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.agent.AgentManager;
@@ -106,6 +109,7 @@ import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupRoutingCommand;
 import com.cloud.agent.manager.allocator.HostAllocator;
 
+
 @Local(value = { DeploymentPlanningManager.class })
 public class DeploymentPlanningManagerImpl extends ManagerBase implements DeploymentPlanningManager, Manager, Listener {
 
@@ -124,9 +128,14 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
     DataCenterDao _dcDao;
     @Inject
     PlannerHostReservationDao _plannerHostReserveDao;
-
+    private int _vmCapacityReleaseInterval;
     @Inject
     MessageBus _messageBus;
+    private Timer _timer = null;
+    private long _hostReservationReleasePeriod = 60L * 60L * 1000L; // one hour by default
+
+    private static final long INITIAL_RESERVATION_RELEASE_CHECKER_DELAY = 30L * 1000L; // thirty seconds expressed in milliseconds
+    protected long _nodeId = -1;
 
     protected List<StoragePoolAllocator> _storagePoolAllocators;
     public List<StoragePoolAllocator> getStoragePoolAllocators() {
@@ -212,7 +221,11 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
 
 
         ServiceOffering offering = vmProfile.getServiceOffering();
-        DeploymentPlanner planner = ComponentContext.getComponent(offering.getDeploymentPlanner());
+        String plannerName = offering.getDeploymentPlanner();
+        if (plannerName == null) {
+            plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key());
+        }
+        DeploymentPlanner planner = ComponentContext.getComponent(plannerName);
 
         int cpu_requested = offering.getCpu() * offering.getSpeed();
         long ram_requested = offering.getRamSize() * 1024L * 1024L;
@@ -352,58 +365,58 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
         DeployDestination dest = null;
         List<Long> clusterList = null;
 
-        if (offering != null && offering.getDeploymentPlanner() != null) {
-            if (planner != null && planner.canHandle(vmProfile, plan, avoids)) {
-                while (true) {
+        if (planner != null && planner.canHandle(vmProfile, plan, avoids)) {
+            while (true) {
 
-                    if (planner instanceof DeploymentClusterPlanner) {
+                if (planner instanceof DeploymentClusterPlanner) {
 
-                        ExcludeList PlannerAvoidInput = new ExcludeList(avoids.getDataCentersToAvoid(),
-                                avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(),
-                                avoids.getPoolsToAvoid());
+                    ExcludeList PlannerAvoidInput = new ExcludeList(avoids.getDataCentersToAvoid(),
+                            avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(),
+                            avoids.getPoolsToAvoid());
 
-                        clusterList = ((DeploymentClusterPlanner) planner).orderClusters(vmProfile, plan, avoids);
+                    clusterList = ((DeploymentClusterPlanner) planner).orderClusters(vmProfile, plan, avoids);
 
-                        if (clusterList != null && !clusterList.isEmpty()) {
-                            // planner refactoring. call allocators to list hosts
-                            ExcludeList PlannerAvoidOutput = new ExcludeList(avoids.getDataCentersToAvoid(),
-                                    avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(),
-                                    avoids.getPoolsToAvoid());
+                    if (clusterList != null && !clusterList.isEmpty()) {
+                        // planner refactoring. call allocators to list hosts
+                        ExcludeList PlannerAvoidOutput = new ExcludeList(avoids.getDataCentersToAvoid(),
+                                avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(),
+                                avoids.getPoolsToAvoid());
 
-                            resetAvoidSet(PlannerAvoidOutput, PlannerAvoidInput);
+                        resetAvoidSet(PlannerAvoidOutput, PlannerAvoidInput);
 
-                            dest = checkClustersforDestination(clusterList, vmProfile, plan, avoids, dc,
-                                    getPlannerUsage(planner), PlannerAvoidOutput);
-                            if(dest != null){
-                                return dest;
-                            }
-                            // reset the avoid input to the planners
-                            resetAvoidSet(avoids, PlannerAvoidOutput);
+                        dest = checkClustersforDestination(clusterList, vmProfile, plan, avoids, dc,
+                                getPlannerUsage(planner), PlannerAvoidOutput);
+                        if (dest != null) {
+                            return dest;
+                        }
+                        // reset the avoid input to the planners
+                        resetAvoidSet(avoids, PlannerAvoidOutput);
 
+                    } else {
+                        return null;
+                    }
+                } else {
+                    dest = planner.plan(vmProfile, plan, avoids);
+                    if (dest != null) {
+                        long hostId = dest.getHost().getId();
+                        avoids.addHost(dest.getHost().getId());
+
+                        if (checkIfHostFitsPlannerUsage(hostId, DeploymentPlanner.PlannerResourceUsage.Shared)) {
+                            // found destination
+                            return dest;
                         } else {
-                            return null;
+                            // find another host - seems some concurrent
+                            // deployment picked it up for dedicated access
+                            continue;
                         }
                     } else {
-                        dest = planner.plan(vmProfile, plan, avoids);
-                        if (dest != null) {
-                            long hostId = dest.getHost().getId();
-                            avoids.addHost(dest.getHost().getId());
-
-                            if (checkIfHostFitsPlannerUsage(hostId, DeploymentPlanner.PlannerResourceUsage.Shared)) {
-                                // found destination
-                                return dest;
-                            } else {
-                                // find another host - seems some concurrent deployment picked it up for dedicated access
-                                continue;
-                            }
-                        }else{
-                            return null;
-                        }
+                        return null;
                     }
                 }
             }
         }
 
+
         return dest;
     }
 
@@ -495,36 +508,69 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
     }
 
     @DB
-    public void checkHostReservationRelease(VMInstanceVO vm) {
-        s_logger.debug("MessageBus message: host reserved capacity released for VM: " + vm.getLastHostId()
-                + ", checking if host reservation can be released for host:" + vm.getLastHostId());
-
-        Long hostId = vm.getLastHostId();
+    public boolean checkHostReservationRelease(Long hostId) {
 
         if (hostId != null) {
-            List<VMInstanceVO> vms = _vmInstanceDao.listUpByHostId(hostId);
-            if (vms.size() > 0) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Cannot release reservation, Found " + vms.size() + " VMs Running on host " + hostId);
+            PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
+            if (reservationEntry != null && reservationEntry.getResourceUsage() != null) {
+
+                // check if any VMs are starting or running on this host
+                List<VMInstanceVO> vms = _vmInstanceDao.listUpByHostId(hostId);
+                if (vms.size() > 0) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Cannot release reservation, Found " + vms.size() + " VMs Running on host "
+                                + hostId);
+                    }
+                    return false;
                 }
-            }
 
-            List<VMInstanceVO> vmsByLastHostId = _vmInstanceDao.listByLastHostId(hostId);
-            if (vmsByLastHostId.size() > 0) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Cannot release reservation, Found " + vmsByLastHostId.size()
-                            + " VMs Stopped but reserved on host " + hostId);
+                List<VMInstanceVO> vmsByLastHostId = _vmInstanceDao.listByLastHostId(hostId);
+                if (vmsByLastHostId.size() > 0) {
+                    // check if any VMs are within skip.counting.hours, if yes
+                    // we
+                    // cannot release the host
+                    for (VMInstanceVO stoppedVM : vmsByLastHostId) {
+                        long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime()
+                                .getTime()) / 1000;
+                        if (secondsSinceLastUpdate < _vmCapacityReleaseInterval) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Cannot release reservation, Found VM: " + stoppedVM
+                                        + " Stopped but reserved on host " + hostId);
+                            }
+                            return false;
+                        }
+                    }
                 }
-            }
 
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Host has no VMs, releasing the planner reservation");
-            }
+                // check if any VMs are stopping on or migrating to this host
+                List<VMInstanceVO> vmsStoppingMigratingByHostId = _vmInstanceDao.findByHostInStates(hostId,
+                        State.Stopping, State.Migrating, State.Starting);
+                if (vmsStoppingMigratingByHostId.size() > 0) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Cannot release reservation, Found " + vms.size()
+                                + " VMs stopping/migrating on host " + hostId);
+                    }
+                    return false;
+                }
 
-            PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
-            if (reservationEntry != null) {
-                long id = reservationEntry.getId();
+                // check if any VMs are in starting state with no hostId set yet
+                // -
+                // just ignore host release to avoid race condition
+                List<VMInstanceVO> vmsStartingNoHost = _vmInstanceDao.listStartingWithNoHostId();
+
+                if (vmsStartingNoHost.size() > 0) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Cannot release reservation, Found " + vms.size()
+                                + " VMs starting as of now and no hostId yet stored");
+                    }
+                    return false;
+                }
 
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Host has no VMs associated, releasing the planner reservation for host " + hostId);
+                }
+
+                long id = reservationEntry.getId();
                 final Transaction txn = Transaction.currentTxn();
 
                 try {
@@ -533,11 +579,13 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
                     final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id, true);
                     if (lockedEntry == null) {
                         s_logger.error("Unable to lock the host entry for reservation, host: " + hostId);
+                        return false;
                     }
                     // check before updating
                     if (lockedEntry.getResourceUsage() != null) {
                         lockedEntry.setResourceUsage(null);
                         _plannerHostReserveDao.persist(lockedEntry);
+                        return true;
                     }
                 } finally {
                     txn.commit();
@@ -545,6 +593,32 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
             }
 
         }
+        return false;
+    }
+
+    class HostReservationReleaseChecker extends TimerTask {
+        @Override
+        public void run() {
+            try {
+                s_logger.debug("Checking if any host reservation can be released ... ");
+                checkHostReservations();
+                s_logger.debug("Done running HostReservationReleaseChecker ... ");
+            } catch (Throwable t) {
+                s_logger.error("Exception in HostReservationReleaseChecker", t);
+            }
+        }
+    }
+
+    private void checkHostReservations() {
+        List<PlannerHostReservationVO> reservedHosts = _plannerHostReserveDao.listAllReservedHosts();
+
+        for (PlannerHostReservationVO hostReservation : reservedHosts) {
+            HostVO host = _hostDao.findById(hostReservation.getHostId());
+            if (host != null && host.getManagementServerId() != null && host.getManagementServerId() == _nodeId) {
+                checkHostReservationRelease(hostReservation.getHostId());
+            }
+        }
+
     }
 
     @Override
@@ -610,14 +684,45 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
         _agentMgr.registerForHostEvents(this, true, false, true);
         _messageBus.subscribe("VM_ReservedCapacity_Free", new MessageSubscriber() {
             @Override
-            public void onPublishMessage(String senderAddress, String subject, Object vm) {
-                checkHostReservationRelease((VMInstanceVO) vm);
+            public void onPublishMessage(String senderAddress, String subject, Object obj) {
+                VMInstanceVO vm = ((VMInstanceVO) obj);
+                s_logger.debug("MessageBus message: host reserved capacity released for VM: " + vm.getLastHostId()
+                        + ", checking if host reservation can be released for host:" + vm.getLastHostId());
+                Long hostId = vm.getLastHostId();
+                checkHostReservationRelease(hostId);
             }
         });
 
+        _vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()),
+                3600);
+
+        String hostReservationReleasePeriod = _configDao.getValue(Config.HostReservationReleasePeriod.key());
+        if (hostReservationReleasePeriod != null) {
+            _hostReservationReleasePeriod = Long.parseLong(hostReservationReleasePeriod);
+            if (_hostReservationReleasePeriod <= 0)
+                _hostReservationReleasePeriod = Long.parseLong(Config.HostReservationReleasePeriod.getDefaultValue());
+        }
+
+        _timer = new Timer("HostReservationReleaseChecker");
+
+        _nodeId = ManagementServerNode.getManagementServerId();
+
         return super.configure(name, params);
     }
 
+    @Override
+    public boolean start() {
+        _timer.schedule(new HostReservationReleaseChecker(), INITIAL_RESERVATION_RELEASE_CHECKER_DELAY,
+                _hostReservationReleasePeriod);
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        _timer.cancel();
+        return true;
+    }
+
     // /refactoring planner methods
     private DeployDestination checkClustersforDestination(List<Long> clusterList,
             VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid,

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/server/src/com/cloud/deploy/FirstFitPlanner.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/com/cloud/deploy/FirstFitPlanner.java
index ad1b9b3..f4dbca5 100755
--- a/server/src/com/cloud/deploy/FirstFitPlanner.java
+++ b/server/src/com/cloud/deploy/FirstFitPlanner.java
@@ -106,6 +106,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentClusterPla
 
 
 	protected String _allocationAlgorithm = "random";
+    protected String _globalDeploymentPlanner = "FirstFitPlanner";
 
 
     @Override
@@ -483,12 +484,16 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentClusterPla
 
     @Override
     public boolean canHandle(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid) {
-        // check what the ServiceOffering says
+        // check what the ServiceOffering says. If null, check the global config
         ServiceOffering offering = vm.getServiceOffering();
         if (offering != null && offering.getDeploymentPlanner() != null) {
             if (offering.getDeploymentPlanner().equals(this.getName())) {
                 return true;
             }
+        } else {
+            if (_globalDeploymentPlanner != null && _globalDeploymentPlanner.equals(this._name)) {
+                return true;
+            }
         }
         return false;
     }
@@ -497,6 +502,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentClusterPla
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
         super.configure(name, params);
         _allocationAlgorithm = _configDao.getValue(Config.VmAllocationAlgorithm.key());
+        _globalDeploymentPlanner = _configDao.getValue(Config.VmDeploymentPlanner.key());
         return true;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/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 71e235d..69118f1 100644
--- a/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java
+++ b/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java
@@ -16,6 +16,8 @@
 // under the License.
 package com.cloud.deploy.dao;
 
+import java.util.List;
+
 import com.cloud.deploy.PlannerHostReservationVO;
 import com.cloud.utils.db.GenericDao;
 
@@ -23,4 +25,6 @@ public interface PlannerHostReservationDao extends GenericDao<PlannerHostReserva
 
     PlannerHostReservationVO findByHostId(long hostId);
 
+    List<PlannerHostReservationVO> listAllReservedHosts();
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/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 7b12067..41e0964 100644
--- a/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java
+++ b/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java
@@ -16,6 +16,8 @@
 // under the License.
 package com.cloud.deploy.dao;
 
+import java.util.List;
+
 import javax.annotation.PostConstruct;
 import javax.ejb.Local;
 import com.cloud.deploy.PlannerHostReservationVO;
@@ -28,6 +30,7 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostRes
         PlannerHostReservationDao {
 
     private SearchBuilder<PlannerHostReservationVO> _hostIdSearch;
+    private SearchBuilder<PlannerHostReservationVO> _reservedHostSearch;
 
     public PlannerHostReservationDaoImpl() {
 
@@ -38,6 +41,10 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostRes
         _hostIdSearch = createSearchBuilder();
         _hostIdSearch.and("hostId", _hostIdSearch.entity().getHostId(), SearchCriteria.Op.EQ);
         _hostIdSearch.done();
+
+        _reservedHostSearch = createSearchBuilder();
+        _reservedHostSearch.and("usage", _reservedHostSearch.entity().getResourceUsage(), SearchCriteria.Op.NNULL);
+        _reservedHostSearch.done();
     }
 
     @Override
@@ -47,4 +54,10 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostRes
         return findOneBy(sc);
     }
 
+    @Override
+    public List<PlannerHostReservationVO> listAllReservedHosts() {
+        SearchCriteria<PlannerHostReservationVO> sc = _reservedHostSearch.create();
+        return listBy(sc);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java
index c9c3f9c..504c6c2 100755
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@ -79,6 +79,10 @@ import com.cloud.dc.dao.ClusterVSMMapDao;
 import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.dc.dao.DataCenterIpAddressDao;
 import com.cloud.dc.dao.HostPodDao;
+import com.cloud.deploy.PlannerHostReservationVO;
+import com.cloud.deploy.dao.PlannerHostReservationDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.DiscoveryException;
 import com.cloud.exception.InvalidParameterValueException;
@@ -206,6 +210,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
     protected HighAvailabilityManager        _haMgr;
     @Inject
     protected StorageService                 _storageSvr;
+    @Inject
+    PlannerHostReservationDao _plannerHostReserveDao;
 
     protected List<? extends Discoverer> _discoverers;
     public List<? extends Discoverer> getDiscoverers() {
@@ -2845,4 +2851,41 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
 				ResourceState.Enabled);
         return sc.list();
 	}
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_HOST_RESERVATION_RELEASE, eventDescription = "releasing host reservation", async = true)
+    public boolean releaseHostReservation(Long hostId) {
+        Transaction txn = Transaction.currentTxn();
+        try {
+            txn.start();
+            PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
+            if (reservationEntry != null) {
+                long id = reservationEntry.getId();
+                PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true);
+                if (hostReservation == null) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Host reservation for host: " + hostId + " does not even exist.  Release reservartion call is ignored.");
+                    }
+                    txn.rollback();
+                    return false;
+                }
+                hostReservation.setResourceUsage(null);
+                _plannerHostReserveDao.persist(hostReservation);
+                txn.commit();
+                return true;
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Host reservation for host: " + hostId
+                        + " does not even exist.  Release reservartion call is ignored.");
+            }
+            return false;
+        } catch (CloudRuntimeException e) {
+            throw e;
+        } catch (Throwable t) {
+            s_logger.error("Unable to release host reservation for host: " + hostId, t);
+            txn.rollback();
+            return false;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 93bb096..3b75a5f 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -2556,6 +2556,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
         cmdList.add(UpdateVMAffinityGroupCmd.class);
         cmdList.add(ListAffinityGroupTypesCmd.class);
         cmdList.add(ListDeploymentPlannersCmd.class);
+        cmdList.add(ReleaseHostReservationCmd.class);
 
         return cmdList;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/server/src/com/cloud/service/ServiceOfferingVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/service/ServiceOfferingVO.java b/server/src/com/cloud/service/ServiceOfferingVO.java
index 32e0e32..fd31d30 100755
--- a/server/src/com/cloud/service/ServiceOfferingVO.java
+++ b/server/src/com/cloud/service/ServiceOfferingVO.java
@@ -69,7 +69,7 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
     int sortKey;
 
     @Column(name = "deployment_planner")
-    private String deploymentPlanner = "FirstFitPlanner";
+    private String deploymentPlanner = null;
 
     protected ServiceOfferingVO() {
         super();
@@ -87,7 +87,6 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
         this.volatileVm = false;
         this.default_use = defaultUse;
         this.vm_type = vm_type == null ? null : vm_type.toString().toLowerCase();
-        this.deploymentPlanner = "FirstFitPlanner";
     }
 
     public ServiceOfferingVO(String name, int cpu, int ramSize, int speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitCpuUse, boolean volatileVm, String displayText, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vm_type, Long domainId) {
@@ -101,13 +100,11 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
         this.limitCpuUse = limitCpuUse;
         this.volatileVm = volatileVm;
         this.vm_type = vm_type == null ? null : vm_type.toString().toLowerCase();
-        this.deploymentPlanner = "FirstFitPlanner";
     }
 
     public ServiceOfferingVO(String name, int cpu, int ramSize, int speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitResourceUse, boolean volatileVm, String displayText, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vm_type, Long domainId, String hostTag) {
         this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm, displayText, useLocalStorage, recreatable, tags, systemUse, vm_type, domainId);
         this.hostTag = hostTag;
-        this.deploymentPlanner = "FirstFitPlanner";
     }
 
     public ServiceOfferingVO(String name, int cpu, int ramSize, int speed, Integer rateMbps, Integer multicastRateMbps,
@@ -116,11 +113,7 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
             String hostTag, String deploymentPlanner) {
         this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm,
                 displayText, useLocalStorage, recreatable, tags, systemUse, vm_type, domainId, hostTag);
-        if (deploymentPlanner != null) {
-            this.deploymentPlanner = deploymentPlanner;
-        } else {
-            this.deploymentPlanner = "FirstFitPlanner";
-        }
+        this.deploymentPlanner = deploymentPlanner;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/server/src/com/cloud/upgrade/dao/Upgrade410to420.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/upgrade/dao/Upgrade410to420.java b/server/src/com/cloud/upgrade/dao/Upgrade410to420.java
index 2f0c2d3..2ee86c0 100644
--- a/server/src/com/cloud/upgrade/dao/Upgrade410to420.java
+++ b/server/src/com/cloud/upgrade/dao/Upgrade410to420.java
@@ -67,7 +67,7 @@ public class Upgrade410to420 implements DbUpgrade {
         updatePrimaryStore(conn);
         addEgressFwRulesForSRXGuestNw(conn);
         upgradeEIPNetworkOfferings(conn);
-        updateServiceOfferingDeploymentPlanner(conn);
+        updateGlobalDeploymentPlanner(conn);
     }
 
     private void updateSystemVmTemplates(Connection conn) {
@@ -402,7 +402,7 @@ public class Upgrade410to420 implements DbUpgrade {
         }
     }
 
-    private void updateServiceOfferingDeploymentPlanner(Connection conn) {
+    private void updateGlobalDeploymentPlanner(Connection conn) {
         PreparedStatement pstmt = null;
         ResultSet rs = null;
 
@@ -429,13 +429,13 @@ public class Upgrade410to420 implements DbUpgrade {
                         plannerName = "UserDispersingPlanner";
                     }
                 }
-                // update service offering with the planner name
-                pstmt = conn.prepareStatement("UPDATE `cloud`.`service_offering` set deployment_planner=?");
+                // update vm.deployment.planner global config
+                pstmt = conn.prepareStatement("UPDATE `cloud`.`configuration` set value=? where name = 'vm.deployment.planner'");
                 pstmt.setString(1, plannerName);
                 pstmt.executeUpdate();
             }
         } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to set deployment_planner for service offerings", e);
+            throw new CloudRuntimeException("Unable to set vm.deployment.planner global config", e);
         } finally {
             try {
                 if (rs != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/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 5e81435..d538884 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -3066,6 +3066,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
         // Get serviceOffering for Virtual Machine
         ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId());
         String plannerName = offering.getDeploymentPlanner();
+        if (plannerName == null) {
+            plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key());
+        }
 
         String reservationId = vmEntity.reserve(plannerName, plan, new ExcludeList(), new Long(callerUser.getId()).toString());
         vmEntity.deploy(reservationId, new Long(callerUser.getId()).toString(), params);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/server/src/com/cloud/vm/dao/VMInstanceDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/dao/VMInstanceDao.java b/server/src/com/cloud/vm/dao/VMInstanceDao.java
index c604027..830e464 100644
--- a/server/src/com/cloud/vm/dao/VMInstanceDao.java
+++ b/server/src/com/cloud/vm/dao/VMInstanceDao.java
@@ -38,14 +38,14 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
      * @return list of VMInstanceVO running on that host.
      */
 	List<VMInstanceVO> listByHostId(long hostId);
-	
+
 	/**
 	 * List VMs by zone ID
 	 * @param zoneId
 	 * @return list of VMInstanceVO in the specified zone
 	 */
 	List<VMInstanceVO> listByZoneId(long zoneId);
-	
+
 	/**
      * List VMs by pod ID
      * @param podId
@@ -59,32 +59,32 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
 	 * @return list of VMInstanceVO in the specified zone, deployed from the specified template, that are not expunged
 	 */
 	public List<VMInstanceVO> listNonExpungedByZoneAndTemplate(long zoneId, long templateId);
-	
+
     /**
      * Find vm instance with names like.
-     * 
+     *
      * @param name name that fits SQL like.
      * @return list of VMInstanceVO
      */
     List<VMInstanceVO> findVMInstancesLike(String name);
-    
+
     List<VMInstanceVO> findVMInTransition(Date time, State... states);
 
     List<VMInstanceVO> listByTypes(VirtualMachine.Type... types);
-    
+
     VMInstanceVO findByIdTypes(long id, VirtualMachine.Type... types);
-    
+
     VMInstanceVO findVMByInstanceName(String name);
 
     void updateProxyId(long id, Long proxyId, Date time);
 
     List<VMInstanceVO> listByHostIdTypes(long hostid, VirtualMachine.Type... types);
-    
+
     List<VMInstanceVO> listUpByHostIdTypes(long hostid, VirtualMachine.Type... types);
     List<VMInstanceVO> listByZoneIdAndType(long zoneId, VirtualMachine.Type type);
 	List<VMInstanceVO> listUpByHostId(Long hostId);
 	List<VMInstanceVO> listByLastHostId(Long hostId);
-	
+
     List<VMInstanceVO> listByTypeAndState(VirtualMachine.Type type, State state);
 
     List<VMInstanceVO> listByAccountId(long accountId);
@@ -92,9 +92,9 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
 
     List<VMInstanceVO> listByClusterId(long clusterId);  // this does not pull up VMs which are starting
     List<VMInstanceVO> listLHByClusterId(long clusterId);  // get all the VMs even starting one on this cluster
-    
+
     List<VMInstanceVO> listVmsMigratingFromHost(Long hostId);
-    
+
     public Long countRunningByHostId(long hostId);
 
     Pair<List<Long>, Map<Long, Double>> listClusterIdsInZoneByVmCount(long zoneId, long accountId);
@@ -106,7 +106,7 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
     List<Long> listHostIdsByVmCount(long dcId, Long podId, Long clusterId, long accountId);
 
     Long countRunningByAccount(long accountId);
-    
+
     List<VMInstanceVO> listNonRemovedVmsByTypeAndNetwork(long networkId, VirtualMachine.Type... types);
 
     /**
@@ -116,4 +116,8 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
      */
     List<String> listDistinctHostNames(long networkId, VirtualMachine.Type... types);
 
+    List<VMInstanceVO> findByHostInStates(Long hostId, State... states);
+
+    List<VMInstanceVO> listStartingWithNoHostId();
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java
index 7198b7c..ffb1a0b 100644
--- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java
+++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java
@@ -5,7 +5,7 @@
 // to you under the Apache License, Version 2.0 (the
 // "License"); you may not use this file except in compliance
 // with the License.  You may obtain a copy of the License at
-// 
+//
 //   http://www.apache.org/licenses/LICENSE-2.0
 //
 // Unless required by applicable law or agreed to in writing,
@@ -83,30 +83,32 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
     protected GenericSearchBuilder<VMInstanceVO, Long> CountRunningByAccount;
     protected SearchBuilder<VMInstanceVO> NetworkTypeSearch;
     protected GenericSearchBuilder<VMInstanceVO, String> DistinctHostNameSearch;
-    
+    protected SearchBuilder<VMInstanceVO> HostAndStateSearch;
+    protected SearchBuilder<VMInstanceVO> StartingWithNoHostSearch;
+
     @Inject ResourceTagDao _tagsDao;
     @Inject NicDao _nicDao;
-    
+
     protected Attribute _updateTimeAttr;
-    
-    private static final String ORDER_CLUSTERS_NUMBER_OF_VMS_FOR_ACCOUNT_PART1 = 
+
+    private static final String ORDER_CLUSTERS_NUMBER_OF_VMS_FOR_ACCOUNT_PART1 =
             "SELECT host.cluster_id, SUM(IF(vm.state='Running' AND vm.account_id = ?, 1, 0)) FROM `cloud`.`host` host LEFT JOIN `cloud`.`vm_instance` vm ON host.id = vm.host_id WHERE ";
     private static final String ORDER_CLUSTERS_NUMBER_OF_VMS_FOR_ACCOUNT_PART2 =
             " AND host.type = 'Routing' GROUP BY host.cluster_id ORDER BY 2 ASC ";
-    
+
     private static final String ORDER_PODS_NUMBER_OF_VMS_FOR_ACCOUNT = "SELECT pod.id, SUM(IF(vm.state='Running' AND vm.account_id = ?, 1, 0)) FROM `cloud`.`host_pod_ref` pod LEFT JOIN `cloud`.`vm_instance` vm ON pod.id = vm.pod_id WHERE pod.data_center_id = ? " +
                                                                        " GROUP BY pod.id ORDER BY 2 ASC ";
-    
+
     private static final String ORDER_HOSTS_NUMBER_OF_VMS_FOR_ACCOUNT =
             "SELECT host.id, SUM(IF(vm.state='Running' AND vm.account_id = ?, 1, 0)) FROM `cloud`.`host` host LEFT JOIN `cloud`.`vm_instance` vm ON host.id = vm.host_id WHERE host.data_center_id = ? " +
     		                                                            " AND host.pod_id = ? AND host.cluster_id = ? AND host.type = 'Routing' " +
     		                                                            " GROUP BY host.id ORDER BY 2 ASC ";
 
     @Inject protected HostDao _hostDao;
-    
+
     public VMInstanceDaoImpl() {
     }
-    
+
     @PostConstruct
     protected void init() {
 
@@ -114,14 +116,14 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         IdStatesSearch.and("id", IdStatesSearch.entity().getId(), Op.EQ);
         IdStatesSearch.and("states", IdStatesSearch.entity().getState(), Op.IN);
         IdStatesSearch.done();
-               
+
         VMClusterSearch = createSearchBuilder();
         SearchBuilder<HostVO> hostSearch = _hostDao.createSearchBuilder();
         VMClusterSearch.join("hostSearch", hostSearch, hostSearch.entity().getId(), VMClusterSearch.entity().getHostId(), JoinType.INNER);
         hostSearch.and("clusterId", hostSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
         VMClusterSearch.done();
 
-        
+
         LHVMClusterSearch = createSearchBuilder();
         SearchBuilder<HostVO> hostSearch1 = _hostDao.createSearchBuilder();
         LHVMClusterSearch.join("hostSearch1", hostSearch1, hostSearch1.entity().getId(), LHVMClusterSearch.entity().getLastHostId(), JoinType.INNER);
@@ -129,7 +131,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         hostSearch1.and("clusterId", hostSearch1.entity().getClusterId(), SearchCriteria.Op.EQ);
         LHVMClusterSearch.done();
 
-        
+
         AllFieldsSearch = createSearchBuilder();
         AllFieldsSearch.and("host", AllFieldsSearch.entity().getHostId(), Op.EQ);
         AllFieldsSearch.and("lastHost", AllFieldsSearch.entity().getLastHostId(), Op.EQ);
@@ -169,23 +171,23 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         IdTypesSearch.and("id", IdTypesSearch.entity().getId(), Op.EQ);
         IdTypesSearch.and("types", IdTypesSearch.entity().getType(), Op.IN);
         IdTypesSearch.done();
-        
+
         HostIdTypesSearch = createSearchBuilder();
         HostIdTypesSearch.and("hostid", HostIdTypesSearch.entity().getHostId(), Op.EQ);
         HostIdTypesSearch.and("types", HostIdTypesSearch.entity().getType(), Op.IN);
         HostIdTypesSearch.done();
-        
+
         HostIdUpTypesSearch = createSearchBuilder();
         HostIdUpTypesSearch.and("hostid", HostIdUpTypesSearch.entity().getHostId(), Op.EQ);
         HostIdUpTypesSearch.and("types", HostIdUpTypesSearch.entity().getType(), Op.IN);
         HostIdUpTypesSearch.and("states", HostIdUpTypesSearch.entity().getState(), Op.NIN);
         HostIdUpTypesSearch.done();
-        
+
         HostUpSearch = createSearchBuilder();
         HostUpSearch.and("host", HostUpSearch.entity().getHostId(), Op.EQ);
         HostUpSearch.and("states", HostUpSearch.entity().getState(), Op.IN);
         HostUpSearch.done();
-        
+
         InstanceNameSearch = createSearchBuilder();
         InstanceNameSearch.and("instanceName", InstanceNameSearch.entity().getInstanceName(), Op.EQ);
         InstanceNameSearch.done();
@@ -194,21 +196,31 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         CountVirtualRoutersByAccount.select(null, Func.COUNT, null);
         CountVirtualRoutersByAccount.and("account", CountVirtualRoutersByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
         CountVirtualRoutersByAccount.and("type", CountVirtualRoutersByAccount.entity().getType(), SearchCriteria.Op.EQ);
-        CountVirtualRoutersByAccount.and("state", CountVirtualRoutersByAccount.entity().getState(), SearchCriteria.Op.NIN);        
+        CountVirtualRoutersByAccount.and("state", CountVirtualRoutersByAccount.entity().getState(), SearchCriteria.Op.NIN);
         CountVirtualRoutersByAccount.done();
-        
+
         CountRunningByHost = createSearchBuilder(Long.class);
         CountRunningByHost.select(null, Func.COUNT, null);
         CountRunningByHost.and("host", CountRunningByHost.entity().getHostId(), SearchCriteria.Op.EQ);
         CountRunningByHost.and("state", CountRunningByHost.entity().getState(), SearchCriteria.Op.EQ);
-        CountRunningByHost.done();        
+        CountRunningByHost.done();
 
         CountRunningByAccount = createSearchBuilder(Long.class);
         CountRunningByAccount.select(null, Func.COUNT, null);
         CountRunningByAccount.and("account", CountRunningByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
         CountRunningByAccount.and("state", CountRunningByAccount.entity().getState(), SearchCriteria.Op.EQ);
-        CountRunningByAccount.done();        
-        
+        CountRunningByAccount.done();
+
+        HostAndStateSearch = createSearchBuilder();
+        HostAndStateSearch.and("host", HostAndStateSearch.entity().getHostId(), Op.EQ);
+        HostAndStateSearch.and("states", HostAndStateSearch.entity().getState(), Op.IN);
+        HostAndStateSearch.done();
+
+        StartingWithNoHostSearch = createSearchBuilder();
+        StartingWithNoHostSearch.and("state", StartingWithNoHostSearch.entity().getState(), Op.EQ);
+        StartingWithNoHostSearch.and("host", StartingWithNoHostSearch.entity().getHostId(), Op.NULL);
+        StartingWithNoHostSearch.done();
+
         _updateTimeAttr = _allAttributes.get("updateTime");
         assert _updateTimeAttr != null : "Couldn't get this updateTime attribute";
     }
@@ -219,7 +231,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         sc.setParameters("account", accountId);
         return listBy(sc);
     }
-    
+
     @Override
     public List<VMInstanceVO> findVMInstancesLike(String name) {
         SearchCriteria<VMInstanceVO> sc = NameLikeSearch.create();
@@ -234,7 +246,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
 
         return listBy(sc);
     }
-    
+
     @Override
     public List<VMInstanceVO> listByZoneId(long zoneId) {
         SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
@@ -242,7 +254,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
 
         return listBy(sc);
     }
-    
+
     @Override
     public List<VMInstanceVO> listByPodId(long podId) {
         SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
@@ -263,7 +275,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         sc.setJoinParameters("hostSearch1", "clusterId", clusterId);
         return listBy(sc);
     }
-    
+
     @Override
     public List<VMInstanceVO> listByZoneIdAndType(long zoneId, VirtualMachine.Type type) {
         SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
@@ -271,8 +283,8 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         sc.setParameters("type", type.toString());
         return listBy(sc);
     }
-    
-    
+
+
     @Override
     public List<VMInstanceVO> listNonExpungedByZoneAndTemplate(long zoneId, long templateId) {
         SearchCriteria<VMInstanceVO> sc = ZoneTemplateNonExpungedSearch.create();
@@ -310,7 +322,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging});
         return listBy(sc);
     }
-    
+
     @Override
     public List<VMInstanceVO> listUpByHostId(Long hostId) {
         SearchCriteria<VMInstanceVO> sc = HostUpSearch.create();
@@ -318,14 +330,14 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         sc.setParameters("states", new Object[] {State.Starting, State.Running});
         return listBy(sc);
     }
-    
+
     @Override
     public List<VMInstanceVO> listByTypes(Type... types) {
         SearchCriteria<VMInstanceVO> sc = TypesSearch.create();
         sc.setParameters("types", (Object[]) types);
         return listBy(sc);
     }
-    
+
     @Override
     public List<VMInstanceVO> listByTypeAndState(VirtualMachine.Type type, State state) {
         SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
@@ -348,7 +360,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         sc.setParameters("instanceName", name);
         return findOneBy(sc);
     }
-   
+
     @Override
     public void updateProxyId(long id, Long proxyId, Date time) {
         VMInstanceVO vo = createForUpdate();
@@ -369,12 +381,12 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
     	@SuppressWarnings("unchecked")
 		Pair<Long, Long> hosts = (Pair<Long,Long>)opaque;
 		Long newHostId = hosts.second();
-    	
+
     	VMInstanceVO vmi = (VMInstanceVO)vm;
     	Long oldHostId = vmi.getHostId();
     	Long oldUpdated = vmi.getUpdated();
     	Date oldUpdateDate = vmi.getUpdateTime();
-    	
+
     	SearchCriteria<VMInstanceVO> sc = StateChangeSearch.create();
     	sc.setParameters("id", vmi.getId());
     	sc.setParameters("states", oldState);
@@ -383,7 +395,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
 
     	vmi.incrUpdated();
     	UpdateBuilder ub = getUpdateBuilder(vmi);
-    	
+
     	ub.set(vmi, "state", newState);
     	ub.set(vmi, "hostId", newHostId);
     	ub.set(vmi, "podIdToDeployIn", vmi.getPodIdToDeployIn());
@@ -393,7 +405,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
     	if (result == 0 && s_logger.isDebugEnabled()) {
 
     		VMInstanceVO vo = findByIdIncludingRemoved(vm.getId());
-    		
+
     		if (vo != null) {
         		StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
         		str.append(": DB Data={Host=").append(vo.getHostId()).append("; State=").append(vo.getState().toString()).append("; updated=").append(vo.getUpdated()).append("; time=").append(vo.getUpdateTime());
@@ -407,7 +419,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
     	}
     	return result > 0;
     }
-    
+
     @Override
 	public List<VMInstanceVO> listByLastHostId(Long hostId) {
 		SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
@@ -415,7 +427,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
 		sc.setParameters("state", State.Stopped);
 		return listBy(sc);
 	}
-    
+
     @Override
     public Long countAllocatedVirtualRoutersForAccount(long accountId) {
     	SearchCriteria<Long> sc = CountVirtualRoutersByAccount.create();
@@ -424,7 +436,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
 		sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging});
         return customSearch(sc, null).get(0);
     }
-    
+
     @Override
     public List<VMInstanceVO> listVmsMigratingFromHost(Long hostId) {
         SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
@@ -432,7 +444,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         sc.setParameters("state", State.Migrating);
         return listBy(sc);
     }
-    
+
     @Override
     public Long countRunningByHostId(long hostId){
         SearchCriteria<Long> sc = CountRunningByHost.create();
@@ -455,7 +467,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
             pstmt = txn.prepareAutoCloseStatement(sql.toString());
             pstmt.setLong(1, accountId);
             pstmt.setLong(2, zoneId);
-            
+
             ResultSet rs = pstmt.executeQuery();
             while (rs.next()) {
                 Long clusterId = rs.getLong(1);
@@ -484,11 +496,11 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
             pstmt = txn.prepareAutoCloseStatement(sql.toString());
             pstmt.setLong(1, accountId);
             pstmt.setLong(2, podId);
-            
+
             ResultSet rs = pstmt.executeQuery();
             while (rs.next()) {
                 Long clusterId = rs.getLong(1);
-                result.add(clusterId);                
+                result.add(clusterId);
                 clusterVmCountMap.put(clusterId, rs.getDouble(2));
             }
             return new Pair<List<Long>, Map<Long, Double>>(result, clusterVmCountMap);
@@ -511,11 +523,11 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
             pstmt = txn.prepareAutoCloseStatement(sql);
             pstmt.setLong(1, accountId);
             pstmt.setLong(2, dataCenterId);
-            
+
             ResultSet rs = pstmt.executeQuery();
             while (rs.next()) {
                 Long podId = rs.getLong(1);
-                result.add(podId);                
+                result.add(podId);
                 podVmCountMap.put(podId, rs.getDouble(2));
             }
             return new Pair<List<Long>, Map<Long, Double>>(result, podVmCountMap);
@@ -523,7 +535,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
             throw new CloudRuntimeException("DB Exception on: " + ORDER_PODS_NUMBER_OF_VMS_FOR_ACCOUNT, e);
         } catch (Throwable e) {
             throw new CloudRuntimeException("Caught: " + ORDER_PODS_NUMBER_OF_VMS_FOR_ACCOUNT, e);
-        }        
+        }
     }
 
     @Override
@@ -538,7 +550,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
             pstmt.setLong(2, dcId);
             pstmt.setLong(3, podId);
             pstmt.setLong(4, clusterId);
-            
+
             ResultSet rs = pstmt.executeQuery();
             while (rs.next()) {
                 result.add(rs.getLong(1));
@@ -548,9 +560,9 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
             throw new CloudRuntimeException("DB Exception on: " + ORDER_PODS_NUMBER_OF_VMS_FOR_ACCOUNT, e);
         } catch (Throwable e) {
             throw new CloudRuntimeException("Caught: " + ORDER_PODS_NUMBER_OF_VMS_FOR_ACCOUNT, e);
-        }   
+        }
     }
-    
+
     @Override
     public Long countRunningByAccount(long accountId){
         SearchCriteria<Long> sc = CountRunningByAccount.create();
@@ -558,18 +570,18 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         sc.setParameters("state", State.Running);
         return customSearch(sc, null).get(0);
     }
-    
+
     @Override
     public List<VMInstanceVO> listNonRemovedVmsByTypeAndNetwork(long networkId, VirtualMachine.Type... types) {
         if (NetworkTypeSearch == null) {
-            
+
             SearchBuilder<NicVO> nicSearch = _nicDao.createSearchBuilder();
             nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
 
             NetworkTypeSearch = createSearchBuilder();
             NetworkTypeSearch.and("types", NetworkTypeSearch.entity().getType(), SearchCriteria.Op.IN);
             NetworkTypeSearch.and("removed", NetworkTypeSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
-            NetworkTypeSearch.join("nicSearch", nicSearch, NetworkTypeSearch.entity().getId(), 
+            NetworkTypeSearch.join("nicSearch", nicSearch, NetworkTypeSearch.entity().getId(),
                     nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
             NetworkTypeSearch.done();
         }
@@ -577,27 +589,27 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         SearchCriteria<VMInstanceVO> sc = NetworkTypeSearch.create();
         if (types != null && types.length != 0) {
             sc.setParameters("types", (Object[]) types);
-        }        
+        }
         sc.setJoinParameters("nicSearch", "networkId", networkId);
 
         return listBy(sc);
     }
-    
-    
-    
+
+
+
     @Override
     public List<String> listDistinctHostNames(long networkId, VirtualMachine.Type... types) {
         if (DistinctHostNameSearch == null) {
-            
+
             SearchBuilder<NicVO> nicSearch = _nicDao.createSearchBuilder();
             nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
 
             DistinctHostNameSearch = createSearchBuilder(String.class);
             DistinctHostNameSearch.selectField(DistinctHostNameSearch.entity().getHostName());
-            
+
             DistinctHostNameSearch.and("types", DistinctHostNameSearch.entity().getType(), SearchCriteria.Op.IN);
             DistinctHostNameSearch.and("removed", DistinctHostNameSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
-            DistinctHostNameSearch.join("nicSearch", nicSearch, DistinctHostNameSearch.entity().getId(), 
+            DistinctHostNameSearch.join("nicSearch", nicSearch, DistinctHostNameSearch.entity().getId(),
                     nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
             DistinctHostNameSearch.done();
         }
@@ -605,12 +617,12 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         SearchCriteria<String> sc = DistinctHostNameSearch.create();
         if (types != null && types.length != 0) {
             sc.setParameters("types", (Object[]) types);
-        }        
+        }
         sc.setJoinParameters("nicSearch", "networkId", networkId);
 
         return  customSearch(sc, null);
     }
-    
+
     @Override
     @DB
     public boolean remove(Long id) {
@@ -625,4 +637,19 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
         return result;
     }
 
+    @Override
+    public List<VMInstanceVO> findByHostInStates(Long hostId, State... states) {
+        SearchCriteria<VMInstanceVO> sc = HostAndStateSearch.create();
+        sc.setParameters("host", hostId);
+        sc.setParameters("states", (Object[]) states);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VMInstanceVO> listStartingWithNoHostId() {
+        SearchCriteria<VMInstanceVO> sc = StartingWithNoHostSearch.create();
+        sc.setParameters("state", State.Starting);
+        return listBy(sc);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/server/test/com/cloud/resource/MockResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/resource/MockResourceManagerImpl.java b/server/test/com/cloud/resource/MockResourceManagerImpl.java
index 5202c31..1fff3a6 100644
--- a/server/test/com/cloud/resource/MockResourceManagerImpl.java
+++ b/server/test/com/cloud/resource/MockResourceManagerImpl.java
@@ -608,4 +608,10 @@ public class MockResourceManagerImpl extends ManagerBase implements ResourceMana
 		return null;
 	}
 
+    @Override
+    public boolean releaseHostReservation(Long hostId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e792eb9/setup/db/db/schema-410to420.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql
index 2e3bcb5..1c82868 100644
--- a/setup/db/db/schema-410to420.sql
+++ b/setup/db/db/schema-410to420.sql
@@ -934,7 +934,10 @@ CREATE TABLE `cloud`.`op_host_planner_reservation` (
   CONSTRAINT `fk_planner_reservation__cluster_id` FOREIGN KEY (`cluster_id`) REFERENCES `cloud`.`cluster`(`id`) ON DELETE CASCADE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
-ALTER TABLE `cloud`.`service_offering` ADD COLUMN `deployment_planner` varchar(255) NOT NULL DEFAULT 'FirstFitPlanner'  COMMENT 'Planner heuristics used to deploy a VM of this offering';
+ALTER TABLE `cloud`.`service_offering` ADD COLUMN `deployment_planner` varchar(255) COMMENT 'Planner heuristics used to deploy a VM of this offering; if null global config vm.deployment.planner is used';
+
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.deployment.planner', 'FirstFitPlanner', '[''FirstFitPlanner'', ''UserDispersingPlanner'', ''UserConcentratedPodPlanner'']: DeploymentPlanner heuristic that will be used for VM deployment.');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'host.reservation.release.period', '300000', 'The interval in milliseconds between host reservation release checks');
 
 DROP VIEW IF EXISTS `cloud`.`service_offering_view`;
 CREATE VIEW `cloud`.`service_offering_view` AS


Mime
View raw message