diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java index 05307eb47aa..ea39d835eb7 100644 --- a/api/src/com/cloud/network/NetworkModel.java +++ b/api/src/com/cloud/network/NetworkModel.java @@ -274,4 +274,6 @@ public interface NetworkModel { Networks.IsolationType[] listNetworkIsolationMethods(); Nic getNicInNetworkIncludingRemoved(long vmId, long networkId); + + boolean getExecuteInSeqNtwkElmtCmd(); } \ No newline at end of file diff --git a/core/src/com/cloud/agent/api/StartCommand.java b/core/src/com/cloud/agent/api/StartCommand.java index ec707d6e851..308730ab5b7 100644 --- a/core/src/com/cloud/agent/api/StartCommand.java +++ b/core/src/com/cloud/agent/api/StartCommand.java @@ -24,6 +24,7 @@ import com.cloud.host.Host; public class StartCommand extends Command { VirtualMachineTO vm; String hostIp; + boolean executeInSequence = false; public VirtualMachineTO getVirtualMachine() { return vm; @@ -31,19 +32,16 @@ public class StartCommand extends Command { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } protected StartCommand() { } - public StartCommand(VirtualMachineTO vm) { - this.vm = vm; - } - - public StartCommand(VirtualMachineTO vm, Host host) { + public StartCommand(VirtualMachineTO vm, Host host, boolean executeInSequence) { this.vm = vm; this.hostIp = host.getPrivateIpAddress(); + this.executeInSequence = executeInSequence; } public String getHostIp() { diff --git a/core/src/com/cloud/agent/api/StopCommand.java b/core/src/com/cloud/agent/api/StopCommand.java index 1c67f3816ca..a3ee3c967d3 100755 --- a/core/src/com/cloud/agent/api/StopCommand.java +++ b/core/src/com/cloud/agent/api/StopCommand.java @@ -23,28 +23,33 @@ public class StopCommand extends RebootCommand { private boolean isProxy=false; private String urlPort=null; private String publicConsoleProxyIpAddress=null; + boolean executeInSequence = false; protected StopCommand() { } - public StopCommand(VirtualMachine vm, boolean isProxy, String urlPort, String publicConsoleProxyIpAddress) { + public StopCommand(VirtualMachine vm, boolean isProxy, String urlPort, String publicConsoleProxyIpAddress, boolean executeInSequence) { super(vm); this.isProxy = isProxy; this.urlPort = urlPort; this.publicConsoleProxyIpAddress = publicConsoleProxyIpAddress; + this.executeInSequence = executeInSequence; } - public StopCommand(VirtualMachine vm, String vnet) { + public StopCommand(VirtualMachine vm, String vnet, boolean executeInSequence) { super(vm); this.vnet = vnet; + this.executeInSequence = executeInSequence; } - public StopCommand(VirtualMachine vm) { + public StopCommand(VirtualMachine vm, boolean executeInSequence) { super(vm); + this.executeInSequence = executeInSequence; } - public StopCommand(String vmName) { + public StopCommand(String vmName, boolean executeInSequence) { super(vmName); + this.executeInSequence = executeInSequence; } public String getVnet() { @@ -53,7 +58,7 @@ public class StopCommand extends RebootCommand { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } public boolean isProxy() { diff --git a/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java b/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java index fd8d84c8c3a..d51ea5e70b5 100644 --- a/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java +++ b/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java @@ -32,6 +32,7 @@ public class DhcpEntryCommand extends NetworkElementCommand { String ip6Gateway; String duid; private boolean isDefault; + boolean executeInSequence = false; protected DhcpEntryCommand() { @@ -39,19 +40,20 @@ public class DhcpEntryCommand extends NetworkElementCommand { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address) { + public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, boolean executeInSequence) { this.vmMac = vmMac; this.vmIpAddress = vmIpAddress; this.vmName = vmName; this.vmIp6Address = vmIp6Address; this.setDefault(true); + this.executeInSequence = executeInSequence; } - public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, String dns, String gateway, String ip6Gateway) { - this(vmMac, vmIpAddress, vmName, vmIp6Address); + public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, String dns, String gateway, String ip6Gateway, boolean executeInSequence) { + this(vmMac, vmIpAddress, vmName, vmIp6Address, executeInSequence); this.dns = dns; this.gateway = gateway; } diff --git a/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java b/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java index 6dac1488e11..c77dbf60987 100644 --- a/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java +++ b/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java @@ -22,19 +22,21 @@ public class SavePasswordCommand extends NetworkElementCommand { String password; String vmIpAddress; String vmName; + boolean executeInSequence = false; protected SavePasswordCommand() { } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public SavePasswordCommand(String password, String vmIpAddress, String vmName) { + public SavePasswordCommand(String password, String vmIpAddress, String vmName, boolean executeInSequence) { this.password = password; this.vmIpAddress = vmIpAddress; this.vmName = vmName; + this.executeInSequence = executeInSequence; } public String getPassword() { diff --git a/core/src/com/cloud/agent/api/routing/UserDataCommand.java b/core/src/com/cloud/agent/api/routing/UserDataCommand.java index f7b38c8c364..cf360023abc 100644 --- a/core/src/com/cloud/agent/api/routing/UserDataCommand.java +++ b/core/src/com/cloud/agent/api/routing/UserDataCommand.java @@ -23,6 +23,7 @@ public class UserDataCommand extends NetworkElementCommand { String vmIpAddress; String routerPrivateIpAddress; String vmName; + boolean executeInSequence = false; protected UserDataCommand() { @@ -30,14 +31,15 @@ public class UserDataCommand extends NetworkElementCommand { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public UserDataCommand(String userData, String vmIpAddress, String routerPrivateIpAddress, String vmName) { + public UserDataCommand(String userData, String vmIpAddress, String routerPrivateIpAddress, String vmName, boolean executeInSequence) { this.userData = userData; this.vmIpAddress = vmIpAddress; this.routerPrivateIpAddress = routerPrivateIpAddress; this.vmName = vmName; + this.executeInSequence = executeInSequence; } public String getRouterPrivateIpAddress() { diff --git a/core/src/com/cloud/agent/api/routing/VmDataCommand.java b/core/src/com/cloud/agent/api/routing/VmDataCommand.java index df882554479..861f7006432 100644 --- a/core/src/com/cloud/agent/api/routing/VmDataCommand.java +++ b/core/src/com/cloud/agent/api/routing/VmDataCommand.java @@ -28,27 +28,29 @@ public class VmDataCommand extends NetworkElementCommand { String vmName; @LogLevel(Log4jLevel.Trace) List vmData; + boolean executeInSequence = false; protected VmDataCommand() { } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public VmDataCommand(String vmIpAddress) { - this(vmIpAddress, null); + public VmDataCommand(String vmIpAddress, boolean executeInSequence) { + this(vmIpAddress, null, executeInSequence); } public String getVmName() { return vmName; } - public VmDataCommand(String vmIpAddress, String vmName) { + public VmDataCommand(String vmIpAddress, String vmName, boolean executeInSequence) { this.vmName = vmName; this.vmIpAddress = vmIpAddress; this.vmData = new ArrayList(); + this.executeInSequence = executeInSequence; } diff --git a/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java index 3d05e9ba69c..1acf2cc13f1 100644 --- a/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java +++ b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java @@ -28,22 +28,24 @@ public class CopyVolumeCommand extends Command { String secondaryStorageURL; boolean toSecondaryStorage; String vmName; + boolean executeInSequence = false; public CopyVolumeCommand() { } - public CopyVolumeCommand(long volumeId, String volumePath, StoragePool pool, String secondaryStorageURL, boolean toSecondaryStorage, int wait) { + public CopyVolumeCommand(long volumeId, String volumePath, StoragePool pool, String secondaryStorageURL, boolean toSecondaryStorage, int wait, boolean executeInSequence) { this.volumeId = volumeId; this.volumePath = volumePath; this.pool = new StorageFilerTO(pool); this.secondaryStorageURL = secondaryStorageURL; this.toSecondaryStorage = toSecondaryStorage; setWait(wait); + this.executeInSequence = executeInSequence; } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } public String getVolumePath() { diff --git a/core/src/com/cloud/agent/api/storage/CreateCommand.java b/core/src/com/cloud/agent/api/storage/CreateCommand.java index fd0375aa6e7..900abfd744e 100644 --- a/core/src/com/cloud/agent/api/storage/CreateCommand.java +++ b/core/src/com/cloud/agent/api/storage/CreateCommand.java @@ -26,6 +26,7 @@ public class CreateCommand extends Command { private StorageFilerTO pool; private DiskProfile diskCharacteristics; private String templateUrl; + boolean executeInSequence = false; protected CreateCommand() { super(); @@ -33,44 +34,47 @@ public class CreateCommand extends Command { /** * Construction for template based volumes. - * - * @param vol - * @param vm * @param diskCharacteristics * @param templateUrl * @param pool + * @param executeInSequence TODO + * @param vol + * @param vm */ - public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StorageFilerTO pool) { - this(diskCharacteristics, pool); + public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StorageFilerTO pool, boolean executeInSequence) { + this(diskCharacteristics, pool, executeInSequence); this.templateUrl = templateUrl; + this.executeInSequence = executeInSequence; } /** * Construction for regular volumes. - * - * @param vol - * @param vm * @param diskCharacteristics * @param pool + * @param executeInSequence TODO + * @param vol + * @param vm */ - public CreateCommand(DiskProfile diskCharacteristics, StorageFilerTO pool) { + public CreateCommand(DiskProfile diskCharacteristics, StorageFilerTO pool, boolean executeInSequence) { this.volId = diskCharacteristics.getVolumeId(); this.diskCharacteristics = diskCharacteristics; this.pool = pool; this.templateUrl = null; + this.executeInSequence = executeInSequence; } - public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StoragePool pool) { - this(diskCharacteristics, templateUrl, new StorageFilerTO(pool)); + public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StoragePool pool, boolean executeInSequence) { + this(diskCharacteristics, templateUrl, new StorageFilerTO(pool), executeInSequence); } - public CreateCommand(DiskProfile diskCharacteristics, StoragePool pool) { - this(diskCharacteristics, new StorageFilerTO(pool)); + public CreateCommand(DiskProfile diskCharacteristics, StoragePool pool, boolean executeInSequence) { + this(diskCharacteristics, new StorageFilerTO(pool), executeInSequence); + this.executeInSequence = executeInSequence; } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } public String getTemplateUrl() { diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index a6880c3f548..cb7940e94e4 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -50,11 +50,11 @@ import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CopyVolumeCommand; -import com.cloud.agent.api.storage.MigrateVolumeAnswer; -import com.cloud.agent.api.storage.MigrateVolumeCommand; import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; +import com.cloud.agent.api.storage.MigrateVolumeAnswer; +import com.cloud.agent.api.storage.MigrateVolumeCommand; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.SwiftTO; @@ -67,6 +67,7 @@ import com.cloud.exception.StorageUnavailableException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; +import com.cloud.server.ManagementServer; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage.ImageFormat; @@ -138,6 +139,11 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { private SwiftManager _swiftMgr; @Inject private S3Manager _s3Mgr; + @Inject + private ManagementServer _mgmtServer; + + protected boolean _executeInSequence; + @Override public boolean canHandle(DataObject srcData, DataObject destData) { @@ -165,7 +171,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { StoragePool destPool = (StoragePool) destData.getDataStore(); CopyVolumeCommand cvCmd = new CopyVolumeCommand(srcData.getId(), volumeUUID, destPool, secondaryStorageURL, false, - _copyvolumewait); + _copyvolumewait, _mgmtServer.getExecuteInSequence()); CopyVolumeAnswer cvAnswer = null; String errMsg = null; try { @@ -321,7 +327,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { null); CreateCommand cmd = new CreateCommand(diskProfile, tmpltStoredOn.getLocalDownloadPath(), - new StorageFilerTO((StoragePool)template.getDataStore())); + new StorageFilerTO((StoragePool)template.getDataStore()), _mgmtServer.getExecuteInSequence()); Answer answer = null; StoragePool pool = (StoragePool)volume.getDataStore(); String errMsg = null; @@ -375,7 +381,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), volume.getPath(), srcPool, secondaryStorageURL, true, - _copyvolumewait); + _copyvolumewait, _mgmtServer.getExecuteInSequence()); CopyVolumeAnswer cvAnswer; try { cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(srcPool, cvCmd); @@ -394,7 +400,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { cvCmd = new CopyVolumeCommand(volume.getId(), secondaryStorageVolumePath, destPool, - secondaryStorageURL, false, _copyvolumewait); + secondaryStorageURL, false, _copyvolumewait, _mgmtServer.getExecuteInSequence()); try { cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(destPool, cvCmd); } catch (StorageUnavailableException e1) { diff --git a/patches/systemvm/debian/config/root/edithosts.sh b/patches/systemvm/debian/config/root/edithosts.sh index fb0c34fbd42..eaa82927803 100755 --- a/patches/systemvm/debian/config/root/edithosts.sh +++ b/patches/systemvm/debian/config/root/edithosts.sh @@ -69,7 +69,9 @@ HOSTS=/etc/hosts source /root/func.sh lock="biglock" -locked=$(getLockFile $lock) +#default timeout value is 30 mins as DhcpEntryCommand is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) if [ "$locked" != "1" ] then exit 1 diff --git a/patches/systemvm/debian/config/root/savepassword.sh b/patches/systemvm/debian/config/root/savepassword.sh index a096b862fce..fc736039c2e 100755 --- a/patches/systemvm/debian/config/root/savepassword.sh +++ b/patches/systemvm/debian/config/root/savepassword.sh @@ -25,7 +25,9 @@ source /root/func.sh lock="passwdlock" -locked=$(getLockFile $lock) +#default timeout value is 30 mins as password reset command is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) if [ "$locked" != "1" ] then exit 1 diff --git a/patches/systemvm/debian/config/root/userdata.sh b/patches/systemvm/debian/config/root/userdata.sh index e5d170b5b23..f9ea644c2fd 100644 --- a/patches/systemvm/debian/config/root/userdata.sh +++ b/patches/systemvm/debian/config/root/userdata.sh @@ -21,7 +21,9 @@ source /root/func.sh lock="biglock" -locked=$(getLockFile $lock) +#default timeout value is 30 mins as userdata command is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) if [ "$locked" != "1" ] then exit 1 diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java index f87bf71ca13..c749211e375 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java @@ -53,6 +53,7 @@ import com.cloud.host.Host.Type; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.network.Network; +import com.cloud.network.NetworkModel; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; @@ -100,6 +101,8 @@ public class BaremetalDhcpManagerImpl extends ManagerBase implements BaremetalDh PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; @Inject BaremetalDhcpDao _extDhcpDao; + @Inject + NetworkModel _ntwkModel; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -147,7 +150,7 @@ public class BaremetalDhcpManagerImpl extends ManagerBase implements BaremetalDh dns = nic.getDns2(); } DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), profile.getVirtualMachine().getHostName(), null, dns, - nic.getGateway(), null); + nic.getGateway(), null, _ntwkModel.getExecuteInSeqNtwkElmtCmd()); String errMsg = String.format("Set dhcp entry on external DHCP %1$s failed(ip=%2$s, mac=%3$s, vmname=%4$s)", h.getPrivateIpAddress(), nic.getIp4Address(), nic.getMacAddress(), profile.getVirtualMachine().getHostName()); // prepareBareMetalDhcpEntry(nic, dhcpCommand); diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java index 59a28117cb5..04f5fbc34a7 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java @@ -45,6 +45,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; +import com.cloud.network.NetworkModel; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.resource.ResourceManager; @@ -81,6 +82,7 @@ public class BaremetalPxeManagerImpl extends ManagerBase implements BaremetalPxe @Inject NicDao _nicDao; @Inject ConfigurationDao _configDao; @Inject PhysicalNetworkDao _phynwDao; + @Inject NetworkModel _ntwkModel; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -184,7 +186,7 @@ public class BaremetalPxeManagerImpl extends ManagerBase implements BaremetalPxe String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId()).getDisplayText(); String zoneName = _dcDao.findById(vm.getDataCenterId()).getName(); NicVO nvo = _nicDao.findById(nic.getId()); - VmDataCommand cmd = new VmDataCommand(nvo.getIp4Address(), vm.getInstanceName()); + VmDataCommand cmd = new VmDataCommand(nvo.getIp4Address(), vm.getInstanceName(), _ntwkModel.getExecuteInSeqNtwkElmtCmd()); cmd.addVmData("userdata", "user-data", vm.getUserData()); cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering)); cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName)); diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 04869020468..fa099d31b9f 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -49,11 +49,12 @@ import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; +import com.cloud.server.ManagementServer; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.ResizeVolumePayload; +import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage; import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.SnapshotVO; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.VMTemplateHostVO; @@ -85,6 +86,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri @Inject SnapshotDao snapshotDao; @Inject PrimaryDataStoreDao primaryStoreDao; @Inject SnapshotManager snapshotMgr; + @Inject ManagementServer _mgmtSrvr; @Override public String grantAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub @@ -152,7 +154,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri String fullTmpltUrl = tmpltHostUrl + "/" + tmpltHostOn.getInstallPath(); cmd = new CreateCommand(diskProfile, fullTmpltUrl, - new StorageFilerTO(pool)); + new StorageFilerTO(pool), _mgmtSrvr.getExecuteInSequence()); } else { tmpltStoredOn = templateMgr.prepareTemplateForCreate( template, pool); @@ -166,7 +168,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri } cmd = new CreateCommand(diskProfile, tmpltStoredOn.getLocalDownloadPath(), - new StorageFilerTO(pool)); + new StorageFilerTO(pool), _mgmtSrvr.getExecuteInSequence()); } } else { if (template != null @@ -180,7 +182,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri } } cmd = new CreateCommand(diskProfile, new StorageFilerTO( - pool)); + pool), _mgmtSrvr.getExecuteInSequence()); } Answer answer = storageMgr.sendToPool(pool, null, cmd); diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 5432ab6dd4e..827b9bbda60 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -422,9 +422,11 @@ public enum Config { BlacklistedRoutes("Advanced", VpcManager.class, String.class, "blacklisted.routes", null, "Routes that are blacklisted, can not be used for Static Routes creation for the VPC Private Gateway", "routes", ConfigurationParameterScope.zone.toString()), - InternalLbVmServiceOfferingId("Advanced", ManagementServer.class, Long.class, "internallbvm.service.offering", null, "Uuid of the service offering used by internal lb vm; if NULL - default system internal lb offering will be used", null); - - + InternalLbVmServiceOfferingId("Advanced", ManagementServer.class, Long.class, "internallbvm.service.offering", null, "Uuid of the service offering used by internal lb vm; if NULL - default system internal lb offering will be used", null), + ExecuteInSequence("Advanced", ManagementServer.class, Boolean.class, "execute.in.sequence.hypervisor.commands", "false", "If set to true, StartCommand, StopCommand, CopyVolumeCommand, CreateCommand will be synchronized on the agent side." + + " If set to false, these commands become asynchronous. Default value is false.", null), + ExecuteInSequenceNetworkElementCommands("Advanced", NetworkManager.class, Boolean.class, "execute.in.sequence.network.element.commands", "false", "If set to true, DhcpEntryCommand, SavePasswordCommand, UserDataCommand, VmDataCommand will be synchronized on the agent side." + + " If set to false, these commands become asynchronous. Default value is false.", null); private final String _category; private final Class _componentClass; diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index bc43daa9975..306169ebcf6 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -386,4 +386,5 @@ public interface NetworkManager { DhcpServiceProvider getDhcpServiceProvider(Network network); PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException; + } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 274e79468e2..745fe2344d4 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -1234,7 +1234,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _configs = _configDao.getConfiguration("AgentManager", params); _networkGcWait = NumbersUtil.parseInt(_configs.get(Config.NetworkGcWait.key()), 600); _networkGcInterval = NumbersUtil.parseInt(_configs.get(Config.NetworkGcInterval.key()), 600); - + _configs = _configDao.getConfiguration("Network", params); _networkLockTimeout = NumbersUtil.parseInt(_configs.get(Config.NetworkLockTimeout.key()), 600); @@ -4364,5 +4364,5 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L nic.setVmType(vmType); return _nicDao.persist(nic); } - + } diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index fa34d65ab1a..4a4da8e3f4f 100755 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -208,11 +208,16 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { private boolean _allowSubdomainNetworkAccess; private Map _configs; + + protected boolean _executeInSequenceNtwkElmtCmd; HashMap _lastNetworkIdsToFree = new HashMap(); static HashMap> s_serviceToImplementedProvidersMap = new HashMap>(); static HashMap s_providerToNetworkElementMap = new HashMap(); + + + /** * */ @@ -1869,6 +1874,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { _configs = _configDao.getConfiguration("Network", params); _networkDomain = _configs.get(Config.GuestDomainSuffix.key()); _allowSubdomainNetworkAccess = Boolean.valueOf(_configs.get(Config.SubDomainNetworkAccess.key())); + _executeInSequenceNtwkElmtCmd = Boolean.valueOf(_configs.get(Config.ExecuteInSequenceNetworkElementCommands.key())); NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPublicNetwork, TrafficType.Public, true); publicNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(publicNetworkOffering); @@ -2112,4 +2118,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { public Networks.IsolationType[] listNetworkIsolationMethods() { return Networks.IsolationType.values(); } + + @Override + public boolean getExecuteInSeqNtwkElmtCmd() { + return _executeInSequenceNtwkElmtCmd; + } } diff --git a/server/src/com/cloud/network/element/CloudZonesNetworkElement.java b/server/src/com/cloud/network/element/CloudZonesNetworkElement.java index 320258b8d37..bdd8e61bbc2 100644 --- a/server/src/com/cloud/network/element/CloudZonesNetworkElement.java +++ b/server/src/com/cloud/network/element/CloudZonesNetworkElement.java @@ -152,7 +152,7 @@ public class CloudZonesNetworkElement extends AdapterBase implements NetworkElem private VmDataCommand generateVmDataCommand(String vmPrivateIpAddress, String userData, String serviceOffering, String zoneName, String guestIpAddress, String vmName, String vmInstanceName, long vmId, String vmUuid, String publicKey) { - VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName); + VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName, _networkMgr.getExecuteInSeqNtwkElmtCmd()); cmd.addVmData("userdata", "user-data", userData); cmd.addVmData("metadata", "service-offering", serviceOffering); @@ -217,7 +217,7 @@ public class CloudZonesNetworkElement extends AdapterBase implements NetworkElem Commands cmds = new Commands(OnError.Continue); if (password != null && nic.isDefaultNic()) { final String encodedPassword = PasswordGenerator.rot13(password); - SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), uservm.getVirtualMachine().getHostName()); + SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), uservm.getVirtualMachine().getHostName(), _networkMgr.getExecuteInSeqNtwkElmtCmd()); cmds.addCommand("password", cmd); } String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(uservm.getServiceOfferingId()).getDisplayText(); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 8da51763982..acf73da8127 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -166,6 +166,7 @@ import com.cloud.offering.ServiceOffering; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.ResourceManager; import com.cloud.server.ConfigurationServer; +import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.GuestOSVO; @@ -797,7 +798,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V private VmDataCommand generateVmDataCommand(VirtualRouter router, String vmPrivateIpAddress, String userData, String serviceOffering, String zoneName, String guestIpAddress, String vmName, String vmInstanceName, long vmId, String vmUuid, String publicKey, long guestNetworkId) { - VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName); + VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName, _networkModel.getExecuteInSeqNtwkElmtCmd()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); @@ -3359,7 +3360,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V if (router.getIsRedundantRouter() && router.getRedundantState() != RedundantState.MASTER) { encodedPassword = PasswordGenerator.rot13("saved_password"); } - SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName()); + SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName(), _networkModel.getExecuteInSeqNtwkElmtCmd()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); @@ -3399,7 +3400,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } private void createDhcpEntryCommand(VirtualRouter router, UserVm vm, NicVO nic, Commands cmds) { - DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), vm.getHostName(), nic.getIp6Address()); + DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), vm.getHostName(), nic.getIp6Address(), _networkModel.getExecuteInSeqNtwkElmtCmd()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); Nic defaultNic = findGatewayIp(vm.getId()); String gatewayIp = defaultNic.getGateway(); diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index f60ce488e10..aec1be705dc 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -72,4 +72,6 @@ public interface ManagementServer extends ManagementService, PluggableService { String getEncryptionIV(); void resetEncryptionKeyIV(); + boolean getExecuteInSequence(); + } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index dea761df5da..cfc8333e9c8 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -766,6 +766,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe ConfigurationServer _configServer; @Inject UserVmManager _userVmMgr; + @Inject ClusterManager _clusterMgr; + private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker")); private final ScheduledExecutorService _alertExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AlertChecker")); @@ -788,10 +790,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe this._planners = _planners; } - @Inject ClusterManager _clusterMgr; private String _hashKey = null; private String _encryptionKey = null; private String _encryptionIV = null; + protected boolean _executeInSequence; @Inject protected AffinityGroupVMMapDao _affinityGroupVMMapDao; @@ -861,6 +863,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe _availableIdsMap.put(id, true); } + _executeInSequence = Boolean.parseBoolean(_configDao.getValue(Config.ExecuteInSequence.key())); + return true; } @@ -3469,7 +3473,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe String value = _configs.get(Config.CopyVolumeWait.toString()); int copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); // Copy the volume from the source storage pool to secondary storage - CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), volume.getPath(), srcPool, secondaryStorageURL, true, copyvolumewait); + CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), volume.getPath(), srcPool, secondaryStorageURL, true, copyvolumewait, _executeInSequence); CopyVolumeAnswer cvAnswer = null; try { cvAnswer = (CopyVolumeAnswer) _storageMgr.sendToPool(srcPool, cvCmd); @@ -4080,5 +4084,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return plannersAvailable; } - + + @Override + public boolean getExecuteInSequence() { + return _executeInSequence; + } } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index f946cd1ebf6..58140750d74 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -130,6 +130,7 @@ import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; import com.cloud.resource.ResourceManager; import com.cloud.server.ConfigurationServer; +import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -259,6 +260,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected AffinityGroupVMMapDao _affinityGroupVMMapDao; @Inject protected ConfigurationServer _configServer; + @Inject + protected ManagementServer _mgmtServer; protected List _planners; public List getPlanners() { @@ -857,7 +860,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac VirtualMachineTO vmTO = hvGuru.implement(vmProfile); cmds = new Commands(OnError.Stop); - cmds.addCommand(new StartCommand(vmTO, dest.getHost())); + cmds.addCommand(new StartCommand(vmTO, dest.getHost(), _mgmtServer.getExecuteInSequence())); vmGuru.finalizeDeployment(cmds, vmProfile, dest, ctx); @@ -897,7 +900,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.info("The guru did not like the answers so stopping " + vm); } - StopCommand cmd = new StopCommand(vm); + StopCommand cmd = new StopCommand(vm, _mgmtServer.getExecuteInSequence()); StopAnswer answer = (StopAnswer) _agentMgr.easySend(destHostId, cmd); if (answer == null || !answer.getResult()) { s_logger.warn("Unable to stop " + vm + " due to " + (answer != null ? answer.getDetails() : "no answers")); @@ -984,7 +987,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected boolean sendStop(VirtualMachineGuru guru, VirtualMachineProfile profile, boolean force) { VMInstanceVO vm = profile.getVirtualMachine(); - StopCommand stop = new StopCommand(vm); + StopCommand stop = new StopCommand(vm, _mgmtServer.getExecuteInSequence()); try { Answer answer = _agentMgr.send(vm.getHostId(), stop); if (!answer.getResult()) { @@ -1170,7 +1173,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac vmGuru.prepareStop(profile); - StopCommand stop = new StopCommand(vm); + StopCommand stop = new StopCommand(vm, _mgmtServer.getExecuteInSequence()); boolean stopped = false; StopAnswer answer = null; try { @@ -1923,11 +1926,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } public Command cleanup(VirtualMachine vm) { - return new StopCommand(vm); + return new StopCommand(vm, _mgmtServer.getExecuteInSequence()); } public Command cleanup(String vmName) { - return new StopCommand(vmName); + return new StopCommand(vmName, _mgmtServer.getExecuteInSequence()); } public Commands fullHostSync(final long hostId, StartupRoutingCommand startup) { diff --git a/server/test/com/cloud/network/MockNetworkModelImpl.java b/server/test/com/cloud/network/MockNetworkModelImpl.java index 3a367480a30..bab9df8dd6d 100644 --- a/server/test/com/cloud/network/MockNetworkModelImpl.java +++ b/server/test/com/cloud/network/MockNetworkModelImpl.java @@ -879,4 +879,10 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) { return null; } + + @Override + public boolean getExecuteInSeqNtwkElmtCmd() { + // TODO Auto-generated method stub + return false; + } } diff --git a/server/test/com/cloud/vpc/MockNetworkModelImpl.java b/server/test/com/cloud/vpc/MockNetworkModelImpl.java index 3e67f5e76e2..a6ab1261c3c 100644 --- a/server/test/com/cloud/vpc/MockNetworkModelImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkModelImpl.java @@ -892,4 +892,10 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { return null; } + @Override + public boolean getExecuteInSeqNtwkElmtCmd() { + // TODO Auto-generated method stub + return false; + } + } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 272fc4276a6..b397559874b 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -1857,3 +1857,7 @@ UPDATE `cloud`.`networks` set name='Shared SG enabled network', display_text='Sh INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'use.system.public.ips', 'true', 'If true, when account has dedicated public ip range(s), once the ips dedicated to the account have been consumed ips will be acquired from the system pool'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'use.system.guest.vlans', 'true', 'If true, when account has dedicated guest vlan range(s), once the vlans dedicated to the account have been consumed vlans will be allocated from the system pool'); + +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'execute.in.sequence.hypervisor.commands', 'false', 'If set to true, StartCommand, StopCommand, CopyVolumeCommand, CreateCommand will be synchronized on the agent side. If set to false, these commands become asynchronous. Default value is false.'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'execute.in.sequence.network.element.commands', 'false', 'If set to true, DhcpEntryCommand, SavePasswordCommand, UserDataCommand, VmDataCommand will be synchronized on the agent side. If set to false, these commands become asynchronous. Default value is false.'); +