incubator-cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From muralire...@apache.org
Subject [6/8] Moving out XenServer support code into plugins/hypervisors/xen
Date Tue, 26 Jun 2012 23:39:10 GMT
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/550b2257/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
new file mode 100644
index 0000000..3917242
--- /dev/null
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -0,0 +1,6993 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License.  Citrix Systems, Inc.
+// reserves all rights not expressly granted by 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.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.hypervisor.xen.resource;
+
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Queue;
+import java.util.Random;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.agent.api.AttachVolumeAnswer;
+import com.cloud.agent.api.AttachVolumeCommand;
+import com.cloud.agent.api.BackupSnapshotAnswer;
+import com.cloud.agent.api.BackupSnapshotCommand;
+import com.cloud.agent.api.BumpUpPriorityCommand;
+import com.cloud.agent.api.CheckHealthAnswer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CheckNetworkAnswer;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.CheckOnHostAnswer;
+import com.cloud.agent.api.CheckOnHostCommand;
+import com.cloud.agent.api.CheckRouterAnswer;
+import com.cloud.agent.api.CheckRouterCommand;
+import com.cloud.agent.api.CheckVirtualMachineAnswer;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+import com.cloud.agent.api.CleanupNetworkRulesCmd;
+import com.cloud.agent.api.ClusterSyncAnswer;
+import com.cloud.agent.api.ClusterSyncCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.CreateStoragePoolCommand;
+import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
+import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.GetDomRVersionAnswer;
+import com.cloud.agent.api.GetDomRVersionCmd;
+import com.cloud.agent.api.GetHostStatsAnswer;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.GetStorageStatsAnswer;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.GetVmStatsAnswer;
+import com.cloud.agent.api.GetVmStatsCommand;
+import com.cloud.agent.api.GetVncPortAnswer;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.HostStatsEntry;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.ManageSnapshotAnswer;
+import com.cloud.agent.api.ManageSnapshotCommand;
+import com.cloud.agent.api.MigrateAnswer;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.ModifySshKeysCommand;
+import com.cloud.agent.api.ModifyStoragePoolAnswer;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.NetworkRulesSystemVmCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
+import com.cloud.agent.api.PingRoutingWithOvsCommand;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.PoolEjectCommand;
+import com.cloud.agent.api.PrepareForMigrationAnswer;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.RebootAnswer;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.RebootRouterCommand;
+import com.cloud.agent.api.SecurityGroupRuleAnswer;
+import com.cloud.agent.api.SecurityGroupRulesCmd;
+import com.cloud.agent.api.SetupAnswer;
+import com.cloud.agent.api.SetupCommand;
+import com.cloud.agent.api.StartAnswer;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.StopAnswer;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.agent.api.UpdateHostPasswordCommand;
+import com.cloud.agent.api.UpgradeSnapshotCommand;
+import com.cloud.agent.api.VmStatsEntry;
+import com.cloud.agent.api.check.CheckSshAnswer;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
+import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
+import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
+import com.cloud.agent.api.routing.DhcpEntryCommand;
+import com.cloud.agent.api.routing.IpAssocAnswer;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
+import com.cloud.agent.api.routing.SavePasswordCommand;
+import com.cloud.agent.api.routing.SetFirewallRulesAnswer;
+import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer;
+import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.routing.VmDataCommand;
+import com.cloud.agent.api.routing.VpnUsersCfgCommand;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+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.DestroyCommand;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.PortForwardingRuleTO;
+import com.cloud.agent.api.to.StaticNatRuleTO;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.agent.api.to.SwiftTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.host.Host.Type;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.HAProxyConfigurator;
+import com.cloud.network.LoadBalancerConfigurator;
+import com.cloud.network.Networks;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetworkSetupInfo;
+import com.cloud.network.ovs.OvsCreateGreTunnelAnswer;
+import com.cloud.network.ovs.OvsCreateGreTunnelCommand;
+import com.cloud.network.ovs.OvsCreateTunnelAnswer;
+import com.cloud.network.ovs.OvsCreateTunnelCommand;
+import com.cloud.network.ovs.OvsDeleteFlowCommand;
+import com.cloud.network.ovs.OvsDestroyBridgeCommand;
+import com.cloud.network.ovs.OvsDestroyTunnelCommand;
+import com.cloud.network.ovs.OvsFetchInterfaceAnswer;
+import com.cloud.network.ovs.OvsFetchInterfaceCommand;
+import com.cloud.network.ovs.OvsSetTagAndFlowAnswer;
+import com.cloud.network.ovs.OvsSetTagAndFlowCommand;
+import com.cloud.network.ovs.OvsSetupBridgeCommand;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.hypervisor.HypervisorResource;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.template.TemplateInfo;
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineName;
+import com.trilead.ssh2.SCPClient;
+import com.xensource.xenapi.Bond;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Console;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.HostCpu;
+import com.xensource.xenapi.HostMetrics;
+import com.xensource.xenapi.Network;
+import com.xensource.xenapi.PBD;
+import com.xensource.xenapi.PIF;
+import com.xensource.xenapi.PIF.Record;
+import com.xensource.xenapi.Pool;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Session;
+import com.xensource.xenapi.Task;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.BadServerResponse;
+import com.xensource.xenapi.Types.ConsoleProtocol;
+import com.xensource.xenapi.Types.IpConfigurationMode;
+import com.xensource.xenapi.Types.VmPowerState;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VBD;
+import com.xensource.xenapi.VDI;
+import com.xensource.xenapi.VIF;
+import com.xensource.xenapi.VLAN;
+import com.xensource.xenapi.VM;
+import com.xensource.xenapi.VMGuestMetrics;
+import com.xensource.xenapi.XenAPIObject;
+
+/**
+ * CitrixResourceBase encapsulates the calls to the XenServer Xapi process
+ * to perform the required functionalities for CloudStack.
+ * 
+ * ==============>  READ THIS  <==============
+ * Because the XenServer objects can expire when the session expires, we cannot
+ * keep any of the actual XenServer objects in this class.  The only
+ * thing that is constant is the UUID of the XenServer objects but not the
+ * objects themselves!  This is very important before you do any changes in
+ * this code here.
+ * 
+ */
+@Local(value = ServerResource.class)
+public abstract class CitrixResourceBase implements ServerResource, HypervisorResource {
+    private static final Logger s_logger = Logger.getLogger(CitrixResourceBase.class);
+    protected static final XenServerConnectionPool _connPool = XenServerConnectionPool.getInstance();
+    protected String _name;
+    protected String _username;
+    protected Queue<String> _password=new LinkedList<String>();
+    protected final int _retry = 100;
+    protected final int _sleep = 10000;
+    protected long _dcId;
+    protected String _pod;
+    protected String _cluster;
+    protected static final XenServerPoolVms s_vms = new XenServerPoolVms();
+    protected String _privateNetworkName;
+    protected String _linkLocalPrivateNetworkName;
+    protected String _publicNetworkName;
+    protected String _storageNetworkName1;
+    protected String _storageNetworkName2;
+    protected String _guestNetworkName;
+    protected int _wait;
+    protected int _migratewait;
+    protected String _instance; //instance name (default is usually "VM")
+    static final Random _rand = new Random(System.currentTimeMillis());
+
+    protected IAgentControl _agentControl;
+
+    final int _maxWeight = 256;
+    protected int _heartbeatInterval = 60;
+    protected final XsHost _host = new XsHost();
+
+    // Guest and Host Performance Statistics
+    protected String _consolidationFunction = "AVERAGE";
+    protected int _pollingIntervalInSeconds = 60;
+    
+    //Hypervisor specific params with generic value, may need to be overridden for specific versions
+    long _xs_memory_used = 128 * 1024 * 1024L; // xen hypervisor used 128 M
+    double _xs_virtualization_factor = 63.0/64.0;  // 1 - virtualization overhead
+
+    protected boolean _canBridgeFirewall = false;
+    protected boolean _isOvs = false;
+    protected List<VIF> _tmpDom0Vif = new ArrayList<VIF>();
+
+    public enum SRType {
+        NFS, LVM, ISCSI, ISO, LVMOISCSI, LVMOHBA, EXT;
+
+        String _str;
+
+        private SRType() {
+            _str = super.toString().toLowerCase();
+        }
+
+        @Override
+        public String toString() {
+            return _str;
+        }
+
+        public boolean equals(String type) {
+            return _str.equalsIgnoreCase(type);
+        }
+    }
+
+    protected static HashMap<Types.VmPowerState, State> s_statesTable;
+    static {
+        s_statesTable = new HashMap<Types.VmPowerState, State>();
+        s_statesTable.put(Types.VmPowerState.HALTED, State.Stopped);
+        s_statesTable.put(Types.VmPowerState.PAUSED, State.Running);
+        s_statesTable.put(Types.VmPowerState.RUNNING, State.Running);
+        s_statesTable.put(Types.VmPowerState.SUSPENDED, State.Running);
+        s_statesTable.put(Types.VmPowerState.UNRECOGNIZED, State.Unknown);
+    }
+
+
+    protected boolean cleanupHaltedVms(Connection conn) throws XenAPIException, XmlRpcException {
+        Host host = Host.getByUuid(conn, _host.uuid);
+        Map<VM, VM.Record> vms = VM.getAllRecords(conn);
+        boolean success = true;
+        for (Map.Entry<VM, VM.Record> entry : vms.entrySet()) {
+            VM vm = entry.getKey();
+            VM.Record vmRec = entry.getValue();
+            if ( vmRec.isATemplate || vmRec.isControlDomain ) {
+                continue;
+            }
+
+            if (VmPowerState.HALTED.equals(vmRec.powerState) && vmRec.affinity.equals(host)) {
+                try {
+                    vm.destroy(conn);
+                } catch (Exception e) {
+                    s_logger.warn("Catch Exception " + e.getClass().getName() + ": unable to destroy VM " + vmRec.nameLabel + " due to ", e);
+                    success = false;
+                }
+            }
+        }
+        return success;
+    }
+
+    protected boolean isRefNull(XenAPIObject object) {
+        return (object == null || object.toWireString().equals("OpaqueRef:NULL") || object.toWireString().equals("<not in database>"));
+    }
+
+    @Override
+    public void disconnected() {
+    }
+
+    protected boolean pingdomr(Connection conn, String host, String port) {
+        String status;
+        status = callHostPlugin(conn, "vmops", "pingdomr", "host", host, "port", port);
+
+        if (status == null || status.isEmpty()) {
+            return false;
+        }
+
+        return true;
+
+    }
+
+    protected boolean pingXenServer() {
+        Session slaveSession = null;
+        Connection slaveConn = null;
+        try {
+            URL slaveUrl = null;
+            slaveUrl = _connPool.getURL(_host.ip);
+            slaveConn = new Connection(slaveUrl, 10);
+            slaveSession = _connPool.slaveLocalLoginWithPassword(slaveConn, _username, _password);
+            return true;
+        } catch (Exception e) {
+        } finally {
+            if( slaveSession != null ){
+                try{
+                    Session.localLogout(slaveConn);
+                } catch (Exception e) {
+                }
+                slaveConn.dispose();
+            }
+        }
+        return false;
+    }
+
+    protected String logX(XenAPIObject obj, String msg) {
+        return new StringBuilder("Host ").append(_host.ip).append(" ").append(obj.toWireString()).append(": ").append(msg).toString();
+    }
+
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        Class<? extends Command> clazz = cmd.getClass();
+        if (clazz == CreateCommand.class) {
+            return execute((CreateCommand) cmd);
+        } else if (clazz == SetPortForwardingRulesCommand.class) {
+            return execute((SetPortForwardingRulesCommand) cmd);
+        } else if (clazz == SetStaticNatRulesCommand.class) {
+            return execute((SetStaticNatRulesCommand) cmd);
+        }  else if (clazz == LoadBalancerConfigCommand.class) {
+            return execute((LoadBalancerConfigCommand) cmd);
+        } else if (clazz == IpAssocCommand.class) {
+            return execute((IpAssocCommand) cmd);
+        } else if (clazz == CheckConsoleProxyLoadCommand.class) {
+            return execute((CheckConsoleProxyLoadCommand) cmd);
+        } else if (clazz == WatchConsoleProxyLoadCommand.class) {
+            return execute((WatchConsoleProxyLoadCommand) cmd);
+        } else if (clazz == SavePasswordCommand.class) {
+            return execute((SavePasswordCommand) cmd);
+        } else if (clazz == DhcpEntryCommand.class) {
+            return execute((DhcpEntryCommand) cmd);
+        } else if (clazz == VmDataCommand.class) {
+            return execute((VmDataCommand) cmd);
+        } else if (clazz == ReadyCommand.class) {
+            return execute((ReadyCommand) cmd);
+        } else if (clazz == GetHostStatsCommand.class) {
+            return execute((GetHostStatsCommand) cmd);
+        } else if (clazz == GetVmStatsCommand.class) {
+            return execute((GetVmStatsCommand) cmd);
+        } else if (clazz == CheckHealthCommand.class) {
+            return execute((CheckHealthCommand) cmd);
+        } else if (clazz == StopCommand.class) {
+            return execute((StopCommand) cmd);
+        } else if (clazz == RebootRouterCommand.class) {
+            return execute((RebootRouterCommand) cmd);
+        } else if (clazz == RebootCommand.class) {
+            return execute((RebootCommand) cmd);
+        } else if (clazz == CheckVirtualMachineCommand.class) {
+            return execute((CheckVirtualMachineCommand) cmd);
+        } else if (clazz == PrepareForMigrationCommand.class) {
+            return execute((PrepareForMigrationCommand) cmd);
+        } else if (clazz == MigrateCommand.class) {
+            return execute((MigrateCommand) cmd);
+        } else if (clazz == DestroyCommand.class) {
+            return execute((DestroyCommand) cmd);
+        } else if (clazz == CreateStoragePoolCommand.class) {
+            return execute((CreateStoragePoolCommand) cmd);
+        } else if (clazz == ModifyStoragePoolCommand.class) {
+            return execute((ModifyStoragePoolCommand) cmd);
+        } else if (clazz == DeleteStoragePoolCommand.class) {
+            return execute((DeleteStoragePoolCommand) cmd);
+        } else if (clazz == CopyVolumeCommand.class) {
+            return execute((CopyVolumeCommand) cmd);
+        } else if (clazz == AttachVolumeCommand.class) {
+            return execute((AttachVolumeCommand) cmd);
+        } else if (clazz == AttachIsoCommand.class) {
+            return execute((AttachIsoCommand) cmd);
+        } else if (clazz == ManageSnapshotCommand.class) {
+            return execute((ManageSnapshotCommand) cmd);
+        } else if (clazz == BackupSnapshotCommand.class) {
+            return execute((BackupSnapshotCommand) cmd);
+        } else if (clazz == CreateVolumeFromSnapshotCommand.class) {
+            return execute((CreateVolumeFromSnapshotCommand) cmd);
+        } else if (clazz == CreatePrivateTemplateFromVolumeCommand.class) {
+            return execute((CreatePrivateTemplateFromVolumeCommand) cmd);
+        } else if (clazz == CreatePrivateTemplateFromSnapshotCommand.class) {
+            return execute((CreatePrivateTemplateFromSnapshotCommand) cmd);
+        } else if (clazz == UpgradeSnapshotCommand.class) {
+            return execute((UpgradeSnapshotCommand) cmd);
+        } else if (clazz == GetStorageStatsCommand.class) {
+            return execute((GetStorageStatsCommand) cmd);
+        } else if (clazz == PrimaryStorageDownloadCommand.class) {
+            return execute((PrimaryStorageDownloadCommand) cmd);
+        } else if (clazz == GetVncPortCommand.class) {
+            return execute((GetVncPortCommand) cmd);
+        } else if (clazz == SetupCommand.class) {
+            return execute((SetupCommand) cmd);
+        } else if (clazz == MaintainCommand.class) {
+            return execute((MaintainCommand) cmd);
+        } else if (clazz == PingTestCommand.class) {
+            return execute((PingTestCommand) cmd);
+        } else if (clazz == CheckOnHostCommand.class) {
+            return execute((CheckOnHostCommand) cmd);
+        } else if (clazz == ModifySshKeysCommand.class) {
+            return execute((ModifySshKeysCommand) cmd);
+        } else if (clazz == PoolEjectCommand.class) {
+            return execute((PoolEjectCommand) cmd);
+        } else if (clazz == StartCommand.class) {
+            return execute((StartCommand)cmd);
+        } else if (clazz == RemoteAccessVpnCfgCommand.class) {
+            return execute((RemoteAccessVpnCfgCommand)cmd);
+        } else if (clazz == VpnUsersCfgCommand.class) {
+            return execute((VpnUsersCfgCommand)cmd);
+        } else if (clazz == CheckSshCommand.class) {
+            return execute((CheckSshCommand)cmd);
+        } else if (clazz == SecurityGroupRulesCmd.class) {
+            return execute((SecurityGroupRulesCmd) cmd);
+        } else if (clazz == OvsFetchInterfaceCommand.class) {
+            return execute((OvsFetchInterfaceCommand)cmd);
+        } else if (clazz == OvsCreateGreTunnelCommand.class) {
+            return execute((OvsCreateGreTunnelCommand)cmd);
+        } else if (clazz == OvsSetTagAndFlowCommand.class) {
+            return execute((OvsSetTagAndFlowCommand)cmd);
+        } else if (clazz == OvsDeleteFlowCommand.class) {
+            return execute((OvsDeleteFlowCommand)cmd);
+        } else if (clazz == CleanupNetworkRulesCmd.class){
+            return execute((CleanupNetworkRulesCmd)cmd);
+        } else if (clazz == NetworkRulesSystemVmCommand.class) {
+            return execute((NetworkRulesSystemVmCommand)cmd);
+        } else if (clazz == OvsCreateTunnelCommand.class) {
+            return execute((OvsCreateTunnelCommand)cmd);
+        } else if (clazz == OvsSetupBridgeCommand.class) {
+            return execute((OvsSetupBridgeCommand)cmd);
+        } else if (clazz == OvsDestroyBridgeCommand.class) {
+            return execute((OvsDestroyBridgeCommand)cmd);
+        } else if (clazz == OvsDestroyTunnelCommand.class) {
+            return execute((OvsDestroyTunnelCommand)cmd);
+        } else if (clazz == UpdateHostPasswordCommand.class) {
+            return execute((UpdateHostPasswordCommand)cmd);
+        } else if (cmd instanceof CheckRouterCommand) {
+            return execute((CheckRouterCommand)cmd);
+        } else if (cmd instanceof SetFirewallRulesCommand) {
+            return execute((SetFirewallRulesCommand)cmd);
+        } else if (cmd instanceof BumpUpPriorityCommand) {
+            return execute((BumpUpPriorityCommand)cmd);
+        } else if (cmd instanceof ClusterSyncCommand) {
+            return execute((ClusterSyncCommand)cmd);
+        } else if (cmd instanceof GetDomRVersionCmd) {
+            return execute((GetDomRVersionCmd)cmd);
+        } else if (clazz == CheckNetworkCommand.class) {
+            return execute((CheckNetworkCommand) cmd);
+        } else {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+
+    protected XsLocalNetwork getNativeNetworkForTraffic(Connection conn, TrafficType type, String name) throws XenAPIException, XmlRpcException {
+        if (name != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Looking for network named " + name);
+            }
+            return getNetworkByName(conn, name);
+        }
+
+        if (type == TrafficType.Guest) {
+            return new XsLocalNetwork(Network.getByUuid(conn, _host.guestNetwork), null, PIF.getByUuid(conn, _host.guestPif), null);
+        } else if (type == TrafficType.Control) {
+            setupLinkLocalNetwork(conn);
+            return new XsLocalNetwork(Network.getByUuid(conn, _host.linkLocalNetwork));
+        } else if (type == TrafficType.Management) {
+            return new XsLocalNetwork(Network.getByUuid(conn, _host.privateNetwork), null, PIF.getByUuid(conn, _host.privatePif), null);
+        } else if (type == TrafficType.Public) {
+            return new XsLocalNetwork(Network.getByUuid(conn, _host.publicNetwork), null, PIF.getByUuid(conn, _host.publicPif), null);
+        } else if (type == TrafficType.Storage) {
+            return new XsLocalNetwork(Network.getByUuid(conn, _host.storageNetwork1), null, PIF.getByUuid(conn, _host.storagePif1), null);
+        }
+
+        throw new CloudRuntimeException("Unsupported network type: " + type);
+    }
+
+    /**
+     * This is a tricky to create network in xenserver.
+     * if you create a network then create bridge by brctl or openvswitch yourself,
+     * then you will get an expection that is "REQUIRED_NETWROK" when you start a
+     * vm with this network. The soultion is, create a vif of dom0 and plug it in
+     * network, xenserver will create the bridge on behalf of you
+     * @throws XmlRpcException
+     * @throws XenAPIException
+     */
+    private void enableXenServerNetwork(Connection conn, Network nw,
+            String vifNameLabel, String networkDesc) throws XenAPIException, XmlRpcException {
+        /* Make sure there is a physical bridge on this network */
+        VIF dom0vif = null;
+        Pair<VM, VM.Record> vm = getControlDomain(conn);
+        VM dom0 = vm.first();
+        // Create a VIF unless there's not already another VIF
+        Set<VIF> dom0Vifs = dom0.getVIFs(conn);
+        for (VIF vif:dom0Vifs) {
+        	vif.getRecord(conn);
+        	if (vif.getNetwork(conn).getUuid(conn) == nw.getUuid(conn)) {
+        		dom0vif = vif;
+        		s_logger.debug("A VIF for dom0 has already been found - No need to create one");
+        	}
+        }
+        if (dom0vif == null) {
+	        s_logger.debug("Create a vif on dom0 for " + networkDesc);
+	        VIF.Record vifr = new VIF.Record();
+	        vifr.VM = dom0;
+	        vifr.device = getLowestAvailableVIFDeviceNum(conn, dom0);
+	        if (vifr.device == null) {
+	            s_logger.debug("Failed to create " + networkDesc + ", no vif available");
+	            return;
+	        }
+	        Map<String, String> config = new HashMap<String, String>();
+	        config.put("nameLabel", vifNameLabel);
+	        vifr.otherConfig = config;
+	        vifr.MAC = "FE:FF:FF:FF:FF:FF";
+	        vifr.network = nw;
+	        
+	        dom0vif = VIF.create(conn, vifr);
+        }
+        // At this stage we surely have a VIF
+        dom0vif.plug(conn);
+        dom0vif.unplug(conn);
+        synchronized(_tmpDom0Vif) {
+            _tmpDom0Vif.add(dom0vif);
+        }
+
+    }
+
+    private synchronized Network setupvSwitchNetwork(Connection conn) {
+        try {
+            if (_host.vswitchNetwork == null) {
+                Network vswitchNw = null;
+                Network.Record rec = new Network.Record();
+                String nwName = Networks.BroadcastScheme.VSwitch.toString();
+                Set<Network> networks = Network.getByNameLabel(conn, nwName);
+
+                if (networks.size() == 0) {
+                    rec.nameDescription = "vswitch network for " + nwName;
+                    rec.nameLabel = nwName;
+                    vswitchNw = Network.create(conn, rec);
+                } else {
+                    vswitchNw = networks.iterator().next();
+                }
+
+                enableXenServerNetwork(conn, vswitchNw, "vswitch", "vswicth network");
+                _host.vswitchNetwork = vswitchNw;
+            }
+            return _host.vswitchNetwork;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    /**
+     * This method just creates a XenServer network following the tunnel network naming convention
+     */
+    private synchronized Network findOrCreateTunnelNetwork(Connection conn, long key) {
+        try {
+            String nwName = "OVSTunnel" + key;
+            Network nw = null;
+            Network.Record rec = new Network.Record();
+            Set<Network> networks = Network.getByNameLabel(conn, nwName);
+
+            if (networks.size() == 0) {
+                rec.nameDescription = "tunnel network id# " + key;
+                rec.nameLabel = nwName;
+                //Initialize the ovs-host-setup to avoid error when doing get-param in plugin
+                Map<String,String> otherConfig = new HashMap<String,String>();
+                otherConfig.put("ovs-host-setup", "");
+                rec.otherConfig = otherConfig;
+                nw = Network.create(conn, rec);
+                // Plug dom0 vif only when creating network
+                enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + key);
+                s_logger.debug("### Xen Server network for tunnels created:" + nwName);                
+            } else {
+                nw = networks.iterator().next();
+                s_logger.debug("Xen Server network for tunnels found:" + nwName);                
+            }
+            return nw;
+        } catch (Exception e) {
+            s_logger.warn("createTunnelNetwork failed", e);
+            return null;
+        }
+    }
+
+    /**
+     * This method creates a XenServer network and configures it for being used as a L2-in-L3 tunneled network
+     */
+    private synchronized Network configureTunnelNetwork(Connection conn, long networkId, long hostId, int key) {
+    	try {
+	    	Network nw = findOrCreateTunnelNetwork(conn, key);
+	    	String nwName = "OVSTunnel" + key;
+	    	//Invoke plugin to setup the bridge which will be used by this network
+	        String bridge = nw.getBridge(conn);
+	        Map<String,String> nwOtherConfig = nw.getOtherConfig(conn);
+	        String configuredHosts = nwOtherConfig.get("ovs-host-setup");
+	        boolean configured = false;
+	        if (configuredHosts!=null) {
+	        	String hostIdsStr[] = configuredHosts.split(",");
+	        	for (String hostIdStr:hostIdsStr) {
+	        		if (hostIdStr.equals(((Long)hostId).toString())) {
+	        			configured = true;
+	        			break;
+	        		}
+	        	}
+	        }
+	        if (!configured) {
+	            // Plug dom0 vif only if not done before for network and host
+	            enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + key);
+	            String result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge,
+	            							   "key", String.valueOf(key),
+	            							   "xs_nw_uuid", nw.getUuid(conn),
+	            							   "cs_host_id", ((Long)hostId).toString());
+	            //Note down the fact that the ovs bridge has been setup
+	            String[] res = result.split(":");
+	            if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
+	            	//TODO: Should make this error not fatal?
+	            	throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge + " for network ID:" + networkId +
+	            									" - " + res);
+	            }
+	        }
+	        return nw;
+        } catch (Exception e) {
+            s_logger.warn("createandConfigureTunnelNetwork failed", e);
+            return null;
+        }
+    }
+    
+    private synchronized void destroyTunnelNetwork(Connection conn, int key) {
+    	try {
+    		Network nw = findOrCreateTunnelNetwork(conn, key);
+            String bridge = nw.getBridge(conn);
+            String result = callHostPlugin(conn, "ovstunnel", "destroy_ovs_bridge", "bridge", bridge);
+            String[] res = result.split(":");
+            if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
+            	//TODO: Should make this error not fatal?
+            	//Can Concurrent VM shutdown/migration/reboot events can cause this method
+            	//to be executed on a bridge which has already been removed?
+            	throw new CloudRuntimeException("Unable to remove OVS bridge " + bridge + ":" + res);
+            }
+            return;
+    	} catch (Exception e) {
+            s_logger.warn("destroyTunnelNetwork failed:", e);
+            return;
+    	}
+    }
+    
+    protected Network getNetwork(Connection conn, NicTO nic) throws XenAPIException, XmlRpcException {
+        String name = nic.getName();
+        XsLocalNetwork network = getNativeNetworkForTraffic(conn, nic.getType(), name);
+        if (network == null) {
+            s_logger.error("Network is not configured on the backend for nic " + nic.toString());
+            throw new CloudRuntimeException("Network for the backend is not configured correctly for network broadcast domain: " + nic.getBroadcastUri());
+        }
+        if (nic.getBroadcastUri() != null && nic.getBroadcastUri().toString().contains("untagged")) {
+            return network.getNetwork();
+        } else if (nic.getBroadcastType() == BroadcastDomainType.Vlan) {
+            URI broadcastUri = nic.getBroadcastUri();
+            assert broadcastUri.getScheme().equals(BroadcastDomainType.Vlan.scheme());
+            long vlan = Long.parseLong(broadcastUri.getHost());
+            return enableVlanNetwork(conn, vlan, network);
+        } else if (nic.getBroadcastType() == BroadcastDomainType.Native || nic.getBroadcastType() == BroadcastDomainType.LinkLocal) {
+            return network.getNetwork();
+        } else if (nic.getBroadcastType() == BroadcastDomainType.Vswitch) {
+            String broadcastUri = nic.getBroadcastUri().toString();
+            String header = broadcastUri.substring(Networks.BroadcastDomainType.Vswitch.scheme().length() + "://".length());
+            if (header.startsWith("vlan")) {
+                _isOvs = true;
+                return setupvSwitchNetwork(conn);
+            } else {
+                long vnetId = Long.parseLong(nic.getBroadcastUri().getHost());
+                return findOrCreateTunnelNetwork(conn, vnetId);
+            }
+        } else if (nic.getBroadcastType() == BroadcastDomainType.Storage) {
+        	URI broadcastUri = nic.getBroadcastUri();
+        	if (broadcastUri == null) {
+        		return network.getNetwork();
+        	} else {
+        		long vlan = Long.parseLong(broadcastUri.getHost());
+        		return enableVlanNetwork(conn, vlan, network);
+        	}
+        }
+
+        throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri());
+    }
+
+    protected VIF createVif(Connection conn, String vmName, VM vm, NicTO nic) throws XmlRpcException, XenAPIException {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Creating VIF for " + vmName + " on nic " + nic);
+        }
+
+        VIF.Record vifr = new VIF.Record();
+        vifr.VM = vm;
+        vifr.device = Integer.toString(nic.getDeviceId());
+        vifr.MAC = nic.getMac();
+
+        vifr.network = getNetwork(conn, nic);
+
+        if (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) {
+            vifr.qosAlgorithmType = "ratelimit";
+            vifr.qosAlgorithmParams = new HashMap<String, String>();
+            // convert mbs to kilobyte per second
+            vifr.qosAlgorithmParams.put("kbps", Integer.toString(nic.getNetworkRateMbps() * 128));
+        }
+
+        VIF vif = VIF.create(conn, vifr);
+        if (s_logger.isDebugEnabled()) {
+            vifr = vif.getRecord(conn);
+            s_logger.debug("Created a vif " + vifr.uuid + " on " + nic.getDeviceId());
+        }
+
+        return vif;
+    }
+
+    protected void prepareISO(Connection conn, String vmName) throws XmlRpcException, XenAPIException {
+
+        Set<VM> vms = VM.getByNameLabel(conn, vmName);
+        if( vms == null || vms.size() != 1) {
+            throw new CloudRuntimeException("There are " + ((vms == null) ? "0" : vms.size()) + " VMs named " + vmName);
+        }
+        VM vm = vms.iterator().next();
+        Set<VBD> vbds = vm.getVBDs(conn);
+        for ( VBD vbd : vbds ) {
+            VBD.Record vbdr = vbd.getRecord(conn);
+            if ( vbdr.type == Types.VbdType.CD && vbdr.empty == false ) {
+                VDI vdi = vbdr.VDI;
+                SR sr = vdi.getSR(conn);
+                Set<PBD> pbds = sr.getPBDs(conn);
+                if( pbds == null ) {
+                    throw new CloudRuntimeException("There is no pbd for sr " + sr);
+                }
+                for ( PBD pbd : pbds ) {
+                    PBD.Record pbdr = pbd.getRecord(conn);
+                    if ( pbdr.host.getUuid(conn).equals(_host.uuid)) {
+                        return;
+                    }
+                }
+                sr.setShared(conn, true);
+                Host host = Host.getByUuid(conn, _host.uuid);
+                PBD.Record pbdr = pbds.iterator().next().getRecord(conn);
+                pbdr.host = host;
+                pbdr.uuid = "";
+                PBD pbd = PBD.create(conn, pbdr);
+                pbdPlug(conn, pbd, pbd.getUuid(conn));
+                break;
+            }
+        }
+    }
+
+    protected VDI mount(Connection conn, String vmName, VolumeTO volume) throws XmlRpcException, XenAPIException {
+        if (volume.getType() == Volume.Type.ISO) {
+        	String isopath = volume.getPath();
+        	if (isopath == null) {
+        		return null;
+        	}
+        	if (isopath.startsWith("xs-tools")) {
+        		try {
+        			Set<VDI> vdis = VDI.getByNameLabel(conn, isopath);
+        			if (vdis.isEmpty()) {
+        				throw new CloudRuntimeException("Could not find ISO with URL: " + isopath);
+        			}
+        			return vdis.iterator().next();
+
+        		} catch (XenAPIException e) {
+        			throw new CloudRuntimeException("Unable to get pv iso: " + isopath + " due to " + e.toString());
+        		} catch (Exception e) {
+        			throw new CloudRuntimeException("Unable to get pv iso: " + isopath + " due to " + e.toString());
+        		}
+        	}
+
+          
+            int index = isopath.lastIndexOf("/");
+
+            String mountpoint = isopath.substring(0, index);
+            URI uri;
+            try {
+                uri = new URI(mountpoint);
+            } catch (URISyntaxException e) {
+                throw new CloudRuntimeException("Incorrect uri " + mountpoint, e);
+            }
+            SR isoSr = createIsoSRbyURI(conn, uri, vmName, false);
+
+            String isoname = isopath.substring(index + 1);
+
+            VDI isoVdi = getVDIbyLocationandSR(conn, isoname, isoSr);
+
+            if (isoVdi == null) {
+                throw new CloudRuntimeException("Unable to find ISO " + volume.getPath());
+            }
+            return isoVdi;
+        } else {
+            return VDI.getByUuid(conn, volume.getPath());
+        }
+    }
+
+    protected VBD createVbd(Connection conn, VolumeTO volume, String vmName, VM vm, BootloaderType bootLoaderType) throws XmlRpcException, XenAPIException {
+        Volume.Type type = volume.getType();
+
+        VDI vdi = mount(conn, vmName, volume);
+
+        VBD.Record vbdr = new VBD.Record();
+        vbdr.VM = vm;
+        if (vdi != null) {
+            vbdr.VDI = vdi;
+        } else {
+            vbdr.empty = true;
+        }
+        if (type == Volume.Type.ROOT && bootLoaderType == BootloaderType.PyGrub) {
+            vbdr.bootable = true;
+        }else if(type == Volume.Type.ISO && bootLoaderType == BootloaderType.CD) {
+            vbdr.bootable = true;
+        }
+
+        vbdr.userdevice = Long.toString(volume.getDeviceId());
+        if (volume.getType() == Volume.Type.ISO) {
+            vbdr.mode = Types.VbdMode.RO;
+            vbdr.type = Types.VbdType.CD;
+        } else if (volume.getType() == Volume.Type.ROOT) {
+            vbdr.mode = Types.VbdMode.RW;
+            vbdr.type = Types.VbdType.DISK;
+            vbdr.unpluggable = false;
+        } else {
+            vbdr.mode = Types.VbdMode.RW;
+            vbdr.type = Types.VbdType.DISK;
+            vbdr.unpluggable = true;
+        }
+        VBD vbd = VBD.create(conn, vbdr);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("VBD " + vbd.getUuid(conn) + " created for " + volume);
+        }
+
+        return vbd;
+    }
+
+    protected VM createVmFromTemplate(Connection conn, VirtualMachineTO vmSpec, Host host) throws XenAPIException, XmlRpcException {
+        String guestOsTypeName = getGuestOsType(vmSpec.getOs(), vmSpec.getBootloader() == BootloaderType.CD);
+        if ( guestOsTypeName == null ) {
+            String msg =  " Hypervisor " + this.getClass().getName() + " doesn't support guest OS type " + vmSpec.getOs()
+                    + ". you can choose 'Other install media' to run it as HVM";
+            s_logger.warn(msg);
+            throw new CloudRuntimeException(msg);
+        }
+        Set<VM> templates = VM.getByNameLabel(conn, guestOsTypeName);
+        assert templates.size() == 1 : "Should only have 1 template but found " + templates.size();
+        VM template = templates.iterator().next();
+
+        VM vm = template.createClone(conn, vmSpec.getName());
+        VM.Record vmr = vm.getRecord(conn);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Created VM " + vmr.uuid + " for " + vmSpec.getName());
+        }
+
+        for (Console console : vmr.consoles) {
+            console.destroy(conn);
+        }
+
+        vm.setIsATemplate(conn, false);
+        vm.setAffinity(conn, host);
+        vm.removeFromOtherConfig(conn, "disks");
+        vm.setNameLabel(conn, vmSpec.getName());
+        setMemory(conn, vm, vmSpec.getMinRam());
+        vm.setVCPUsMax(conn, (long)vmSpec.getCpus());
+        vm.setVCPUsAtStartup(conn, (long)vmSpec.getCpus());
+
+        Map<String, String> vcpuParams = new HashMap<String, String>();
+
+        Integer speed = vmSpec.getSpeed();
+        if (speed != null) {
+
+            int cpuWeight = _maxWeight; //cpu_weight
+            long utilization = 0; // max CPU cap, default is unlimited
+
+            // weight based allocation
+            cpuWeight = (int)((speed*0.99) / _host.speed * _maxWeight);
+            if (cpuWeight > _maxWeight) {
+                cpuWeight = _maxWeight;
+            }
+
+            if (vmSpec.getLimitCpuUse()) {
+                utilization = ((long)speed * 100 * vmSpec.getCpus()) / _host.speed ;
+            }
+
+            vcpuParams.put("weight", Integer.toString(cpuWeight));
+            vcpuParams.put("cap", Long.toString(utilization));
+
+        }
+
+        if (vcpuParams.size() > 0) {
+            vm.setVCPUsParams(conn, vcpuParams);
+        }
+
+        vm.setActionsAfterCrash(conn, Types.OnCrashBehaviour.DESTROY);
+        vm.setActionsAfterShutdown(conn, Types.OnNormalExit.DESTROY);
+
+        String bootArgs = vmSpec.getBootArgs();
+        if (bootArgs != null && bootArgs.length() > 0) {
+            String pvargs = vm.getPVArgs(conn);
+            pvargs = pvargs + vmSpec.getBootArgs().replaceAll(" ", "%");
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("PV args are " + pvargs);
+            }
+            vm.setPVArgs(conn, pvargs);
+        }
+
+        if (!(guestOsTypeName.startsWith("Windows") || guestOsTypeName.startsWith("Citrix") || guestOsTypeName.startsWith("Other"))) {
+            if (vmSpec.getBootloader() == BootloaderType.CD) {
+                VolumeTO [] disks = vmSpec.getDisks();
+                for (VolumeTO disk : disks) {
+                    if (disk.getType() == Volume.Type.ISO && disk.getOsType() != null) {
+                        String isoGuestOsName = getGuestOsType(disk.getOsType(), vmSpec.getBootloader() == BootloaderType.CD);
+                        if (!isoGuestOsName.equals(guestOsTypeName)) {
+                            vmSpec.setBootloader(BootloaderType.PyGrub);
+                        }
+                    }
+                }
+            }
+            if (vmSpec.getBootloader() == BootloaderType.CD) {
+                vm.setPVBootloader(conn, "eliloader");
+                Map<String, String> otherConfig = vm.getOtherConfig(conn);
+                if ( ! vm.getOtherConfig(conn).containsKey("install-repository") ) {
+                    otherConfig.put( "install-repository", "cdrom");
+                }
+                vm.setOtherConfig(conn, otherConfig);
+            } else if (vmSpec.getBootloader() == BootloaderType.PyGrub ){
+                vm.setPVBootloader(conn, "pygrub");
+            } else {
+                vm.destroy(conn);
+                throw new CloudRuntimeException("Unable to handle boot loader type: " + vmSpec.getBootloader());
+            }
+        }
+        return vm;
+    }
+
+    protected String handleVmStartFailure(Connection conn, String vmName, VM vm, String message, Throwable th) {
+        String msg = "Unable to start " + vmName + " due to " + message;
+        s_logger.warn(msg, th);
+
+        if (vm == null) {
+            return msg;
+        }
+
+        try {
+            VM.Record vmr = vm.getRecord(conn);
+            List<Network> networks = new ArrayList<Network>();
+            for (VIF vif : vmr.VIFs) {
+                try {
+                    VIF.Record rec = vif.getRecord(conn);
+                    networks.add(rec.network);
+                } catch (Exception e) {
+                    s_logger.warn("Unable to cleanup VIF", e);
+                }
+            }
+            if (vmr.powerState == VmPowerState.RUNNING) {
+                try {
+                    vm.hardShutdown(conn);
+                } catch (Exception e) {
+                    s_logger.warn("VM hardshutdown failed due to ", e);
+                }
+            }
+            if (vm.getPowerState(conn) == VmPowerState.HALTED) {
+                try {
+                    vm.destroy(conn);
+                } catch (Exception e) {
+                    s_logger.warn("VM destroy failed due to ", e);
+                }
+            }
+            for (VBD vbd : vmr.VBDs) {
+                try {
+                    vbd.unplug(conn);
+                    vbd.destroy(conn);
+                } catch (Exception e) {
+                    s_logger.warn("Unable to clean up VBD due to ", e);
+                }
+            }
+            for (VIF vif : vmr.VIFs) {
+                try {
+                    vif.unplug(conn);
+                    vif.destroy(conn);
+                } catch (Exception e) {
+                    s_logger.warn("Unable to cleanup VIF", e);
+                }
+            }
+            for (Network network : networks) {
+                if (network.getNameLabel(conn).startsWith("VLAN")) {
+                    disableVlanNetwork(conn, network);
+                }
+            }                    
+        } catch (Exception e) {
+            s_logger.warn("VM getRecord failed due to ", e);
+        }
+
+        return msg;
+    }
+
+    protected VBD createPatchVbd(Connection conn, String vmName, VM vm) throws XmlRpcException, XenAPIException {
+
+        if(  _host.systemvmisouuid == null ) {
+            Set<SR> srs = SR.getByNameLabel(conn, "XenServer Tools");
+            if( srs.size() != 1 ) {
+                throw new CloudRuntimeException("There are " + srs.size() + " SRs with name XenServer Tools");
+            }
+            SR sr = srs.iterator().next();
+            sr.scan(conn);
+
+            SR.Record srr = sr.getRecord(conn);
+
+            if(  _host.systemvmisouuid == null ) {
+                for( VDI vdi : srr.VDIs ) {
+                    VDI.Record vdir = vdi.getRecord(conn);
+                    if(vdir.nameLabel.contains("systemvm.iso")){
+                        _host.systemvmisouuid = vdir.uuid;
+                        break;
+                    }
+                }
+            }
+            if(  _host.systemvmisouuid == null ) {
+                throw new CloudRuntimeException("can not find systemvmiso");
+            }
+        }
+
+        VBD.Record cdromVBDR = new VBD.Record();
+        cdromVBDR.VM = vm;
+        cdromVBDR.empty = true;
+        cdromVBDR.bootable = false;
+        cdromVBDR.userdevice = "3";
+        cdromVBDR.mode = Types.VbdMode.RO;
+        cdromVBDR.type = Types.VbdType.CD;
+        VBD cdromVBD = VBD.create(conn, cdromVBDR);
+        cdromVBD.insert(conn, VDI.getByUuid(conn, _host.systemvmisouuid));
+
+        return cdromVBD;
+    }
+
+    protected void destroyPatchVbd(Connection conn, String vmName) throws XmlRpcException, XenAPIException {
+        try {
+            if( !vmName.startsWith("r-") && !vmName.startsWith("s-") && !vmName.startsWith("v-") ) {
+                return;
+            }
+            Set<VM> vms = VM.getByNameLabel(conn, vmName);
+            for ( VM vm : vms ) {
+                Set<VBD> vbds = vm.getVBDs(conn);
+                for( VBD vbd : vbds ) {
+                   if (vbd.getType(conn) == Types.VbdType.CD ) {
+                       vbd.eject(conn);
+                       vbd.destroy(conn);
+                       break;
+                   }
+                }
+            }
+        } catch (Exception e) {
+            s_logger.debug("Cannot destory CD-ROM device for VM " + vmName + " due to " + e.toString(), e);
+        }
+    }
+
+    protected CheckSshAnswer execute(CheckSshCommand cmd) {
+        Connection conn = getConnection();
+        String vmName = cmd.getName();
+        String privateIp = cmd.getIp();
+        int cmdPort = cmd.getPort();
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort);
+        }
+
+        try {
+            String result = connect(conn, cmd.getName(), privateIp, cmdPort);
+            if (result != null) {
+                return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + "due to:" + result);
+            }
+            destroyPatchVbd(conn, vmName);
+        } catch (Exception e) {
+            return new CheckSshAnswer(cmd, e);
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Ping command port succeeded for vm " + vmName);
+        }
+
+        return new CheckSshAnswer(cmd);
+    }
+
+    private HashMap<String, String> parseDefaultOvsRuleComamnd(String str) {
+        HashMap<String, String> cmd = new HashMap<String, String>();
+        String[] sarr = str.split("/");
+        for (int i = 0; i < sarr.length; i++) {
+            String c = sarr[i];
+            c = c.startsWith("/") ? c.substring(1) : c;
+            c = c.endsWith("/") ? c.substring(0, c.length() - 1) : c;
+            String[] p = c.split(";");
+            if (p.length != 2) {
+                continue;
+            }
+            if (p[0].equalsIgnoreCase("vlans")) {
+                p[1] = p[1].replace("@", "[");
+                p[1] = p[1].replace("#", "]");
+            }
+            cmd.put(p[0], p[1]);
+        }
+        return cmd;
+    }
+
+    private void cleanUpTmpDomVif(Connection conn) {
+        List<VIF> vifs;
+        synchronized(_tmpDom0Vif) {
+            vifs = _tmpDom0Vif;
+            _tmpDom0Vif = new ArrayList<VIF>();
+        }
+
+        for (VIF v : vifs) {
+            String vifName = "unkown";
+            try {
+                VIF.Record vifr = v.getRecord(conn);
+                Map<String, String> config = vifr.otherConfig;
+                vifName = config.get("nameLabel");
+                v.destroy(conn);
+                s_logger.debug("Destroy temp dom0 vif" + vifName + " success");
+            } catch (Exception e) {
+                s_logger.warn("Destroy temp dom0 vif " + vifName + "failed", e);
+            }
+        }
+    }
+
+    @Override
+    public StartAnswer execute(StartCommand cmd) {
+        Connection conn = getConnection();
+        VirtualMachineTO vmSpec = cmd.getVirtualMachine();
+        String vmName = vmSpec.getName();
+        State state = State.Stopped;
+        VM vm = null;
+        try {
+            Set<VM> vms = VM.getByNameLabel(conn, vmName);
+            if ( vms != null ) {
+                for ( VM v : vms ) {
+                    VM.Record vRec = v.getRecord(conn);
+                    if ( vRec.powerState == VmPowerState.HALTED ) {
+                        v.destroy(conn);
+                    } else if ( vRec.powerState == VmPowerState.RUNNING ) {
+                        String host = vRec.residentOn.getUuid(conn);
+                        String msg = "VM " + vmName + " is runing on host " + host;
+                        s_logger.debug(msg);
+                        return new StartAnswer(cmd, msg, host);
+                    } else {
+                        String msg = "There is already a VM having the same name " + vmName + " vm record " +  vRec.toString();
+                        s_logger.warn(msg);
+                        return new StartAnswer(cmd, msg);
+                    }
+                }
+            }
+            synchronized (_cluster.intern()) {
+	            s_vms.put(_cluster, _name, vmName, State.Starting);
+            }
+            s_logger.debug("1. The VM " + vmName + " is in Starting state.");
+
+            Host host = Host.getByUuid(conn, _host.uuid);
+            vm = createVmFromTemplate(conn, vmSpec, host);
+
+            for (VolumeTO disk : vmSpec.getDisks()) {
+                createVbd(conn, disk, vmName, vm, vmSpec.getBootloader());
+            }
+
+            if (vmSpec.getType() != VirtualMachine.Type.User) {
+                createPatchVbd(conn, vmName, vm);
+            }
+
+            for (NicTO nic : vmSpec.getNics()) {
+                createVif(conn, vmName, vm, nic);
+            }
+
+            startVM(conn, host, vm, vmName);
+
+            if (_isOvs) {
+            	// TODO(Salvatore-orlando): This code should go
+                for (NicTO nic : vmSpec.getNics()) {
+                    if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vswitch) {
+                        HashMap<String, String> args = parseDefaultOvsRuleComamnd(nic.getBroadcastUri().toString().substring(Networks.BroadcastDomainType.Vswitch.scheme().length() + "://".length()));
+                        OvsSetTagAndFlowCommand flowCmd = new OvsSetTagAndFlowCommand(args.get("vmName"), args.get("tag"), args.get("vlans"),
+                                args.get("seqno"), Long.parseLong(args.get("vmId")));
+                        OvsSetTagAndFlowAnswer r = execute(flowCmd);
+                        if (!r.getResult()) {
+                            s_logger.warn("Failed to set flow for VM " + r.getVmId());
+                        } else {
+                            s_logger.info("Success to set flow for VM " + r.getVmId());
+                        }
+                    }
+                }
+            }
+            cleanUpTmpDomVif(conn);
+
+            if (_canBridgeFirewall) {
+                String result = null;
+                if (vmSpec.getType() != VirtualMachine.Type.User) {
+                    NicTO[] nics = vmSpec.getNics();
+                    boolean secGrpEnabled = false;
+                    for (NicTO nic : nics) {
+                        if (nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) {
+                            secGrpEnabled = true;
+                            break;
+                        }
+                    }
+                    if (secGrpEnabled) {
+                        result = callHostPlugin(conn, "vmops", "default_network_rules_systemvm", "vmName", vmName);
+                        if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
+                            s_logger.warn("Failed to program default network rules for " + vmName);
+                        } else {
+                            s_logger.info("Programmed default network rules for " + vmName);
+                        }
+                    }
+
+                } else {
+                    //For user vm, program the rules for each nic if the isolation uri scheme is ec2
+                    NicTO[] nics = vmSpec.getNics();
+                    for (NicTO nic : nics) {
+                        if (nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) {
+                            result = callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), "vmID", Long.toString(vmSpec.getId()));
+
+                            if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
+                                s_logger.warn("Failed to program default network rules for " + vmName+" on nic with ip:"+nic.getIp()+" mac:"+nic.getMac());
+                            } else {
+                                s_logger.info("Programmed default network rules for " + vmName+" on nic with ip:"+nic.getIp()+" mac:"+nic.getMac());
+                            }
+                        }
+                    }
+                }
+            }
+
+            state = State.Running;
+            return new StartAnswer(cmd);
+        } catch (Exception e) {
+            s_logger.warn("Catch Exception: " + e.getClass().toString() + " due to " + e.toString(), e);
+            String msg = handleVmStartFailure(conn, vmName, vm, "", e);
+            return new StartAnswer(cmd, msg);
+        } finally {
+            synchronized (_cluster.intern()) {
+                if (state != State.Stopped) { 
+                    s_vms.put(_cluster, _name, vmName, state);
+                	s_logger.debug("2. The VM " + vmName + " is in " + state + " state.");
+                } else {
+                    s_vms.remove(_cluster, _name, vmName);
+                	s_logger.debug("The VM is in stopped state, detected problem during startup : " + vmName);
+                }
+            }
+        }
+    }
+
+    protected Answer execute(ModifySshKeysCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    private boolean doPingTest(Connection conn, final String computingHostIp) {
+        String args = "-h " + computingHostIp;
+        String result = callHostPlugin(conn, "vmops", "pingtest", "args", args);
+        if (result == null || result.isEmpty()) {
+            return false;
+        }
+        return true;
+    }
+
+    protected CheckOnHostAnswer execute(CheckOnHostCommand cmd) {
+        return new CheckOnHostAnswer(cmd, null, "Not Implmeneted");
+    }
+
+    private boolean doPingTest(Connection conn, final String domRIp, final String vmIp) {
+        String args = "-i " + domRIp + " -p " + vmIp;
+        String result = callHostPlugin(conn, "vmops", "pingtest", "args", args);
+        if (result == null || result.isEmpty()) {
+            return false;
+        }
+        return true;
+    }
+
+    private Answer execute(PingTestCommand cmd) {
+        Connection conn = getConnection();
+        boolean result = false;
+        final String computingHostIp = cmd.getComputingHostIp();
+
+        if (computingHostIp != null) {
+            result = doPingTest(conn, computingHostIp);
+        } else {
+            result = doPingTest(conn, cmd.getRouterIp(), cmd.getPrivateIp());
+        }
+
+        if (!result) {
+            return new Answer(cmd, false, "PingTestCommand failed");
+        }
+        return new Answer(cmd);
+    }
+
+    private CheckRouterAnswer execute(CheckRouterCommand cmd) {
+        Connection conn = getConnection();
+        String args = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        String result = callHostPlugin(conn, "vmops", "checkRouter", "args", args);
+        if (result == null || result.isEmpty()) {
+            return new CheckRouterAnswer(cmd, "CheckRouterCommand failed");
+        }
+        return new CheckRouterAnswer(cmd, result, true);
+    }
+
+    private GetDomRVersionAnswer execute(GetDomRVersionCmd cmd) {
+        Connection conn = getConnection();
+        String args = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        String result = callHostPlugin(conn, "vmops", "getDomRVersion", "args", args);
+        if (result == null || result.isEmpty()) {
+            return new GetDomRVersionAnswer(cmd, "getDomRVersionCmd failed");
+        }
+        String[] lines = result.split("&");
+        if (lines.length != 2) {
+            return new GetDomRVersionAnswer(cmd, result);
+        }
+        return new GetDomRVersionAnswer(cmd, result, lines[0], lines[1]);
+    }
+
+    private Answer execute(BumpUpPriorityCommand cmd) {
+        Connection conn = getConnection();
+        String args = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        String result = callHostPlugin(conn, "vmops", "bumpUpPriority", "args", args);
+        if (result == null || result.isEmpty()) {
+            return new Answer(cmd, false, "BumpUpPriorityCommand failed");
+        }
+        return new Answer(cmd, true, result);
+    }
+
+    protected MaintainAnswer execute(MaintainCommand cmd) {
+        Connection conn = getConnection();
+        try {
+            Pool 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)) {
+                s_logger.debug("Not the master node so just return ok: " + _host.ip);
+                return new MaintainAnswer(cmd);
+            }
+            Map<Host, Host.Record> hostMap = Host.getAllRecords(conn);
+            if (hostMap.size() == 1) {
+                s_logger.debug("There is the last host in pool " + poolr.uuid );
+                return new MaintainAnswer(cmd);
+            }
+            Host newMaster = null;
+            Host.Record newMasterRecord = null;
+            for (Map.Entry<Host, Host.Record> entry : hostMap.entrySet()) {
+                if (!_host.uuid.equals(entry.getValue().uuid)) {
+                    newMaster = entry.getKey();
+                    newMasterRecord = entry.getValue();
+                    s_logger.debug("New master for the XenPool is " + newMasterRecord.uuid + " : " + newMasterRecord.address);
+                    try {
+                        _connPool.switchMaster(_host.ip, _host.pool, conn, newMaster, _username, _password, _wait);
+                        return new MaintainAnswer(cmd, "New Master is " + newMasterRecord.address);
+                    } catch (XenAPIException e) {
+                        s_logger.warn("Unable to switch the new master to " + newMasterRecord.uuid + ": " + newMasterRecord.address + " Trying again...");
+                    } catch (XmlRpcException e) {
+                        s_logger.warn("Unable to switch the new master to " + newMasterRecord.uuid + ": " + newMasterRecord.address + " Trying again...");
+                    }
+                }
+            }
+            return new MaintainAnswer(cmd, false, "Unable to find an appropriate host to set as the new master");
+        } catch (XenAPIException e) {
+            s_logger.warn("Unable to put server in maintainence mode", e);
+            return new MaintainAnswer(cmd, false, e.getMessage());
+        } catch (XmlRpcException e) {
+            s_logger.warn("Unable to put server in maintainence mode", e);
+            return new MaintainAnswer(cmd, false, e.getMessage());
+        }
+    }
+
+    protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesCommand cmd) {
+        Connection conn = getConnection();
+
+        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        String[] results = new String[cmd.getRules().length];
+        int i = 0;
+
+        boolean endResult = true;
+        for (PortForwardingRuleTO rule : cmd.getRules()) {
+            StringBuilder args = new StringBuilder();
+            args.append(routerIp);
+            args.append(rule.revoked() ? " -D " : " -A ");
+            args.append(" -P ").append(rule.getProtocol().toLowerCase());
+            args.append(" -l ").append(rule.getSrcIp());
+            args.append(" -p ").append(rule.getStringSrcPortRange());
+            args.append(" -r ").append(rule.getDstIp());
+            args.append(" -d ").append(rule.getStringDstPortRange());
+
+            String result = callHostPlugin(conn, "vmops", "setFirewallRule", "args", args.toString());
+
+            if (result == null || result.isEmpty()) {
+                results[i++] = "Failed";
+                endResult = false;
+            } else {
+                results[i++] = null;
+            }
+        }
+
+        return new SetPortForwardingRulesAnswer(cmd, results, endResult);
+    }
+
+    protected SetStaticNatRulesAnswer execute(SetStaticNatRulesCommand cmd) {
+        Connection conn = getConnection();
+
+        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        //String args = routerIp;
+        String[] results = new String[cmd.getRules().length];
+        int i = 0;
+        boolean endResult = true;
+        for (StaticNatRuleTO rule : cmd.getRules()) {
+            //1:1 NAT needs instanceip;publicip;domrip;op
+            StringBuilder args = new StringBuilder();
+            args.append(routerIp);
+            args.append(rule.revoked() ? " -D " : " -A ");
+            args.append(" -l ").append(rule.getSrcIp());
+            args.append(" -r ").append(rule.getDstIp());
+
+            if (rule.getProtocol() != null) {
+                args.append(" -P ").append(rule.getProtocol().toLowerCase());
+            }
+
+            args.append(" -d ").append(rule.getStringSrcPortRange());
+            args.append(" -G ");
+
+            String result = callHostPlugin(conn, "vmops", "setFirewallRule", "args", args.toString());
+
+            if (result == null || result.isEmpty()) {
+                results[i++] = "Failed";
+                endResult = false;
+            } else {
+                results[i++] = null;
+            }
+        }
+
+        return new SetStaticNatRulesAnswer(cmd, results, endResult);
+    }
+
+    protected Answer execute(final LoadBalancerConfigCommand cmd) {
+        Connection conn = getConnection();
+        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+
+        if (routerIp == null) {
+            return new Answer(cmd);
+        }
+
+        LoadBalancerConfigurator cfgtr = new HAProxyConfigurator();
+        String[] config = cfgtr.generateConfiguration(cmd);
+
+        String[][] rules = cfgtr.generateFwRules(cmd);
+        String tmpCfgFilePath = "/tmp/" + routerIp.replace('.', '_') + ".cfg";
+        String tmpCfgFileContents = "";
+        for (int i = 0; i < config.length; i++) {
+            tmpCfgFileContents += config[i];
+            tmpCfgFileContents += "\n";
+        }
+
+        String result = callHostPlugin(conn, "vmops", "createFile", "filepath", tmpCfgFilePath, "filecontents", tmpCfgFileContents);
+
+        if (result == null || result.isEmpty()) {
+            return new Answer(cmd, false, "LoadBalancerConfigCommand failed to create HA proxy cfg file.");
+        }
+
+        String[] addRules = rules[LoadBalancerConfigurator.ADD];
+        String[] removeRules = rules[LoadBalancerConfigurator.REMOVE];
+        String[] statRules = rules[LoadBalancerConfigurator.STATS];
+
+        String args = "";
+        args += "-i " + routerIp;
+        args += " -f " + tmpCfgFilePath;
+
+        StringBuilder sb = new StringBuilder();
+        if (addRules.length > 0) {
+            for (int i = 0; i < addRules.length; i++) {
+                sb.append(addRules[i]).append(',');
+            }
+
+            args += " -a " + sb.toString();
+        }
+
+        sb = new StringBuilder();
+        if (removeRules.length > 0) {
+            for (int i = 0; i < removeRules.length; i++) {
+                sb.append(removeRules[i]).append(',');
+            }
+
+            args += " -d " + sb.toString();
+        }
+
+        sb = new StringBuilder();
+        if (statRules.length > 0) {
+            for (int i = 0; i < statRules.length; i++) {
+                sb.append(statRules[i]).append(',');
+            }
+
+            args += " -s " + sb.toString();
+        }
+
+        result = callHostPlugin(conn, "vmops", "setLoadBalancerRule", "args", args);
+
+        if (result == null || result.isEmpty()) {
+            return new Answer(cmd, false, "LoadBalancerConfigCommand failed");
+        }
+
+        callHostPlugin(conn, "vmops", "deleteFile", "filepath", tmpCfgFilePath);
+
+        return new Answer(cmd);
+    }
+
+    protected synchronized Answer execute(final DhcpEntryCommand cmd) {
+        Connection conn = getConnection();
+        String args = "-r " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        args += " -v " + cmd.getVmIpAddress();
+        args += " -m " + cmd.getVmMac();
+        args += " -n " + cmd.getVmName();
+        if (cmd.getDefaultRouter() != null) {
+            args += " -d " + cmd.getDefaultRouter();
+        }
+        if (cmd.getStaticRoutes() != null) {
+            args += " -s " + cmd.getStaticRoutes();
+        }
+        
+        if (cmd.getDefaultDns() != null) {
+        	args += " -N " + cmd.getDefaultDns();
+        }
+        
+        String result = callHostPlugin(conn, "vmops", "saveDhcpEntry", "args", args);
+        if (result == null || result.isEmpty()) {
+            return new Answer(cmd, false, "DhcpEntry failed");
+        }
+        return new Answer(cmd);
+    }
+
+    protected synchronized Answer execute(final RemoteAccessVpnCfgCommand cmd) {
+        Connection conn = getConnection();
+        String args = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        if (cmd.isCreate()) {
+            args += " -r " + cmd.getIpRange();
+            args += " -p " + cmd.getPresharedKey();
+            args += " -s " + cmd.getVpnServerIp();
+            args += " -l " + cmd.getLocalIp();
+            args += " -c ";
+
+        } else {
+            args += " -d ";
+            args += " -s " + cmd.getVpnServerIp();
+        }
+        String result = callHostPlugin(conn, "vmops", "lt2p_vpn", "args", args);
+        if (result == null || result.isEmpty()) {
+            return new Answer(cmd, false, "Configure VPN failed");
+        }
+        return new Answer(cmd);
+    }
+
+    protected synchronized Answer execute(final VpnUsersCfgCommand cmd) {
+        Connection conn = getConnection();
+        for (VpnUsersCfgCommand.UsernamePassword userpwd: cmd.getUserpwds()) {
+            String args = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+            if (!userpwd.isAdd()) {
+                args += " -U " + userpwd.getUsername();
+            } else {
+                args += " -u " + userpwd.getUsernamePassword();
+            }
+            String result = callHostPlugin(conn, "vmops", "lt2p_vpn", "args", args);
+            if (result == null || result.isEmpty()) {
+                return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername());
+            }
+        }
+
+        return new Answer(cmd);
+    }
+
+    protected Answer execute(final VmDataCommand cmd) {
+        Connection conn = getConnection();
+        String routerPrivateIpAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        String vmIpAddress = cmd.getVmIpAddress();
+        List<String[]> vmData = cmd.getVmData();
+        String[] vmDataArgs = new String[vmData.size() * 2 + 4];
+        vmDataArgs[0] = "routerIP";
+        vmDataArgs[1] = routerPrivateIpAddress;
+        vmDataArgs[2] = "vmIP";
+        vmDataArgs[3] = vmIpAddress;
+        int i = 4;
+        for (String[] vmDataEntry : vmData) {
+            String folder = vmDataEntry[0];
+            String file = vmDataEntry[1];
+            String contents = (vmDataEntry[2] != null) ? vmDataEntry[2] : "none";
+
+            vmDataArgs[i] = folder + "," + file;
+            vmDataArgs[i + 1] = contents;
+            i += 2;
+        }
+
+        String result = callHostPlugin(conn, "vmops", "vm_data", vmDataArgs);
+
+        if (result == null || result.isEmpty()) {
+            return new Answer(cmd, false, "vm_data failed");
+        } else {
+            return new Answer(cmd);
+        }
+
+    }
+
+    protected Answer execute(final SavePasswordCommand cmd) {
+        Connection conn = getConnection();
+        final String password = cmd.getPassword();
+        final String routerPrivateIPAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        final String vmName = cmd.getVmName();
+        final String vmIpAddress = cmd.getVmIpAddress();
+        final String local = vmName;
+
+        // Run save_password_to_domr.sh
+        String args = "-r " + routerPrivateIPAddress;
+        args += " -v " + vmIpAddress;
+        args += " -p " + password;
+        args += " " + local;
+        String result = callHostPlugin(conn, "vmops", "savePassword", "args", args);
+
+        if (result == null || result.isEmpty()) {
+            return new Answer(cmd, false, "savePassword failed");
+        }
+        return new Answer(cmd);
+    }
+
+    protected void assignPublicIpAddress(Connection conn, String vmName, String privateIpAddress, String publicIpAddress, boolean add, boolean firstIP,
+            boolean sourceNat, String vlanId, String vlanGateway, String vlanNetmask, String vifMacAddress, String guestIp, Integer networkRate, TrafficType trafficType, String name) throws InternalErrorException {
+
+        try {
+            VM router = getVM(conn, vmName);
+
+            NicTO nic = new NicTO();
+            nic.setMac(vifMacAddress);
+            nic.setType(trafficType);
+            if (vlanId == null) {
+                nic.setBroadcastType(BroadcastDomainType.Native);
+            } else {
+                nic.setBroadcastType(BroadcastDomainType.Vlan);
+                nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlanId));
+            }
+            nic.setDeviceId(0);
+            nic.setNetworkRateMbps(networkRate);
+            nic.setName(name);
+
+            Network network = getNetwork(conn, nic);
+
+            // Determine the correct VIF on DomR to associate/disassociate the
+            // IP address with
+            VIF correctVif = getCorrectVif(conn, router, network);
+
+            // If we are associating an IP address and DomR doesn't have a VIF
+            // for the specified vlan ID, we need to add a VIF
+            // If we are disassociating the last IP address in the VLAN, we need
+            // to remove a VIF
+            boolean addVif = false;
+            boolean removeVif = false;
+            if (add && correctVif == null) {
+                addVif = true;
+            }
+
+            if (addVif) {
+                // Add a new VIF to DomR
+                String vifDeviceNum = getLowestAvailableVIFDeviceNum(conn, router);
+
+                if (vifDeviceNum == null) {
+                    throw new InternalErrorException("There were no more available slots for a new VIF on router: " + router.getNameLabel(conn));
+                }
+
+                nic.setDeviceId(Integer.parseInt(vifDeviceNum));
+
+                correctVif = createVif(conn, vmName, router, nic);
+                correctVif.plug(conn);
+                // Add iptables rule for network usage
+                networkUsage(conn, privateIpAddress, "addVif", "eth" + correctVif.getDevice(conn));
+            }
+
+            if (correctVif == null) {
+                throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with.");
+            }
+
+            String args = privateIpAddress;
+
+            if (add) {
+                args += " -A ";
+            } else {
+                args += " -D ";
+            }
+
+            if (sourceNat) {
+                args += " -s";
+            }
+            if (firstIP) {
+                args += " -f";
+            }
+
+            String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask));
+            args += " -l ";
+            args += publicIpAddress + "/" + cidrSize;
+
+            args += " -c ";
+            args += "eth" + correctVif.getDevice(conn);
+            
+            args += " -g ";
+            args += vlanGateway;
+            
+
+            String result = callHostPlugin(conn, "vmops", "ipassoc", "args", args);
+            if (result == null || result.isEmpty()) {
+                throw new InternalErrorException("Xen plugin \"ipassoc\" failed.");
+            }
+
+            if (removeVif) {
+                network = correctVif.getNetwork(conn);
+
+                // Mark this vif to be removed from network usage
+                networkUsage(conn, privateIpAddress, "deleteVif", "eth" + correctVif.getDevice(conn));
+
+                // Remove the VIF from DomR
+                correctVif.unplug(conn);
+                correctVif.destroy(conn);
+
+                // Disable the VLAN network if necessary
+                disableVlanNetwork(conn, network);
+            }
+
+        } catch (XenAPIException e) {
+            String msg = "Unable to assign public IP address due to " + e.toString();
+            s_logger.warn(msg, e);
+            throw new InternalErrorException(msg);
+        } catch (final XmlRpcException e) {
+            String msg = "Unable to assign public IP address due to " + e.getMessage();
+            s_logger.warn(msg, e);
+            throw new InternalErrorException(msg);
+        }
+    }
+
+    protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) {
+
+        if (option.equals("get")) {
+            return "0:0";
+        }
+        return null;
+    }
+
+    protected Answer execute(IpAssocCommand cmd) {
+        Connection conn = getConnection();
+        String[] results = new String[cmd.getIpAddresses().length];
+        int i = 0;
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        try {
+            IpAddressTO[] ips = cmd.getIpAddresses();
+            for (IpAddressTO ip : ips) {
+
+                assignPublicIpAddress(conn, routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getVlanId(),
+                        ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress(), ip.getGuestIp(), ip.getNetworkRate(), ip.getTrafficType(), ip.getNetworkName());
+                results[i++] = ip.getPublicIp() + " - success";
+            }
+        } catch (InternalErrorException e) {
+            s_logger.error(
+                    "Ip Assoc failure on applying one ip due to exception:  ", e);
+            results[i++] = IpAssocAnswer.errorResult;
+        }
+
+        return new IpAssocAnswer(cmd, results);
+    }
+
+    protected GetVncPortAnswer execute(GetVncPortCommand cmd) {
+        Connection conn = getConnection();
+        try {
+            Set<VM> vms = VM.getByNameLabel(conn, cmd.getName());
+            if(vms.size() == 1) {
+            	int vncport = getVncPort(conn, vms.iterator().next());
+            	String consoleurl;
+            	consoleurl = "consoleurl=" +getVncUrl(conn, vms.iterator().next()) + "&" +"sessionref="+ conn.getSessionReference();
+                return new GetVncPortAnswer(cmd, consoleurl, vncport);
+            } else {
+                return new GetVncPortAnswer(cmd, "There are " + vms.size() + " VMs named " + cmd.getName());
+            }
+        } catch (Exception e) {
+            String msg = "Unable to get vnc port due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new GetVncPortAnswer(cmd, msg);
+        }
+    }
+
+    protected Storage.StorageResourceType getStorageResourceType() {
+        return Storage.StorageResourceType.STORAGE_POOL;
+    }
+
+    protected CheckHealthAnswer execute(CheckHealthCommand cmd) {
+        boolean result = pingXenServer();
+        return new CheckHealthAnswer(cmd, result);
+    }
+
+
+    protected long[] getNetworkStats(Connection conn, String privateIP) {
+        String result = networkUsage(conn, privateIP, "get", null);
+        long[] stats = new long[2];
+        if (result != null) {
+            String[] splitResult = result.split(":");
+            int i = 0;
+            while (i < splitResult.length - 1) {
+                stats[0] += (new Long(splitResult[i++])).longValue();
+                stats[1] += (new Long(splitResult[i++])).longValue();
+            }
+        }
+        return stats;
+    }
+
+    /**
+     * This is the method called for getting the HOST stats
+     * 
+     * @param cmd
+     * @return
+     */
+    protected GetHostStatsAnswer execute(GetHostStatsCommand cmd) {
+        Connection conn = getConnection();
+        try {
+            HostStatsEntry hostStats = getHostStats(conn, cmd, cmd.getHostGuid(), cmd.getHostId());
+            return new GetHostStatsAnswer(cmd, hostStats);
+        } catch (Exception e) {
+            String msg = "Unable to get Host stats" + e.toString();
+            s_logger.warn(msg, e);
+            return new GetHostStatsAnswer(cmd, null);
+        }
+    }
+
+    protected HostStatsEntry getHostStats(Connection conn, GetHostStatsCommand cmd, String hostGuid, long hostId) {
+
+        HostStatsEntry hostStats = new HostStatsEntry(hostId, 0, 0, 0, "host", 0, 0, 0, 0);
+        Object[] rrdData = getRRDData(conn, 1); // call rrd method with 1 for host
+
+        if (rrdData == null) {
+            return null;
+        }
+
+        Integer numRows = (Integer) rrdData[0];
+        Integer numColumns = (Integer) rrdData[1];
+        Node legend = (Node) rrdData[2];
+        Node dataNode = (Node) rrdData[3];
+
+        NodeList legendChildren = legend.getChildNodes();
+        for (int col = 0; col < numColumns; col++) {
+
+            if (legendChildren == null || legendChildren.item(col) == null) {
+                continue;
+            }
+
+            String columnMetadata = getXMLNodeValue(legendChildren.item(col));
+
+            if (columnMetadata == null) {
+                continue;
+            }
+
+            String[] columnMetadataList = columnMetadata.split(":");
+
+            if (columnMetadataList.length != 4) {
+                continue;
+            }
+
+            String type = columnMetadataList[1];
+            String param = columnMetadataList[3];
+
+            if (type.equalsIgnoreCase("host")) {
+
+                if (param.contains("pif_eth0_rx")) {
+                    hostStats.setNetworkReadKBs(getDataAverage(dataNode, col, numRows));
+                }
+
+                if (param.contains("pif_eth0_tx")) {
+                    hostStats.setNetworkWriteKBs(getDataAverage(dataNode, col, numRows));
+                }
+
+                if (param.contains("memory_total_kib")) {
+                    hostStats.setTotalMemoryKBs(getDataAverage(dataNode, col, numRows));
+                }
+
+                if (param.contains("memory_free_kib")) {
+                    hostStats.setFreeMemoryKBs(getDataAverage(dataNode, col, numRows));
+                }
+
+                if (param.contains("cpu")) {
+                    // hostStats.setNumCpus(hostStats.getNumCpus() + 1);
+                    hostStats.setCpuUtilization(hostStats.getCpuUtilization() + getDataAverage(dataNode, col, numRows));
+                }
+
+                /*
+                if (param.contains("loadavg")) {
+                    hostStats.setAverageLoad((hostStats.getAverageLoad() + getDataAverage(dataNode, col, numRows)));
+                }
+                 */
+            }
+        }
+
+        // add the host cpu utilization
+        /*
+        if (hostStats.getNumCpus() != 0) {
+            hostStats.setCpuUtilization(hostStats.getCpuUtilization() / hostStats.getNumCpus());
+            s_logger.debug("Host cpu utilization " + hostStats.getCpuUtilization());
+        }
+         */
+
+        return hostStats;
+    }
+
+    protected GetVmStatsAnswer execute( GetVmStatsCommand cmd) {
+        Connection conn = getConnection();
+        List<String> vmNames = cmd.getVmNames();
+        HashMap<String, VmStatsEntry> vmStatsNameMap = new HashMap<String, VmStatsEntry>();
+        if( vmNames.size() == 0 ) {
+            return new GetVmStatsAnswer(cmd, vmStatsNameMap);
+        }
+        try {
+
+            // Determine the UUIDs of the requested VMs
+            List<String> vmUUIDs = new ArrayList<String>();
+
+            for (String vmName : vmNames) {
+                VM vm = getVM(conn, vmName);
+                vmUUIDs.add(vm.getUuid(conn));
+            }
+
+            HashMap<String, VmStatsEntry> vmStatsUUIDMap = getVmStats(conn, cmd, vmUUIDs, cmd.getHostGuid());
+            if( vmStatsUUIDMap == null ) {
+                return new GetVmStatsAnswer(cmd, vmStatsNameMap);
+            }
+
+            for (String vmUUID : vmStatsUUIDMap.keySet()) {
+                vmStatsNameMap.put(vmNames.get(vmUUIDs.indexOf(vmUUID)), vmStatsUUIDMap.get(vmUUID));
+            }
+
+            return new GetVmStatsAnswer(cmd, vmStatsNameMap);
+        } catch (XenAPIException e) {
+            String msg = "Unable to get VM stats" + e.toString();
+            s_logger.warn(msg, e);
+            return new GetVmStatsAnswer(cmd, vmStatsNameMap);
+        } catch (XmlRpcException e) {
+            String msg = "Unable to get VM stats" + e.getMessage();
+            s_logger.warn(msg, e);
+            return new GetVmStatsAnswer(cmd, vmStatsNameMap);
+        }
+    }
+
+    protected HashMap<String, VmStatsEntry> getVmStats(Connection conn, GetVmStatsCommand cmd, List<String> vmUUIDs, String hostGuid) {
+        HashMap<String, VmStatsEntry> vmResponseMap = new HashMap<String, VmStatsEntry>();
+
+        for (String vmUUID : vmUUIDs) {
+            vmResponseMap.put(vmUUID, new VmStatsEntry(0, 0, 0, 0, "vm"));
+        }
+
+        Object[] rrdData = getRRDData(conn, 2); // call rrddata with 2 for vm
+
+        if (rrdData == null) {
+            return null;
+        }
+
+        Integer numRows = (Integer) rrdData[0];
+        Integer numColumns = (Integer) rrdData[1];
+        Node legend = (Node) rrdData[2];
+        Node dataNode = (Node) rrdData[3];
+
+        NodeList legendChildren = legend.getChildNodes();
+        for (int col = 0; col < numColumns; col++) {
+
+            if (legendChildren == null || legendChildren.item(col) == null) {
+                continue;
+            }
+
+            String columnMetadata = getXMLNodeValue(legendChildren.item(col));
+
+            if (columnMetadata == null) {
+                continue;
+            }
+
+            String[] columnMetadataList = columnMetadata.split(":");
+
+            if (columnMetadataList.length != 4) {
+                continue;
+            }
+
+            String type = columnMetadataList[1];
+            String uuid = columnMetadataList[2];
+            String param = columnMetadataList[3];
+
+            if (type.equals("vm") && vmResponseMap.keySet().contains(uuid)) {
+                VmStatsEntry vmStatsAnswer = vmResponseMap.get(uuid);
+
+                vmStatsAnswer.setEntityType("vm");
+
+                if (param.contains("cpu")) {
+                    vmStatsAnswer.setNumCPUs(vmStatsAnswer.getNumCPUs() + 1);
+                    vmStatsAnswer.setCPUUtilization(((vmStatsAnswer.getCPUUtilization() + getDataAverage(dataNode, col, numRows))));
+                } else if (param.matches("vif_\\d_rx")) {
+                    vmStatsAnswer.setNetworkReadKBs(vmStatsAnswer.getNetworkReadKBs() + (getDataAverage(dataNode, col, numRows)/(8*2)));
+                } else if (param.matches("vif_\\d_tx")) {
+      

<TRUNCATED>

Mime
View raw message