diff --git a/core/src/com/cloud/agent/api/StopAnswer.java b/core/src/com/cloud/agent/api/StopAnswer.java index 614835e2a37..e417e0bb89f 100755 --- a/core/src/com/cloud/agent/api/StopAnswer.java +++ b/core/src/com/cloud/agent/api/StopAnswer.java @@ -18,36 +18,29 @@ package com.cloud.agent.api; public class StopAnswer extends RebootAnswer { - private String hypervisortoolsversion; - Integer timeOffset; + private String platform; protected StopAnswer() { } - public StopAnswer(StopCommand cmd, String details, String hypervisortoolsversion, Integer timeOffset, boolean success) { + public StopAnswer(StopCommand cmd, String details, String platform, boolean success) { super(cmd, details, success); - this.hypervisortoolsversion = hypervisortoolsversion; - this.timeOffset = timeOffset; + this.platform = platform; } public StopAnswer(StopCommand cmd, String details, boolean success) { super(cmd, details, success); - this.hypervisortoolsversion = null; - this.timeOffset = null; + this.platform = null; } public StopAnswer(StopCommand cmd, Exception e) { super(cmd, e); - this.hypervisortoolsversion = null; - this.timeOffset = null; + this.platform = null; } - public String getHypervisorToolsVersion() { - return hypervisortoolsversion; + public String getPlatform() { + return platform; } - public Integer getTimeOffset() { - return timeOffset; - } } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 5a3cdc1a4a7..6fc64b3b657 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -213,6 +213,7 @@ import com.cloud.utils.S3Utils; import com.cloud.utils.StringUtils; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; +import com.cloud.utils.StringUtils; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; @@ -1298,23 +1299,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vmr.VCPUsMax = 32L; } - Map details = vmSpec.getDetails(); - if ( details != null ) { - String timeoffset = details.get("timeoffset"); - if (timeoffset != null) { - Map platform = vmr.platform; - platform.put("timeoffset", timeoffset); - vmr.platform = platform; - } - - String coresPerSocket = details.get("cpu.corespersocket"); - if (coresPerSocket != null) { - Map platform = vmr.platform; - platform.put("cores-per-socket", coresPerSocket); - vmr.platform = platform; - } - } - vmr.VCPUsAtStartup = (long) vmSpec.getCpus(); vmr.consoles.clear(); @@ -1399,9 +1383,40 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected void finalizeVmMetaData(VM vm, Connection conn, VirtualMachineTO vmSpec) throws Exception { + + Map details = vmSpec.getDetails(); + if ( details != null ) { + String platformstring = details.get("platform"); + if (platformstring != null && !platformstring.isEmpty() ) { + Map platform = StringUtils.stringToMap(platformstring); + vm.setPlatform(conn, platform); + } else { + String timeoffset = details.get("timeoffset"); + if (timeoffset != null) { + Map platform = vm.getPlatform(conn); + platform.put("timeoffset", timeoffset); + vm.setPlatform(conn, platform); + } + String coresPerSocket = details.get("cpu.corespersocket"); + if (coresPerSocket != null) { + Map platform = vm.getPlatform(conn); + platform.put("cores-per-socket", coresPerSocket); + vm.setPlatform(conn, platform); + } + + String xentoolsversion = details.get("hypervisortoolsversion"); + if ( xentoolsversion == null || !xentoolsversion.equalsIgnoreCase("xenserver61") ) { + Map platform = vm.getPlatform(conn); + platform.remove("device_id"); + vm.setPlatform(conn, platform); + } + + } + } } + protected String handleVmStartFailure(Connection conn, String vmName, VM vm, String message, Throwable th) { String msg = "Unable to start " + vmName + " due to " + message; s_logger.warn(msg, th); @@ -2957,7 +2972,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.trace("VM " + record.nameLabel + ": powerstate = " + ps + "; vm state=" + state.toString()); } Host host = record.residentOn; - String xstoolsversion = getVMXenToolsVersion(record.platform); + String platformstring = StringUtils.mapToString(record.platform); String host_uuid = null; if( ! isRefNull(host) ) { try { @@ -2969,7 +2984,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(host_uuid, state, xstoolsversion)); + vmStates.put(record.nameLabel, new Ternary(host_uuid, state, platformstring)); } } @@ -3974,6 +3989,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe @Override public StopAnswer execute(StopCommand cmd) { String vmName = cmd.getVmName(); + String platformstring = null; try { Connection conn = getConnection(); Set vms = VM.getByNameLabel(conn, vmName); @@ -4003,7 +4019,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } for (VM vm : vms) { VM.Record vmr = vm.getRecord(conn); - + platformstring = StringUtils.mapToString(vmr.platform); if (vmr.isControlDomain) { String msg = "Tring to Shutdown control domain"; s_logger.warn(msg); @@ -4013,7 +4029,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (vmr.powerState == VmPowerState.RUNNING && !isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(_host.uuid)) { String msg = "Stop Vm " + vmName + " failed due to this vm is not running on this host: " + _host.uuid + " but host:" + vmr.residentOn.getUuid(conn); s_logger.warn(msg); - return new StopAnswer(cmd, msg, false); + return new StopAnswer(cmd, msg, platformstring, false); } State state = s_vms.getState(_cluster, vmName); @@ -4042,21 +4058,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } catch (Exception e) { String msg = "Catch exception " + e.getClass().getName() + " when stop VM:" + cmd.getVmName() + " due to " + e.toString(); s_logger.debug(msg); - return new StopAnswer(cmd, msg, false); + return new StopAnswer(cmd, msg, platformstring, false); } finally { try { if (vm.getPowerState(conn) == VmPowerState.HALTED) { - Map platform = vm.getPlatform(conn); - Integer timeoffset = null; - try { - if (platform.containsKey("timeoffset")) { - timeoffset = Integer.valueOf(platform.get("timeoffset")); - } - } catch (NumberFormatException e) { - s_logger.error("Error while reading the platform:timeoffset field of the instance", e); - } - String xentoolsversion = getVMXenToolsVersion(platform); Set vifs = vm.getVIFs(conn); List networks = new ArrayList(); @@ -4078,11 +4084,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe // network might be destroyed by other host } } - return new StopAnswer(cmd, "Stop VM " + vmName + " Succeed", xentoolsversion, timeoffset, true); + return new StopAnswer(cmd, "Stop VM " + vmName + " Succeed", platformstring ,true); } - } catch (XenAPIException e) { - String msg = "VM destroy failed in Stop " + vmName + " Command due to " + e.toString(); - s_logger.warn(msg, e); } catch (Exception e) { String msg = "VM destroy failed in Stop " + vmName + " Command due to " + e.getMessage(); s_logger.warn(msg, e); @@ -4095,19 +4098,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - } catch (XenAPIException e) { + } catch (Exception e) { String msg = "Stop Vm " + vmName + " fail due to " + e.toString(); s_logger.warn(msg, e); - return new StopAnswer(cmd, msg, false); - } catch (XmlRpcException e) { - String msg = "Stop Vm " + vmName + " fail due to " + e.getMessage(); - s_logger.warn(msg, e); - return new StopAnswer(cmd, msg, false); - } catch (Exception e) { - s_logger.warn("Unable to stop " + vmName + " due to ", e); - return new StopAnswer(cmd, e); + return new StopAnswer(cmd, msg, platformstring, false); } - return new StopAnswer(cmd, "Stop VM failed", false); + return new StopAnswer(cmd, "Stop VM failed", platformstring, false); } @@ -8132,13 +8128,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String vm_name = record.nameLabel; VmPowerState ps = record.powerState; final State state = convertToState(ps); - String xstoolsversion = getVMXenToolsVersion(record.platform); Host host = record.residentOn; String host_uuid = null; if( ! isRefNull(host) ) { host_uuid = host.getUuid(conn); synchronized (_cluster.intern()) { - s_vms.put(_cluster, host_uuid, vm_name, state, xstoolsversion); + s_vms.put(_cluster, host_uuid, vm_name, state, null); } } if (s_logger.isTraceEnabled()) { @@ -8169,19 +8164,19 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe for (final Map.Entry> entry : newStates.entrySet()) { final String vm = entry.getKey(); - String xstoolsversion = entry.getValue().third(); + String platform = entry.getValue().third(); State newState = entry.getValue().second(); String host_uuid = entry.getValue().first(); final Ternary oldState = oldStates.remove(vm); - // check if xstoolsversion changed - if (xstoolsversion != null && oldState != null){ - if (xstoolsversion != oldState.third() && newState != State.Stopped && newState != State.Stopping){ - s_logger.warn("Detecting a change in xstoolsversion for " + vm); - changes.put(vm, new Ternary(host_uuid, newState, xstoolsversion)); + // 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(host_uuid, newState, platform)); s_logger.debug("11. The VM " + vm + " is in " + newState + " state"); - s_vms.put(_cluster, host_uuid, vm, newState, xstoolsversion); + s_vms.put(_cluster, host_uuid, vm, newState, platform); continue; } } @@ -8189,10 +8184,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe 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(host_uuid, newState, null)); + changes.put(vm, new Ternary(host_uuid, newState, platform)); s_logger.debug("11. The VM " + vm + " is in " + newState + " state"); - s_vms.put(_cluster, host_uuid, vm, newState, xstoolsversion); + s_vms.put(_cluster, host_uuid, vm, newState, platform); continue; } } @@ -8211,31 +8206,31 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe continue; } if (oldState == null) { - s_vms.put(_cluster, host_uuid, vm, newState, xstoolsversion); + s_vms.put(_cluster, host_uuid, vm, newState, platform); 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(host_uuid, newState, null)); + changes.put(vm, new Ternary(host_uuid, newState, platform)); } 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, xstoolsversion); + s_vms.put(_cluster, host_uuid, vm, newState, platform); } 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, xstoolsversion); + s_vms.put(_cluster, host_uuid, vm, newState, platform); } } 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, xstoolsversion); + s_vms.put(_cluster, host_uuid, vm, newState, platform); } 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, xstoolsversion); + s_vms.put(_cluster, host_uuid, vm, newState, platform); if (newState == State.Stopped) { /* * if (s_vmsKilled.remove(vm)) { s_logger.debug("VM " + vm + " has been killed for storage. "); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java index 2603922fd18..69c45f07c11 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java @@ -462,17 +462,4 @@ public class XenServer610Resource extends XenServer56FP1Resource { return "xenserver56"; } - @Override - protected void finalizeVmMetaData(VM vm, Connection conn, VirtualMachineTO vmSpec) throws Exception { - Map details = vmSpec.getDetails(); - if ( details!= null ) { - String xentoolsversion = details.get("hypervisortoolsversion"); - if ( xentoolsversion == null || !xentoolsversion.equalsIgnoreCase("xenserver61") ) { - Map platform = vm.getPlatform(conn); - platform.remove("device_id"); - vm.setPlatform(conn, platform); - } - } - } - } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java index f22fb286c8a..694353ccb47 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java @@ -52,9 +52,9 @@ public class XenServerPoolVms { } - public void put(String clusterId, String hostUuid, String name, State state, String xstoolsversion){ + public void put(String clusterId, String hostUuid, String name, State state, String platform){ HashMap> vms= getClusterVmState(clusterId); - vms.put(name, new Ternary(hostUuid, state, xstoolsversion)); + vms.put(name, new Ternary(hostUuid, state, platform)); } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index dff0b3fc39d..3a058825a3c 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.HashMap; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -181,6 +182,7 @@ import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.dao.UserVmDetailsDao; import com.cloud.vm.dao.VMInstanceDao; @Component @@ -196,6 +198,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Inject VMTemplateZoneDao _tmpltZoneDao; @Inject + protected UserVmDetailsDao _vmDetailsDao; + @Inject protected VMTemplateDetailsDao _templateDetailsDao; @Inject VMInstanceDao _vmInstanceDao; @@ -1634,8 +1638,21 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, VMTemplateVO template = this._tmpltDao.persist(privateTemplate); // Increment the number of templates if (template != null) { - if (cmd.getDetails() != null) { - this._templateDetailsDao.persist(template.getId(), cmd.getDetails()); + Map details = new HashMap(); + if ( volume != null ) { + Long vmId = volume.getInstanceId(); + if ( vmId != null ) { + Map vmdetails = _vmDetailsDao.findDetails(vmId); + if ( vmdetails != null ) { + details.putAll(vmdetails); + } + } + } + if(cmd.getDetails() != null) { + details.putAll(cmd.getDetails()); + } + if( !details.isEmpty()) { + this._templateDetailsDao.persist(template.getId(), details); } _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.template); diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 08eda787ad8..e451ecacaa4 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -947,12 +947,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac StopCommand cmd = new StopCommand(vm, _mgmtServer.getExecuteInSequence()); StopAnswer answer = (StopAnswer) _agentMgr.easySend(destHostId, cmd); if ( answer != null ) { - String hypervisortoolsversion = answer.getHypervisorToolsVersion(); - if (hypervisortoolsversion != null) { - if (vm.getType() == VirtualMachine.Type.User) { + if (vm.getType() == VirtualMachine.Type.User) { + String platform = answer.getPlatform(); + if (platform != null) { UserVmVO userVm = _userVmDao.findById(vm.getId()); _userVmDao.loadDetails(userVm); - userVm.setDetail("hypervisortoolsversion", hypervisortoolsversion); + userVm.setDetail("platform", platform); _userVmDao.saveDetails(userVm); } } @@ -1064,12 +1064,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac try { StopAnswer answer = (StopAnswer) _agentMgr.send(vm.getHostId(), stop); if ( answer != null ) { - String hypervisortoolsversion = answer.getHypervisorToolsVersion(); - if (hypervisortoolsversion != null) { - if (vm.getType() == VirtualMachine.Type.User) { + if (vm.getType() == VirtualMachine.Type.User) { + String platform = answer.getPlatform(); + if (platform != null) { UserVmVO userVm = _userVmDao.findById(vm.getId()); _userVmDao.loadDetails(userVm); - userVm.setDetail("hypervisortoolsversion", hypervisortoolsversion); + userVm.setDetail("platform", platform); _userVmDao.saveDetails(userVm); } } @@ -1263,12 +1263,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac answer = (StopAnswer) _agentMgr.send(vm.getHostId(), stop); if ( answer != null ) { - String hypervisortoolsversion = answer.getHypervisorToolsVersion(); - if (hypervisortoolsversion != null) { - if (vm.getType() == VirtualMachine.Type.User) { + if (vm.getType() == VirtualMachine.Type.User) { + String platform = answer.getPlatform(); + if ( platform != null) { UserVmVO userVm = _userVmDao.findById(vm.getId()); _userVmDao.loadDetails(userVm); - userVm.setDetail("hypervisortoolsversion", hypervisortoolsversion); + userVm.setDetail("platform", platform); _userVmDao.saveDetails(userVm); } } @@ -1276,16 +1276,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac stopped = answer.getResult(); if (!stopped) { throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails()); - } else { - Integer timeoffset = answer.getTimeOffset(); - if (timeoffset != null) { - if (vm.getType() == VirtualMachine.Type.User) { - UserVmVO userVm = _userVmDao.findById(vm.getId()); - _userVmDao.loadDetails(userVm); - userVm.setDetail("timeoffset", timeoffset.toString()); - _userVmDao.saveDetails(userVm); - } - } } vmGuru.finalizeStop(profile, answer); @@ -2473,11 +2463,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac + " due to storage failure", "Virtual Machine " + vm.getInstanceName() + " (id: " + vm.getId() + ") running on host [" + vm.getHostId() + "] stopped due to storage failure."); } // track hypervsion tools version - if( info.hvtoolsversion != null && !info.hvtoolsversion.isEmpty() ) { + if( info.platform != null && !info.platform.isEmpty() ) { if (vm.getType() == VirtualMachine.Type.User) { UserVmVO userVm = _userVmDao.findById(vm.getId()); _userVmDao.loadDetails(userVm); - userVm.setDetail("hypervisortoolsversion", info.hvtoolsversion); + userVm.setDetail("platform", info.platform); _userVmDao.saveDetails(userVm); } } @@ -2845,19 +2835,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac public String name; public State state; public String hostUuid; - public String hvtoolsversion; + public String platform; public VMInstanceVO vm; public VirtualMachineGuru guru; @SuppressWarnings("unchecked") - public AgentVmInfo(String name, VirtualMachineGuru guru, VMInstanceVO vm, State state, String host, String hvtoolsversion) { + public AgentVmInfo(String name, VirtualMachineGuru guru, VMInstanceVO vm, State state, String host, String platform) { this.name = name; this.state = state; this.vm = vm; this.guru = (VirtualMachineGuru) guru; this.hostUuid = host; - this.hvtoolsversion= hvtoolsversion; + this.platform = platform; } @@ -2873,9 +2863,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac return hostUuid; } - public String getHvtoolsversion() { - return hvtoolsversion; - } + public String getPlatform() { + return platform; + } } @Override diff --git a/utils/src/com/cloud/utils/StringUtils.java b/utils/src/com/cloud/utils/StringUtils.java index c02082cca42..340b97dc855 100644 --- a/utils/src/com/cloud/utils/StringUtils.java +++ b/utils/src/com/cloud/utils/StringUtils.java @@ -19,6 +19,9 @@ package com.cloud.utils; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.HashMap; +import java.util.Map; + import java.util.regex.Pattern; import org.owasp.esapi.StringUtilities; @@ -177,4 +180,27 @@ public class StringUtils { int found = searchable.lastIndexOf(separator); return found > 0 ? found : end - start; } + + + public static Map stringToMap(String s){ + Map map=new HashMap(); + String[] elements = s.split(";"); + for (String parts: elements) { + String[] keyValue = parts.split(":"); + map.put(keyValue[0], keyValue[1]); + } + return map; + } + + + public static String mapToString(Map map){ + String s = ""; + for (Map.Entry entry: map.entrySet()) { + s += entry.getKey() + ":" + entry.getValue() +";"; + } + if (s.length() > 0) { + s = s.substring(0, s.length()-1); + } + return s; + } }