You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by pr...@apache.org on 2014/02/05 00:39:32 UTC

[48/50] [abbrv] Merge branch 'master' into rbac

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f8437544/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
index 28eecf1,3c87b24..ee8cc4d
--- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
+++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
@@@ -1,56 -1,57 +1,57 @@@
 -// 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 com.cloud.deploy;
 -
 -import java.util.ArrayList;
 +// 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 com.cloud.deploy;
 +
 +import java.util.ArrayList;
+ import java.util.Arrays;
 -import java.util.Comparator;
 -import java.util.HashMap;
 +import java.util.Comparator;
 +import java.util.HashMap;
  import java.util.HashSet;
 -import java.util.List;
 -import java.util.Map;
 +import java.util.List;
 +import java.util.Map;
  import java.util.Set;
 -import java.util.Timer;
 -import java.util.TreeSet;
 -
 -import javax.ejb.Local;
 -import javax.inject.Inject;
 -import javax.naming.ConfigurationException;
 -
 +import java.util.Timer;
 +import java.util.TreeSet;
 +
 +import javax.ejb.Local;
 +import javax.inject.Inject;
 +import javax.naming.ConfigurationException;
 +
  import org.apache.log4j.Logger;
  
 -import org.apache.cloudstack.affinity.AffinityGroupProcessor;
 -import org.apache.cloudstack.affinity.AffinityGroupService;
 +import org.apache.cloudstack.affinity.AffinityGroupProcessor;
 +import org.apache.cloudstack.affinity.AffinityGroupService;
  import org.apache.cloudstack.affinity.AffinityGroupVMMapVO;
 -import org.apache.cloudstack.affinity.AffinityGroupVO;
 -import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
 -import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
 -import org.apache.cloudstack.engine.cloud.entity.api.db.VMReservationVO;
 -import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMReservationDao;
 -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 -import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
 -import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 -import org.apache.cloudstack.framework.messagebus.MessageBus;
 -import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
 -import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
 -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 -import org.apache.cloudstack.utils.identity.ManagementServerNode;
 -
 +import org.apache.cloudstack.affinity.AffinityGroupVO;
 +import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
 +import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
 +import org.apache.cloudstack.engine.cloud.entity.api.db.VMReservationVO;
 +import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMReservationDao;
 +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 +import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
 +import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 +import org.apache.cloudstack.framework.messagebus.MessageBus;
 +import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
 +import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
 +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 +import org.apache.cloudstack.utils.identity.ManagementServerNode;
 +
  import com.cloud.agent.AgentManager;
  import com.cloud.agent.Listener;
  import com.cloud.agent.api.AgentControlAnswer;
@@@ -60,120 -61,121 +61,121 @@@ import com.cloud.agent.api.Command
  import com.cloud.agent.api.StartupCommand;
  import com.cloud.agent.api.StartupRoutingCommand;
  import com.cloud.agent.manager.allocator.HostAllocator;
 -import com.cloud.capacity.CapacityManager;
 -import com.cloud.capacity.dao.CapacityDao;
 -import com.cloud.configuration.Config;
 -import com.cloud.dc.ClusterDetailsDao;
 -import com.cloud.dc.ClusterDetailsVO;
 -import com.cloud.dc.ClusterVO;
 -import com.cloud.dc.DataCenter;
 -import com.cloud.dc.DataCenterVO;
 +import com.cloud.capacity.CapacityManager;
 +import com.cloud.capacity.dao.CapacityDao;
 +import com.cloud.configuration.Config;
 +import com.cloud.dc.ClusterDetailsDao;
 +import com.cloud.dc.ClusterDetailsVO;
 +import com.cloud.dc.ClusterVO;
 +import com.cloud.dc.DataCenter;
 +import com.cloud.dc.DataCenterVO;
  import com.cloud.dc.DedicatedResourceVO;
 -import com.cloud.dc.Pod;
 -import com.cloud.dc.dao.ClusterDao;
 -import com.cloud.dc.dao.DataCenterDao;
 +import com.cloud.dc.Pod;
 +import com.cloud.dc.dao.ClusterDao;
 +import com.cloud.dc.dao.DataCenterDao;
  import com.cloud.dc.dao.DedicatedResourceDao;
 -import com.cloud.dc.dao.HostPodDao;
 -import com.cloud.deploy.DeploymentPlanner.ExcludeList;
 -import com.cloud.deploy.DeploymentPlanner.PlannerResourceUsage;
 -import com.cloud.deploy.dao.PlannerHostReservationDao;
 -import com.cloud.exception.AffinityConflictException;
 -import com.cloud.exception.ConnectionException;
 -import com.cloud.exception.InsufficientServerCapacityException;
 -import com.cloud.host.Host;
 -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.offering.ServiceOffering;
 -import com.cloud.org.Cluster;
 -import com.cloud.org.Grouping;
 -import com.cloud.resource.ResourceState;
 -import com.cloud.storage.DiskOfferingVO;
 -import com.cloud.storage.ScopeType;
 +import com.cloud.dc.dao.HostPodDao;
 +import com.cloud.deploy.DeploymentPlanner.ExcludeList;
 +import com.cloud.deploy.DeploymentPlanner.PlannerResourceUsage;
 +import com.cloud.deploy.dao.PlannerHostReservationDao;
 +import com.cloud.exception.AffinityConflictException;
 +import com.cloud.exception.ConnectionException;
 +import com.cloud.exception.InsufficientServerCapacityException;
 +import com.cloud.host.Host;
 +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.offering.ServiceOffering;
 +import com.cloud.org.Cluster;
 +import com.cloud.org.Grouping;
 +import com.cloud.resource.ResourceState;
 +import com.cloud.storage.DiskOfferingVO;
 +import com.cloud.storage.ScopeType;
