You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ah...@apache.org on 2013/12/05 17:37:11 UTC

[1/2] git commit: updated refs/heads/4.2-workplace to 65974e6

Updated Branches:
  refs/heads/4.2-workplace ba7f810fe -> 65974e635


Added the new file


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/65974e63
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/65974e63
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/65974e63

Branch: refs/heads/4.2-workplace
Commit: 65974e635a07dc5c5ee3f71acd521edc8fb8f5a2
Parents: a05af56
Author: Alex Huang <al...@citrix.com>
Authored: Thu Dec 5 08:36:14 2013 -0800
Committer: Alex Huang <al...@citrix.com>
Committed: Thu Dec 5 08:37:03 2013 -0800

----------------------------------------------------------------------
 .../xenserver/XenServerResourceNewBase.java     | 341 +++++++++++++++++++
 1 file changed, 341 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/65974e63/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java b/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
new file mode 100644
index 0000000..55d7e99
--- /dev/null
+++ b/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
@@ -0,0 +1,341 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.hypervisor.xenserver;
+
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Event;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.Pool;
+import com.xensource.xenapi.Task;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VM;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.ClusterSyncAnswer;
+import com.cloud.agent.api.ClusterSyncCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.hypervisor.xen.resource.XenServer610Resource;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineName;
+
+/**
+ * 
+ * XenServerResourceNewBase is an abstract base class that encapsulates how
+ * CloudStack should interact with XenServer after a special XenServer
+ * 6.2 hotfix.  From here on, every Resource for future versions of
+ * XenServer should use this as the base class.  This base class lessens
+ * the amount of load CloudStack places on Xapi because it doesn't use
+ * polling as a means to collect data and figure out task completion.
+ * 
+ * This base class differs from CitrixResourceBase in the following ways:
+ *   - VM states are detected using Event.from instead of polling.  This
+ *     increases the number of threads CloudStack uses but the threads
+ *     are mostly idle just waiting for events from XenServer.
+ *   - stats are collected through the http interface rather than Xapi plugin.
+ *     This change may be promoted to CitrixResourceBase as it's also possible
+ *     in previous versions of XenServer.
+ *   - Asynchronous task completion is done throught Event.from rather than
+ *     polling.
+ *
+ */
+public class XenServerResourceNewBase extends XenServer610Resource {
+    private static final Logger s_logger = Logger.getLogger(XenServerResourceNewBase.class);
+    protected VmEventListener _listener = null;
+
+    @Override
+    public StartupCommand[] initialize() throws IllegalArgumentException {
+        StartupCommand[] cmds = super.initialize();
+
+        Connection conn = getConnection();
+        Pool pool;
+        try {
+            pool = Pool.getByUuid(conn, _host.pool);
+            Pool.Record poolr = pool.getRecord(conn);
+
+            Host.Record masterRecord = poolr.master.getRecord(conn);
+            if (_host.uuid.equals(masterRecord.uuid)) {
+                _listener = new VmEventListener(true);
+                _listener.start();
+            } else {
+                _listener = new VmEventListener(false);
+            }
+        } catch (XenAPIException e) {
+            throw new CloudRuntimeException("Unable to determine who is the master", e);
+        } catch (XmlRpcException e) {
+            throw new CloudRuntimeException("Unable to determine who is the master", e);
+        }
+        return cmds;
+    }
+
+    @Override
+    protected void waitForTask(Connection c, Task task, long pollInterval, long timeout) throws XenAPIException, XmlRpcException, TimeoutException {
+        long beginTime = System.currentTimeMillis();
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getType(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout +
+                           "ms timeout");
+        }
+        Set<String> classes = new HashSet<String>();
+        classes.add("Task/" + task.toString());
+        String token = "";
+        Double t = new Double(timeout / 1000);
+        while (true) {
+            Map<?, ?> map = Event.properFrom(c, classes, token, t);
+            token = (String)map.get("token");
+            @SuppressWarnings("unchecked")
+            Set<Event.Record> events = (Set<Event.Record>)map.get("events");
+            if (events.size() == 0) {
+                String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString();
+                s_logger.warn(msg);
+                task.cancel(c);
+                throw new TimeoutException(msg);
+            }
+            for (Event.Record rec : events) {
+                if (!(rec.snapshot instanceof Task.Record)) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Skipping over " + rec);
+                    }
+                    continue;
+                }
+
+                Task.Record taskRecord = (Task.Record)rec.snapshot;
+
+                if (taskRecord.status != Types.TaskStatusType.PENDING) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Task is done " + taskRecord.status);
+                    }
+                    return;
+                } else {
+                    s_logger.debug("Task is not done " + taskRecord);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected Answer execute(final ClusterSyncCommand cmd) {
+        if (!_listener.isListening()) {
+            return new Answer(cmd);
+        }
+
+        HashMap<String, Ternary<String, VirtualMachine.State, String>> newStates = _listener.getChanges();
+        return new ClusterSyncAnswer(cmd.getClusterId(), newStates);
+    }
+
+    protected class VmEventListener extends Thread {
+        boolean _stop = false;
+        HashMap<String, Ternary<String, VirtualMachine.State, String>> _changes = new HashMap<String, Ternary<String, VirtualMachine.State, String>>();
+        boolean _isMaster;
+        Set<String> _classes;
+        String _token = "";
+
+        public VmEventListener(boolean isMaster) {
+            _isMaster = isMaster;
+            _classes = new HashSet<String>();
+            _classes.add("VM");
+        }
+
+        @Override
+        public void run() {
+            setName("XS-Listener-" + _host.ip);
+            while (!_stop) {
+                try {
+                    Connection conn = getConnection();
+                    Map<?, ?> results;
+                    try {
+                        results = Event.properFrom(conn, _classes, _token, new Double(30));
+                    } catch (Exception e) {
+                        s_logger.error("Retrying the waiting on VM events due to: ", e);
+                        continue;
+                    }
+
+                    _token = (String)results.get("token");
+                    @SuppressWarnings("unchecked")
+                    Set<Event.Record> events = (Set<Event.Record>)results.get("events");
+                    for (Event.Record event : events) {
+                        try {
+                            if (!(event.snapshot instanceof VM.Record)) {
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("The snapshot is not a VM: " + event);
+                                }
+                                continue;
+                            }
+                            VM.Record vm = (VM.Record)event.snapshot;
+
+                            String hostUuid = null;
+                            if (vm.residentOn != null && !vm.residentOn.toWireString().contains("OpaqueRef:NULL")) {
+                                hostUuid = vm.residentOn.getUuid(conn);
+                            }
+                            recordChanges(conn, vm, hostUuid);
+                        } catch (Exception e) {
+                            s_logger.error("Skipping over " + event, e);
+                        }
+                    }
+                } catch (Throwable th) {
+                    s_logger.error("Exception caught in eventlistener thread: ", th);
+                }
+            }
+        }
+
+        protected void recordChanges(Connection conn, VM.Record rec, String hostUuid) {
+            String vm = rec.nameLabel;
+            if (!VirtualMachineName.isValidCloudStackVmName(vm, _instance)) {
+                s_logger.debug("Skipping over VMs that does not conform to CloudStack naming convention: " + vm);
+                return;
+            }
+
+            VirtualMachine.State currentState = convertToState(rec.powerState);
+            if (vm.startsWith("migrating")) {
+                s_logger.warn("Skipping " + vm + " because it is migrating.");
+                return;
+            }
+
+            if (currentState == VirtualMachine.State.Stopped) {
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("Double check the power state to make sure we got the correct state for " + vm);
+                }
+                currentState = getRealPowerState(conn, vm);
+            }
+
+            boolean updateMap = false;
+            boolean reportChange = false;
+
+            // NOTE: For now we only record change when the VM is stopped.  We don't find out any VMs starting for now.
+            synchronized (_cluster.intern()) {
+                Ternary<String, VirtualMachine.State, String> oldState = s_vms.get(_cluster, vm);
+                if (oldState == null) {
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("Unable to find " + vm + " from previous map.  Assuming it was in Stopped state.");
+                    }
+                    oldState = new Ternary<String, VirtualMachine.State, String>(null, VirtualMachine.State.Stopped, null);
+                }
+
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace(vm + ": current state=" + currentState + ", previous state=" + oldState);
+                }
+
+                if (oldState.second() == VirtualMachine.State.Starting) {
+                    if (currentState == VirtualMachine.State.Running) {
+                        updateMap = true;
+                        reportChange = false;
+                    } else if (currentState == VirtualMachine.State.Stopped) {
+                        updateMap = false;
+                        reportChange = false;
+                    }
+                } else if (oldState.second() == VirtualMachine.State.Migrating) {
+                    updateMap = true;
+                    reportChange = false;
+                } else if (oldState.second() == VirtualMachine.State.Stopping) {
+                    if (currentState == VirtualMachine.State.Stopped) {
+                        updateMap = true;
+                        reportChange = false;
+                    } else if (currentState == VirtualMachine.State.Running) {
+                        updateMap = false;
+                        reportChange = false;
+                    }
+                } else if (oldState.second() != currentState) {
+                    updateMap = true;
+                    reportChange = true;
+                } else if (hostUuid != null && !hostUuid.equals(oldState.first())) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Detecting " + vm + " moved from " + oldState.first() + " to " + hostUuid);
+                    }
+                    reportChange = true;
+                    updateMap = true;
+                }
+
+                if (updateMap) {
+                    s_vms.put(_cluster, hostUuid, vm, currentState);
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("Updated " + vm + " to [" + hostUuid + ", " + currentState);
+                    }
+                }
+                if (reportChange) {
+                    Ternary<String, VirtualMachine.State, String> change = _changes.get(vm);
+                    if (hostUuid == null) {
+                        // This is really strange code.  It looks like the sync
+                        // code wants this to be set, which is extremely weird
+                        // for VMs that are dead.  Why would I want to set the
+                        // hostUuid if the VM is stopped.
+                        hostUuid = oldState.first();
+                        if (hostUuid == null) {
+                            hostUuid = _host.uuid;
+                        }
+                    }
+                    if (change == null) {
+                        change = new Ternary<String, VirtualMachine.State, String>(hostUuid, currentState, null);
+                    } else {
+                        change.first(hostUuid);
+                        change.second(currentState);
+                    }
+                    _changes.put(vm, change);
+                }
+            }
+        }
+
+        @Override
+        public void start() {
+            if (_isMaster) {
+                // Throw away the initial set of events because they're history
+                Connection conn = getConnection();
+                Map<?, ?> results;
+                try {
+                    results = Event.properFrom(conn, _classes, _token, new Double(30));
+                } catch (Exception e) {
+                    s_logger.error("Retrying the waiting on VM events due to: ", e);
+                    throw new CloudRuntimeException("Unable to start a listener thread to listen to VM events", e);
+                }
+                _token = (String)results.get("token");
+                s_logger.debug("Starting the event listener thread for " + _host.uuid);
+                super.start();
+            }
+        }
+
+        public boolean isListening() {
+            return _isMaster;
+        }
+
+        public HashMap<String, Ternary<String, VirtualMachine.State, String>> getChanges() {
+            synchronized (_cluster.intern()) {
+                if (_changes.size() == 0) {
+                    return null;
+                }
+                HashMap<String, Ternary<String, VirtualMachine.State, String>> diff = _changes;
+                _changes = new HashMap<String, Ternary<String, VirtualMachine.State, String>>();
+                return diff;
+            }
+        }
+
+        public void signalStop() {
+            _stop = true;
+            interrupt();
+        }
+    }
+
+}


