if (vms.size() == 0) {
synchronized (_cluster.intern()) {
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 , true);
}
for (VM vm : vms) {
VM.Record vmr = vm.getRecord(conn);
if (vmr.isControlDomain) {
String msg = "Tring to Shutdown control domain";
s_logger.warn(msg);
return new StopAnswer(cmd, msg, false);
}
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);
}
State state = s_vms.getState(_cluster, vmName);
synchronized (_cluster.intern()) {
s_vms.put(_cluster, _name, vmName, State.Stopping);
}
s_logger.debug("9. The VM " + vmName + " is in Stopping state");
try {
if (vmr.powerState == VmPowerState.RUNNING) {
/* when stop a vm, set affinity to current xenserver */
vm.setAffinity(conn, vm.getResidentOn(conn));
if (_canBridgeFirewall) {
String result = callHostPlugin(conn, "vmops", "destroy_network_rules_for_vm", "vmName", cmd
.getVmName());
if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
s_logger.warn("Failed to remove network rules for vm " + cmd.getVmName());
} else {
s_logger.info("Removed network rules for vm " + cmd.getVmName());
}
}
shutdownVM(conn, vm, vmName);
}
} 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);
} finally {
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) {
networks.add(vif.getNetwork(conn));
}
vm.destroy(conn);
state = State.Stopped;
SR sr = getISOSRbyVmName(conn, cmd.getVmName());
removeSR(conn, sr);
// Disable any VLAN networks that aren't used
// anymore
for (Network network : networks) {
try {
if (network.getNameLabel(conn).startsWith("VLAN")) {
disableVlanNetwork(conn, network);
}
} catch (Exception e) {
// network might be destroyed by other host
}
}
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();
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);
} finally {
synchronized (_cluster.intern()) {
s_vms.put(_cluster, _name, vmName, state);
}
s_logger.debug("10. The VM " + vmName + " is in " + state + " state");
}
}
}
} catch (XenAPIException 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, "Stop VM failed", false);
}