+ import com.cloud.storage.Storage;
 -import com.cloud.storage.StorageManager;
 -import com.cloud.storage.StoragePool;
 -import com.cloud.storage.StoragePoolHostVO;
 -import com.cloud.storage.Volume;
 -import com.cloud.storage.VolumeVO;
 -import com.cloud.storage.dao.DiskOfferingDao;
 -import com.cloud.storage.dao.GuestOSCategoryDao;
 -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.Manager;
 -import com.cloud.utils.component.ManagerBase;
 -import com.cloud.utils.db.DB;
 -import com.cloud.utils.db.SearchCriteria;
 -import com.cloud.utils.db.Transaction;
 -import com.cloud.utils.db.TransactionCallback;
 -import com.cloud.utils.db.TransactionStatus;
 +import com.cloud.storage.StorageManager;
 +import com.cloud.storage.StoragePool;
 +import com.cloud.storage.StoragePoolHostVO;
 +import com.cloud.storage.Volume;
 +import com.cloud.storage.VolumeVO;
 +import com.cloud.storage.dao.DiskOfferingDao;
 +import com.cloud.storage.dao.GuestOSCategoryDao;
 +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.Manager;
 +import com.cloud.utils.component.ManagerBase;
 +import com.cloud.utils.db.DB;
 +import com.cloud.utils.db.SearchCriteria;
 +import com.cloud.utils.db.Transaction;
 +import com.cloud.utils.db.TransactionCallback;
 +import com.cloud.utils.db.TransactionStatus;
  import com.cloud.utils.exception.CloudRuntimeException;
 -import com.cloud.utils.fsm.StateListener;
 -import com.cloud.vm.DiskProfile;
 -import com.cloud.vm.ReservationContext;
 -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.utils.fsm.StateListener;
 +import com.cloud.vm.DiskProfile;
 +import com.cloud.vm.ReservationContext;
 +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.VirtualMachineProfile;
 -import com.cloud.vm.dao.UserVmDao;
 -import com.cloud.vm.dao.VMInstanceDao;
 -
 +import com.cloud.vm.dao.UserVmDao;
 +import com.cloud.vm.dao.VMInstanceDao;
 +
  @Local(value = {DeploymentPlanningManager.class})
 -public class DeploymentPlanningManagerImpl extends ManagerBase implements DeploymentPlanningManager, Manager, Listener,
 -        StateListener<State, VirtualMachine.Event, VirtualMachine> {
 -
 -    private static final Logger s_logger = Logger.getLogger(DeploymentPlanningManagerImpl.class);
 -    @Inject
 -    AgentManager _agentMgr;
 -    @Inject
 -    protected UserVmDao _vmDao;
 -    @Inject
 -    protected VMInstanceDao _vmInstanceDao;
 -    @Inject
 -    protected AffinityGroupDao _affinityGroupDao;
 -    @Inject
 -    protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
 -    @Inject
 -    AffinityGroupService _affinityGroupService;
 -    @Inject
 -    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
 -    @Inject
 -    protected VMReservationDao _reservationDao;
 -
 -    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() {
 -        return _storagePoolAllocators;
 -    }
 +public class DeploymentPlanningManagerImpl extends ManagerBase implements DeploymentPlanningManager, Manager, Listener,
 +        StateListener<State, VirtualMachine.Event, VirtualMachine> {
 +
 +    private static final Logger s_logger = Logger.getLogger(DeploymentPlanningManagerImpl.class);
 +    @Inject
 +    AgentManager _agentMgr;
 +    @Inject
 +    protected UserVmDao _vmDao;
 +    @Inject
 +    protected VMInstanceDao _vmInstanceDao;
 +    @Inject
 +    protected AffinityGroupDao _affinityGroupDao;
 +    @Inject
 +    protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
 +    @Inject
 +    AffinityGroupService _affinityGroupService;
 +    @Inject
 +    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
 +    @Inject
 +    protected VMReservationDao _reservationDao;
 +
 +    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() {
 +        return _storagePoolAllocators;
 +    }
  
      public void setStoragePoolAllocators(List<StoragePoolAllocator> storagePoolAllocators) {
-         this._storagePoolAllocators = storagePoolAllocators;
+         _storagePoolAllocators = storagePoolAllocators;
 -    }
 +    }
 +
 +    protected List<HostAllocator> _hostAllocators;
  
 -    protected List<HostAllocator> _hostAllocators;
 -
 -    public List<HostAllocator> getHostAllocators() {
 -        return _hostAllocators;
 -    }
 +    public List<HostAllocator> getHostAllocators() {
 +        return _hostAllocators;
 +    }
  
      public void setHostAllocators(List<HostAllocator> hostAllocators) {
-         this._hostAllocators = hostAllocators;
+         _hostAllocators = hostAllocators;
      }
  
      @Inject
@@@ -211,296 -213,315 +213,315 @@@
      DataStoreManager dataStoreMgr;
      @Inject
      protected ClusterDetailsDao _clusterDetailsDao;
 +
 +    protected List<DeploymentPlanner> _planners;
  
 -    protected List<DeploymentPlanner> _planners;
 -
 -    public List<DeploymentPlanner> getPlanners() {
 -        return _planners;
 -    }
 +    public List<DeploymentPlanner> getPlanners() {
 +        return _planners;
 +    }
  
      public void setPlanners(List<DeploymentPlanner> planners) {
-         this._planners = planners;
+         _planners = planners;
 -    }
 -
 -    protected List<AffinityGroupProcessor> _affinityProcessors;
 +    }
 +
 +    protected List<AffinityGroupProcessor> _affinityProcessors;
  
 -    public List<AffinityGroupProcessor> getAffinityGroupProcessors() {
 -        return _affinityProcessors;
 -    }
 +    public List<AffinityGroupProcessor> getAffinityGroupProcessors() {
 +        return _affinityProcessors;
 +    }
  
 -    public void setAffinityGroupProcessors(List<AffinityGroupProcessor> affinityProcessors) {
 +    public void setAffinityGroupProcessors(List<AffinityGroupProcessor> affinityProcessors) {
-         this._affinityProcessors = affinityProcessors;
+         _affinityProcessors = affinityProcessors;
 -    }
 -
 -    @Override
 +    }
 +
 +    @Override
      public DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids, DeploymentPlanner planner)
              throws InsufficientServerCapacityException, AffinityConflictException {
 -
 -        // call affinitygroup chain
 -        VirtualMachine vm = vmProfile.getVirtualMachine();
 -        long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId());
 +
 +        // call affinitygroup chain
 +        VirtualMachine vm = vmProfile.getVirtualMachine();
 +        long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId());
          DataCenter dc = _dcDao.findById(vm.getDataCenterId());
 -
 -        if (vmGroupCount > 0) {
 -            for (AffinityGroupProcessor processor : _affinityProcessors) {
 -                processor.process(vmProfile, plan, avoids);
 -            }
 +
 +        if (vmGroupCount > 0) {
 +            for (AffinityGroupProcessor processor : _affinityProcessors) {
 +                processor.process(vmProfile, plan, avoids);
 +            }
 +        }
 +
 +        if (vm.getType() == VirtualMachine.Type.User) {
 +            checkForNonDedicatedResources(vmProfile, dc, avoids);
          }
 -
 -        if (vm.getType() == VirtualMachine.Type.User) {
 -            checkForNonDedicatedResources(vmProfile, dc, avoids);
 -        }
 -        if (s_logger.isDebugEnabled()) {
 +        if (s_logger.isDebugEnabled()) {
              s_logger.debug("Deploy avoids pods: " + avoids.getPodsToAvoid() + ", clusters: " + avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid());
 -        }
 -
 -        // call planners
 +        }
 +
 +        // call planners
          //DataCenter dc = _dcDao.findById(vm.getDataCenterId());
 -        // check if datacenter is in avoid set
 -        if (avoids.shouldAvoid(dc)) {
 -            if (s_logger.isDebugEnabled()) {
 +        // check if datacenter is in avoid set
 +        if (avoids.shouldAvoid(dc)) {
 +            if (s_logger.isDebugEnabled()) {
                  s_logger.debug("DataCenter id = '" + dc.getId() + "' provided is in avoid set, DeploymentPlanner cannot allocate the VM, returning.");
 -            }
 -            return null;
 -        }
 -
 -        ServiceOffering offering = vmProfile.getServiceOffering();
 +            }
 +            return null;
 +        }
 +
 +        ServiceOffering offering = vmProfile.getServiceOffering();
          if(planner == null){
 -            String plannerName = offering.getDeploymentPlanner();
 -            if (plannerName == null) {
 -                if (vm.getHypervisorType() == HypervisorType.BareMetal) {
 -                    plannerName = "BareMetalPlanner";
 -                } else {
 -                    plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key());
 -                }
 -            }
 -            for (DeploymentPlanner plannerInList : _planners) {
 -                if (plannerName.equals(plannerInList.getName())) {
 -                    planner = plannerInList;
 -                    break;
 -                }
 -            }
 +        String plannerName = offering.getDeploymentPlanner();
 +        if (plannerName == null) {
 +            if (vm.getHypervisorType() == HypervisorType.BareMetal) {
 +                plannerName = "BareMetalPlanner";
 +            } else {
 +                plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key());
 +            }
 +        }
 +        for (DeploymentPlanner plannerInList : _planners) {
 +            if (plannerName.equals(plannerInList.getName())) {
 +                planner = plannerInList;
 +                break;
 +            }
 +        }
          }
 -
 -        int cpu_requested = offering.getCpu() * offering.getSpeed();
 -        long ram_requested = offering.getRamSize() * 1024L * 1024L;
 -
 -        if (s_logger.isDebugEnabled()) {
 -            s_logger.debug("DeploymentPlanner allocation algorithm: " + planner);
 -
 +
 +        int cpu_requested = offering.getCpu() * offering.getSpeed();
 +        long ram_requested = offering.getRamSize() * 1024L * 1024L;
 +
 +        if (s_logger.isDebugEnabled()) {
 +            s_logger.debug("DeploymentPlanner allocation algorithm: " + planner);
 +
              s_logger.debug("Trying to allocate a host and storage pools from dc:" + plan.getDataCenterId() + ", pod:" + plan.getPodId() + ",cluster:" +
                  plan.getClusterId() + ", requested cpu: " + cpu_requested + ", requested ram: " + ram_requested);
 -
 +
              s_logger.debug("Is ROOT volume READY (pool already allocated)?: " + (plan.getPoolId() != null ? "Yes" : "No"));
 -        }
 -
 +        }
 +
          String haVmTag = (String)vmProfile.getParameter(VirtualMachineProfile.Param.HaTag);
 -
 -        if (plan.getHostId() != null && haVmTag == null) {
 -            Long hostIdSpecified = plan.getHostId();
 -            if (s_logger.isDebugEnabled()) {
 +
 +        if (plan.getHostId() != null && haVmTag == null) {
 +            Long hostIdSpecified = plan.getHostId();
 +            if (s_logger.isDebugEnabled()) {
                  s_logger.debug("DeploymentPlan has host_id specified, choosing this host and making no checks on this host: " + hostIdSpecified);
 -            }
 -            HostVO host = _hostDao.findById(hostIdSpecified);
 -            if (host == null) {
 -                s_logger.debug("The specified host cannot be found");
 -            } else if (avoids.shouldAvoid(host)) {
 -                s_logger.debug("The specified host is in avoid set");
 -            } else {
 -                if (s_logger.isDebugEnabled()) {
 +            }
 +            HostVO host = _hostDao.findById(hostIdSpecified);
 +            if (host == null) {
 +                s_logger.debug("The specified host cannot be found");
 +            } else if (avoids.shouldAvoid(host)) {
 +                s_logger.debug("The specified host is in avoid set");
 +            } else {
 +                if (s_logger.isDebugEnabled()) {
                      s_logger.debug("Looking for suitable pools for this host under zone: " + host.getDataCenterId() + ", pod: " + host.getPodId() + ", cluster: " +
                          host.getClusterId());
 -                }
 -
 -                // search for storage under the zone, pod, cluster of the host.
 +                }
 +
 +                // search for storage under the zone, pod, cluster of the host.
                  DataCenterDeployment lastPlan =
                      new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), hostIdSpecified, plan.getPoolId(), null,
                          plan.getReservationContext());
 -
 +
                  Pair<Map<Volume, List<StoragePool>>, List<Volume>> result = findSuitablePoolsForVolumes(vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL);
 -                Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
 -                List<Volume> readyAndReusedVolumes = result.second();
 -
 -                // choose the potential pool for this VM for this host
 -                if (!suitableVolumeStoragePools.isEmpty()) {
 -                    List<Host> suitableHosts = new ArrayList<Host>();
 -                    suitableHosts.add(host);
 -                    Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(
 +                Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
 +                List<Volume> readyAndReusedVolumes = result.second();
 +
 +                // choose the potential pool for this VM for this host
 +                if (!suitableVolumeStoragePools.isEmpty()) {
 +                    List<Host> suitableHosts = new ArrayList<Host>();
 +                    suitableHosts.add(host);
 +                    Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(
                          suitableHosts, suitableVolumeStoragePools, avoids,
                          getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes);
 -                    if (potentialResources != null) {
 -                        Pod pod = _podDao.findById(host.getPodId());
 -                        Cluster cluster = _clusterDao.findById(host.getClusterId());
 -                        Map<Volume, StoragePool> storageVolMap = potentialResources.second();
 -                        // remove the reused vol<->pool from destination, since
 -                        // we don't have to prepare this volume.
 -                        for (Volume vol : readyAndReusedVolumes) {
 -                            storageVolMap.remove(vol);
 -                        }
 -                        DeployDestination dest = new DeployDestination(dc, pod, cluster, host, storageVolMap);
 -                        s_logger.debug("Returning Deployment Destination: " + dest);
 -                        return dest;
 -                    }
 -                }
 -            }
 -            s_logger.debug("Cannnot deploy to specified host, returning.");
 -            return null;
 -        }
 -
 -        if (vm.getLastHostId() != null && haVmTag == null) {
 -            s_logger.debug("This VM has last host_id specified, trying to choose the same host: " + vm.getLastHostId());
 -
 -            HostVO host = _hostDao.findById(vm.getLastHostId());
 -            if (host == null) {
 -                s_logger.debug("The last host of this VM cannot be found");
 -            } else if (avoids.shouldAvoid(host)) {
 -                s_logger.debug("The last host of this VM is in avoid set");
 -            } else if (_capacityMgr.checkIfHostReachMaxGuestLimit(host)) {
 +                    if (potentialResources != null) {
 +                        Pod pod = _podDao.findById(host.getPodId());
 +                        Cluster cluster = _clusterDao.findById(host.getClusterId());
 +                        Map<Volume, StoragePool> storageVolMap = potentialResources.second();
 +                        // remove the reused vol<->pool from destination, since
 +                        // we don't have to prepare this volume.
 +                        for (Volume vol : readyAndReusedVolumes) {
 +                            storageVolMap.remove(vol);
 +                        }
 +                        DeployDestination dest = new DeployDestination(dc, pod, cluster, host, storageVolMap);
 +                        s_logger.debug("Returning Deployment Destination: " + dest);
 +                        return dest;
 +                    }
 +                }
 +            }
 +            s_logger.debug("Cannnot deploy to specified host, returning.");
 +            return null;
 +        }
 +
 +        if (vm.getLastHostId() != null && haVmTag == null) {
 +            s_logger.debug("This VM has last host_id specified, trying to choose the same host: " + vm.getLastHostId());
 +
 +            HostVO host = _hostDao.findById(vm.getLastHostId());
 +            if (host == null) {
 +                s_logger.debug("The last host of this VM cannot be found");
 +            } else if (avoids.shouldAvoid(host)) {
 +                s_logger.debug("The last host of this VM is in avoid set");
 +            } else if (_capacityMgr.checkIfHostReachMaxGuestLimit(host)) {
                  s_logger.debug("The last Host, hostId: " + host.getId() +
                      " already has max Running VMs(count includes system VMs), skipping this and trying other available hosts");
 -            } else {
 -                if (host.getStatus() == Status.Up && host.getResourceState() == ResourceState.Enabled) {
 +            } else {
 +                if (host.getStatus() == Status.Up && host.getResourceState() == ResourceState.Enabled) {
+                     boolean hostTagsMatch = true;
+                     if(offering.getHostTag() != null){
+                         _hostDao.loadHostTags(host);
+                         if (!(host.getHostTags() != null && host.getHostTags().contains(offering.getHostTag()))) {
+                             hostTagsMatch = false;
+                         }
+                     }
+                     if (hostTagsMatch) {
 -                        long cluster_id = host.getClusterId();
 +                    long cluster_id = host.getClusterId();
-                     ClusterDetailsVO cluster_detail_cpu = _clusterDetailsDao.findDetail(cluster_id, "cpuOvercommitRatio");
-                     ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao.findDetail(cluster_id, "memoryOvercommitRatio");
+                         ClusterDetailsVO cluster_detail_cpu = _clusterDetailsDao.findDetail(cluster_id,
+                                 "cpuOvercommitRatio");
+                         ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao.findDetail(cluster_id,
+                                 "memoryOvercommitRatio");
 -                        Float cpuOvercommitRatio = Float.parseFloat(cluster_detail_cpu.getValue());
 -                        Float memoryOvercommitRatio = Float.parseFloat(cluster_detail_ram.getValue());
 +                    Float cpuOvercommitRatio = Float.parseFloat(cluster_detail_cpu.getValue());
 +                    Float memoryOvercommitRatio = Float.parseFloat(cluster_detail_ram.getValue());
-                     if (_capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, true, cpuOvercommitRatio, memoryOvercommitRatio, true)
-                         && _capacityMgr.checkIfHostHasCpuCapability(host.getId(), offering.getCpu(), offering.getSpeed())) {
+                         if (_capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, true,
+                                 cpuOvercommitRatio, memoryOvercommitRatio, true)
+                                 && _capacityMgr.checkIfHostHasCpuCapability(host.getId(), offering.getCpu(),
+                                         offering.getSpeed())) {
 -                            s_logger.debug("The last host of this VM is UP and has enough capacity");
 +                        s_logger.debug("The last host of this VM is UP and has enough capacity");
-                         s_logger.debug("Now checking for suitable pools under zone: " + host.getDataCenterId() + ", pod: " + host.getPodId() + ", cluster: " +
-                             host.getClusterId());
-                         // search for storage under the zone, pod, cluster of
+                             s_logger.debug("Now checking for suitable pools under zone: " + host.getDataCenterId()
+                                     + ", pod: " + host.getPodId() + ", cluster: " + host.getClusterId());
+                             // search for storage under the zone, pod, cluster
+                             // of
 -                            // the last host.
 +                        // the last host.
-                         DataCenterDeployment lastPlan =
-                             new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId(), null);
-                         Pair<Map<Volume, List<StoragePool>>, List<Volume>> result =
-                             findSuitablePoolsForVolumes(vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL);
+                             DataCenterDeployment lastPlan = new DataCenterDeployment(host.getDataCenterId(),
+                                     host.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId(), null);
+                             Pair<Map<Volume, List<StoragePool>>, List<Volume>> result = findSuitablePoolsForVolumes(
+                                     vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL);
 -                            Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
 -                            List<Volume> readyAndReusedVolumes = result.second();
 +                        Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
 +                        List<Volume> readyAndReusedVolumes = result.second();
  
-                         // choose the potential pool for this VM for this host
+                             // choose the potential pool for this VM for this
+                             // host
 -                            if (!suitableVolumeStoragePools.isEmpty()) {
 -                                List<Host> suitableHosts = new ArrayList<Host>();
 -                                suitableHosts.add(host);
 -                                Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(
 -                                        suitableHosts, suitableVolumeStoragePools, avoids,
 -                                        getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes);
 -                                if (potentialResources != null) {
 -                                    Pod pod = _podDao.findById(host.getPodId());
 -                                    Cluster cluster = _clusterDao.findById(host.getClusterId());
 -                                    Map<Volume, StoragePool> storageVolMap = potentialResources.second();
 -                                    // remove the reused vol<->pool from
 +                        if (!suitableVolumeStoragePools.isEmpty()) {
 +                            List<Host> suitableHosts = new ArrayList<Host>();
 +                            suitableHosts.add(host);
 +                            Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(
 +                                suitableHosts, suitableVolumeStoragePools, avoids,
 +                                getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes);
 +                            if (potentialResources != null) {
 +                                Pod pod = _podDao.findById(host.getPodId());
 +                                Cluster cluster = _clusterDao.findById(host.getClusterId());
 +                                Map<Volume, StoragePool> storageVolMap = potentialResources.second();
 +                                // remove the reused vol<->pool from
-                                 // destination, since we don't have to prepare
+                                     // destination, since we don't have to
+                                     // prepare
 -                                    // this volume.
 -                                    for (Volume vol : readyAndReusedVolumes) {
 -                                        storageVolMap.remove(vol);
 -                                    }
 +                                // this volume.
 +                                for (Volume vol : readyAndReusedVolumes) {
 +                                    storageVolMap.remove(vol);
 +                                }
-                                 DeployDestination dest = new DeployDestination(dc, pod, cluster, host, storageVolMap);
+                                     DeployDestination dest = new DeployDestination(dc, pod, cluster, host,
+                                             storageVolMap);
 -                                    s_logger.debug("Returning Deployment Destination: " + dest);
 -                                    return dest;
 -                                }
 -                            }
 -                        } else {
 -                            s_logger.debug("The last host of this VM does not have enough capacity");
 -                        }
 -                    } else {
 +                                s_logger.debug("Returning Deployment Destination: " + dest);
 +                                return dest;
 +                            }
 +                        }
 +                    } else {
 +                        s_logger.debug("The last host of this VM does not have enough capacity");
 +                    }
 +                } else {
+                         s_logger.debug("Service Offering host tag does not match the last host of this VM");
+                     }
+                 } else {
                      s_logger.debug("The last host of this VM is not UP or is not enabled, host status is: " + host.getStatus().name() + ", host resource state is: " +
                          host.getResourceState());
 -                }
 -            }
 -            s_logger.debug("Cannot choose the last host to deploy this VM ");
 -        }
 -
 -        DeployDestination dest = null;
 -        List<Long> clusterList = null;
 -
 -        if (planner != null && planner.canHandle(vmProfile, plan, avoids)) {
 -            while (true) {
 -
 -                if (planner instanceof DeploymentClusterPlanner) {
 -
 +                }
 +            }
 +            s_logger.debug("Cannot choose the last host to deploy this VM ");
 +        }
 +
 +        DeployDestination dest = null;
 +        List<Long> clusterList = null;
 +
 +        if (planner != null && planner.canHandle(vmProfile, plan, avoids)) {
 +            while (true) {
 +
 +                if (planner instanceof DeploymentClusterPlanner) {
 +
                      ExcludeList plannerAvoidInput =
                          new ExcludeList(avoids.getDataCentersToAvoid(), avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(),
 -                            avoids.getPoolsToAvoid());
 -
 +                            avoids.getPoolsToAvoid());
 +
                      clusterList = ((DeploymentClusterPlanner)planner).orderClusters(vmProfile, plan, avoids);
 -
 -                    if (clusterList != null && !clusterList.isEmpty()) {
 -                        // planner refactoring. call allocators to list hosts
 +
 +                    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);
 -
 +                                avoids.getPoolsToAvoid());
 +
 +                        resetAvoidSet(plannerAvoidOutput, plannerAvoidInput);
 +
                          dest =
                              checkClustersforDestination(clusterList, vmProfile, plan, avoids, dc, getPlannerUsage(planner, vmProfile, plan, avoids), 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 {
 -                            // find another host - seems some concurrent
 -                            // deployment picked it up for dedicated access
 -                            continue;
 -                        }
 -                    } else {
 -                        return null;
 -                    }
 -                }
 -            }
 -        }
 -
 -        return dest;
 -    }
 -
 +                        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 {
 +                            // find another host - seems some concurrent
 +                            // deployment picked it up for dedicated access
 +                            continue;
 +                        }
 +                    } else {
 +                        return null;
 +                    }
 +                }
 +            }
 +        }
 +
 +        return dest;
 +    }
 +
      private void checkForNonDedicatedResources(VirtualMachineProfile vmProfile, DataCenter dc, ExcludeList avoids) {
 -        boolean isExplicit = false;
 -        VirtualMachine vm = vmProfile.getVirtualMachine();
 -
 -        // check if zone is dedicated. if yes check if vm owner has acess to it.
 -        DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(dc.getId());
 +        boolean isExplicit = false;
 +        VirtualMachine vm = vmProfile.getVirtualMachine();
 +
 +        // check if zone is dedicated. if yes check if vm owner has acess to it.
 +        DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(dc.getId());
          if (dedicatedZone != null && !_accountMgr.isRootAdmin(vmProfile.getOwner().getType())) {
 -            long accountDomainId = vmProfile.getOwner().getDomainId();
 -            long accountId = vmProfile.getOwner().getAccountId();
 -
 -            // If a zone is dedicated to an account then all hosts in this zone
 -            // will be explicitly dedicated to
 -            // that account. So there won't be any shared hosts in the zone, the
 -            // only way to deploy vms from that
 -            // account will be to use explicit dedication affinity group.
 -            if (dedicatedZone.getAccountId() != null) {
 -                if (dedicatedZone.getAccountId().equals(accountId)) {
 -                    return;
 -                } else {
 +            long accountDomainId = vmProfile.getOwner().getDomainId();
 +            long accountId = vmProfile.getOwner().getAccountId();
 +
 +            // If a zone is dedicated to an account then all hosts in this zone
 +            // will be explicitly dedicated to
 +            // that account. So there won't be any shared hosts in the zone, the
 +            // only way to deploy vms from that
 +            // account will be to use explicit dedication affinity group.
 +            if (dedicatedZone.getAccountId() != null) {
 +                if (dedicatedZone.getAccountId().equals(accountId)) {
 +                    return;
 +                } else {
                      throw new CloudRuntimeException("Failed to deploy VM, Zone " + dc.getName() + " not available for the user account " + vmProfile.getOwner());
 -                }
 -            }
 -
 -            // if zone is dedicated to a domain. Check owner's access to the
 -            // domain level dedication group
 +                }
 +            }
 +
 +            // if zone is dedicated to a domain. Check owner's access to the
 +            // domain level dedication group
              if (!_affinityGroupService.isAffinityGroupAvailableInDomain(dedicatedZone.getAffinityGroupId(), accountDomainId)) {
                  throw new CloudRuntimeException("Failed to deploy VM, Zone " + dc.getName() + " not available for the user domain " + vmProfile.getOwner());
 -            }
 -
 -        }
 -
 -        // check affinity group of type Explicit dedication exists. If No put
 +            }
 +
 +        }
 +
 +        // check affinity group of type Explicit dedication exists. If No put
          // dedicated pod/cluster/host in avoid list
          List<AffinityGroupVMMapVO> vmGroupMappings = _affinityGroupVMMapDao.findByVmIdType(vm.getId(), "ExplicitDedication");
  