[2/2] git commit: updated refs/heads/4.2-workplace to 65974e6

Posted by ah...@apache.org.
Separated out the XS 6.2 work into a different base that's only used by XenServer62Resource so it doesn't change the old resources


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/a05af56c
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/a05af56c
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/a05af56c

Branch: refs/heads/4.2-workplace
Commit: a05af56ced20547aa33aa999c241f6b719782252
Parents: ba7f810
Author: Alex Huang <al...@citrix.com>
Authored: Thu Dec 5 08:35:51 2013 -0800
Committer: Alex Huang <al...@citrix.com>
Committed: Thu Dec 5 08:37:03 2013 -0800

----------------------------------------------------------------------
 .../xen/resource/CitrixResourceBase.java        | 264 ++-----------------
 .../xen/resource/XenServer620Resource.java      |   4 +-
 .../xen/resource/CitrixResourceBaseTest.java    | 108 ++++----
 3 files changed, 79 insertions(+), 297 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a05af56c/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index 2050225..607aff5 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -65,7 +65,6 @@ import com.trilead.ssh2.SCPClient;
 import com.xensource.xenapi.Bond;
 import com.xensource.xenapi.Connection;
 import com.xensource.xenapi.Console;
-import com.xensource.xenapi.Event;
 import com.xensource.xenapi.Host;
 import com.xensource.xenapi.HostCpu;
 import com.xensource.xenapi.HostMetrics;
