From c528e71fec9f81c9475a8ae427ef95e9550909ad Mon Sep 17 00:00:00 2001 From: Kelven Yang Date: Sun, 18 Aug 2013 23:12:37 -0700 Subject: [PATCH] CLOUDSTACK-4390, CLOUDSTACK-4358: Enable full-clone deployment by default for VMware. Apply keep-alive kick for all outstanding vCenter sessions --- .../vmware/resource/VmwareContextFactory.java | 5 +- .../VmwareSecondaryStorageContextFactory.java | 10 +-- .../src/com/cloud/configuration/Config.java | 2 +- .../hypervisor/vmware/util/VmwareContext.java | 5 ++ .../vmware/util/VmwareContextPool.java | 78 +++++++++++++++---- 5 files changed, 75 insertions(+), 25 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareContextFactory.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareContextFactory.java index a647560c48d..c0b716cc394 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareContextFactory.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareContextFactory.java @@ -67,6 +67,9 @@ public class VmwareContextFactory { context.registerStockObject("serviceconsole", s_vmwareMgr.getServiceConsolePortGroupName()); context.registerStockObject("manageportgroup", s_vmwareMgr.getManagementPortGroupName()); + context.setPoolInfo(s_pool, VmwareContextPool.composePoolKey(vCenterAddress, vCenterUserName)); + s_pool.registerOutstandingContext(context); + return context; } @@ -76,8 +79,6 @@ public class VmwareContextFactory { context = create(vCenterAddress, vCenterUserName, vCenterPassword); if(context != null) { - context.setPoolInfo(s_pool, VmwareContextPool.composePoolKey(vCenterAddress, vCenterUserName)); - context.registerStockObject(VmwareManager.CONTEXT_STOCK_NAME, s_vmwareMgr); context.registerStockObject("serviceconsole", s_vmwareMgr.getServiceConsolePortGroupName()); diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageContextFactory.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageContextFactory.java index 5032c98f375..5365e58e78e 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageContextFactory.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageContextFactory.java @@ -16,10 +16,6 @@ // under the License. package com.cloud.storage.resource; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - import com.cloud.hypervisor.vmware.util.VmwareClient; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.hypervisor.vmware.util.VmwareContextPool; @@ -44,6 +40,10 @@ public class VmwareSecondaryStorageContextFactory { vimClient.connect(serviceUrl, vCenterUserName, vCenterPassword); VmwareContext context = new VmwareContext(vimClient, vCenterAddress); assert(context != null); + + context.setPoolInfo(s_pool, VmwareContextPool.composePoolKey(vCenterAddress, vCenterUserName)); + s_pool.registerOutstandingContext(context); + return context; } @@ -54,8 +54,6 @@ public class VmwareSecondaryStorageContextFactory { } if(context != null) { - context.setPoolInfo(s_pool, VmwareContextPool.composePoolKey(vCenterAddress, vCenterUserName)); - context.registerStockObject("username", vCenterUserName); context.registerStockObject("password", vCenterPassword); } diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index b6500e4d935..be5df492f85 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -282,7 +282,7 @@ public enum Config { VmwareUseNexusVSwitch("Network", ManagementServer.class, Boolean.class, "vmware.use.nexus.vswitch", "false", "Enable/Disable Cisco Nexus 1000v vSwitch in VMware environment", null), VmwareUseDVSwitch("Network", ManagementServer.class, Boolean.class, "vmware.use.dvswitch", "false", "Enable/Disable Nexus/Vmware dvSwitch in VMware environment", null), VmwarePortsPerDVPortGroup("Network", ManagementServer.class, Integer.class, "vmware.ports.per.dvportgroup", "256", "Default number of ports per Vmware dvPortGroup in VMware environment", null), - VmwareCreateFullClone("Advanced", ManagementServer.class, Boolean.class, "vmware.create.full.clone", "false", "If set to true, creates guest VMs as full clones on ESX", null), + VmwareCreateFullClone("Advanced", ManagementServer.class, Boolean.class, "vmware.create.full.clone", "true", "If set to true, creates guest VMs as full clones on ESX", null), VmwareServiceConsole("Advanced", ManagementServer.class, String.class, "vmware.service.console", "Service Console", "Specify the service console network name(for ESX hosts)", null), VmwareManagementPortGroup("Advanced", ManagementServer.class, String.class, "vmware.management.portgroup", "Management Network", "Specify the management network name(for ESXi hosts)", null), VmwareAdditionalVncPortRangeStart("Advanced", ManagementServer.class, Integer.class, "vmware.additional.vnc.portrange.start", "50000", "Start port number of additional VNC port range", null), diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContext.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContext.java index 79fa5a6749c..6c3dab7f790 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContext.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContext.java @@ -624,6 +624,11 @@ public class VmwareContext { } catch(Exception e) { s_logger.warn("Unexpected exception: ", e); } + + if(_pool != null) { + _pool.unregisterOutstandingContext(this); + } + unregisterOutstandingContext(); } diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContextPool.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContextPool.java index a9d1ab9a61d..18af7cd2338 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContextPool.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContextPool.java @@ -31,6 +31,8 @@ public class VmwareContextPool { private static final long DEFAULT_CHECK_INTERVAL = 10000; private static final int DEFAULT_IDLE_QUEUE_LENGTH = 128; + private List _outstandingRegistry = new ArrayList(); + private Map> _pool; private int _maxIdleQueueLength = DEFAULT_IDLE_QUEUE_LENGTH; private long _idleCheckIntervalMs = DEFAULT_CHECK_INTERVAL; @@ -54,9 +56,23 @@ public class VmwareContextPool { _timer.scheduleAtFixedRate(getTimerTask(), _idleCheckIntervalMs, _idleCheckIntervalMs); } + public void registerOutstandingContext(VmwareContext context) { + assert(context != null); + synchronized(this) { + _outstandingRegistry.add(context); + } + } + + public void unregisterOutstandingContext(VmwareContext context) { + assert(context != null); + synchronized(this) { + _outstandingRegistry.remove(context); + } + } + public VmwareContext getContext(String vCenterAddress, String vCenterUserName) { String poolKey = composePoolKey(vCenterAddress, vCenterUserName); - synchronized(_pool) { + synchronized(this) { List l = _pool.get(poolKey); if(l == null) return null; @@ -78,7 +94,7 @@ public class VmwareContextPool { public void returnContext(VmwareContext context) { assert(context.getPool() == this); assert(context.getPoolKey() != null); - synchronized(_pool) { + synchronized(this) { List l = _pool.get(context.getPoolKey()); if(l == null) { l = new ArrayList(); @@ -100,8 +116,23 @@ public class VmwareContextPool { } } + private TimerTask getTimerTask() { + return new TimerTask() { + @Override + public void run() { + try { + // doIdleCheck(); + + doKeepAlive(); + } catch (Throwable e) { + s_logger.error("Unexpected exception", e); + } + } + }; + } + private void getIdleCheckContexts(List l, int batchSize) { - synchronized(_pool) { + synchronized(this) { for(Map.Entry> entry : _pool.entrySet()) { if(entry.getValue() != null) { int count = 0; @@ -116,19 +147,6 @@ public class VmwareContextPool { } } - private TimerTask getTimerTask() { - return new TimerTask() { - @Override - public void run() { - try { - doIdleCheck(); - } catch (Throwable e) { - s_logger.error("Unexpected exception", e); - } - } - }; - } - private void doIdleCheck() { List l = new ArrayList(); int batchSize = (int)(_idleCheckIntervalMs / 1000); // calculate batch size at 1 request/sec rate @@ -148,6 +166,34 @@ public class VmwareContextPool { } } + private void getKeepAliveCheckContexts(List l, int batchSize) { + synchronized(this) { + int size = Math.min(_outstandingRegistry.size(), batchSize); + while(size > 0) { + VmwareContext context = _outstandingRegistry.remove(0); + l.add(context); + + _outstandingRegistry.add(context); + size--; + } + } + } + + private void doKeepAlive() { + List l = new ArrayList(); + int batchSize = (int)(_idleCheckIntervalMs / 1000); // calculate batch size at 1 request/sec rate + getKeepAliveCheckContexts(l, batchSize); + + for(VmwareContext context : l) { + try { + context.idleCheck(); + } catch(Throwable e) { + s_logger.warn("Exception caught during VmwareContext idle check, close and discard the context", e); + context.close(); + } + } + } + public static String composePoolKey(String vCenterAddress, String vCenterUserName) { assert(vCenterUserName != null); assert(vCenterAddress != null);