@@@ -1128,134 -1149,143 +1149,143 @@@
          }
          Set<Long> poolsToAvoidOutput = new HashSet<Long>(originalAvoidPoolSet);
  
 -        for (VolumeVO toBeCreated : volumesTobeCreated) {
 +        for (VolumeVO toBeCreated : volumesTobeCreated) {
              s_logger.debug("Checking suitable pools for volume (Id, Type): (" + toBeCreated.getId() + "," + toBeCreated.getVolumeType().name() + ")");
 -
 -            // If the plan specifies a poolId, it means that this VM's ROOT
 -            // volume is ready and the pool should be reused.
 -            // In this case, also check if rest of the volumes are ready and can
 -            // be reused.
 -            if (plan.getPoolId() != null) {
 +
 +            // If the plan specifies a poolId, it means that this VM's ROOT
 +            // volume is ready and the pool should be reused.
 +            // In this case, also check if rest of the volumes are ready and can
 +            // be reused.
 +            if (plan.getPoolId() != null) {
                  s_logger.debug("Volume has pool already allocated, checking if pool can be reused, poolId: " + toBeCreated.getPoolId());
 -                List<StoragePool> suitablePools = new ArrayList<StoragePool>();
 -                StoragePool pool = null;
 -                if (toBeCreated.getPoolId() != null) {
 +                List<StoragePool> suitablePools = new ArrayList<StoragePool>();
 +                StoragePool pool = null;
 +                if (toBeCreated.getPoolId() != null) {
-                     pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(toBeCreated.getPoolId());
+                     pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(toBeCreated.getPoolId());
 -                } else {
 +                } else {
-                     pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(plan.getPoolId());
+                     pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(plan.getPoolId());
 -                }
 -
 -                if (!pool.isInMaintenance()) {
 -                    if (!avoid.shouldAvoid(pool)) {
 -                        long exstPoolDcId = pool.getDataCenterId();
 -                        long exstPoolPodId = pool.getPodId() != null ? pool.getPodId() : -1;
 -                        long exstPoolClusterId = pool.getClusterId() != null ? pool.getClusterId() : -1;
 -                        boolean canReusePool = false;
 +                }
 +
 +                if (!pool.isInMaintenance()) {
 +                    if (!avoid.shouldAvoid(pool)) {
 +                        long exstPoolDcId = pool.getDataCenterId();
 +                        long exstPoolPodId = pool.getPodId() != null ? pool.getPodId() : -1;
 +                        long exstPoolClusterId = pool.getClusterId() != null ? pool.getClusterId() : -1;
 +                        boolean canReusePool = false;
                          if (plan.getDataCenterId() == exstPoolDcId && plan.getPodId() == exstPoolPodId && plan.getClusterId() == exstPoolClusterId) {
 -                            canReusePool = true;
 -                        } else if (plan.getDataCenterId() == exstPoolDcId) {
 +                            canReusePool = true;
 +                        } else if (plan.getDataCenterId() == exstPoolDcId) {
-                             DataStore dataStore = this.dataStoreMgr.getPrimaryDataStore(pool.getId());
+                             DataStore dataStore = dataStoreMgr.getPrimaryDataStore(pool.getId());
                              if (dataStore != null && dataStore.getScope() != null && dataStore.getScope().getScopeType() == ScopeType.ZONE) {
 -                                canReusePool = true;
 -                            }
 -                        } else {
 -                            s_logger.debug("Pool of the volume does not fit the specified plan, need to reallocate a pool for this volume");
 -                            canReusePool = false;
 -                        }
 -
 -                        if (canReusePool) {
 -                            s_logger.debug("Planner need not allocate a pool for this volume since its READY");
 -                            suitablePools.add(pool);
 -                            suitableVolumeStoragePools.put(toBeCreated, suitablePools);
 -                            if (!(toBeCreated.getState() == Volume.State.Allocated || toBeCreated.getState() == Volume.State.Creating)) {
 -                                readyAndReusedVolumes.add(toBeCreated);
 -                            }
 -                            continue;
 -                        }
 -                    } else {
 -                        s_logger.debug("Pool of the volume is in avoid set, need to reallocate a pool for this volume");
 -                    }
 -                } else {
 -                    s_logger.debug("Pool of the volume is in maintenance, need to reallocate a pool for this volume");
 -                }
 -            }
 -
 -            if (s_logger.isDebugEnabled()) {
 -                s_logger.debug("We need to allocate new storagepool for this volume");
 -            }
 -            if (!isRootAdmin(plan.getReservationContext())) {
 -                if (!isEnabledForAllocation(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId())) {
 -                    if (s_logger.isDebugEnabled()) {
 -                        s_logger.debug("Cannot allocate new storagepool for this volume in this cluster, allocation state is disabled");
 -                        s_logger.debug("Cannot deploy to this specified plan, allocation state is disabled, returning.");
 -                    }
 -                    // Cannot find suitable storage pools under this cluster for
 -                    // this volume since allocation_state is disabled.
 -                    // - remove any suitable pools found for other volumes.
 -                    // All volumes should get suitable pools under this cluster;
 -                    // else we cant use this cluster.
 -                    suitableVolumeStoragePools.clear();
 -                    break;
 -                }
 -            }
 -
 -            s_logger.debug("Calling StoragePoolAllocators to find suitable pools");
 -
 -            DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId());
 -
 +                                canReusePool = true;
 +                            }
 +                        } else {
 +                            s_logger.debug("Pool of the volume does not fit the specified plan, need to reallocate a pool for this volume");
 +                            canReusePool = false;
 +                        }
 +
 +                        if (canReusePool) {
 +                            s_logger.debug("Planner need not allocate a pool for this volume since its READY");
 +                            suitablePools.add(pool);
 +                            suitableVolumeStoragePools.put(toBeCreated, suitablePools);
 +                            if (!(toBeCreated.getState() == Volume.State.Allocated || toBeCreated.getState() == Volume.State.Creating)) {
 +                                readyAndReusedVolumes.add(toBeCreated);
 +                            }
 +                            continue;
 +                        }
 +                    } else {
 +                        s_logger.debug("Pool of the volume is in avoid set, need to reallocate a pool for this volume");
 +                    }
 +                } else {
 +                    s_logger.debug("Pool of the volume is in maintenance, need to reallocate a pool for this volume");
 +                }
 +            }
 +
 +            if (s_logger.isDebugEnabled()) {
 +                s_logger.debug("We need to allocate new storagepool for this volume");
 +            }
 +            if (!isRootAdmin(plan.getReservationContext())) {
 +                if (!isEnabledForAllocation(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId())) {
 +                    if (s_logger.isDebugEnabled()) {
 +                        s_logger.debug("Cannot allocate new storagepool for this volume in this cluster, allocation state is disabled");
 +                        s_logger.debug("Cannot deploy to this specified plan, allocation state is disabled, returning.");
 +                    }
 +                    // Cannot find suitable storage pools under this cluster for
 +                    // this volume since allocation_state is disabled.
 +                    // - remove any suitable pools found for other volumes.
 +                    // All volumes should get suitable pools under this cluster;
 +                    // else we cant use this cluster.
 +                    suitableVolumeStoragePools.clear();
 +                    break;
 +                }
 +            }
 +
 +            s_logger.debug("Calling StoragePoolAllocators to find suitable pools");
 +
 +            DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId());
