CLOUDSTACK-3443: Timeoffset on windows guest not persisted between VM stop and start on XenServer.

The problem was because in cloudstack when a vm is stopped it gets destroyed on the host. For a
windows vm the timeoffset (which can be set by changing the timezone from within the vm) is stored
in the platform:timeoffset attribute of vm record. The information is lost when the vm is destroted.
Made change to read and persist the platform:timeoffset vm attribute when an instance is stopped.
The value is persisted in the user_vm_details table. When the vm is started again the attribute is
set for the vm instance that gets created.
This commit is contained in:
Devdeep Singh 2013-07-10 17:36:06 +05:30
parent 3c1b3c71fe
commit 033d05fa20
4 changed files with 40 additions and 2 deletions

View File

@ -18,19 +18,27 @@ package com.cloud.agent.api;
public class StopAnswer extends RebootAnswer {
Integer vncPort;
Integer timeOffset;
protected StopAnswer() {
}
public StopAnswer(StopCommand cmd, String details, Integer vncPort, Integer timeOffset, boolean success) {
super(cmd, details, success);
this.vncPort = vncPort;
this.timeOffset = timeOffset;
}
public StopAnswer(StopCommand cmd, String details, Integer vncPort, boolean success) {
super(cmd, details, success);
this.vncPort = vncPort;
this.timeOffset = null;
}
public StopAnswer(StopCommand cmd, String details, boolean success) {
super(cmd, details, success);
vncPort = null;
timeOffset = null;
}
public StopAnswer(StopCommand cmd, Exception e) {
@ -42,4 +50,7 @@ public class StopAnswer extends RebootAnswer {
return vncPort;
}
public Integer getTimeOffset() {
return timeOffset;
}
}

View File

@ -4112,6 +4112,16 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
try {
if (vm.getPowerState(conn) == VmPowerState.HALTED) {
Map<String, String> 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);
}
Set<VIF> vifs = vm.getVIFs(conn);
List<Network> networks = new ArrayList<Network>();
for (VIF vif : vifs) {
@ -4132,7 +4142,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
// network might be destroyed by other host
}
}
return new StopAnswer(cmd, "Stop VM " + vmName + " Succeed", 0, true);
return new StopAnswer(cmd, "Stop VM " + vmName + " Succeed", 0, timeoffset, true);
}
} catch (XenAPIException e) {
String msg = "VM destroy failed in Stop " + vmName + " Command due to " + e.toString();

View File

@ -193,6 +193,13 @@ public class XenServer56FP1Resource extends XenServer56Resource {
vmr.VCPUsMax = 32L;
}
String timeoffset = details.get("timeoffset");
if (timeoffset != null) {
Map<String, String> platform = vmr.platform;
platform.put("timeoffset", timeoffset);
vmr.platform = platform;
}
vmr.VCPUsAtStartup = (long) vmSpec.getCpus();
vmr.consoles.clear();

View File

@ -1184,6 +1184,16 @@ 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);