diff --git a/api/src/com/cloud/agent/api/ClusterSyncAnswer.java b/api/src/com/cloud/agent/api/ClusterSyncAnswer.java index 6da1aff460c..e0689b906f6 100644 --- a/api/src/com/cloud/agent/api/ClusterSyncAnswer.java +++ b/api/src/com/cloud/agent/api/ClusterSyncAnswer.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Cloud.com, Inc. All rights reserved. +/* Copyright (C) 2012 Citrix.com, Inc. All rights reserved. * * This software is licensed under the GNU General Public License v3 or later. * @@ -27,21 +27,27 @@ public class ClusterSyncAnswer extends Answer { private HashMap> _newStates; private HashMap> _allStates; private int _type = -1; // 0 for full, 1 for delta + private boolean _isExecuted=false; public static final int FULL_SYNC=0; public static final int DELTA_SYNC=1; + + // this is here because a cron command answer is being sent twice + // AgentAttache.processAnswers + // AgentManagerImpl.notifyAnswersToMonitors + public boolean isExceuted(){ + return _isExecuted; + } - public ClusterSyncAnswer(long clusterId) { - _clusterId = clusterId; - result = false; - this.details = "Ignore sync as this is not a pool master"; - _type = -1; + public void setExecuted(){ + _isExecuted = true; } public ClusterSyncAnswer(long clusterId, HashMap> newStates){ _clusterId = clusterId; _newStates = newStates; + _allStates = null; _type = DELTA_SYNC; result = true; } diff --git a/api/src/com/cloud/agent/api/ClusterSyncCommand.java b/api/src/com/cloud/agent/api/ClusterSyncCommand.java index 46490ac6908..f70a8398a21 100644 --- a/api/src/com/cloud/agent/api/ClusterSyncCommand.java +++ b/api/src/com/cloud/agent/api/ClusterSyncCommand.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Cloud.com, Inc. All rights reserved. +/* Copyright (C) 2012 Citrix.com, Inc. All rights reserved. * * This software is licensed under the GNU General Public License v3 or later. * @@ -46,11 +46,11 @@ public class ClusterSyncCommand extends Command implements CronCommand { public void incrStep(){ _steps++; - if (_steps>_skipSteps)_steps=0; + if (_steps>=_skipSteps)_steps=0; } - public boolean isRightStep(){ - return (_steps==_skipSteps); + public boolean isRightStep(){ + return (_steps==0); } public long getClusterId() { diff --git a/api/src/com/cloud/agent/api/StartupRoutingCommand.java b/api/src/com/cloud/agent/api/StartupRoutingCommand.java index 616b5c7f10f..c5fae0738de 100755 --- a/api/src/com/cloud/agent/api/StartupRoutingCommand.java +++ b/api/src/com/cloud/agent/api/StartupRoutingCommand.java @@ -23,6 +23,7 @@ import java.util.Map; import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Networks.RouterPrivateIpStrategy; +import com.cloud.utils.Pair; import com.cloud.vm.VirtualMachine.State; public class StartupRoutingCommand extends StartupCommand { @@ -48,6 +49,7 @@ public class StartupRoutingCommand extends StartupCommand { long dom0MinMemory; boolean poolSync; Map vms; + HashMap> _allStates; String caps; String pool; HypervisorType hypervisorType; @@ -121,6 +123,10 @@ getHostDetails().put(RouterPrivateIpStrategy.class.getCanonicalName(), privIpStr this.vms.put(vm_name, new VmState(vms.get(vm_name), null)); } } + + public void setClusterVMStateChanges(HashMap> allStates) { + _allStates = allStates; + } public int getCpus() { return cpus; @@ -145,6 +151,10 @@ getHostDetails().put(RouterPrivateIpStrategy.class.getCanonicalName(), privIpStr public Map getVmStates() { return vms; } + + public HashMap> getClusterVMStateChanges() { + return _allStates; + } public void setSpeed(long speed) { this.speed = speed; diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index d6675a959f7..3100fda09b7 100755 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -1074,9 +1074,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } } - - s_vms.put(_cluster, _name, vmName, State.Starting); - + + synchronized (s_vms) { + s_logger.debug("1. The VM " + vmName + " is in Starting state."); + s_vms.put(_cluster, _name, vmName, State.Starting); + } + Host host = Host.getByUuid(conn, _host.uuid); vm = createVmFromTemplate(conn, vmSpec, host); @@ -1156,11 +1159,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new StartAnswer(cmd, msg); } finally { synchronized (s_vms) { - if (state != State.Stopped) { - s_vms.put(_cluster, _name, vmName, state); - } else { - s_vms.remove(_cluster, _name, vmName); - } + if (state != State.Stopped) { + s_logger.debug("2. The VM " + vmName + " is in " + state + " state."); + s_vms.put(_cluster, _name, vmName, state); + } else { + s_logger.debug("The VM is in stopped state, detected problem during startup : " + vmName); + s_vms.remove(_cluster, _name, vmName); + } } } } @@ -2134,6 +2139,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Integer vncPort = null; if (state == State.Running) { synchronized (s_vms) { + s_logger.debug("3. The VM " + vmName + " is in " + State.Running + " state"); s_vms.put(_cluster, _name, vmName, State.Running); } } @@ -2156,7 +2162,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe for (NicTO nic : nics) { getNetwork(conn, nic); } - s_vms.put(_cluster, _name, vm.getName(), State.Migrating); + synchronized (s_vms) { + s_logger.debug("4. The VM " + vm.getName() + " is in " + State.Migrating + " state"); + s_vms.put(_cluster, _name, vm.getName(), State.Migrating); + } return new PrepareForMigrationAnswer(cmd); } catch (Exception e) { @@ -2391,7 +2400,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe State state = null; state = s_vms.getState(_cluster, vmName); - s_vms.put(_cluster, _name, vmName, State.Stopping); + + synchronized (s_vms) { + s_logger.debug("5. The VM " + vmName + " is in " + State.Stopping + " state"); + s_vms.put(_cluster, _name, vmName, State.Stopping); + } try { Set vms = VM.getByNameLabel(conn, vmName); @@ -2454,7 +2467,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.warn(msg, e); return new MigrateAnswer(cmd, false, msg, null); } finally { - s_vms.put(_cluster, _name, vmName, state); + synchronized (s_vms) { + s_logger.debug("6. The VM " + vmName + " is in " + State.Stopping + " state"); + s_vms.put(_cluster, _name, vmName, state); + } } } @@ -2576,7 +2592,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe @Override public RebootAnswer execute(RebootCommand cmd) { Connection conn = getConnection(); - s_vms.put(_cluster, _name, cmd.getVmName(), State.Starting); + synchronized (s_vms) { + s_logger.debug("7. The VM " + cmd.getVmName() + " is in " + State.Starting + " state"); + s_vms.put(_cluster, _name, cmd.getVmName(), State.Starting); + } try { Set vms = null; try { @@ -2599,7 +2618,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } return new RebootAnswer(cmd, "reboot succeeded", null, null); } finally { - s_vms.put(_cluster, _name, cmd.getVmName(), State.Running); + synchronized (s_vms) { + s_logger.debug("8. The VM " + cmd.getVmName() + " is in " + State.Running + " state"); + s_vms.put(_cluster, _name, cmd.getVmName(), State.Running); + } } } @@ -3060,8 +3082,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (vms.size() == 0) { - s_logger.warn("VM does not exist on XenServer" + _host.uuid); - s_vms.remove(_cluster, _name, vmName); + synchronized (s_vms) { + s_logger.info("VM does not exist on XenServer" + _host.uuid); + s_vms.remove(_cluster, _name, vmName); + } return new StopAnswer(cmd, "VM does not exist", 0 , 0L, 0L); } Long bytesSent = 0L; @@ -3082,7 +3106,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } State state = s_vms.getState(_cluster, vmName); - s_vms.put(_cluster, _name, vmName, State.Stopping); + + synchronized (s_vms) { + s_logger.debug("9. The VM " + vmName + " is in " + State.Stopping + " state"); + s_vms.put(_cluster, _name, vmName, State.Stopping); + } try { if (vmr.powerState == VmPowerState.RUNNING) { @@ -3143,7 +3171,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String msg = "VM destroy failed in Stop " + vmName + " Command due to " + e.getMessage(); s_logger.warn(msg, e); } finally { - s_vms.put(_cluster, _name, vmName, state); + synchronized (s_vms) { + s_logger.debug("10. The VM " + vmName + " is in " + state + " state"); + s_vms.put(_cluster, _name, vmName, state); + } } } } @@ -3958,6 +3989,20 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe cmd.setHypervisorType(HypervisorType.XenServer); cmd.setCluster(_cluster); cmd.setPoolSync(false); + + Pool pool; + try { + pool = Pool.getByUuid(conn, _host.pool); + Pool.Record poolr = pool.getRecord(conn); + + Host.Record hostr = poolr.master.getRecord(conn); + if (_host.uuid.equals(hostr.uuid)) { + HashMap> allStates=fullClusterSync(conn); + cmd.setClusterVMStateChanges(allStates); + } + } catch (Throwable e) { + s_logger.warn("Check for master failed, failing the FULL Cluster sync command"); + } StartupStorageCommand sscmd = initializeLocalSR(conn); if (sscmd != null) { @@ -6522,29 +6567,28 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Host.Record hostr = poolr.master.getRecord(conn); if (!_host.uuid.equals(hostr.uuid)) { - return new ClusterSyncAnswer(cmd.getClusterId()); + return new Answer(cmd); } - } catch (Exception e) { + } catch (Throwable e) { s_logger.warn("Check for master failed, failing the Cluster sync command"); - return new ClusterSyncAnswer(cmd.getClusterId()); - } + return new Answer(cmd); + } HashMap> newStates = deltaClusterSync(conn); cmd.incrStep(); if (cmd.isRightStep()){ // do full sync - HashMap> allStates=fullClusterSync(conn); - return new ClusterSyncAnswer(cmd.getClusterId(), newStates, allStates); + HashMap> allStates=fullClusterSync(conn); + return new ClusterSyncAnswer(cmd.getClusterId(), newStates, allStates); } else { + cmd.incrStep(); return new ClusterSyncAnswer(cmd.getClusterId(), newStates); } } - - + protected HashMap> fullClusterSync(Connection conn) { - s_vms.clear(_cluster); + XenServerPoolVms vms = new XenServerPoolVms(); try { - Host lhost = Host.getByUuid(conn, _host.uuid); Map vm_map = VM.getAllRecords(conn); //USE THIS TO GET ALL VMS FROM A CLUSTER for (VM.Record record: vm_map.values()) { if (record.isControlDomain || record.isASnapshot || record.isATemplate) { @@ -6557,35 +6601,32 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String host_uuid = null; if( ! isRefNull(host) ) { host_uuid = host.getUuid(conn); - s_vms.put(_cluster, host_uuid, vm_name, state); + vms.put(_cluster, host_uuid, vm_name, state); } if (s_logger.isTraceEnabled()) { s_logger.trace("VM " + vm_name + ": powerstate = " + ps + "; vm state=" + state.toString()); - } + } } } catch (final Throwable e) { - String msg = "Unable to get vms through host " + _host.uuid + " due to to " + e.toString(); + String msg = "Unable to get vms through host " + _host.uuid + " due to to " + e.toString(); s_logger.warn(msg, e); throw new CloudRuntimeException(msg); } - return s_vms.getClusterVmState(_cluster); + return vms.getClusterVmState(_cluster); } - + protected HashMap> deltaClusterSync(Connection conn) { - HashMap> newStates; - HashMap> oldStates = null; - final HashMap> changes = new HashMap>(); - - newStates = getAllVms(conn); - if (newStates == null) { - s_logger.warn("Unable to get the vm states so no state sync at this point."); - return null; - } - + synchronized (s_vms) { - oldStates = new HashMap>(s_vms.size(_cluster)); + HashMap> newStates = getAllVms(conn); + if (newStates == null) { + s_logger.warn("Unable to get the vm states so no state sync at this point."); + return null; + } + + HashMap> oldStates = new HashMap>(s_vms.size(_cluster)); oldStates.putAll(s_vms.getClusterVmState(_cluster)); for (final Map.Entry> entry : newStates.entrySet()) { @@ -6668,6 +6709,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.warn("Ignoring VM " + vm + " in migrating state."); } else { State newState = State.Stopped; + s_logger.warn("The VM is now missing marking it as Stopped " + vm); changes.put(vm, new Pair(host_uuid, newState)); } } diff --git a/core/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java b/core/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java index 59c4e45a867..3cb6a9e93ea 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java +++ b/core/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java @@ -1,9 +1,22 @@ +/* Copyright (C) 2012 Citrix.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ package com.cloud.hypervisor.xen.resource; -import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; import org.apache.log4j.Logger; @@ -13,7 +26,7 @@ import com.cloud.vm.VirtualMachine.State; public class XenServerPoolVms { private static final Logger s_logger = Logger.getLogger(XenServerPoolVms.class); - HashMap>> _cluster_vms = + private HashMap>> _cluster_vms = new HashMap>>(); public HashMap> getClusterVmState(String clusterId){ @@ -28,9 +41,7 @@ public class XenServerPoolVms { public void clear(String clusterId){ HashMap> _vms= getClusterVmState(clusterId); - synchronized (_vms) { - _vms.clear(); - } + _vms.clear(); } public State getState(String clusterId, String name){ @@ -41,34 +52,23 @@ public class XenServerPoolVms { public void put(String clusterId, String hostUuid, String name, State state){ HashMap> vms= getClusterVmState(clusterId); - synchronized (vms) { - vms.put(name, new Pair(hostUuid, state)); - } + vms.put(name, new Pair(hostUuid, state)); } public void remove(String clusterId, String hostUuid, String name){ HashMap> vms= getClusterVmState(clusterId); - synchronized (vms) { - vms.remove(name); - } + vms.remove(name); } public void putAll(String clusterId, HashMap> new_vms){ HashMap> vms= getClusterVmState(clusterId); - synchronized (vms) { - vms.putAll(new_vms); - } + vms.putAll(new_vms); } public int size(String clusterId){ HashMap> vms= getClusterVmState(clusterId); return vms.size(); } - - - public static void main(String args[]){ - XenServerPoolVms vms = new XenServerPoolVms(); - } @Override public String toString(){ diff --git a/core/src/com/cloud/vm/VMInstanceVO.java b/core/src/com/cloud/vm/VMInstanceVO.java index df02d666230..74b9246d863 100644 --- a/core/src/com/cloud/vm/VMInstanceVO.java +++ b/core/src/com/cloud/vm/VMInstanceVO.java @@ -421,5 +421,32 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + VMInstanceVO other = (VMInstanceVO) obj; + if (id != other.id) + return false; + return true; + } + + } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 789b0d19687..7762822af62 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -19,11 +19,14 @@ package com.cloud.vm; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -104,6 +107,7 @@ import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; +import com.cloud.resource.ResourceManager; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -223,7 +227,11 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene protected Adapters _planners; @Inject(adapter = HostAllocator.class) - protected Adapters _hostAllocators; + protected Adapters _hostAllocators; + + @Inject + protected ResourceManager _resourceMgr; + Map> _vmGurus = new HashMap>(); protected StateMachine2 _stateMachine; @@ -1603,55 +1611,96 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } - - public Commands deltaSync(Map> newStates) { + public void deltaSync(Map> newStates) { Map states = convertToInfos(newStates); - Commands commands = new Commands(OnError.Continue); for (Map.Entry entry : states.entrySet()) { AgentVmInfo info = entry.getValue(); - VMInstanceVO vm = info.vm; - Command command = null; if (vm != null) { - String host_guid = info.getHostUuid(); - Host host = _hostDao.findByGuid(host_guid); + Host host = _hostDao.findByGuid(info.getHostUuid()); long hId = host.getId(); HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); command = compareState(hId, vm, info, false, hvGuru.trackVmHostChange()); } else { if (s_logger.isDebugEnabled()) { - s_logger.debug("Cleaning up a VM that is no longer found: " + info.name); + s_logger.debug("Cleaning up a VM that is no longer found : " + info.name); } command = cleanup(info.name); } + if (command != null){ + try { + Host host = _hostDao.findByGuid(info.getHostUuid()); + if (host != null){ + Answer answer = _agentMgr.send(host.getId(), cleanup(info.name)); + if (!answer.getResult()) { + s_logger.warn("Unable to stop a VM due to " + answer.getDetails()); + } + } + } catch (Exception e) { + s_logger.warn("Unable to stop a VM due to " + e.getMessage()); + } + } + } + } - if (command != null) { - commands.addCommand(command); + + public void fullSync(final long clusterId, Map> newStates, boolean init) { + Map infos = convertToInfos(newStates); + Set set_vms = Collections.synchronizedSet(new HashSet()); + set_vms.addAll(_vmDao.listByClusterId(clusterId)); + set_vms.addAll(_vmDao.listStartingByClusterId(clusterId)); + + for (VMInstanceVO vm : set_vms) { + if (vm.isRemoved() || vm.getState() == State.Destroyed || vm.getState() == State.Expunging) continue; + AgentVmInfo info = infos.remove(vm.getId()); + if (init){ // mark the VMs real state on initial sync + VMInstanceVO castedVm = null; + if (info == null){ + if (vm.getState() == State.Running || vm.getState() == State.Starting) { // only work on VMs which were supposed to be starting/running earlier + info = new AgentVmInfo(vm.getInstanceName(), getVmGuru(vm), vm, State.Stopped); + castedVm = info.guru.findById(vm.getId()); + try { + Host host = _hostDao.findByGuid(info.getHostUuid()); + long hostId = host == null ? (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId()) : host.getId(); + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(castedVm.getHypervisorType()); + Command command = compareState(hostId, castedVm, info, true, hvGuru.trackVmHostChange()); + if (command != null){ + Answer answer = _agentMgr.send(hostId, command); + if (!answer.getResult()) { + s_logger.warn("Failed to update state of the VM due to " + answer.getDetails()); + } + } + } catch (Exception e) { + s_logger.warn("Unable to update state of the VM due to exception " + e.getMessage()); + e.printStackTrace(); + } + } + } + } + + } + + for (final AgentVmInfo left : infos.values()) { + try { + Host host = _hostDao.findByGuid(left.getHostUuid()); + if (host != null){ + s_logger.warn("Stopping a VM which we do not have any record of " + left.name); + Answer answer = _agentMgr.send(host.getId(), cleanup(left.name)); + if (!answer.getResult()) { + s_logger.warn("Unable to stop a VM due to " + answer.getDetails()); + } + } + } catch (Exception e) { + s_logger.warn("Unable to stop a VM due to " + e.getMessage()); } } - return commands; } - - public Commands fullSync(final long clusterId, Map> newStates) { - Commands commands = new Commands(OnError.Continue); - Map infos = convertToInfos(newStates); - final List vms = _vmDao.listByClusterId(clusterId); - for (VMInstanceVO vm : vms) { - infos.remove(vm.getId()); - } - for (final AgentVmInfo left : infos.values()) { - s_logger.warn("Stopping a VM that we have no record of: " + left.name); - commands.addCommand(cleanup(left.name)); - } - return commands; - } - protected Map convertToInfos(final Map> newStates) { final HashMap map = new HashMap(); if (newStates == null) { @@ -1960,7 +2009,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene ClusterSyncAnswer hs = (ClusterSyncAnswer) answer; if (hs.isFull()) { deltaSync(hs.getNewStates()); - fullSync(hs.getClusterId(), hs.getAllStates()); + fullSync(hs.getClusterId(), hs.getAllStates(), false); } else if (hs.isDelta()) { deltaSync(hs.getNewStates()); } @@ -2030,7 +2079,13 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene long agentId = agent.getId(); Long clusterId = agent.getClusterId(); - if (agent.getHypervisorType() == HypervisorType.XenServer || agent.getHypervisorType() == HypervisorType.Xen){ // only fro Xen + if (agent.getHypervisorType() == HypervisorType.XenServer || agent.getHypervisorType() == HypervisorType.Xen){ // only for Xen + StartupRoutingCommand startup = (StartupRoutingCommand) cmd; + HashMap> allStates = startup.getClusterVMStateChanges(); + if (allStates != null){ + this.fullSync(clusterId, allStates, true); + } + ClusterSyncCommand syncCmd = new ClusterSyncCommand(Integer.parseInt(Config.ClusterDeltaSyncInterval.getDefaultValue()), Integer.parseInt(Config.ClusterFullSyncSkipSteps.getDefaultValue()), clusterId); try { diff --git a/server/src/com/cloud/vm/dao/VMInstanceDao.java b/server/src/com/cloud/vm/dao/VMInstanceDao.java index 80440bc15bf..68bd7eed8d4 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDao.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDao.java @@ -82,5 +82,6 @@ public interface VMInstanceDao extends GenericDao, StateDao< public Long countAllocatedVirtualRoutersForAccount(long accountId); List listByClusterId(long clusterId); + List listStartingByClusterId(long clusterId); // get all the VMs even starting one on this cluster List listVmsMigratingFromHost(Long hostId); } diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index d2b6322790b..8d41e8bda1b 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -50,6 +50,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem public static final Logger s_logger = Logger.getLogger(VMInstanceDaoImpl.class); protected final SearchBuilder VMClusterSearch; + protected final SearchBuilder StartingVMClusterSearch; protected final SearchBuilder IdStatesSearch; protected final SearchBuilder AllFieldsSearch; protected final SearchBuilder ZoneTemplateNonExpungedSearch; @@ -78,6 +79,13 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem hostSearch.and("clusterId", hostSearch.entity().getClusterId(), SearchCriteria.Op.EQ); VMClusterSearch.done(); + + StartingVMClusterSearch = createSearchBuilder(); + SearchBuilder hostSearch1 = _hostDao.createSearchBuilder(); + StartingVMClusterSearch.join("hostSearch1", hostSearch1, hostSearch1.entity().getId(), StartingVMClusterSearch.entity().getHostId(), JoinType.INNER); + hostSearch1.and("clusterId", hostSearch1.entity().getClusterId(), SearchCriteria.Op.EQ); + StartingVMClusterSearch.done(); + AllFieldsSearch = createSearchBuilder(); AllFieldsSearch.and("host", AllFieldsSearch.entity().getHostId(), Op.EQ); AllFieldsSearch.and("lastHost", AllFieldsSearch.entity().getLastHostId(), Op.EQ); @@ -182,6 +190,14 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem return listBy(sc); } + + + @Override + public List listStartingByClusterId(long clusterId) { + SearchCriteria sc = StartingVMClusterSearch.create(); + sc.setJoinParameters("hostSearch1", "clusterId", clusterId); + return listBy(sc); + } @Override public List listByZoneIdAndType(long zoneId, VirtualMachine.Type type) {