-             DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType());
 +
+             if (vmProfile.getTemplate().getFormat() == Storage.ImageFormat.ISO && vmProfile.getServiceOffering().getTagsArray().length != 0) {
+                 diskOffering.setTagsArray(Arrays.asList(vmProfile.getServiceOffering().getTagsArray()));
+             }
+ 
+             DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType());
 -            boolean useLocalStorage = false;
 -            if (vmProfile.getType() != VirtualMachine.Type.User) {
 -                String ssvmUseLocalStorage = _configDao.getValue(Config.SystemVMUseLocalStorage.key());
 -                if (ssvmUseLocalStorage.equalsIgnoreCase("true")) {
 -                    useLocalStorage = true;
 -                }
 -            } else {
 -                useLocalStorage = diskOffering.getUseLocalStorage();
 -
 -                // TODO: this is a hacking fix for the problem of deploy
 -                // ISO-based VM on local storage
 -                // when deploying VM based on ISO, we have a service offering
 -                // and an additional disk offering, use-local storage flag is
 -                // actually
 -                // saved in service offering, overrde the flag from service
 -                // offering when it is a ROOT disk
 -                if (!useLocalStorage && vmProfile.getServiceOffering().getUseLocalStorage()) {
 -                    if (toBeCreated.getVolumeType() == Volume.Type.ROOT)
 -                        useLocalStorage = true;
 -                }
 -            }
 -            diskProfile.setUseLocalStorage(useLocalStorage);
 -
 -            boolean foundPotentialPools = false;
 -            for (StoragePoolAllocator allocator : _storagePoolAllocators) {
 +            boolean useLocalStorage = false;
 +            if (vmProfile.getType() != VirtualMachine.Type.User) {
 +                String ssvmUseLocalStorage = _configDao.getValue(Config.SystemVMUseLocalStorage.key());
 +                if (ssvmUseLocalStorage.equalsIgnoreCase("true")) {
 +                    useLocalStorage = true;
 +                }
 +            } else {
 +                useLocalStorage = diskOffering.getUseLocalStorage();
 +
 +                // TODO: this is a hacking fix for the problem of deploy
 +                // ISO-based VM on local storage
 +                // when deploying VM based on ISO, we have a service offering
 +                // and an additional disk offering, use-local storage flag is
 +                // actually
 +                // saved in service offering, overrde the flag from service
 +                // offering when it is a ROOT disk
 +                if (!useLocalStorage && vmProfile.getServiceOffering().getUseLocalStorage()) {
 +                    if (toBeCreated.getVolumeType() == Volume.Type.ROOT)
 +                        useLocalStorage = true;
 +                }
 +            }
 +            diskProfile.setUseLocalStorage(useLocalStorage);
 +
 +            boolean foundPotentialPools = false;
 +            for (StoragePoolAllocator allocator : _storagePoolAllocators) {
                  final List<StoragePool> suitablePools = allocator.allocateToPool(diskProfile, vmProfile, plan, avoid, returnUpTo);
 -                if (suitablePools != null && !suitablePools.isEmpty()) {
 -                    suitableVolumeStoragePools.put(toBeCreated, suitablePools);
 -                    foundPotentialPools = true;
 -                    break;
 -                }
 -            }
 -
 +                if (suitablePools != null && !suitablePools.isEmpty()) {
 +                    suitableVolumeStoragePools.put(toBeCreated, suitablePools);
 +                    foundPotentialPools = true;
 +                    break;
 +                }
 +            }
 +
              if (avoid.getPoolsToAvoid() != null) {
                  poolsToAvoidOutput.addAll(avoid.getPoolsToAvoid());
                  avoid.getPoolsToAvoid().retainAll(originalAvoidPoolSet);
              }
  
 -            if (!foundPotentialPools) {
 +            if (!foundPotentialPools) {
                  s_logger.debug("No suitable pools found for volume: " + toBeCreated + " under cluster: " + plan.getClusterId());
 -                // No suitable storage pools found under this cluster for this
 -                // volume. - remove any suitable pools found for other volumes.
 -                // All volumes should get suitable pools under this cluster;
 -                // else we cant use this cluster.
 -                suitableVolumeStoragePools.clear();
 -                break;
 -            }
 -        }
 -
 +                // No suitable storage pools found under this cluster for this
 +                // volume. - remove any suitable pools found for other volumes.
 +                // All volumes should get suitable pools under this cluster;
 +                // else we cant use this cluster.
 +                suitableVolumeStoragePools.clear();
 +                break;
 +            }
 +        }
 +
