diff --git a/core/src/com/cloud/agent/api/RebootCommand.java b/core/src/com/cloud/agent/api/RebootCommand.java index d8f1ce95694..eecf7f635d3 100644 --- a/core/src/com/cloud/agent/api/RebootCommand.java +++ b/core/src/com/cloud/agent/api/RebootCommand.java @@ -19,29 +19,25 @@ package com.cloud.agent.api; -import com.cloud.vm.VirtualMachine; - public class RebootCommand extends Command { String vmName; + protected boolean executeInSequence = false; protected RebootCommand() { } - public RebootCommand(VirtualMachine vm) { - vmName = vm.getInstanceName(); - } - - public RebootCommand(String vmName) { + public RebootCommand(String vmName, boolean executeInSequence) { this.vmName = vmName; + this.executeInSequence = executeInSequence; } public String getVmName() { - return vmName; + return this.vmName; } @Override public boolean executeInSequence() { - return true; + return this.executeInSequence; } } diff --git a/core/src/com/cloud/agent/api/RebootRouterCommand.java b/core/src/com/cloud/agent/api/RebootRouterCommand.java index 149ac5d7b3f..6d6c0a90380 100644 --- a/core/src/com/cloud/agent/api/RebootRouterCommand.java +++ b/core/src/com/cloud/agent/api/RebootRouterCommand.java @@ -27,7 +27,7 @@ public class RebootRouterCommand extends RebootCommand { } public RebootRouterCommand(String vmName, String privateIp) { - super(vmName); + super(vmName, true); this.privateIp = privateIp; } diff --git a/core/src/com/cloud/agent/api/StopCommand.java b/core/src/com/cloud/agent/api/StopCommand.java index c4948cd631b..b723d746cc3 100644 --- a/core/src/com/cloud/agent/api/StopCommand.java +++ b/core/src/com/cloud/agent/api/StopCommand.java @@ -26,7 +26,6 @@ public class StopCommand extends RebootCommand { private boolean isProxy = false; private String urlPort = null; private String publicConsoleProxyIpAddress = null; - boolean executeInSequence = false; private GPUDeviceTO gpuDevice; boolean checkBeforeCleanup = false; @@ -34,33 +33,30 @@ public class StopCommand extends RebootCommand { } public StopCommand(VirtualMachine vm, boolean isProxy, String urlPort, String publicConsoleProxyIpAddress, boolean executeInSequence, boolean checkBeforeCleanup) { - super(vm); + super(vm.getInstanceName(), executeInSequence); this.isProxy = isProxy; this.urlPort = urlPort; this.publicConsoleProxyIpAddress = publicConsoleProxyIpAddress; - this.executeInSequence = executeInSequence; this.checkBeforeCleanup = checkBeforeCleanup; } public StopCommand(VirtualMachine vm, boolean executeInSequence, boolean checkBeforeCleanup) { - super(vm); - this.executeInSequence = executeInSequence; + super(vm.getInstanceName(), executeInSequence); this.checkBeforeCleanup = checkBeforeCleanup; } public StopCommand(String vmName, boolean executeInSequence, boolean checkBeforeCleanup) { - super(vmName); - this.executeInSequence = executeInSequence; + super(vmName, executeInSequence); this.checkBeforeCleanup = checkBeforeCleanup; } @Override public boolean executeInSequence() { - //VR stop doesn't go through queue - if (vmName != null && vmName.startsWith("r-")) { + // VR stop doesn't go through queue + if (this.vmName != null && this.vmName.startsWith("r-")) { return false; } - return executeInSequence; + return this.executeInSequence; } public boolean isProxy() { diff --git a/engine/api/src/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/com/cloud/vm/VirtualMachineManager.java index 8b226564229..d68f3485b09 100644 --- a/engine/api/src/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/com/cloud/vm/VirtualMachineManager.java @@ -49,11 +49,10 @@ import com.cloud.utils.fsm.NoTransitionException; public interface VirtualMachineManager extends Manager { static final ConfigKey ExecuteInSequence = new ConfigKey("Advanced", Boolean.class, "execute.in.sequence.hypervisor.commands", "false", - "If set to true, StartCommand, StopCommand, CopyCommand, MigrateCommand will be synchronized on the agent side." - + " If set to false, these commands become asynchronous. Default value is false.", false); + "If set to true, start, stop, reboot, copy and migrate commands will be serialized on the agent side. If set to false the commands are executed in parallel. Default value is false.", false); static final ConfigKey VmConfigDriveLabel = new ConfigKey("Hidden", String.class, "vm.configdrive.label", "config", - "The default lable name for the config drive", false); + "The default label name for the config drive", false); public interface Topics { public static final String VM_POWER_STATE = "vm.powerstate"; @@ -199,4 +198,6 @@ public interface VirtualMachineManager extends Manager { ConcurrentOperationException, ResourceUnavailableException; void migrateForScale(String vmUuid, long srcHostId, DeployDestination dest, Long newSvcOfferingId) throws ResourceUnavailableException, ConcurrentOperationException; + + boolean getExecuteInSequence(HypervisorType hypervisorType); } diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 11c0b869dff..c8e7d5f1670 100644 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1241,11 +1241,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } } - - protected boolean getExecuteInSequence(final HypervisorType hypervisorType) { - if (HypervisorType.KVM == hypervisorType || HypervisorType.LXC == hypervisorType || HypervisorType.XenServer == hypervisorType) { + @Override + public boolean getExecuteInSequence(final HypervisorType hypervisorType) { + if (HypervisorType.KVM == hypervisorType || HypervisorType.XenServer == hypervisorType || HypervisorType.Hyperv == hypervisorType || HypervisorType.LXC == hypervisorType) { return false; - } else if(HypervisorType.VMware == hypervisorType) { + } else if (HypervisorType.VMware == hypervisorType) { final Boolean fullClone = HypervisorGuru.VmwareFullClone.value(); return fullClone; } else { @@ -2585,7 +2585,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac try { final Commands cmds = new Commands(Command.OnError.Stop); - cmds.addCommand(new RebootCommand(vm.getInstanceName())); + cmds.addCommand(new RebootCommand(vm.getInstanceName(), getExecuteInSequence(vm.getHypervisorType()))); _agentMgr.send(host.getId(), cmds); final Answer rebootAnswer = cmds.getAnswer(RebootAnswer.class); diff --git a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java index 865b0662ec0..a101dfb005b 100644 --- a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java +++ b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java @@ -17,6 +17,7 @@ package com.cloud.vm; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.isA; @@ -505,4 +506,12 @@ public class VirtualMachineManagerImplTest { Assert.assertFalse(actual); } + + @Test + public void testExeceuteInSequence() { + assertTrue(_vmMgr.getExecuteInSequence(HypervisorType.XenServer) == false); + assertTrue(_vmMgr.getExecuteInSequence(HypervisorType.KVM) == false); + assertTrue(_vmMgr.getExecuteInSequence(HypervisorType.VMware) == HypervisorGuru.VmwareFullClone.value()); + assertTrue(_vmMgr.getExecuteInSequence(HypervisorType.Ovm3) == VirtualMachineManager.ExecuteInSequence.value()); + } } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootRouterCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootRouterCommandWrapper.java index 4d13c1bf5c9..b5604d41e76 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootRouterCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootRouterCommandWrapper.java @@ -34,7 +34,7 @@ public final class LibvirtRebootRouterCommandWrapper extends CommandWrapper