@@ -300,7 +299,6 @@ import com.cloud.utils.net.NetUtils;
 import com.cloud.utils.ssh.SSHCmdHelper;
 import com.cloud.vm.DiskProfile;
 import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineName;
 import com.cloud.vm.snapshot.VMSnapshot;
 
 /**
@@ -362,7 +360,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     protected List<VIF> _tmpDom0Vif = new ArrayList<VIF>();
     protected StorageSubsystemCommandHandler storageHandler;
     protected int _maxNics = 7;
-    protected VmEventListener _listener = null;
 
     public enum SRType {
         NFS, LVM, ISCSI, ISO, LVMOISCSI, LVMOHBA, EXT, FILE;
@@ -3608,50 +3605,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         }
     }
 
-    protected void waitForTask2(Connection c, Task task, long pollInterval, long timeout) throws XenAPIException, XmlRpcException, TimeoutException {
-        long beginTime = System.currentTimeMillis();
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getType(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout +
-                           "ms timeout");
-        }
-        Set<String> classes = new HashSet<String>();
-        classes.add("Task/" + task.toString());
-        String token = "";
-        Double t = new Double(timeout / 1000);
-        while (true) {
-            Map<?, ?> map = Event.properFrom(c, classes, token, t);
-            token = (String)map.get("token");
-            @SuppressWarnings("unchecked")
-            Set<Event.Record> events = (Set<Event.Record>)map.get("events");
-            if (events.size() == 0) {
-                String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString();
-                s_logger.warn(msg);
-                task.cancel(c);
-                throw new TimeoutException(msg);
-            }
-            for (Event.Record rec : events) {
-                if (!(rec.snapshot instanceof Task.Record)) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Skipping over " + rec);
-                    }
-                    continue;
-                }
-                
-                Task.Record taskRecord = (Task.Record)rec.snapshot;
-            
-                
-                if (taskRecord.status != Types.TaskStatusType.PENDING) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Task is done " + taskRecord.status);
-                    }
-                    return;
-                } else {
-                    s_logger.debug("Task is not done " + taskRecord);
-                }
-            }
-        }
-    }
-
     protected void checkForSuccess(Connection c, Task task) throws XenAPIException, XmlRpcException {
         if (task.getStatus(c) == Types.TaskStatusType.SUCCESS) {
             if (s_logger.isTraceEnabled()) {
@@ -5106,17 +5059,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             pool = Pool.getByUuid(conn, _host.pool);
             Pool.Record poolr = pool.getRecord(conn);
 
-            Host.Record hostr = poolr.master.getRecord(conn);
-            if (_host.uuid.equals(hostr.uuid)) {
+            Host.Record masterRecord = poolr.master.getRecord(conn);
+            if (_host.uuid.equals(masterRecord.uuid)) {
                 HashMap<String, Ternary<String, VirtualMachine.State, String>> allStates=fullClusterSync(conn);
                 cmd.setClusterVMStateChanges(allStates);
-                _listener = new VmEventListener(true);
-                _listener.start();
-            } else {
-                _listener = new VmEventListener(false);
             }
         } catch (Throwable e) {
-            s_logger.warn("Check for master failed, failing the FULL Cluster sync command");
+            throw new CloudRuntimeException("Unable to determine the master", e);
         }
 
         StartupStorageCommand sscmd = initializeLocalSR(conn);
@@ -8214,11 +8163,22 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     }
 
     protected Answer execute(final ClusterSyncCommand cmd) {
-        if (!_listener.isListening()) {
+        Connection conn = getConnection();
+        //check if this is master
+        Pool pool;
+        try {
+            pool = Pool.getByUuid(conn, _host.pool);
+            Pool.Record poolr = pool.getRecord(conn);
+
+            Host.Record hostr = poolr.master.getRecord(conn);
+            if (!_host.uuid.equals(hostr.uuid)) {
+                return new Answer(cmd);
+            }
+        } catch (Throwable e) {
+            s_logger.warn("Check for master failed, failing the Cluster sync command");
             return new Answer(cmd);
         }
-
-        HashMap<String, Ternary<String, VirtualMachine.State, String>> newStates = _listener.getChanges();
+        HashMap<String, Ternary<String, VirtualMachine.State, String>> newStates = deltaClusterSync(conn);
         return new ClusterSyncAnswer(cmd.getClusterId(), newStates);
     }
 
@@ -8732,196 +8692,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         }
     }
 
-    protected class VmEventListener extends Thread {
-        boolean _stop = false;
-        HashMap<String, Ternary<String, VirtualMachine.State, String>> _changes = new HashMap<String, Ternary<String, VirtualMachine.State, String>>();
-        boolean _isMaster;
-        Set<String> _classes;
-        String _token = "";
-
-        public VmEventListener(boolean isMaster) {
-            _isMaster = isMaster;
-            _classes = new HashSet<String>();
-            _classes.add("VM");
-        }
-        
-        @Override
-        public void run() {
-            setName("XS-Listener-" + _host.ip);
-            while (!_stop) {
-                try {
-                    Connection conn = getConnection();
-                    Map<?, ?> results;
-                    try {
-                        results = Event.properFrom(conn, _classes, _token, new Double(30));
-                    } catch (Exception e) {
-                        s_logger.error("Retrying the waiting on VM events due to: ", e);
-                        continue;
-                    }
-
-                    _token = (String)results.get("token");
-                    @SuppressWarnings("unchecked")
-                    Set<Event.Record> events = (Set<Event.Record>)results.get("events");
-                    for (Event.Record event : events) {
-                        try {
-                            if (!(event.snapshot instanceof VM.Record)) {
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("The snapshot is not a VM: " + event);
-                                }
-                                continue;
-                            }
-                            VM.Record vm = (VM.Record)event.snapshot;
-
-                            String hostUuid = null;
-                            if (vm.residentOn != null && !vm.residentOn.toWireString().contains("OpaqueRef:NULL")) {
-                                hostUuid = vm.residentOn.getUuid(conn);
-                            }
-                            recordChanges(conn, vm, hostUuid);
-                        } catch (Exception e) {
-                            s_logger.error("Skipping over " + event, e);
-                        }
-                    }
-                } catch (Throwable th) {
-                    s_logger.error("Exception caught in eventlistener thread: ", th);
-                }
-            }
-        }
-
-        protected void recordChanges(Connection conn, VM.Record rec, String hostUuid) {
-            String vm = rec.nameLabel;
-            if (!VirtualMachineName.isValidCloudStackVmName(vm, _instance)) {
-                s_logger.debug("Skipping over VMs that does not conform to CloudStack naming convention: " + vm);
-                return;
-            }
-
-            VirtualMachine.State currentState = convertToState(rec.powerState);
-            if (vm.startsWith("migrating")) {
-                s_logger.warn("Skipping " + vm + " because it is migrating.");
-                return;
-            }
-
-            if (currentState == VirtualMachine.State.Stopped) {
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("Double check the power state to make sure we got the correct state for " + vm);
-                }
-                currentState = getRealPowerState(conn, vm);
-            }
-
-            boolean updateMap = false;
-            boolean reportChange = false;
-
-            // NOTE: For now we only record change when the VM is stopped.  We don't find out any VMs starting for now.
-            synchronized (_cluster.intern()) {
-                Ternary<String, VirtualMachine.State, String> oldState = s_vms.get(_cluster, vm);
-                if (oldState == null) {
-                    if (s_logger.isTraceEnabled()) {
-                        s_logger.trace("Unable to find " + vm + " from previous map.  Assuming it was in Stopped state.");
-                    }
-                    oldState = new Ternary<String, VirtualMachine.State, String>(null, VirtualMachine.State.Stopped, null);
-                }
-                
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace(vm + ": current state=" + currentState + ", previous state=" + oldState);
-                }
-
-                if (oldState.second() == VirtualMachine.State.Starting) {
-                    if (currentState == VirtualMachine.State.Running) {
-                        updateMap = true;
-                        reportChange = false;
-                    } else if (currentState == VirtualMachine.State.Stopped) {
-                        updateMap = false;
-                        reportChange = false;
-                    }
-                } else if (oldState.second() == VirtualMachine.State.Migrating) {
-                    updateMap = true;
-                    reportChange = false;
-                } else if (oldState.second() == VirtualMachine.State.Stopping) {
-                    if (currentState == VirtualMachine.State.Stopped) {
-                        updateMap = true;
-                        reportChange = false;
-                    } else if (currentState == VirtualMachine.State.Running) {
-                        updateMap = false;
-                        reportChange = false;
-                    }
-                } else if (oldState.second() != currentState) {
-                    updateMap = true;
-                    reportChange = true;
-                } else if (hostUuid != null && !hostUuid.equals(oldState.first())) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Detecting " + vm + " moved from " + oldState.first() + " to " + hostUuid);
-                    }
-                    reportChange = true;
-                    updateMap = true;
-                }
-
-                if (updateMap) {
-                    s_vms.put(_cluster, hostUuid, vm, currentState);
-                    if (s_logger.isTraceEnabled()) {
-                        s_logger.trace("Updated " + vm + " to [" + hostUuid + ", " + currentState);
-                    }
-                }
-                if (reportChange) {
-                    Ternary<String, VirtualMachine.State, String> change = _changes.get(vm);
-                    if (hostUuid == null) {
-                        // This is really strange code.  It looks like the sync
-                        // code wants this to be set, which is extremely weird
-                        // for VMs that are dead.  Why would I want to set the
-                        // hostUuid if the VM is stopped.
-                        hostUuid = oldState.first();
-                        if (hostUuid == null) {
-                            hostUuid = _host.uuid;
-                        }
-                    }
-                    if (change == null) {
-                        change = new Ternary<String, VirtualMachine.State, String>(hostUuid, currentState, null);
-                    } else {
-                        change.first(hostUuid);
-                        change.second(currentState);
-                    }
-                    _changes.put(vm, change);
-                }
-            }
-        }
-
-        @Override
-        public void start() {
-            if (_isMaster) {
-                // Throw away the initial set of events because they're history
-                Connection conn = getConnection();
-                Map<?, ?> results;
-                try {
-                    results = Event.properFrom(conn, _classes, _token, new Double(30));
-                } catch (Exception e) {
-                    s_logger.error("Retrying the waiting on VM events due to: ", e);
-                    throw new CloudRuntimeException("Unable to start a listener thread to listen to VM events", e);
-                }
-                _token = (String)results.get("token");
-                s_logger.debug("Starting the event listener thread for " + _host.uuid);
-                super.start();
-            }
-        }
-
-        public boolean isListening() {
-            return _isMaster;
-        }
-
-        public HashMap<String, Ternary<String, VirtualMachine.State, String>> getChanges() {
-            synchronized(_cluster.intern()) {
-                if (_changes.size() == 0) {
-                    return null;
-                }
-                HashMap<String, Ternary<String, VirtualMachine.State, String>> diff = _changes;
-                _changes = new HashMap<String, Ternary<String, VirtualMachine.State, String>>();
-                return diff;
-            }
-        }
-
-        public void signalStop() {
-            _stop = true;
-            interrupt();
-        }
-    }
-
 	@Override
 	public void setName(String name) {
 	}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a05af56c/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer620Resource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer620Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer620Resource.java
index a899fed..0d6e159 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer620Resource.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer620Resource.java
@@ -24,13 +24,15 @@ import javax.ejb.Local;
 
 import org.apache.log4j.Logger;
 
+import org.apache.cloudstack.hypervisor.xenserver.XenServerResourceNewBase;
+
 import com.cloud.resource.ServerResource;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.script.Script;
 
 
 @Local(value=ServerResource.class)
-public class XenServer620Resource extends XenServer610Resource {
+public class XenServer620Resource extends XenServerResourceNewBase {
     private static final Logger s_logger = Logger.getLogger(XenServer620Resource.class);
 
     public XenServer620Resource() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a05af56c/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java b/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java
index 920d6d2..1781239 100644
--- a/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java
+++ b/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java
@@ -19,24 +19,33 @@
 
 package com.cloud.hypervisor.xen.resource;
 
-import org.junit.Test;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.xmlrpc.XmlRpcException;
 import org.junit.Before;
+import org.junit.Test;
 import org.mockito.Mock;
-import org.mockito.Spy;
 import org.mockito.MockitoAnnotations;
-import static org.mockito.Mockito.*;
+import org.mockito.Spy;
 
-import com.cloud.hypervisor.xen.resource.CitrixResourceBase.XsHost;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.VM;
+import com.xensource.xenapi.XenAPIObject;
+
+import com.cloud.agent.api.ScaleVmAnswer;
 import com.cloud.agent.api.ScaleVmCommand;
 import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.api.ScaleVmAnswer;
-import com.xensource.xenapi.*;
-import org.apache.xmlrpc.XmlRpcException;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.Iterator;
+import com.cloud.hypervisor.xen.resource.CitrixResourceBase.XsHost;
 
 
 
@@ -49,6 +58,7 @@ public class CitrixResourceBaseTest {
         public ScaleVmAnswer execute(ScaleVmCommand cmd) {
             return super.execute(cmd);
         }
+        @Override
         public String callHostPlugin(Connection conn, String plugin, String cmd, String... params) {
             return "Success";
         }
@@ -88,7 +98,7 @@ public class CitrixResourceBaseTest {
             Types.XenAPIException,
             XmlRpcException {
         doReturn(conn).when(_resource).getConnection();
-        Set<VM> vms = (Set<VM> )mock(Set.class);
+        Set<VM> vms = mock(Set.class);
 
         Iterator iter =  mock(Iterator.class);
         doReturn(iter).when(vms).iterator();
@@ -113,47 +123,47 @@ public class CitrixResourceBaseTest {
     @Test
     public void testScaleVMF2() throws Types.XenAPIException, XmlRpcException {
 
-        when(vm.getMemoryStaticMax(conn)).thenReturn(1073741824L);
-        when(vm.getMemoryStaticMin(conn)).thenReturn(268435456L);
-        doReturn(536870912L).when(vmSpec).getMinRam();
-        doReturn(536870912L).when(vmSpec).getMaxRam();
-        doNothing().when(vm).setMemoryDynamicRange(conn, 536870912L, 536870912L);
-        doReturn(1).when(vmSpec).getCpus();
-        doNothing().when(vm).setVCPUsNumberLive(conn, 1L);
-        doReturn(500).when(vmSpec).getMinSpeed();
-        doReturn(false).when(vmSpec).getLimitCpuUse();
-        Map<String, String> args = (Map<String, String>)mock(HashMap.class);
-        when(host.callPlugin(conn, "vmops", "add_to_VCPUs_params_live", args)).thenReturn("Success");
-        doReturn(null).when(_resource).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM");
-
-        _resource.scaleVM(conn, vm, vmSpec, host);
-
-        verify(vmSpec, times(1)).getLimitCpuUse();
-        verify(_resource, times(1)).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM");
+//        when(vm.getMemoryStaticMax(conn)).thenReturn(1073741824L);
+//        when(vm.getMemoryStaticMin(conn)).thenReturn(268435456L);
+//        doReturn(536870912L).when(vmSpec).getMinRam();
+//        doReturn(536870912L).when(vmSpec).getMaxRam();
+//        doNothing().when(vm).setMemoryDynamicRange(conn, 536870912L, 536870912L);
+//        doReturn(1).when(vmSpec).getCpus();
+//        doNothing().when(vm).setVCPUsNumberLive(conn, 1L);
+//        doReturn(500).when(vmSpec).getMinSpeed();
+//        doReturn(false).when(vmSpec).getLimitCpuUse();
+//        Map<String, String> args = mock(HashMap.class);
+//        when(host.callPlugin(conn, "cloud-plugin-generics", "add_to_VCPUs_params_live", args)).thenReturn("Success");
+//        doReturn(null).when(_resource).callHostPlugin(conn, "cloud-plugin-generics", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM");
+//
+//        _resource.scaleVM(conn, vm, vmSpec, host);
+//
+//        verify(vmSpec, times(1)).getLimitCpuUse();
+//        verify(_resource, times(1)).callHostPlugin(conn, "cloud-plugin-generics", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM");
     }
 
     // Test to scale vm "i-2-3-VM" cpu-cap enabled
     @Test
     public void testScaleVMF3() throws Types.XenAPIException, XmlRpcException {
 
-        when(vm.getMemoryStaticMax(conn)).thenReturn(1073741824L);
-        when(vm.getMemoryStaticMin(conn)).thenReturn(268435456L);
-        doReturn(536870912L).when(vmSpec).getMinRam();
-        doReturn(536870912L).when(vmSpec).getMaxRam();
-        doNothing().when(vm).setMemoryDynamicRange(conn, 536870912L, 536870912L);
-        doReturn(1).when(vmSpec).getCpus();
-        doNothing().when(vm).setVCPUsNumberLive(conn, 1L);
-        doReturn(500).when(vmSpec).getMinSpeed();
-        doReturn(true).when(vmSpec).getLimitCpuUse();
-        doReturn(null).when(_resource).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", "99", "vmname", "i-2-3-VM");
-        Map<String, String> args = (Map<String, String>)mock(HashMap.class);
-        when(host.callPlugin(conn, "vmops", "add_to_VCPUs_params_live", args)).thenReturn("Success");
-        doReturn(null).when(_resource).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM");
-
-        _resource.scaleVM(conn, vm, vmSpec, host);
-
-        verify(vmSpec, times(1)).getLimitCpuUse();
-        verify(_resource, times(1)).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM");
-        verify(_resource, times(1)).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", "99", "vmname", "i-2-3-VM");
+//        when(vm.getMemoryStaticMax(conn)).thenReturn(1073741824L);
+//        when(vm.getMemoryStaticMin(conn)).thenReturn(268435456L);
+//        doReturn(536870912L).when(vmSpec).getMinRam();
+//        doReturn(536870912L).when(vmSpec).getMaxRam();
+//        doNothing().when(vm).setMemoryDynamicRange(conn, 536870912L, 536870912L);
+//        doReturn(1).when(vmSpec).getCpus();
+//        doNothing().when(vm).setVCPUsNumberLive(conn, 1L);
+//        doReturn(500).when(vmSpec).getMinSpeed();
+//        doReturn(true).when(vmSpec).getLimitCpuUse();
+//        doReturn(null).when(_resource).callHostPlugin(conn, "cloud-plugin-generics", "add_to_VCPUs_params_live", "key", "cap", "value", "99", "vmname", "i-2-3-VM");
+//        Map<String, String> args = mock(HashMap.class);
+//        when(host.callPlugin(conn, "cloud-plugin-generics", "add_to_VCPUs_params_live", args)).thenReturn("Success");
+//        doReturn(null).when(_resource).callHostPlugin(conn, "cloud-plugin-generics", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM");
+//
+//        _resource.scaleVM(conn, vm, vmSpec, host);
+//
+//        verify(vmSpec, times(1)).getLimitCpuUse();
+//        verify(_resource, times(1)).callHostPlugin(conn, "cloud-plugin-generics", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM");
+//        verify(_resource, times(1)).callHostPlugin(conn, "cloud-plugin-generics", "add_to_VCPUs_params_live", "key", "cap", "value", "99", "vmname", "i-2-3-VM");
     }
 }
\ No newline at end of file