-         if (suitableVolumeStoragePools.values() != null) {
-             poolsToAvoidOutput.removeAll(suitableVolumeStoragePools.values());
+         HashSet<Long> toRemove = new HashSet<Long>();
+         for (List<StoragePool> lsp : suitableVolumeStoragePools.values()) {
+             for (StoragePool sp : lsp) {
+                 toRemove.add(sp.getId());
+             }
          }
+         poolsToAvoidOutput.removeAll(toRemove);
+ 
          if (avoid.getPoolsToAvoid() != null) {
              avoid.getPoolsToAvoid().addAll(poolsToAvoidOutput);
          }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f8437544/server/src/com/cloud/network/IpAddressManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/network/IpAddressManagerImpl.java
index e8de7f0,09f73a4..5e2046c
--- a/server/src/com/cloud/network/IpAddressManagerImpl.java
+++ b/server/src/com/cloud/network/IpAddressManagerImpl.java
@@@ -654,129 -657,129 +657,129 @@@ public class IpAddressManagerImpl exten
          IPAddressVO addr = Transaction.execute(new TransactionCallbackWithException<IPAddressVO, InsufficientAddressCapacityException>() {
              @Override
              public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
 -                StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in ");
 -                boolean fetchFromDedicatedRange = false;
 -                List<Long> dedicatedVlanDbIds = new ArrayList<Long>();
 -                List<Long> nonDedicatedVlanDbIds = new ArrayList<Long>();
 -
 -                SearchCriteria<IPAddressVO> sc = null;
 -                if (podId != null) {
 -                    sc = AssignIpAddressFromPodVlanSearch.create();
 -                    sc.setJoinParameters("podVlanMapSB", "podId", podId);
 -                    errorMessage.append(" pod id=" + podId);
 -                } else {
 -                    sc = AssignIpAddressSearch.create();
 -                    errorMessage.append(" zone id=" + dcId);
 -                }
 +        StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in ");
 +        boolean fetchFromDedicatedRange = false;
 +        List<Long> dedicatedVlanDbIds = new ArrayList<Long>();
 +        List<Long> nonDedicatedVlanDbIds = new ArrayList<Long>();
 +
 +        SearchCriteria<IPAddressVO> sc = null;
 +        if (podId != null) {
 +            sc = AssignIpAddressFromPodVlanSearch.create();
 +            sc.setJoinParameters("podVlanMapSB", "podId", podId);
 +            errorMessage.append(" pod id=" + podId);
 +        } else {
 +            sc = AssignIpAddressSearch.create();
 +            errorMessage.append(" zone id=" + dcId);
 +        }
  
 -                // If owner has dedicated Public IP ranges, fetch IP from the dedicated range
 -                // Otherwise fetch IP from the system pool
 -                List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId());
 -                for (AccountVlanMapVO map : maps) {
 -                    if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
 -                        dedicatedVlanDbIds.add(map.getVlanDbId());
 -                }
 -                List<VlanVO> nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId);
 -                for (VlanVO nonDedicatedVlan : nonDedicatedVlans) {
 -                    if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId()))
 -                        nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId());
 -                }
 -                if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
 -                    fetchFromDedicatedRange = true;
 -                    sc.setParameters("vlanId", dedicatedVlanDbIds.toArray());
 +        // If owner has dedicated Public IP ranges, fetch IP from the dedicated range
 +        // Otherwise fetch IP from the system pool
 +        List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId());
 +        for (AccountVlanMapVO map : maps) {
 +            if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
 +                dedicatedVlanDbIds.add(map.getVlanDbId());
 +        }
 +        List<VlanVO> nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId);
 +        for (VlanVO nonDedicatedVlan : nonDedicatedVlans) {
 +            if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId()))
 +                nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId());
 +        }
 +        if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
 +            fetchFromDedicatedRange = true;
 +            sc.setParameters("vlanId", dedicatedVlanDbIds.toArray());
