mirror of https://github.com/apache/cloudstack.git
bug 12189: bringing vm sync at par with master fixes
This commit is contained in:
parent
4ccc2c3a50
commit
17b1324284
|
|
@ -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<String, Pair<String, State>> _newStates;
|
||||
private HashMap<String, Pair<String, State>> _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<String, Pair<String, State>> newStates){
|
||||
_clusterId = clusterId;
|
||||
_newStates = newStates;
|
||||
_allStates = null;
|
||||
_type = DELTA_SYNC;
|
||||
result = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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<String, VmState> vms;
|
||||
HashMap<String, Pair<String, State>> _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<String, Pair<String, State>> allStates) {
|
||||
_allStates = allStates;
|
||||
}
|
||||
|
||||
public int getCpus() {
|
||||
return cpus;
|
||||
|
|
@ -145,6 +151,10 @@ getHostDetails().put(RouterPrivateIpStrategy.class.getCanonicalName(), privIpStr
|
|||
public Map<String, VmState> getVmStates() {
|
||||
return vms;
|
||||
}
|
||||
|
||||
public HashMap<String, Pair<String, State>> getClusterVMStateChanges() {
|
||||
return _allStates;
|
||||
}
|
||||
|
||||
public void setSpeed(long speed) {
|
||||
this.speed = speed;
|
||||
|
|
|
|||
|
|
@ -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<VM> 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<VM> 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<String, Pair<String, State>> 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<String, Pair<String, State>> newStates = deltaClusterSync(conn);
|
||||
cmd.incrStep();
|
||||
if (cmd.isRightStep()){
|
||||
// do full sync
|
||||
HashMap<String, Pair<String, State>> allStates=fullClusterSync(conn);
|
||||
return new ClusterSyncAnswer(cmd.getClusterId(), newStates, allStates);
|
||||
HashMap<String, Pair<String, State>> allStates=fullClusterSync(conn);
|
||||
return new ClusterSyncAnswer(cmd.getClusterId(), newStates, allStates);
|
||||
}
|
||||
else {
|
||||
cmd.incrStep();
|
||||
return new ClusterSyncAnswer(cmd.getClusterId(), newStates);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected HashMap<String, Pair<String, State>> fullClusterSync(Connection conn) {
|
||||
s_vms.clear(_cluster);
|
||||
XenServerPoolVms vms = new XenServerPoolVms();
|
||||
try {
|
||||
Host lhost = Host.getByUuid(conn, _host.uuid);
|
||||
Map<VM, VM.Record> 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<String, Pair<String, State>> deltaClusterSync(Connection conn) {
|
||||
HashMap<String, Pair<String, State>> newStates;
|
||||
HashMap<String, Pair<String, State>> oldStates = null;
|
||||
|
||||
final HashMap<String, Pair<String, State>> changes = new HashMap<String, Pair<String, State>>();
|
||||
|
||||
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<String, Pair<String, State>>(s_vms.size(_cluster));
|
||||
HashMap<String, Pair<String, State>> 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<String, Pair<String, State>> oldStates = new HashMap<String, Pair<String, State>>(s_vms.size(_cluster));
|
||||
oldStates.putAll(s_vms.getClusterVmState(_cluster));
|
||||
|
||||
for (final Map.Entry<String, Pair<String, State>> 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<String, State>(host_uuid, newState));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
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<String/* clusterId */, HashMap<String/* vm name */, Pair<String/* host uuid */, State/* vm state */>>> _cluster_vms =
|
||||
private HashMap<String/* clusterId */, HashMap<String/* vm name */, Pair<String/* host uuid */, State/* vm state */>>> _cluster_vms =
|
||||
new HashMap<String, HashMap<String, Pair<String, State>>>();
|
||||
|
||||
public HashMap<String, Pair<String, State>> getClusterVmState(String clusterId){
|
||||
|
|
@ -28,9 +41,7 @@ public class XenServerPoolVms {
|
|||
|
||||
public void clear(String clusterId){
|
||||
HashMap<String, Pair<String, State>> _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<String, Pair<String, State>> vms= getClusterVmState(clusterId);
|
||||
synchronized (vms) {
|
||||
vms.put(name, new Pair<String, State>(hostUuid, state));
|
||||
}
|
||||
vms.put(name, new Pair<String, State>(hostUuid, state));
|
||||
}
|
||||
|
||||
public void remove(String clusterId, String hostUuid, String name){
|
||||
HashMap<String, Pair<String, State>> vms= getClusterVmState(clusterId);
|
||||
synchronized (vms) {
|
||||
vms.remove(name);
|
||||
}
|
||||
vms.remove(name);
|
||||
}
|
||||
|
||||
public void putAll(String clusterId, HashMap<String, Pair<String, State>> new_vms){
|
||||
HashMap<String, Pair<String, State>> vms= getClusterVmState(clusterId);
|
||||
synchronized (vms) {
|
||||
vms.putAll(new_vms);
|
||||
}
|
||||
vms.putAll(new_vms);
|
||||
}
|
||||
|
||||
public int size(String clusterId){
|
||||
HashMap<String, Pair<String, State>> vms= getClusterVmState(clusterId);
|
||||
return vms.size();
|
||||
}
|
||||
|
||||
|
||||
public static void main(String args[]){
|
||||
XenServerPoolVms vms = new XenServerPoolVms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
|
|
|
|||
|
|
@ -421,5 +421,32 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
|
|||
toString = new StringBuilder("VM[").append(type.toString()).append("|").append(instanceName).append("]").toString();
|
||||
}
|
||||
return toString;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (int) (id ^ (id >>> 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<DeploymentPlanner> _planners;
|
||||
|
||||
@Inject(adapter = HostAllocator.class)
|
||||
protected Adapters<HostAllocator> _hostAllocators;
|
||||
protected Adapters<HostAllocator> _hostAllocators;
|
||||
|
||||
@Inject
|
||||
protected ResourceManager _resourceMgr;
|
||||
|
||||
|
||||
Map<VirtualMachine.Type, VirtualMachineGuru<? extends VMInstanceVO>> _vmGurus = new HashMap<VirtualMachine.Type, VirtualMachineGuru<? extends VMInstanceVO>>();
|
||||
protected StateMachine2<State, VirtualMachine.Event, VirtualMachine> _stateMachine;
|
||||
|
|
@ -1603,55 +1611,96 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
|
|||
}
|
||||
|
||||
|
||||
|
||||
public Commands deltaSync(Map<String, Pair<String, State>> newStates) {
|
||||
public void deltaSync(Map<String, Pair<String, State>> newStates) {
|
||||
Map<Long, AgentVmInfo> states = convertToInfos(newStates);
|
||||
Commands commands = new Commands(OnError.Continue);
|
||||
|
||||
for (Map.Entry<Long, AgentVmInfo> 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 <deltaSync>: " + 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<String, Pair<String, State>> newStates, boolean init) {
|
||||
Map<Long, AgentVmInfo> infos = convertToInfos(newStates);
|
||||
Set<VMInstanceVO> set_vms = Collections.synchronizedSet(new HashSet<VMInstanceVO>());
|
||||
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<String, Pair<String, State>> newStates) {
|
||||
Commands commands = new Commands(OnError.Continue);
|
||||
Map<Long, AgentVmInfo> infos = convertToInfos(newStates);
|
||||
final List<VMInstanceVO> 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<Long, AgentVmInfo> convertToInfos(final Map<String, Pair<String, State>> newStates) {
|
||||
final HashMap<Long, AgentVmInfo> map = new HashMap<Long, AgentVmInfo>();
|
||||
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<String, Pair<String, State>> 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 {
|
||||
|
|
|
|||
|
|
@ -82,5 +82,6 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
|
|||
public Long countAllocatedVirtualRoutersForAccount(long accountId);
|
||||
|
||||
List<VMInstanceVO> listByClusterId(long clusterId);
|
||||
List<VMInstanceVO> listStartingByClusterId(long clusterId); // get all the VMs even starting one on this cluster
|
||||
List<VMInstanceVO> listVmsMigratingFromHost(Long hostId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
|||
public static final Logger s_logger = Logger.getLogger(VMInstanceDaoImpl.class);
|
||||
|
||||
protected final SearchBuilder<VMInstanceVO> VMClusterSearch;
|
||||
protected final SearchBuilder<VMInstanceVO> StartingVMClusterSearch;
|
||||
protected final SearchBuilder<VMInstanceVO> IdStatesSearch;
|
||||
protected final SearchBuilder<VMInstanceVO> AllFieldsSearch;
|
||||
protected final SearchBuilder<VMInstanceVO> ZoneTemplateNonExpungedSearch;
|
||||
|
|
@ -78,6 +79,13 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
|||
hostSearch.and("clusterId", hostSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
|
||||
VMClusterSearch.done();
|
||||
|
||||
|
||||
StartingVMClusterSearch = createSearchBuilder();
|
||||
SearchBuilder<HostVO> 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<VMInstanceVO, Long> implem
|
|||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<VMInstanceVO> listStartingByClusterId(long clusterId) {
|
||||
SearchCriteria<VMInstanceVO> sc = StartingVMClusterSearch.create();
|
||||
sc.setJoinParameters("hostSearch1", "clusterId", clusterId);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMInstanceVO> listByZoneIdAndType(long zoneId, VirtualMachine.Type type) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue