Use seperate path to sync VM metadata for XS

VM status sync only does VM status sync
This commit is contained in:
Anthony Xu 2014-03-05 15:08:48 -08:00
parent d1c0b81dc1
commit ab1d3af460
16 changed files with 271 additions and 149 deletions

View File

@ -32,16 +32,12 @@ public class HostVmStateReportEntry {
// host name or host uuid
String host;
// XS needs Xen Tools version info
String hostToolsVersion;
public HostVmStateReportEntry() {
}
public HostVmStateReportEntry(PowerState state, String host, String hostToolsVersion) {
public HostVmStateReportEntry(PowerState state, String host) {
this.state = state;
this.host = host;
this.hostToolsVersion = hostToolsVersion;
}
public PowerState getState() {
@ -51,8 +47,4 @@ public class HostVmStateReportEntry {
public String getHost() {
return host;
}
public String getHostToolsVersion() {
return hostToolsVersion;
}
}

View File

@ -18,18 +18,18 @@ package com.cloud.agent.api;
import java.util.HashMap;
import com.cloud.utils.Ternary;
import com.cloud.utils.Pair;
import com.cloud.vm.VirtualMachine.State;
public class ClusterSyncAnswer extends Answer {
private long _clusterId;
private HashMap<String, Ternary<String, State, String>> _newStates;
private HashMap<String, Pair<String, State>> _newStates;
private boolean _isExecuted = false;
// this is here because a cron command answer is being sent twice
// AgentAttache.processAnswers
// AgentManagerImpl.notifyAnswersToMonitors
public boolean isExceuted() {
public boolean isExecuted() {
return _isExecuted;
}
@ -37,7 +37,7 @@ public class ClusterSyncAnswer extends Answer {
_isExecuted = true;
}
public ClusterSyncAnswer(long clusterId, HashMap<String, Ternary<String, State, String>> newStates) {
public ClusterSyncAnswer(long clusterId, HashMap<String, Pair<String, State>> newStates) {
_clusterId = clusterId;
_newStates = newStates;
result = true;
@ -47,7 +47,7 @@ public class ClusterSyncAnswer extends Answer {
return _clusterId;
}
public HashMap<String, Ternary<String, State, String>> getNewStates() {
public HashMap<String, Pair<String, State>> getNewStates() {
return _newStates;
}

View File

@ -0,0 +1,52 @@
// 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.agent.api;
import java.util.HashMap;
public class ClusterVMMetaDataSyncAnswer extends Answer {
private long _clusterId;
private HashMap<String, String> _vmMetaDatum;
private boolean _isExecuted=false;
// this is here because a cron command answer is being sent twice
// AgentAttache.processAnswers
// AgentManagerImpl.notifyAnswersToMonitors
public boolean isExecuted(){
return _isExecuted;
}
public void setExecuted(){
_isExecuted = true;
}
public ClusterVMMetaDataSyncAnswer(long clusterId, HashMap<String, String> vmMetaDatum){
_clusterId = clusterId;
_vmMetaDatum = vmMetaDatum;
result = true;
}
public long getClusterId() {
return _clusterId;
}
public HashMap<String, String> getVMMetaDatum() {
return _vmMetaDatum;
}
}

View File

@ -0,0 +1,47 @@
// 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.agent.api;
public class ClusterVMMetaDataSyncCommand extends Command implements CronCommand {
int _interval;
long _clusterId;
public ClusterVMMetaDataSyncCommand() {
}
public ClusterVMMetaDataSyncCommand(int interval, long clusterId){
_interval = interval;
_clusterId = clusterId;
}
@Override
public int getInterval() {
return _interval;
}
public long getClusterId() {
return _clusterId;
}
@Override
public boolean executeInSequence() {
return false;
}
}

View File

@ -22,7 +22,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.Ternary;
import com.cloud.utils.Pair;
import com.cloud.vm.VirtualMachine.State;
public class StartupRoutingCommand extends StartupCommand {
@ -63,7 +63,7 @@ public class StartupRoutingCommand extends StartupCommand {
// TODO vmsync
// deprecated, will delete after full replacement
Map<String, VmState> vms;
HashMap<String, Ternary<String, State, String>> _clusterVMStates;
HashMap<String, Pair<String, State>> _clusterVMStates;
String caps;
String pool;
@ -137,7 +137,7 @@ public class StartupRoutingCommand extends StartupCommand {
}
}
public void setClusterVMStateChanges(HashMap<String, Ternary<String, State, String>> allStates) {
public void setClusterVMStateChanges(HashMap<String, Pair<String, State>> allStates) {
_clusterVMStates = allStates;
}
@ -169,7 +169,7 @@ public class StartupRoutingCommand extends StartupCommand {
return vms;
}
public HashMap<String, Ternary<String, State, String>> getClusterVMStateChanges() {
public HashMap<String, Pair<String, State>> getClusterVMStateChanges() {
return _clusterVMStates;
}

View File

@ -80,6 +80,8 @@ import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.ClusterSyncAnswer;
import com.cloud.agent.api.ClusterSyncCommand;
import com.cloud.agent.api.ClusterVMMetaDataSyncCommand;
import com.cloud.agent.api.ClusterVMMetaDataSyncAnswer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.MigrateAnswer;
import com.cloud.agent.api.MigrateCommand;
@ -340,6 +342,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
static final ConfigKey<Integer> ClusterDeltaSyncInterval = new ConfigKey<Integer>("Advanced", Integer.class, "sync.interval", "60",
"Cluster Delta sync interval in seconds",
false);
static final ConfigKey<Integer> ClusterVMMetaDataSyncInterval = new ConfigKey<Integer>("Advanced", Integer.class, "vmmetadata.sync.interval", "180", "Cluster VM metadata sync interval in seconds",
false);
static final ConfigKey<Boolean> VmJobEnabled = new ConfigKey<Boolean>("Advanced",
Boolean.class, "vm.job.enabled", "true",
@ -2521,7 +2525,35 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
return commands;
}
public void deltaSync(Map<String, Ternary<String, State, String>> newStates) {
// this is XenServer specific
public void syncVMMetaData(Map<String, String> vmMetadatum) {
if (vmMetadatum == null || vmMetadatum.isEmpty()) {
return;
}
for (Map.Entry<String, String> entry : vmMetadatum.entrySet()) {
String name = entry.getKey();
String platform = entry.getValue();
if (platform == null || platform.isEmpty()) {
continue;
}
VMInstanceVO vm = _vmDao.findVMByInstanceName(name);
if (vm != null && vm.getType() == VirtualMachine.Type.User) {
// track platform info
UserVmVO userVm = _userVmDao.findById(vm.getId());
_userVmDao.loadDetails(userVm);
userVm.setDetail("platform", platform);
String pvdriver = "xenserver56";
if ( platform.contains("device_id")) {
pvdriver = "xenserver61";
}
userVm.setDetail("hypervisortoolsversion", pvdriver);
_userVmDao.saveDetails(userVm);
}
}
}
public void deltaSync(Map<String, Pair<String, State>> newStates) {
Map<Long, AgentVmInfo> states = convertToInfos(newStates);
for (Map.Entry<Long, AgentVmInfo> entry : states.entrySet()) {
@ -2556,7 +2588,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
}
public void fullSync(final long clusterId, Map<String, Ternary<String, State, String>> newStates) {
public void fullSync(final long clusterId, Map<String, Pair<String, State>> newStates) {
if (newStates == null)
return;
Map<Long, AgentVmInfo> infos = convertToInfos(newStates);
@ -2686,24 +2718,24 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
protected Map<Long, AgentVmInfo> convertToInfos(final Map<String, Ternary<String, State, String>> newStates) {
protected Map<Long, AgentVmInfo> convertToInfos(final Map<String, Pair<String, State>> newStates) {
final HashMap<Long, AgentVmInfo> map = new HashMap<Long, AgentVmInfo>();
if (newStates == null) {
return map;
}
boolean is_alien_vm = true;
long alien_vm_count = -1;
for (Map.Entry<String, Ternary<String, State, String>> entry : newStates.entrySet()) {
for (Map.Entry<String, Pair<String, State>> entry : newStates.entrySet()) {
is_alien_vm = true;
String name = entry.getKey();
VMInstanceVO vm = _vmDao.findVMByInstanceName(name);
if (vm != null) {
map.put(vm.getId(), new AgentVmInfo(entry.getKey(), vm, entry.getValue().second(), entry.getValue().first(), entry.getValue().third()));
map.put(vm.getId(), new AgentVmInfo(entry.getKey(), vm, entry.getValue().second(), entry.getValue().first()));
is_alien_vm = false;
}
// alien VMs
if (is_alien_vm) {
map.put(alien_vm_count--, new AgentVmInfo(entry.getKey(), null, entry.getValue().second(), entry.getValue().first(), entry.getValue().third()));
map.put(alien_vm_count--, new AgentVmInfo(entry.getKey(), null, entry.getValue().second(), entry.getValue().first()));
s_logger.warn("Found an alien VM " + entry.getKey());
}
}
@ -2784,15 +2816,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
") stopped on host " + hostDesc + " due to storage failure", "Virtual Machine " + vm.getInstanceName() + " (id: " + vm.getId() + ") running on host [" +
vm.getHostId() + "] stopped due to storage failure.");
}
// track platform info
if (info.platform != null && !info.platform.isEmpty()) {
if (vm.getType() == VirtualMachine.Type.User) {
UserVmVO userVm = _userVmDao.findById(vm.getId());
_userVmDao.loadDetails(userVm);
userVm.setDetail("platform", info.platform);
_userVmDao.saveDetails(userVm);
}
}
if (trackExternalChange) {
if (serverState == State.Starting) {
@ -3013,6 +3036,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
hs.setExecuted();
}
}
} else if ( answer instanceof ClusterVMMetaDataSyncAnswer) {
ClusterVMMetaDataSyncAnswer cvms = (ClusterVMMetaDataSyncAnswer)answer;
if (!cvms.isExecuted()) {
syncVMMetaData(cvms.getVMMetaDatum());
cvms.setExecuted();
}
}
}
return true;
@ -3046,7 +3075,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
}
}
if(VmJobEnabled.value()) {
if (ping.getHostVmStateReport() != null) {
_syncMgr.processHostVmStatePingReport(agentId, ping.getHostVmStateReport());
@ -3105,7 +3133,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
if (allStates != null) {
fullSync(clusterId, allStates);
}
// initiate the cron job
ClusterSyncCommand syncCmd = new ClusterSyncCommand(ClusterDeltaSyncInterval.value(), clusterId);
try {
@ -3115,6 +3142,14 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
s_logger.fatal("The Cluster VM sync process failed for cluster id " + clusterId + " with ", e);
}
}
// initiate the cron job
ClusterVMMetaDataSyncCommand syncVMMetaDataCmd = new ClusterVMMetaDataSyncCommand(ClusterVMMetaDataSyncInterval.value(), clusterId);
try {
long seq_no = _agentMgr.send(agentId, new Commands(syncVMMetaDataCmd), this);
s_logger.debug("Cluster VM metadata sync started with jobid " + seq_no);
} catch (AgentUnavailableException e) {
s_logger.fatal("The Cluster VM metadata sync process failed for cluster id " + clusterId + " with ", e);
}
} else { // for others KVM and VMWare
if (!VmJobEnabled.value()) {
StartupRoutingCommand startup = (StartupRoutingCommand)cmd;
@ -3185,33 +3220,22 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
public State state;
public String hostUuid;
public VMInstanceVO vm;
public String platform;
@SuppressWarnings("unchecked")
public AgentVmInfo(String name, VMInstanceVO vm, State state, String host, String platform) {
public AgentVmInfo(String name, VMInstanceVO vm, State state, String host) {
this.name = name;
this.state = state;
this.vm = vm;
hostUuid = host;
this.platform = platform;
}
public AgentVmInfo(String name, VMInstanceVO vm, State state, String host) {
this(name, vm, state, host, null);
}
public AgentVmInfo(String name, VMInstanceVO vm, State state) {
this(name, vm, state, null, null);
this(name, vm, state, null);
}
public String getHostUuid() {
return hostUuid;
}
public String getPlatform() {
return platform;
}
}
@Override

View File

@ -340,8 +340,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
vmDao = ComponentContext.getComponent(VMInstanceDao.class);
final List<? extends VMInstanceVO> vms = vmDao.listByHostId(hostId);
for (VMInstanceVO vm : vms) {
states.put(vm.getInstanceName(), new HostVmStateReportEntry(vm.getState() == State.Running ? PowerState.PowerOn : PowerState.PowerOff, "host-" + hostId,
null));
states.put(vm.getInstanceName(), new HostVmStateReportEntry(vm.getState() == State.Running ? PowerState.PowerOn : PowerState.PowerOff, "host-" + hostId));
}
}
/*

View File

@ -358,7 +358,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
for (Map<String, String> vmMap : vmList) {
String name = (String)vmMap.keySet().toArray()[0];
vmStates.put(name, new HostVmStateReportEntry(PowerState.valueOf(vmMap.get(name)), _guid, null));
vmStates.put(name, new HostVmStateReportEntry(PowerState.valueOf(vmMap.get(name)), _guid));
}
return vmStates;
}

View File

@ -4530,7 +4530,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
// Stopped VM around, to work-around that, reporting only powered-on VM
//
if (state == PowerState.PowerOn)
vmStates.put(vmName, new HostVmStateReportEntry(state, conn.getHostName(), null));
vmStates.put(vmName, new HostVmStateReportEntry(state, conn.getHostName()));
} catch (final LibvirtException e) {
s_logger.warn("Unable to get vms", e);
} finally {
@ -4559,7 +4559,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
// Stopped VM around, to work-around that, reporting only powered-on VM
//
if (state == PowerState.PowerOn)
vmStates.put(vmName, new HostVmStateReportEntry(state, conn.getHostName(), null));
vmStates.put(vmName, new HostVmStateReportEntry(state, conn.getHostName()));
} catch (final LibvirtException e) {
s_logger.warn("Unable to get vms", e);
} finally {

View File

@ -808,7 +808,7 @@ public class OvmResourceBase implements ServerResource, HypervisorResource {
Map<String, String> vms = OvmHost.getAllVms(_conn);
for (final Map.Entry<String, String> entry : vms.entrySet()) {
PowerState state = toPowerState(entry.getKey(), entry.getValue());
vmStates.put(entry.getKey(), new HostVmStateReportEntry(state, _conn.getIp(), null));
vmStates.put(entry.getKey(), new HostVmStateReportEntry(state, _conn.getIp()));
}
return vmStates;
}

View File

@ -280,7 +280,7 @@ public class AgentRoutingResource extends AgentStorageResource {
HashMap<String, HostVmStateReportEntry> report = new HashMap<String, HostVmStateReportEntry>();
for (String vmName : _runningVms.keySet()) {
report.put(vmName, new HostVmStateReportEntry(PowerState.PowerOn, agentHost.getName(), null));
report.put(vmName, new HostVmStateReportEntry(PowerState.PowerOn, agentHost.getName()));
}
return report;

View File

@ -5238,7 +5238,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
name = VMInternalCSName;
if (!isTemplate) {
newStates.put(name, new HostVmStateReportEntry(convertPowerState(powerState), hyperHost.getHyperHostName(), null));
newStates.put(name, new HostVmStateReportEntry(convertPowerState(powerState), hyperHost.getHyperHostName()));
}
}
}

View File

@ -99,6 +99,8 @@ import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.CleanupNetworkRulesCmd;
import com.cloud.agent.api.ClusterSyncAnswer;
import com.cloud.agent.api.ClusterSyncCommand;
import com.cloud.agent.api.ClusterVMMetaDataSyncCommand;
import com.cloud.agent.api.ClusterVMMetaDataSyncAnswer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreateStoragePoolCommand;
import com.cloud.agent.api.CreateVMSnapshotAnswer;
@ -511,6 +513,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return execute((UpdateHostPasswordCommand)cmd);
} else if (cmd instanceof ClusterSyncCommand) {
return execute((ClusterSyncCommand)cmd);
} else if (cmd instanceof ClusterVMMetaDataSyncCommand) {
return execute((ClusterVMMetaDataSyncCommand)cmd);
} else if (clazz == CheckNetworkCommand.class) {
return execute((CheckNetworkCommand)cmd);
} else if (clazz == PlugNicCommand.class) {
@ -1432,14 +1436,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
platform.put("cores-per-socket", coresPerSocket);
vm.setPlatform(conn, platform);
}
String xentoolsversion = details.get("hypervisortoolsversion");
if (xentoolsversion == null || !xentoolsversion.equalsIgnoreCase("xenserver61")) {
Map<String, String> platform = vm.getPlatform(conn);
platform.remove("device_id");
vm.setPlatform(conn, platform);
}
}
String xentoolsversion = details.get("hypervisortoolsversion");
if (xentoolsversion == null || !xentoolsversion.equalsIgnoreCase("xenserver61")) {
Map<String, String> platform = vm.getPlatform(conn);
platform.remove("device_id");
vm.setPlatform(conn, platform);
}
}
}
@ -2538,7 +2540,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
VmPowerState ps = record.powerState;
Host host = record.residentOn;
String xstoolsversion = getVMXenToolsVersion(record.platform);
String host_uuid = null;
if (!isRefNull(host)) {
try {
@ -2554,7 +2555,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
if (host_uuid.equalsIgnoreCase(_host.uuid)) {
vmStates.put(
record.nameLabel,
new HostVmStateReportEntry(convertPowerState(ps), host_uuid, xstoolsversion)
new HostVmStateReportEntry(convertPowerState(ps), host_uuid)
);
}
}
@ -2564,8 +2565,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
// TODO vmsync {
protected HashMap<String, Ternary<String, State, String>> getAllVms(Connection conn) {
final HashMap<String, Ternary<String, State, String>> vmStates = new HashMap<String, Ternary<String, State, String>>();
protected HashMap<String, Pair<String, State>> getAllVms(Connection conn) {
final HashMap<String, Pair<String, State>> vmStates = new HashMap<String, Pair<String, State>>();
Map<VM, VM.Record> vm_map = null;
for (int i = 0; i < 2; i++) {
try {
@ -2595,7 +2596,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
s_logger.trace("VM " + record.nameLabel + ": powerstate = " + ps + "; vm state=" + state.toString());
}
Host host = record.residentOn;
String platformstring = StringUtils.mapToString(record.platform);
String host_uuid = null;
if (!isRefNull(host)) {
try {
@ -2607,7 +2607,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
} catch (XmlRpcException e) {
s_logger.error("Failed to get host uuid for host " + host.toWireString(), e);
}
vmStates.put(record.nameLabel, new Ternary<String, State, String>(host_uuid, state, platformstring));
vmStates.put(record.nameLabel, new Pair<String, State>(host_uuid, state));
}
}
@ -3602,11 +3602,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return new StopAnswer(cmd, "Stop VM failed", platformstring, false);
}
/*Override by subclass*/
protected String getVMXenToolsVersion(Map<String, String> platform) {
return "xenserver56";
}
private List<VDI> getVdis(Connection conn, VM vm) {
List<VDI> vdis = new ArrayList<VDI>();
try {
@ -4480,7 +4475,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
Host.Record hostr = poolr.master.getRecord(conn);
if (_host.uuid.equals(hostr.uuid)) {
HashMap<String, Ternary<String, State, String>> allStates = fullClusterSync(conn);
HashMap<String, Pair<String, State>> allStates = fullClusterSync(conn);
cmd.setClusterVMStateChanges(allStates);
}
} catch (Throwable e) {
@ -7052,11 +7047,49 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
s_logger.warn("Check for master failed, failing the Cluster sync command");
return new Answer(cmd);
}
HashMap<String, Ternary<String, State, String>> newStates = deltaClusterSync(conn);
HashMap<String, Pair<String, State>> newStates = deltaClusterSync(conn);
return new ClusterSyncAnswer(cmd.getClusterId(), newStates);
}
protected HashMap<String, Ternary<String, State, String>> fullClusterSync(Connection conn) {
protected ClusterVMMetaDataSyncAnswer execute(final ClusterVMMetaDataSyncCommand cmd) {
Connection conn = getConnection();
//check if this is master
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)) {
return new ClusterVMMetaDataSyncAnswer(cmd.getClusterId(), null);
}
} catch (Throwable e) {
s_logger.warn("Check for master failed, failing the Cluster sync VMMetaData command");
return new ClusterVMMetaDataSyncAnswer(cmd.getClusterId(), null);
}
HashMap<String, String> vmMetadatum = clusterVMMetaDataSync(conn);
return new ClusterVMMetaDataSyncAnswer(cmd.getClusterId(), vmMetadatum);
}
protected HashMap<String, String> clusterVMMetaDataSync(Connection conn) {
final HashMap<String, String> vmMetaDatum = new HashMap<String, String>();
try {
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) {
continue; // Skip DOM0
}
vmMetaDatum.put(record.nameLabel, StringUtils.mapToString(record.platform));
}
} catch (final Throwable e) {
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 vmMetaDatum;
}
protected HashMap<String, Pair<String, State>> fullClusterSync(Connection conn) {
synchronized (_cluster.intern()) {
s_vms.clear(_cluster);
}
@ -7074,7 +7107,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
if (!isRefNull(host)) {
host_uuid = host.getUuid(conn);
synchronized (_cluster.intern()) {
s_vms.put(_cluster, host_uuid, vm_name, state, null);
s_vms.put(_cluster, host_uuid, vm_name, state);
}
}
if (s_logger.isTraceEnabled()) {
@ -7089,44 +7122,32 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return s_vms.getClusterVmState(_cluster);
}
protected HashMap<String, Ternary<String, State, String>> deltaClusterSync(Connection conn) {
final HashMap<String, Ternary<String, State, String>> changes = new HashMap<String, Ternary<String, State, String>>();
protected HashMap<String, Pair<String, State>> deltaClusterSync(Connection conn) {
final HashMap<String, Pair<String, State>> changes = new HashMap<String, Pair<String, State>>();
synchronized (_cluster.intern()) {
HashMap<String, Ternary<String, State, String>> newStates = getAllVms(conn);
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, Ternary<String, State, String>> oldStates = new HashMap<String, Ternary<String, State, String>>(s_vms.size(_cluster));
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, Ternary<String, State, String>> entry : newStates.entrySet()) {
for (final Map.Entry<String, Pair<String, State>> entry : newStates.entrySet()) {
final String vm = entry.getKey();
String platform = entry.getValue().third();
State newState = entry.getValue().second();
String host_uuid = entry.getValue().first();
final Ternary<String, State, String> oldState = oldStates.remove(vm);
final Pair<String, State> oldState = oldStates.remove(vm);
// check if platform changed
if (platform != null && oldState != null) {
if (!platform.equals(oldState.third()) && newState != State.Stopped && newState != State.Stopping) {
s_logger.warn("Detecting a change in platform for " + vm);
changes.put(vm, new Ternary<String, State, String>(host_uuid, newState, platform));
s_logger.debug("11. The VM " + vm + " is in " + newState + " state");
s_vms.put(_cluster, host_uuid, vm, newState, platform);
continue;
}
}
//check if host is changed
if (host_uuid != null && oldState != null) {
if (!host_uuid.equals(oldState.first()) && newState != State.Stopped && newState != State.Stopping) {
s_logger.warn("Detecting a change in host for " + vm);
changes.put(vm, new Ternary<String, State, String>(host_uuid, newState, platform));
changes.put(vm, new Pair<String, State>(host_uuid, newState));
s_logger.debug("11. The VM " + vm + " is in " + newState + " state");
s_vms.put(_cluster, host_uuid, vm, newState, platform);
s_vms.put(_cluster, host_uuid, vm, newState);
continue;
}
}
@ -7144,42 +7165,42 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
continue;
}
if (oldState == null) {
s_vms.put(_cluster, host_uuid, vm, newState, platform);
s_vms.put(_cluster, host_uuid, vm, newState);
s_logger.warn("Detecting a new state but couldn't find a old state so adding it to the changes: " + vm);
changes.put(vm, new Ternary<String, State, String>(host_uuid, newState, platform));
changes.put(vm, new Pair<String, State>(host_uuid, newState));
} else if (oldState.second() == State.Starting) {
if (newState == State.Running) {
s_logger.debug("12. The VM " + vm + " is in " + State.Running + " state");
s_vms.put(_cluster, host_uuid, vm, newState, platform);
s_vms.put(_cluster, host_uuid, vm, newState);
} else if (newState == State.Stopped) {
s_logger.warn("Ignoring vm " + vm + " because of a lag in starting the vm.");
}
} else if (oldState.second() == State.Migrating) {
if (newState == State.Running) {
s_logger.debug("Detected that an migrating VM is now running: " + vm);
s_vms.put(_cluster, host_uuid, vm, newState, platform);
s_vms.put(_cluster, host_uuid, vm, newState);
}
} else if (oldState.second() == State.Stopping) {
if (newState == State.Stopped) {
s_logger.debug("13. The VM " + vm + " is in " + State.Stopped + " state");
s_vms.put(_cluster, host_uuid, vm, newState, platform);
s_vms.put(_cluster, host_uuid, vm, newState);
} else if (newState == State.Running) {
s_logger.warn("Ignoring vm " + vm + " because of a lag in stopping the vm. ");
}
} else if (oldState.second() != newState) {
s_logger.debug("14. The VM " + vm + " is in " + newState + " state was " + oldState.second());
s_vms.put(_cluster, host_uuid, vm, newState, platform);
s_vms.put(_cluster, host_uuid, vm, newState);
if (newState == State.Stopped) {
/*
* if (s_vmsKilled.remove(vm)) { s_logger.debug("VM " + vm + " has been killed for storage. ");
* newState = State.Error; }
*/
}
changes.put(vm, new Ternary<String, State, String>(host_uuid, newState, null));
changes.put(vm, new Pair<String, State>(host_uuid, newState));
}
}
for (final Map.Entry<String, Ternary<String, State, String>> entry : oldStates.entrySet()) {
for (final Map.Entry<String, Pair<String, State>> entry : oldStates.entrySet()) {
final String vm = entry.getKey();
final State oldState = entry.getValue().second();
String host_uuid = entry.getValue().first();
@ -7201,7 +7222,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
} else {
State newState = State.Stopped;
s_logger.warn("The VM is now missing marking it as Stopped " + vm);
changes.put(vm, new Ternary<String, State, String>(host_uuid, newState, null));
changes.put(vm, new Pair<String, State>(host_uuid, newState));
}
}
}

View File

@ -446,12 +446,4 @@ public class XenServer610Resource extends XenServer56FP1Resource {
protected void plugDom0Vif(Connection conn, VIF dom0Vif) throws XmlRpcException, XenAPIException {
// do nothing. In xenserver 6.1 and beyond this step isn't needed.
}
@Override
protected String getVMXenToolsVersion(Map<String, String> platform) {
if (platform.containsKey("device_id")) {
return "xenserver61";
}
return "xenserver56";
}
}

View File

@ -22,18 +22,18 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.log4j.Logger;
import com.cloud.utils.Ternary;
import com.cloud.utils.Pair;
import com.cloud.vm.VirtualMachine.State;
public class XenServerPoolVms {
private static final Logger s_logger = Logger.getLogger(XenServerPoolVms.class);
private final Map<String/* clusterId */, HashMap<String/* vm name */, Ternary<String/* host uuid */, State/* vm state */, String/* PV driver version*/>>> _clusterVms =
new ConcurrentHashMap<String, HashMap<String, Ternary<String, State, String>>>();
private final Map<String/* clusterId */, HashMap<String/* vm name */, Pair<String/* host uuid */, State/* vm state */>>> _clusterVms =
new ConcurrentHashMap<String, HashMap<String, Pair<String, State>>>();
public HashMap<String, Ternary<String, State, String>> getClusterVmState(String clusterId) {
HashMap<String, Ternary<String, State, String>> _vms = _clusterVms.get(clusterId);
public HashMap<String, Pair<String, State>> getClusterVmState(String clusterId) {
HashMap<String, Pair<String, State>> _vms = _clusterVms.get(clusterId);
if (_vms == null) {
HashMap<String, Ternary<String, State, String>> vmStates = new HashMap<String, Ternary<String, State, String>>();
HashMap<String, Pair<String, State>> vmStates = new HashMap<String, Pair<String, State>>();
_clusterVms.put(clusterId, vmStates);
return vmStates;
} else
@ -41,50 +41,45 @@ public class XenServerPoolVms {
}
public void clear(String clusterId) {
HashMap<String, Ternary<String, State, String>> _vms = getClusterVmState(clusterId);
HashMap<String, Pair<String, State>> _vms = getClusterVmState(clusterId);
_vms.clear();
}
public State getState(String clusterId, String name) {
HashMap<String, Ternary<String, State, String>> vms = getClusterVmState(clusterId);
Ternary<String, State, String> pv = vms.get(name);
HashMap<String, Pair<String, State>> vms = getClusterVmState(clusterId);
Pair<String, State> pv = vms.get(name);
return pv == null ? State.Stopped : pv.second(); // if a VM is absent on the cluster, it is effectively in stopped state.
}
public Ternary<String, State, String> get(String clusterId, String name) {
HashMap<String, Ternary<String, State, String>> vms = getClusterVmState(clusterId);
public Pair<String, State> get(String clusterId, String name) {
HashMap<String, Pair<String, State>> vms = getClusterVmState(clusterId);
return vms.get(name);
}
public void put(String clusterId, String hostUuid, String name, State state, String platform) {
HashMap<String, Ternary<String, State, String>> vms = getClusterVmState(clusterId);
vms.put(name, new Ternary<String, State, String>(hostUuid, state, platform));
}
public void put(String clusterId, String hostUuid, String name, State state) {
HashMap<String, Ternary<String, State, String>> vms = getClusterVmState(clusterId);
vms.put(name, new Ternary<String, State, String>(hostUuid, state, null));
HashMap<String, Pair<String, State>> vms = getClusterVmState(clusterId);
vms.put(name, new Pair<String, State>(hostUuid, state));
}
public void remove(String clusterId, String hostUuid, String name) {
HashMap<String, Ternary<String, State, String>> vms = getClusterVmState(clusterId);
HashMap<String, Pair<String, State>> vms = getClusterVmState(clusterId);
vms.remove(name);
}
public void putAll(String clusterId, HashMap<String, Ternary<String, State, String>> newVms) {
HashMap<String, Ternary<String, State, String>> vms = getClusterVmState(clusterId);
public void putAll(String clusterId, HashMap<String, Pair<String, State>> newVms) {
HashMap<String, Pair<String, State>> vms = getClusterVmState(clusterId);
vms.putAll(newVms);
}
public int size(String clusterId) {
HashMap<String, Ternary<String, State, String>> vms = getClusterVmState(clusterId);
HashMap<String, Pair<String, State>> vms = getClusterVmState(clusterId);
return vms.size();
}
@Override
public String toString() {
StringBuilder sbuf = new StringBuilder("PoolVms=");
for (HashMap<String/* vm name */, Ternary<String/* host uuid */, State/* vm state */, String>> clusterVM : _clusterVms.values()) {
for (HashMap<String/* vm name */, Pair<String/* host uuid */, State/* vm state */>> clusterVM : _clusterVms.values()) {
for (String vmname : clusterVM.keySet()) {
sbuf.append(vmname).append("-").append(clusterVM.get(vmname).second()).append(",");
}

View File

@ -40,7 +40,7 @@ import com.cloud.agent.api.ClusterSyncAnswer;
import com.cloud.agent.api.ClusterSyncCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.hypervisor.xen.resource.XenServer610Resource;
import com.cloud.utils.Ternary;
import com.cloud.utils.Pair;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineName;
@ -148,13 +148,13 @@ public class XenServerResourceNewBase extends XenServer610Resource {
return new Answer(cmd);
}
HashMap<String, Ternary<String, VirtualMachine.State, String>> newStates = _listener.getChanges();
HashMap<String, Pair<String, VirtualMachine.State>> newStates = _listener.getChanges();
return new ClusterSyncAnswer(cmd.getClusterId(), newStates);
}
protected class VmEventListener extends Thread {
boolean _stop = false;
HashMap<String, Ternary<String, VirtualMachine.State, String>> _changes = new HashMap<String, Ternary<String, VirtualMachine.State, String>>();
HashMap<String, Pair<String, VirtualMachine.State>> _changes = new HashMap<String, Pair<String, VirtualMachine.State>>();
boolean _isMaster;
Set<String> _classes;
String _token = "";
@ -232,12 +232,12 @@ public class XenServerResourceNewBase extends XenServer610Resource {
// NOTE: For now we only record change when the VM is stopped. We don't find out any VMs starting for now.
synchronized (_cluster.intern()) {
Ternary<String, VirtualMachine.State, String> oldState = s_vms.get(_cluster, vm);
Pair<String, VirtualMachine.State> oldState = s_vms.get(_cluster, vm);
if (oldState == null) {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Unable to find " + vm + " from previous map. Assuming it was in Stopped state.");
}
oldState = new Ternary<String, VirtualMachine.State, String>(null, VirtualMachine.State.Stopped, null);
oldState = new Pair<String, VirtualMachine.State>(null, VirtualMachine.State.Stopped);
}
if (s_logger.isTraceEnabled()) {
@ -281,7 +281,7 @@ public class XenServerResourceNewBase extends XenServer610Resource {
}
}
if (reportChange) {
Ternary<String, VirtualMachine.State, String> change = _changes.get(vm);
Pair<String, VirtualMachine.State> change = _changes.get(vm);
if (hostUuid == null) {
// This is really strange code. It looks like the sync
// code wants this to be set, which is extremely weird
@ -293,7 +293,7 @@ public class XenServerResourceNewBase extends XenServer610Resource {
}
}
if (change == null) {
change = new Ternary<String, VirtualMachine.State, String>(hostUuid, currentState, null);
change = new Pair<String, VirtualMachine.State>(hostUuid, currentState);
} else {
change.first(hostUuid);
change.second(currentState);
@ -325,13 +325,13 @@ public class XenServerResourceNewBase extends XenServer610Resource {
return _isMaster;
}
public HashMap<String, Ternary<String, VirtualMachine.State, String>> getChanges() {
public HashMap<String, Pair<String, VirtualMachine.State>> getChanges() {
synchronized (_cluster.intern()) {
if (_changes.size() == 0) {
return null;
}
HashMap<String, Ternary<String, VirtualMachine.State, String>> diff = _changes;
_changes = new HashMap<String, Ternary<String, VirtualMachine.State, String>>();
HashMap<String, Pair<String, VirtualMachine.State>> diff = _changes;
_changes = new HashMap<String, Pair<String, VirtualMachine.State>>();
return diff;
}
}