-             errorMessage.append(", vlanId id=" + dedicatedVlanDbIds.toArray());
+                     errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray()));
 -                } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
 -                    sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
 +        } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
 +            sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
-             errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
+                     errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
 -                } else {
 -                    if (podId != null) {
 -                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
 -                        ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
 -                        throw ex;
 -                    }
 -                    s_logger.warn(errorMessage.toString());
 -                    InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
 -                    ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
 -                    throw ex;
 -                }
 +        } else {
 +            if (podId != null) {
 +                InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
 +                ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
 +                throw ex;
 +            }
 +            s_logger.warn(errorMessage.toString());
 +            InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
 +            ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
 +            throw ex;
 +        }
  
 -                sc.setParameters("dc", dcId);
 +        sc.setParameters("dc", dcId);
  
 -                DataCenter zone = _entityMgr.findById(DataCenter.class, dcId);
 +        DataCenter zone = _entityMgr.findById(DataCenter.class, dcId);
  
 -                // for direct network take ip addresses only from the vlans belonging to the network
 -                if (vlanUse == VlanType.DirectAttached) {
 -                    sc.setJoinParameters("vlan", "networkId", guestNetworkId);
 -                    errorMessage.append(", network id=" + guestNetworkId);
 -                }
 -                sc.setJoinParameters("vlan", "type", vlanUse);
 +        // for direct network take ip addresses only from the vlans belonging to the network
 +        if (vlanUse == VlanType.DirectAttached) {
 +            sc.setJoinParameters("vlan", "networkId", guestNetworkId);
 +            errorMessage.append(", network id=" + guestNetworkId);
 +        }
 +        sc.setJoinParameters("vlan", "type", vlanUse);
  
 -                if (requestedIp != null) {
 -                    sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
 -                    errorMessage.append(": requested ip " + requestedIp + " is not available");
 -                }
 +        if (requestedIp != null) {
 +            sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
 +            errorMessage.append(": requested ip " + requestedIp + " is not available");
 +        }
  
 -                Filter filter = new Filter(IPAddressVO.class, "vlanId", true, 0l, 1l);
 +        Filter filter = new Filter(IPAddressVO.class, "vlanId", true, 0l, 1l);
  
 -                List<IPAddressVO> addrs = _ipAddressDao.lockRows(sc, filter, true);
 +        List<IPAddressVO> addrs = _ipAddressDao.lockRows(sc, filter, true);
  
 -                // If all the dedicated IPs of the owner are in use fetch an IP from the system pool
 -                if (addrs.size() == 0 && fetchFromDedicatedRange) {
 -                    // Verify if account is allowed to acquire IPs from the system
 -                    boolean useSystemIps = UseSystemPublicIps.valueIn(owner.getId());
 -                    if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
 -                        fetchFromDedicatedRange = false;
 -                        sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
 +        // If all the dedicated IPs of the owner are in use fetch an IP from the system pool
 +        if (addrs.size() == 0 && fetchFromDedicatedRange) {
 +            // Verify if account is allowed to acquire IPs from the system
 +            boolean useSystemIps = UseSystemPublicIps.valueIn(owner.getId());
 +            if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
 +                fetchFromDedicatedRange = false;
 +                sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
-                 errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
+                         errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
 -                        addrs = _ipAddressDao.lockRows(sc, filter, true);
 -                    }
 -                }
 +                addrs = _ipAddressDao.lockRows(sc, filter, true);
 +            }
 +        }
  
 -                if (addrs.size() == 0) {
 -                    if (podId != null) {
 -                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
 -                        // for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object.
 -                        ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
 -                        throw ex;
 -                    }
 -                    s_logger.warn(errorMessage.toString());
 -                    InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
 -                    ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
 -                    throw ex;
 -                }
 +        if (addrs.size() == 0) {
 +            if (podId != null) {
 +                InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
 +                // for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object.
 +                ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
 +                throw ex;
 +            }
 +            s_logger.warn(errorMessage.toString());
 +            InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
 +            ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
 +            throw ex;
 +        }
  
 -                assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size();
 +        assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size();
  
 -                if (!fetchFromDedicatedRange) {
 -                    // Check that the maximum number of public IPs for the given accountId will not be exceeded
 -                    try {
 -                        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
 -                    } catch (ResourceAllocationException ex) {
 -                        s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner);
 -                        throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded.");
 -                    }
 -                }
 +        if (!fetchFromDedicatedRange) {
 +            // Check that the maximum number of public IPs for the given accountId will not be exceeded
 +            try {
 +                _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
 +            } catch (ResourceAllocationException ex) {
 +                s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner);
 +                throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded.");
 +            }
 +        }
  
 -                IPAddressVO addr = addrs.get(0);
 -                addr.setSourceNat(sourceNat);
 -                addr.setAllocatedTime(new Date());
 -                addr.setAllocatedInDomainId(owner.getDomainId());
 -                addr.setAllocatedToAccountId(owner.getId());
 -                addr.setSystem(isSystem);
 +        IPAddressVO addr = addrs.get(0);
 +        addr.setSourceNat(sourceNat);
 +        addr.setAllocatedTime(new Date());
 +        addr.setAllocatedInDomainId(owner.getDomainId());
 +        addr.setAllocatedToAccountId(owner.getId());
 +        addr.setSystem(isSystem);
  
 -                if (assign) {
 -                    markPublicIpAsAllocated(addr);
 -                } else {
 -                    addr.setState(IpAddress.State.Allocating);
 -                }
 -                addr.setState(assign ? IpAddress.State.Allocated : IpAddress.State.Allocating);
 +        if (assign) {
 +            markPublicIpAsAllocated(addr);
 +        } else {
 +            addr.setState(IpAddress.State.Allocating);
 +        }
 +        addr.setState(assign ? IpAddress.State.Allocated : IpAddress.State.Allocating);
  
 -                if (vlanUse != VlanType.DirectAttached) {
 -                    addr.setAssociatedWithNetworkId(guestNetworkId);
 -                    addr.setVpcId(vpcId);
 -                }
 +        if (vlanUse != VlanType.DirectAttached) {
 +            addr.setAssociatedWithNetworkId(guestNetworkId);
 +            addr.setVpcId(vpcId);
 +        }
  
 -                _ipAddressDao.update(addr.getId(), addr);
 +        _ipAddressDao.update(addr.getId(), addr);
  
                  return addr;
              }
@@@ -883,13 -891,11 +891,11 @@@
  
              return ip;
          } finally {
-             if (owner != null) {
 -            if (s_logger.isDebugEnabled()) {
 -                s_logger.debug("Releasing lock account " + ownerId);
 -            }
 -            _accountDao.releaseFromLockTable(ownerId);
 +                if (s_logger.isDebugEnabled()) {
 +                    s_logger.debug("Releasing lock account " + ownerId);
 +                }
- 
 +                _accountDao.releaseFromLockTable(ownerId);
-             }
+ 
              if (ip == null) {
                  s_logger.error("Unable to get source nat ip address for account " + ownerId);
              }
@@@ -1235,22 -1241,20 +1241,20 @@@
              return ip;
          } finally {
              if (!success && releaseOnFailure) {
-                 if (ip != null) {
 -                try {
 -                    s_logger.warn("Failed to associate ip address, so releasing ip from the database " + ip);
 -                    _ipAddressDao.markAsUnavailable(ip.getId());
 -                    if (!applyIpAssociations(network, true)) {
 -                        // if fail to apply ip assciations again, unassign ip address without updating resource
 -                        // count and generating usage event as there is no need to keep it in the db
 -                        _ipAddressDao.unassignIpAddress(ip.getId());
 +                    try {
 +                        s_logger.warn("Failed to associate ip address, so releasing ip from the database " + ip);
 +                        _ipAddressDao.markAsUnavailable(ip.getId());
 +                        if (!applyIpAssociations(network, true)) {
 +                            // if fail to apply ip assciations again, unassign ip address without updating resource
 +                            // count and generating usage event as there is no need to keep it in the db
 +                            _ipAddressDao.unassignIpAddress(ip.getId());
 +                        }
 +                    } catch (Exception e) {
 +                        s_logger.warn("Unable to disassociate ip address for recovery", e);
                      }
                  }
              }
          }
--    }
  
      protected boolean isSharedNetworkOfferingWithServices(long networkOfferingId) {
          NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f8437544/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f8437544/server/src/com/cloud/network/as/AutoScaleManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/network/as/AutoScaleManagerImpl.java
index 367b8e6,a2cc32e..0e6a6b4
--- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java
+++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java
@@@ -55,8 -50,10 +55,9 @@@ import org.apache.cloudstack.api.comman
  import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmGroupCmd;
  import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmProfileCmd;
  import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
+ import org.apache.cloudstack.config.ApiServiceConfiguration;
  import org.apache.cloudstack.context.CallContext;
  import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 -import org.apache.log4j.Logger;
  
  import com.cloud.api.ApiDBUtils;
  import com.cloud.api.ApiDispatcher;
@@@ -439,9 -437,10 +439,11 @@@ public class AutoScaleManagerImpl<Type
          Long id = cmd.getId();
          Long templateId = cmd.getTemplateId();
          String otherDeployParams = cmd.getOtherDeployParams();
+         Long serviceOffId = cmd.getServiceOfferingId();
+         Long zoneId = cmd.getZoneId();
  
 -        SearchWrapper<AutoScaleVmProfileVO> searchWrapper = new SearchWrapper<AutoScaleVmProfileVO>(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId());
 +        SearchWrapper<AutoScaleVmProfileVO> searchWrapper = new SearchWrapper<AutoScaleVmProfileVO>(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId(),
 +                "listAutoScaleVmProfiles");
          SearchBuilder<AutoScaleVmProfileVO> sb = searchWrapper.getSearchBuilder();
  
          sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f8437544/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f8437544/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f8437544/server/src/com/cloud/projects/ProjectManagerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f8437544/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
index 6b4bdd9,13c3051..74cfc31
--- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
+++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
@@@ -835,55 -832,55 +835,55 @@@ public class ResourceLimitManagerImpl e
          Long newCount = Transaction.execute(new TransactionCallback<Long>() {
              @Override
              public Long doInTransaction(TransactionStatus status) {
 -                Long newCount = null;
 -
 -                // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table
 -                // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too
 -                SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
 -                sc.setParameters("accountId", accountId);
 -                _resourceCountDao.lockRows(sc, null, true);
 -
 -                ResourceCountVO accountRC = _resourceCountDao.findByOwnerAndType(accountId, ResourceOwnerType.Account, type);
 -                long oldCount = 0;
 -                if (accountRC != null)
 -                    oldCount = accountRC.getCount();
 -
 -                if (type == Resource.ResourceType.user_vm) {
 -                    newCount = _userVmDao.countAllocatedVMsForAccount(accountId);
 -                } else if (type == Resource.ResourceType.volume) {
 -                    newCount = _volumeDao.countAllocatedVolumesForAccount(accountId);
 -                    long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size();
 -                    newCount = newCount - virtualRouterCount; // don't count the volumes of virtual router
 -                } else if (type == Resource.ResourceType.snapshot) {
 -                    newCount = _snapshotDao.countSnapshotsForAccount(accountId);
 -                } else if (type == Resource.ResourceType.public_ip) {
 -                    newCount = calculatePublicIpForAccount(accountId);
 -                } else if (type == Resource.ResourceType.template) {
 -                    newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
 -                } else if (type == Resource.ResourceType.project) {
 -                    newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
 -                } else if (type == Resource.ResourceType.network) {
 -                    newCount = _networkDao.countNetworksUserCanCreate(accountId);
 -                } else if (type == Resource.ResourceType.vpc) {
 -                    newCount = _vpcDao.countByAccountId(accountId);
 -                } else if (type == Resource.ResourceType.cpu) {
 -                    newCount = countCpusForAccount(accountId);
 -                } else if (type == Resource.ResourceType.memory) {
 -                    newCount = calculateMemoryForAccount(accountId);
 -                } else if (type == Resource.ResourceType.primary_storage) {
 -                    List<Long> virtualRouters = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId);
 -                    newCount = _volumeDao.primaryStorageUsedForAccount(accountId, virtualRouters);
 -                } else if (type == Resource.ResourceType.secondary_storage) {
 -                    newCount = calculateSecondaryStorageForAccount(accountId);
 -                } else {
 -                    throw new InvalidParameterValueException("Unsupported resource type " + type);
 -                }
 -                _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue());
 +        Long newCount = null;
 +
 +        // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table
 +        // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too
 +        SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
 +        sc.setParameters("accountId", accountId);
 +        _resourceCountDao.lockRows(sc, null, true);
 +
 +        ResourceCountVO accountRC = _resourceCountDao.findByOwnerAndType(accountId, ResourceOwnerType.Account, type);
 +        long oldCount = 0;
 +        if (accountRC != null)
 +            oldCount = accountRC.getCount();
 +
 +        if (type == Resource.ResourceType.user_vm) {
 +            newCount = _userVmDao.countAllocatedVMsForAccount(accountId);
 +        } else if (type == Resource.ResourceType.volume) {
 +            newCount = _volumeDao.countAllocatedVolumesForAccount(accountId);
 +            long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size();
 +            newCount = newCount - virtualRouterCount; // don't count the volumes of virtual router
 +        } else if (type == Resource.ResourceType.snapshot) {
 +            newCount = _snapshotDao.countSnapshotsForAccount(accountId);
 +        } else if (type == Resource.ResourceType.public_ip) {
 +            newCount = calculatePublicIpForAccount(accountId);
 +        } else if (type == Resource.ResourceType.template) {
 +            newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
 +        } else if (type == Resource.ResourceType.project) {
 +            newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
 +        } else if (type == Resource.ResourceType.network) {
 +            newCount = _networkDao.countNetworksUserCanCreate(accountId);
 +        } else if (type == Resource.ResourceType.vpc) {
 +            newCount = _vpcDao.countByAccountId(accountId);
 +        } else if (type == Resource.ResourceType.cpu) {
 +            newCount = countCpusForAccount(accountId);
 +        } else if (type == Resource.ResourceType.memory) {
 +            newCount = calculateMemoryForAccount(accountId);
 +        } else if (type == Resource.ResourceType.primary_storage) {
 +            List<Long> virtualRouters = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId);
 +            newCount = _volumeDao.primaryStorageUsedForAccount(accountId, virtualRouters);
 +        } else if (type == Resource.ResourceType.secondary_storage) {
 +            newCount = calculateSecondaryStorageForAccount(accountId);
 +        } else {
 +            throw new InvalidParameterValueException("Unsupported resource type " + type);
 +        }
 +        _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue());
  
-         if (oldCount != newCount) {
+                 if (!Long.valueOf(oldCount).equals(newCount)) {
                      s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " + newCount + ") for type " + type +
                          " for account ID " + accountId + " is fixed during resource count recalculation.");
 -                }
 +        }
  
                  return newCount;
              }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f8437544/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f8437544/server/src/com/cloud/servlet/ConsoleProxyServlet.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/servlet/ConsoleProxyServlet.java
index f39dcb5,6a5c6a9..60f32cf
--- a/server/src/com/cloud/servlet/ConsoleProxyServlet.java
+++ b/server/src/com/cloud/servlet/ConsoleProxyServlet.java
@@@ -328,16 -328,22 +328,22 @@@ public class ConsoleProxyServlet extend
  
          s_logger.info("Parse host info returned from executing GetVNCPortCommand. host info: " + hostInfo);
  
-         if (hostInfo != null && hostInfo.startsWith("consoleurl")) {
+         if (hostInfo != null) {
+             if (hostInfo.startsWith("consoleurl")) {
 -                String tokens[] = hostInfo.split("&");
 +            String tokens[] = hostInfo.split("&");
  
 -                if (hostInfo.length() > 19 && hostInfo.indexOf('/', 19) > 19) {
 -                    host = hostInfo.substring(19, hostInfo.indexOf('/', 19)).trim();
 -                    tunnelUrl = tokens[0].substring("consoleurl=".length());
 -                    tunnelSession = tokens[1].split("=")[1];
 -                } else {
 -                    host = "";
 -                }
 +            if (hostInfo.length() > 19 && hostInfo.indexOf('/', 19) > 19) {
 +                host = hostInfo.substring(19, hostInfo.indexOf('/', 19)).trim();
 +                tunnelUrl = tokens[0].substring("consoleurl=".length());
 +                tunnelSession = tokens[1].split("=")[1];
 +            } else {
 +                host = "";
 +            }
+             } else if (hostInfo.startsWith("instanceId")) {
+                 host = hostInfo.substring(hostInfo.indexOf('=') + 1);
+             } else {
+                 host = hostInfo;
+             }
          } else {
              host = hostInfo;
          }
@@@ -410,7 -442,14 +442,14 @@@
          if (details != null) {
              param.setLocale(details.getValue());
          }
+ 
+         if (portInfo.second() == -9) {
+             //For Hyperv Clinet Host Address will send Instance id
+             param.setHypervHost(host);
+             param.setUsername(_ms.findDetail(hostVo.getId(), "username").getValue());
+             param.setPassword(_ms.findDetail(hostVo.getId(), "password").getValue());
+         }
 -        if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) {
 +        if (parsedHostInfo.second() != null  && parsedHostInfo.third() != null) {
              param.setClientTunnelUrl(parsedHostInfo.second());
              param.setClientTunnelSession(parsedHostInfo.third());
          }