You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by al...@apache.org on 2012/07/31 22:40:02 UTC

[25/50] [abbrv] Move KVM related code into plugins/hypervisor/kvm, a new jar file is created: cloud-kvm.jar

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7a0a9231/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
new file mode 100755
index 0000000..ea12b98
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -0,0 +1,4118 @@
+// 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 com.cloud.hypervisor.kvm.resource;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.libvirt.Connect;
+import org.libvirt.Domain;
+import org.libvirt.DomainInfo;
+import org.libvirt.DomainInterfaceStats;
+import org.libvirt.DomainSnapshot;
+import org.libvirt.LibvirtException;
+import org.libvirt.NodeInfo;
+
+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.CheckHealthAnswer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CheckNetworkAnswer;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.CheckStateCommand;
+import com.cloud.agent.api.CheckVirtualMachineAnswer;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+import com.cloud.agent.api.CleanupNetworkRulesCmd;
+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.DeleteSnapshotBackupAnswer;
+import com.cloud.agent.api.DeleteSnapshotBackupCommand;
+import com.cloud.agent.api.DeleteSnapshotsDirCommand;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+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.NetworkUsageAnswer;
+import com.cloud.agent.api.NetworkUsageCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
+import com.cloud.agent.api.PingTestCommand;
+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.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.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.IpAssocAnswer;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+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.StorageFilerTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.hypervisor.kvm.resource.KVMHABase.NfsStoragePool;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ConsoleDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DevicesDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.diskProtocol;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.FeaturesDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GraphicDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestResourceDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InputDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef.hostNicType;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ClockDef;
+import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
+import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
+import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat;
+import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
+import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
+import com.cloud.dc.Vlan;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.host.Host.Type;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.Networks.RouterPrivateIpStrategy;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetworkSetupInfo;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.Volume;
+import com.cloud.storage.template.Processor;
+import com.cloud.storage.template.Processor.FormatInfo;
+import com.cloud.storage.template.QCOW2Processor;
+import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateLocation;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.component.ComponentLocator;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineName;
+
+/**
+ * LibvirtComputingResource execute requests on the computing/routing host using
+ * the libvirt API
+ * 
+ * @config {@table || Param Name | Description | Values | Default || ||
+ *         hypervisor.type | type of local hypervisor | string | kvm || ||
+ *         hypervisor.uri | local hypervisor to connect to | URI |
+ *         qemu:///system || || domr.arch | instruction set for domr template |
+ *         string | i686 || || private.bridge.name | private bridge where the
+ *         domrs have their private interface | string | vmops0 || ||
+ *         public.bridge.name | public bridge where the domrs have their public
+ *         interface | string | br0 || || private.network.name | name of the
+ *         network where the domrs have their private interface | string |
+ *         vmops-private || || private.ipaddr.start | start of the range of
+ *         private ip addresses for domrs | ip address | 192.168.166.128 || ||
+ *         private.ipaddr.end | end of the range of private ip addresses for
+ *         domrs | ip address | start + 126 || || private.macaddr.start | start
+ *         of the range of private mac addresses for domrs | mac address |
+ *         00:16:3e:77:e2:a0 || || private.macaddr.end | end of the range of
+ *         private mac addresses for domrs | mac address | start + 126 || ||
+ *         pool | the parent of the storage pool hierarchy * }
+ **/
+@Local(value = { ServerResource.class })
+public class LibvirtComputingResource extends ServerResourceBase implements
+        ServerResource {
+    private static final Logger s_logger = Logger
+            .getLogger(LibvirtComputingResource.class);
+
+    private String _modifyVlanPath;
+    private String _versionstringpath;
+    private String _patchdomrPath;
+    private String _createvmPath;
+    private String _manageSnapshotPath;
+    private String _createTmplPath;
+    private String _heartBeatPath;
+    private String _securityGroupPath;
+    private String _networkUsagePath;
+    private String _host;
+    private String _dcId;
+    private String _pod;
+    private String _clusterId;
+    private int _migrateSpeed;
+
+    private long _hvVersion;
+    private KVMHAMonitor _monitor;
+    private final String _SSHKEYSPATH = "/root/.ssh";
+    private final String _SSHPRVKEYPATH = _SSHKEYSPATH + File.separator
+            + "id_rsa.cloud";
+    private final String _SSHPUBKEYPATH = _SSHKEYSPATH + File.separator
+            + "id_rsa.pub.cloud";
+    private String _mountPoint = "/mnt";
+    StorageLayer _storage;
+    private KVMStoragePoolManager _storagePoolMgr;
+
+    private static final class KeyValueInterpreter extends OutputInterpreter {
+        private final Map<String, String> map = new HashMap<String, String>();
+
+        @Override
+        public String interpret(BufferedReader reader) throws IOException {
+            String line = null;
+            int numLines = 0;
+            while ((line = reader.readLine()) != null) {
+                String[] toks = line.trim().split("=");
+                if (toks.length < 2) {
+                    s_logger.warn("Failed to parse Script output: " + line);
+                } else {
+                    map.put(toks[0].trim(), toks[1].trim());
+                }
+                numLines++;
+            }
+            if (numLines == 0) {
+                s_logger.warn("KeyValueInterpreter: no output lines?");
+            }
+            return null;
+        }
+
+        public Map<String, String> getKeyValues() {
+            return map;
+        }
+    }
+
+    @Override
+    protected String getDefaultScriptsDir() {
+        return null;
+    }
+
+    protected static MessageFormat SnapshotXML = new MessageFormat(
+            "   <domainsnapshot>" + "       <name>{0}</name>" + "          <domain>"
+                    + "            <uuid>{1}</uuid>" + "        </domain>"
+                    + "    </domainsnapshot>");
+
+    protected String _hypervisorType;
+    protected String _hypervisorURI;
+    protected String _hypervisorPath;
+    protected String _sysvmISOPath;
+    protected String _privNwName;
+    protected String _privBridgeName;
+    protected String _linkLocalBridgeName;
+    protected String _publicBridgeName;
+    protected String _guestBridgeName;
+    protected String _privateIp;
+    protected String _pool;
+    protected String _localGateway;
+    private boolean _can_bridge_firewall;
+    protected String _localStoragePath;
+    protected String _localStorageUUID;
+    private Pair<String, String> _pifs;
+    private final Map<String, vmStats> _vmStats = new ConcurrentHashMap<String, vmStats>();
+
+    protected boolean _disconnected = true;
+    protected int _timeout;
+    protected int _cmdsTimeout;
+    protected int _stopTimeout;
+    protected static HashMap<DomainInfo.DomainState, State> s_statesTable;
+    static {
+        s_statesTable = new HashMap<DomainInfo.DomainState, State>();
+        s_statesTable.put(DomainInfo.DomainState.VIR_DOMAIN_SHUTOFF,
+                State.Stopped);
+        s_statesTable.put(DomainInfo.DomainState.VIR_DOMAIN_PAUSED,
+                State.Running);
+        s_statesTable.put(DomainInfo.DomainState.VIR_DOMAIN_RUNNING,
+                State.Running);
+        s_statesTable.put(DomainInfo.DomainState.VIR_DOMAIN_BLOCKED,
+                State.Running);
+        s_statesTable.put(DomainInfo.DomainState.VIR_DOMAIN_NOSTATE,
+                State.Unknown);
+        s_statesTable.put(DomainInfo.DomainState.VIR_DOMAIN_SHUTDOWN,
+                State.Stopping);
+    }
+
+    protected HashMap<String, State> _vms = new HashMap<String, State>(20);
+    protected List<String> _vmsKilled = new ArrayList<String>();
+
+    private VirtualRoutingResource _virtRouterResource;
+
+    private String _pingTestPath;
+
+    private int _dom0MinMem;
+
+    protected enum defineOps {
+        UNDEFINE_VM, DEFINE_VM
+    }
+
+    private String getEndIpFromStartIp(String startIp, int numIps) {
+        String[] tokens = startIp.split("[.]");
+        assert (tokens.length == 4);
+        int lastbyte = Integer.parseInt(tokens[3]);
+        lastbyte = lastbyte + numIps;
+        tokens[3] = Integer.toString(lastbyte);
+        StringBuilder end = new StringBuilder(15);
+        end.append(tokens[0]).append(".").append(tokens[1]).append(".")
+                .append(tokens[2]).append(".").append(tokens[3]);
+        return end.toString();
+    }
+
+    private Map<String, Object> getDeveloperProperties()
+            throws ConfigurationException {
+        final File file = PropertiesUtil.findConfigFile("developer.properties");
+        if (file == null) {
+            throw new ConfigurationException(
+                    "Unable to find developer.properties.");
+        }
+
+        s_logger.info("developer.properties found at " + file.getAbsolutePath());
+        Properties properties = new Properties();
+        try {
+            properties.load(new FileInputStream(file));
+
+            String startMac = (String) properties.get("private.macaddr.start");
+            if (startMac == null) {
+                throw new ConfigurationException(
+                        "Developers must specify start mac for private ip range");
+            }
+
+            String startIp = (String) properties.get("private.ipaddr.start");
+            if (startIp == null) {
+                throw new ConfigurationException(
+                        "Developers must specify start ip for private ip range");
+            }
+            final Map<String, Object> params = PropertiesUtil.toMap(properties);
+
+            String endIp = (String) properties.get("private.ipaddr.end");
+            if (endIp == null) {
+                endIp = getEndIpFromStartIp(startIp, 16);
+                params.put("private.ipaddr.end", endIp);
+            }
+            return params;
+        } catch (final FileNotFoundException ex) {
+            throw new CloudRuntimeException("Cannot find the file: "
+                    + file.getAbsolutePath(), ex);
+        } catch (final IOException ex) {
+            throw new CloudRuntimeException("IOException in reading "
+                    + file.getAbsolutePath(), ex);
+        }
+    }
+
+    protected String getDefaultNetworkScriptsDir() {
+        return "scripts/vm/network/vnet";
+    }
+
+    protected String getDefaultStorageScriptsDir() {
+        return "scripts/storage/qcow2";
+    }
+
+    private void saveProperties(Map<String, Object> params)
+            throws ConfigurationException {
+        final File file = PropertiesUtil.findConfigFile("agent.properties");
+        if (file == null) {
+            throw new ConfigurationException("Unable to find agent.properties.");
+        }
+
+        s_logger.info("agent.properties found at " + file.getAbsolutePath());
+
+        try {
+            Properties _properties = new Properties();
+            _properties.load(new FileInputStream(file));
+            Set<String> names = _properties.stringPropertyNames();
+            for (String key : params.keySet()) {
+                if (!names.contains(key)) {
+                    _properties.setProperty(key, (String) params.get(key));
+                }
+            }
+            _properties.store(new FileOutputStream(file), "");
+        } catch (final FileNotFoundException ex) {
+            throw new CloudRuntimeException("Cannot find the file: "
+                    + file.getAbsolutePath(), ex);
+        } catch (final IOException ex) {
+            throw new CloudRuntimeException("IOException in reading "
+                    + file.getAbsolutePath(), ex);
+        }
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+        boolean success = super.configure(name, params);
+        if (!success) {
+            return false;
+        }
+
+        try {
+            Class<?> clazz = Class
+                    .forName("com.cloud.storage.JavaStorageLayer");
+            _storage = (StorageLayer) ComponentLocator.inject(clazz);
+            _storage.configure("StorageLayer", params);
+        } catch (ClassNotFoundException e) {
+            throw new ConfigurationException("Unable to find class "
+                    + "com.cloud.storage.JavaStorageLayer");
+        }
+
+        _virtRouterResource = new VirtualRoutingResource();
+
+        // Set the domr scripts directory
+        params.put("domr.scripts.dir", "scripts/network/domr/kvm");
+
+        success = _virtRouterResource.configure(name, params);
+
+        String kvmScriptsDir = (String) params.get("kvm.scripts.dir");
+        if (kvmScriptsDir == null) {
+            kvmScriptsDir = "scripts/vm/hypervisor/kvm";
+        }
+
+        String networkScriptsDir = (String) params.get("network.scripts.dir");
+        if (networkScriptsDir == null) {
+            networkScriptsDir = getDefaultNetworkScriptsDir();
+        }
+
+        String storageScriptsDir = (String) params.get("storage.scripts.dir");
+        if (storageScriptsDir == null) {
+            storageScriptsDir = getDefaultStorageScriptsDir();
+        }
+
+        if (!success) {
+            return false;
+        }
+
+        _host = (String) params.get("host");
+        if (_host == null) {
+            _host = "localhost";
+        }
+
+        _dcId = (String) params.get("zone");
+        if (_dcId == null) {
+            _dcId = "default";
+        }
+
+        _pod = (String) params.get("pod");
+        if (_pod == null) {
+            _pod = "default";
+        }
+
+        _clusterId = (String) params.get("cluster");
+
+        _modifyVlanPath = Script.findScript(networkScriptsDir, "modifyvlan.sh");
+        if (_modifyVlanPath == null) {
+            throw new ConfigurationException("Unable to find modifyvlan.sh");
+        }
+
+        _versionstringpath = Script.findScript(kvmScriptsDir, "versions.sh");
+        if (_versionstringpath == null) {
+            throw new ConfigurationException("Unable to find versions.sh");
+        }
+
+        _patchdomrPath = Script.findScript(kvmScriptsDir + "/patch/",
+                "rundomrpre.sh");
+        if (_patchdomrPath == null) {
+            throw new ConfigurationException("Unable to find rundomrpre.sh");
+        }
+
+        _heartBeatPath = Script.findScript(kvmScriptsDir, "kvmheartbeat.sh");
+        if (_heartBeatPath == null) {
+            throw new ConfigurationException("Unable to find kvmheartbeat.sh");
+        }
+
+        _createvmPath = Script.findScript(storageScriptsDir, "createvm.sh");
+        if (_createvmPath == null) {
+            throw new ConfigurationException("Unable to find the createvm.sh");
+        }
+
+        _manageSnapshotPath = Script.findScript(storageScriptsDir,
+                "managesnapshot.sh");
+        if (_manageSnapshotPath == null) {
+            throw new ConfigurationException(
+                    "Unable to find the managesnapshot.sh");
+        }
+
+        _createTmplPath = Script
+                .findScript(storageScriptsDir, "createtmplt.sh");
+        if (_createTmplPath == null) {
+            throw new ConfigurationException(
+                    "Unable to find the createtmplt.sh");
+        }
+
+        _securityGroupPath = Script.findScript(networkScriptsDir,
+                "security_group.py");
+        if (_securityGroupPath == null) {
+            throw new ConfigurationException(
+                    "Unable to find the security_group.py");
+        }
+
+        _networkUsagePath = Script.findScript("scripts/network/domr/",
+                "networkUsage.sh");
+        if (_networkUsagePath == null) {
+            throw new ConfigurationException(
+                    "Unable to find the networkUsage.sh");
+        }
+
+        String value = (String) params.get("developer");
+        boolean isDeveloper = Boolean.parseBoolean(value);
+
+        if (isDeveloper) {
+            params.putAll(getDeveloperProperties());
+        }
+
+        _pool = (String) params.get("pool");
+        if (_pool == null) {
+            _pool = "/root";
+        }
+
+        String instance = (String) params.get("instance");
+
+        _hypervisorType = (String) params.get("hypervisor.type");
+        if (_hypervisorType == null) {
+            _hypervisorType = "kvm";
+        }
+
+        _hypervisorURI = (String) params.get("hypervisor.uri");
+        if (_hypervisorURI == null) {
+            _hypervisorURI = "qemu:///system";
+        }
+        String startMac = (String) params.get("private.macaddr.start");
+        if (startMac == null) {
+            startMac = "00:16:3e:77:e2:a0";
+        }
+
+        String startIp = (String) params.get("private.ipaddr.start");
+        if (startIp == null) {
+            startIp = "192.168.166.128";
+        }
+
+        _pingTestPath = Script.findScript(kvmScriptsDir, "pingtest.sh");
+        if (_pingTestPath == null) {
+            throw new ConfigurationException("Unable to find the pingtest.sh");
+        }
+
+        _linkLocalBridgeName = (String) params.get("private.bridge.name");
+        if (_linkLocalBridgeName == null) {
+            if (isDeveloper) {
+                _linkLocalBridgeName = "cloud-" + instance + "-0";
+            } else {
+                _linkLocalBridgeName = "cloud0";
+            }
+        }
+
+        _publicBridgeName = (String) params.get("public.network.device");
+        if (_publicBridgeName == null) {
+            _publicBridgeName = "cloudbr0";
+        }
+
+        _privBridgeName = (String) params.get("private.network.device");
+        if (_privBridgeName == null) {
+            _privBridgeName = "cloudbr1";
+        }
+
+        _guestBridgeName = (String) params.get("guest.network.device");
+        if (_guestBridgeName == null) {
+            _guestBridgeName = _privBridgeName;
+        }
+
+        _privNwName = (String) params.get("private.network.name");
+        if (_privNwName == null) {
+            if (isDeveloper) {
+                _privNwName = "cloud-" + instance + "-private";
+            } else {
+                _privNwName = "cloud-private";
+            }
+        }
+
+        _localStoragePath = (String) params.get("local.storage.path");
+        if (_localStoragePath == null) {
+            _localStoragePath = "/var/lib/libvirt/images/";
+        }
+
+        _localStorageUUID = (String) params.get("local.storage.uuid");
+        if (_localStorageUUID == null) {
+            _localStorageUUID = UUID.randomUUID().toString();
+            params.put("local.storage.uuid", _localStorageUUID);
+        }
+
+        value = (String) params.get("scripts.timeout");
+        _timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
+
+        value = (String) params.get("stop.script.timeout");
+        _stopTimeout = NumbersUtil.parseInt(value, 120) * 1000;
+
+        value = (String) params.get("cmds.timeout");
+        _cmdsTimeout = NumbersUtil.parseInt(value, 7200) * 1000;
+
+        value = (String) params.get("host.reserved.mem.mb");
+        _dom0MinMem = NumbersUtil.parseInt(value, 0) * 1024 * 1024;
+
+        value = (String) params.get("debug.mode");
+
+        LibvirtConnection.initialize(_hypervisorURI);
+        Connect conn = null;
+        try {
+            conn = LibvirtConnection.getConnection();
+        } catch (LibvirtException e) {
+            throw new CloudRuntimeException(e.getMessage());
+        }
+
+        /* Does node support HVM guest? If not, exit */
+        if (!IsHVMEnabled(conn)) {
+            throw new ConfigurationException(
+                    "NO HVM support on this machine, pls make sure: "
+                            + "1. VT/SVM is supported by your CPU, or is enabled in BIOS. "
+                            + "2. kvm modules is installed");
+        }
+
+        _hypervisorPath = getHypervisorPath(conn);
+        try {
+            _hvVersion = conn.getVersion();
+            _hvVersion = (_hvVersion % 1000000) / 1000;
+        } catch (LibvirtException e) {
+
+        }
+
+        String[] info = NetUtils.getNetworkParams(_privateNic);
+
+        _monitor = new KVMHAMonitor(null, info[0], _heartBeatPath);
+        Thread ha = new Thread(_monitor);
+        ha.start();
+
+        _storagePoolMgr = new KVMStoragePoolManager(_storage, _monitor);
+
+        _sysvmISOPath = (String) params.get("systemvm.iso.path");
+        if (_sysvmISOPath == null) {
+            String[] isoPaths = { "/usr/lib64/cloud/agent/vms/systemvm.iso",
+                    "/usr/lib/cloud/agent/vms/systemvm.iso" };
+            for (String isoPath : isoPaths) {
+                if (_storage.exists(isoPath)) {
+                    _sysvmISOPath = isoPath;
+                    break;
+                }
+            }
+            if (_sysvmISOPath == null) {
+                s_logger.debug("Can't find system vm ISO");
+            }
+        }
+
+        try {
+            createControlNetwork(conn);
+        } catch (LibvirtException e) {
+            throw new ConfigurationException(e.getMessage());
+        }
+
+        _pifs = getPifs();
+        if (_pifs.first() == null) {
+            s_logger.debug("Failed to get private nic name");
+            throw new ConfigurationException("Failed to get private nic name");
+        }
+
+        if (_pifs.second() == null) {
+            s_logger.debug("Failed to get public nic name");
+            throw new ConfigurationException("Failed to get public nic name");
+        }
+        s_logger.debug("Found pif: " + _pifs.first() + " on " + _privBridgeName
+                + ", pif: " + _pifs.second() + " on " + _publicBridgeName);
+
+        _can_bridge_firewall = can_bridge_firewall(_pifs.second());
+
+        _localGateway = Script
+                .runSimpleBashScript("ip route |grep default|awk '{print $3}'");
+        if (_localGateway == null) {
+            s_logger.debug("Failed to found the local gateway");
+        }
+
+        _mountPoint = (String) params.get("mount.path");
+        if (_mountPoint == null) {
+            _mountPoint = "/mnt";
+        }
+        
+        value = (String) params.get("vm.migrate.speed");
+        _migrateSpeed = NumbersUtil.parseInt(value, -1);
+        if (_migrateSpeed == -1) {
+            //get guest network device speed
+            _migrateSpeed = 0;
+            String speed = Script.runSimpleBashScript("ethtool " + _pifs.second() + " |grep Speed | cut -d \\  -f 2");
+            if (speed != null) {
+                String[] tokens = speed.split("M");
+                if (tokens.length == 2) {
+                    try {
+                        _migrateSpeed = Integer.parseInt(tokens[0]);
+                    } catch (Exception e) {
+                        
+                    }
+                    s_logger.debug("device " + _pifs.second() + " has speed: " + String.valueOf(_migrateSpeed));
+                }
+            }
+            params.put("vm.migrate.speed", String.valueOf(_migrateSpeed));
+        }
+        saveProperties(params);
+
+        return true;
+    }
+
+    private Pair<String, String> getPifs() {
+        /* get pifs from bridge */
+        String pubPif = null;
+        String privPif = null;
+        String vlan = null;
+        if (_publicBridgeName != null) {
+            pubPif = Script.runSimpleBashScript("brctl show | grep "
+                    + _publicBridgeName + " | awk '{print $4}'");
+            vlan = Script.runSimpleBashScript("ls /proc/net/vlan/" + pubPif);
+            if (vlan != null && !vlan.isEmpty()) {
+                pubPif = Script
+                        .runSimpleBashScript("grep ^Device\\: /proc/net/vlan/"
+                                + pubPif + " | awk {'print $2'}");
+            }
+        }
+        if (_guestBridgeName != null) {
+            privPif = Script.runSimpleBashScript("brctl show | grep "
+                    + _guestBridgeName + " | awk '{print $4}'");
+            vlan = Script.runSimpleBashScript("ls /proc/net/vlan/" + privPif);
+            if (vlan != null && !vlan.isEmpty()) {
+                privPif = Script
+                        .runSimpleBashScript("grep ^Device\\: /proc/net/vlan/"
+                                + privPif + " | awk {'print $2'}");
+            }
+        }
+        return new Pair<String, String>(privPif, pubPif);
+    }
+
+    private boolean checkNetwork(String networkName) {
+        if (networkName == null) {
+            return true;
+        }
+
+        String name = Script.runSimpleBashScript("brctl show | grep "
+                + networkName + " | awk '{print $4}'");
+        if (name == null) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    private String getVnetId(String vnetId) {
+        return vnetId;
+    }
+
+    private void patchSystemVm(String cmdLine, String dataDiskPath,
+            String vmName) throws InternalErrorException {
+        String result;
+        final Script command = new Script(_patchdomrPath, _timeout, s_logger);
+        command.add("-l", vmName);
+        command.add("-t", "all");
+        command.add("-d", dataDiskPath);
+        command.add("-p", cmdLine.replaceAll(" ", "%"));
+        result = command.execute();
+        if (result != null) {
+            throw new InternalErrorException(result);
+        }
+    }
+
+    boolean isDirectAttachedNetwork(String type) {
+        if ("untagged".equalsIgnoreCase(type)) {
+            return true;
+        } else {
+            try {
+                Long.valueOf(type);
+            } catch (NumberFormatException e) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    protected String startDomain(Connect conn, String vmName, String domainXML)
+            throws LibvirtException, InternalErrorException {
+        /* No duplicated vm, we will success, or failed */
+        boolean failed = false;
+        Domain dm = null;
+        try {
+            dm = conn.domainDefineXML(domainXML);
+        } catch (final LibvirtException e) {
+            /* Duplicated defined vm */
+            s_logger.warn("Failed to define domain " + vmName + ": "
+                    + e.getMessage());
+            failed = true;
+        } finally {
+            try {
+                if (dm != null) {
+                    dm.free();
+                }
+            } catch (final LibvirtException e) {
+
+            }
+        }
+
+        /* If failed, undefine the vm */
+        Domain dmOld = null;
+        Domain dmNew = null;
+        try {
+            if (failed) {
+                dmOld = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName
+                        .getBytes()));
+                dmOld.undefine();
+                dmNew = conn.domainDefineXML(domainXML);
+            }
+        } catch (final LibvirtException e) {
+            s_logger.warn("Failed to define domain (second time) " + vmName
+                    + ": " + e.getMessage());
+            throw e;
+        } catch (Exception e) {
+            s_logger.warn("Failed to define domain (second time) " + vmName
+                    + ": " + e.getMessage());
+            throw new InternalErrorException(e.toString());
+        } finally {
+            try {
+                if (dmOld != null) {
+                    dmOld.free();
+                }
+                if (dmNew != null) {
+                    dmNew.free();
+                }
+            } catch (final LibvirtException e) {
+
+            }
+        }
+
+        /* Start the VM */
+        try {
+            dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName
+                    .getBytes()));
+            dm.create();
+        } catch (LibvirtException e) {
+            s_logger.warn("Failed to start domain: " + vmName + ": "
+                    + e.getMessage());
+            throw e;
+        } finally {
+            try {
+                if (dm != null) {
+                    dm.free();
+                }
+            } catch (final LibvirtException e) {
+
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean stop() {
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+            conn.close();
+        } catch (LibvirtException e) {
+        }
+
+        return true;
+    }
+
+    public static void main(String[] args) {
+        s_logger.addAppender(new org.apache.log4j.ConsoleAppender(
+                new org.apache.log4j.PatternLayout(), "System.out"));
+        LibvirtComputingResource test = new LibvirtComputingResource();
+        Map<String, Object> params = new HashMap<String, Object>();
+        try {
+            test.configure("test", params);
+        } catch (ConfigurationException e) {
+            System.out.println(e.getMessage());
+            e.printStackTrace();
+        }
+        String result = null;
+        // String result = test.startDomainRouter("domr1",
+        // "/var/lib/images/centos.5-4.x86-64/centos-small.img", 128, "0064",
+        // "02:00:30:00:01:01", "00:16:3e:77:e2:a1", "02:00:30:00:64:01");
+        boolean created = (result == null);
+        s_logger.info("Domain " + (created ? " " : " not ") + " created");
+
+        s_logger.info("Rule " + (created ? " " : " not ") + " created");
+        test.stop();
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+
+        try {
+            if (cmd instanceof StopCommand) {
+                return execute((StopCommand) cmd);
+            } else if (cmd instanceof GetVmStatsCommand) {
+                return execute((GetVmStatsCommand) cmd);
+            } else if (cmd instanceof RebootRouterCommand) {
+                return execute((RebootRouterCommand) cmd);
+            } else if (cmd instanceof RebootCommand) {
+                return execute((RebootCommand) cmd);
+            } else if (cmd instanceof GetHostStatsCommand) {
+                return execute((GetHostStatsCommand) cmd);
+            } else if (cmd instanceof CheckStateCommand) {
+                return executeRequest(cmd);
+            } else if (cmd instanceof CheckHealthCommand) {
+                return execute((CheckHealthCommand) cmd);
+            } else if (cmd instanceof PrepareForMigrationCommand) {
+                return execute((PrepareForMigrationCommand) cmd);
+            } else if (cmd instanceof MigrateCommand) {
+                return execute((MigrateCommand) cmd);
+            } else if (cmd instanceof PingTestCommand) {
+                return execute((PingTestCommand) cmd);
+            } else if (cmd instanceof CheckVirtualMachineCommand) {
+                return execute((CheckVirtualMachineCommand) cmd);
+            } else if (cmd instanceof ReadyCommand) {
+                return execute((ReadyCommand) cmd);
+            } else if (cmd instanceof AttachIsoCommand) {
+                return execute((AttachIsoCommand) cmd);
+            } else if (cmd instanceof AttachVolumeCommand) {
+                return execute((AttachVolumeCommand) cmd);
+            } else if (cmd instanceof StopCommand) {
+                return execute((StopCommand) cmd);
+            } else if (cmd instanceof CheckConsoleProxyLoadCommand) {
+                return execute((CheckConsoleProxyLoadCommand) cmd);
+            } else if (cmd instanceof WatchConsoleProxyLoadCommand) {
+                return execute((WatchConsoleProxyLoadCommand) cmd);
+            } else if (cmd instanceof GetVncPortCommand) {
+                return execute((GetVncPortCommand) cmd);
+            } else if (cmd instanceof ModifySshKeysCommand) {
+                return execute((ModifySshKeysCommand) cmd);
+            } else if (cmd instanceof MaintainCommand) {
+                return execute((MaintainCommand) cmd);
+            } else if (cmd instanceof CreateCommand) {
+                return execute((CreateCommand) cmd);
+            } else if (cmd instanceof DestroyCommand) {
+                return execute((DestroyCommand) cmd);
+            } else if (cmd instanceof PrimaryStorageDownloadCommand) {
+                return execute((PrimaryStorageDownloadCommand) cmd);
+            } else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) {
+                return execute((CreatePrivateTemplateFromVolumeCommand) cmd);
+            } else if (cmd instanceof GetStorageStatsCommand) {
+                return execute((GetStorageStatsCommand) cmd);
+            } else if (cmd instanceof ManageSnapshotCommand) {
+                return execute((ManageSnapshotCommand) cmd);
+            } else if (cmd instanceof BackupSnapshotCommand) {
+                return execute((BackupSnapshotCommand) cmd);
+            } else if (cmd instanceof CreateVolumeFromSnapshotCommand) {
+                return execute((CreateVolumeFromSnapshotCommand) cmd);
+            } else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) {
+                return execute((CreatePrivateTemplateFromSnapshotCommand) cmd);
+            } else if (cmd instanceof UpgradeSnapshotCommand) {
+                return execute((UpgradeSnapshotCommand) cmd);
+            } else if (cmd instanceof CreateStoragePoolCommand) {
+                return execute((CreateStoragePoolCommand) cmd);
+            } else if (cmd instanceof ModifyStoragePoolCommand) {
+                return execute((ModifyStoragePoolCommand) cmd);
+            } else if (cmd instanceof SecurityGroupRulesCmd) {
+                return execute((SecurityGroupRulesCmd) cmd);
+            } else if (cmd instanceof DeleteStoragePoolCommand) {
+                return execute((DeleteStoragePoolCommand) cmd);
+            } else if (cmd instanceof FenceCommand) {
+                return execute((FenceCommand) cmd);
+            } else if (cmd instanceof StartCommand) {
+                return execute((StartCommand) cmd);
+            } else if (cmd instanceof IpAssocCommand) {
+                return execute((IpAssocCommand) cmd);
+            } else if (cmd instanceof NetworkElementCommand) {
+                return _virtRouterResource.executeRequest(cmd);
+            } else if (cmd instanceof CheckSshCommand) {
+                return execute((CheckSshCommand) cmd);
+            } else if (cmd instanceof NetworkUsageCommand) {
+                return execute((NetworkUsageCommand) cmd);
+            } else if (cmd instanceof NetworkRulesSystemVmCommand) {
+                return execute((NetworkRulesSystemVmCommand) cmd);
+            } else if (cmd instanceof CleanupNetworkRulesCmd) {
+                return execute((CleanupNetworkRulesCmd) cmd);
+            } else if (cmd instanceof CopyVolumeCommand) {
+                return execute((CopyVolumeCommand) cmd);
+            } else if (cmd instanceof CheckNetworkCommand) {
+                return execute((CheckNetworkCommand) cmd);
+            } else {
+                s_logger.warn("Unsupported command ");
+                return Answer.createUnsupportedCommandAnswer(cmd);
+            }
+        } catch (final IllegalArgumentException e) {
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    private CheckNetworkAnswer execute(CheckNetworkCommand cmd) {
+        List<PhysicalNetworkSetupInfo> phyNics = cmd
+                .getPhysicalNetworkInfoList();
+        String errMsg = null;
+        for (PhysicalNetworkSetupInfo nic : phyNics) {
+            if (!checkNetwork(nic.getGuestNetworkName())) {
+                errMsg = "Can not find network: " + nic.getGuestNetworkName();
+                break;
+            } else if (!checkNetwork(nic.getPrivateNetworkName())) {
+                errMsg = "Can not find network: " + nic.getPrivateNetworkName();
+                break;
+            } else if (!checkNetwork(nic.getPublicNetworkName())) {
+                errMsg = "Can not find network: " + nic.getPublicNetworkName();
+                break;
+            }
+        }
+
+        if (errMsg != null) {
+            return new CheckNetworkAnswer(cmd, false, errMsg);
+        } else {
+            return new CheckNetworkAnswer(cmd, true, null);
+        }
+    }
+
+    private CopyVolumeAnswer execute(CopyVolumeCommand cmd) {
+        boolean copyToSecondary = cmd.toSecondaryStorage();
+        String volumePath = cmd.getVolumePath();
+        StorageFilerTO pool = cmd.getPool();
+        String secondaryStorageUrl = cmd.getSecondaryStorageURL();
+        KVMStoragePool secondaryStoragePool = null;
+        try {
+            KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(pool
+                    .getUuid());
+            String volumeName = UUID.randomUUID().toString();
+
+            if (copyToSecondary) {
+                String destVolumeName = volumeName + ".qcow2";
+                KVMPhysicalDisk volume = primaryPool.getPhysicalDisk(cmd
+                        .getVolumePath());
+                String volumeDestPath = "/volumes/" + cmd.getVolumeId()
+                        + File.separator;
+                secondaryStoragePool = _storagePoolMgr
+                        .getStoragePoolByURI(secondaryStorageUrl);
+                secondaryStoragePool.createFolder(volumeDestPath);
+                secondaryStoragePool.delete();
+                secondaryStoragePool = _storagePoolMgr
+                        .getStoragePoolByURI(secondaryStorageUrl
+                                + volumeDestPath);
+                _storagePoolMgr.copyPhysicalDisk(volume, destVolumeName,
+                        secondaryStoragePool);
+                return new CopyVolumeAnswer(cmd, true, null, null, volumeName);
+            } else {
+                volumePath = "/volumes/" + cmd.getVolumeId() + File.separator;
+                secondaryStoragePool = _storagePoolMgr
+                        .getStoragePoolByURI(secondaryStorageUrl + volumePath);
+                KVMPhysicalDisk volume = secondaryStoragePool
+                        .getPhysicalDisk(cmd.getVolumePath() + ".qcow2");
+                _storagePoolMgr.copyPhysicalDisk(volume, volumeName,
+                        primaryPool);
+                return new CopyVolumeAnswer(cmd, true, null, null, volumeName);
+            }
+        } catch (CloudRuntimeException e) {
+            return new CopyVolumeAnswer(cmd, false, e.toString(), null, null);
+        } finally {
+            if (secondaryStoragePool != null) {
+                secondaryStoragePool.delete();
+            }
+        }
+    }
+
+    protected Answer execute(DeleteStoragePoolCommand cmd) {
+        try {
+            _storagePoolMgr.deleteStoragePool(cmd.getPool().getUuid());
+            return new Answer(cmd);
+        } catch (CloudRuntimeException e) {
+            return new Answer(cmd, false, e.toString());
+        }
+    }
+
+    protected FenceAnswer execute(FenceCommand cmd) {
+        ExecutorService executors = Executors.newSingleThreadExecutor();
+        List<NfsStoragePool> pools = _monitor.getStoragePools();
+        KVMHAChecker ha = new KVMHAChecker(pools, cmd.getHostIp());
+        Future<Boolean> future = executors.submit(ha);
+        try {
+            Boolean result = future.get();
+            if (result) {
+                return new FenceAnswer(cmd, false, "Heart is still beating...");
+            } else {
+                return new FenceAnswer(cmd);
+            }
+        } catch (InterruptedException e) {
+            s_logger.warn("Unable to fence", e);
+            return new FenceAnswer(cmd, false, e.getMessage());
+        } catch (ExecutionException e) {
+            s_logger.warn("Unable to fence", e);
+            return new FenceAnswer(cmd, false, e.getMessage());
+        }
+
+    }
+
+    protected Storage.StorageResourceType getStorageResourceType() {
+        return Storage.StorageResourceType.STORAGE_POOL;
+    }
+
+    protected Answer execute(CreateCommand cmd) {
+        StorageFilerTO pool = cmd.getPool();
+        DiskProfile dskch = cmd.getDiskCharacteristics();
+        KVMPhysicalDisk BaseVol = null;
+        KVMStoragePool primaryPool = null;
+        KVMPhysicalDisk vol = null;
+        long disksize;
+        try {
+            primaryPool = _storagePoolMgr.getStoragePool(pool.getUuid());
+
+            if (cmd.getTemplateUrl() != null) {
+
+                BaseVol = primaryPool.getPhysicalDisk(cmd.getTemplateUrl());
+                vol = _storagePoolMgr.createDiskFromTemplate(BaseVol, UUID
+                        .randomUUID().toString(), primaryPool);
+
+                if (vol == null) {
+                    return new Answer(cmd, false,
+                            " Can't create storage volume on storage pool");
+                }
+                disksize = vol.getSize();
+            } else {
+                disksize = dskch.getSize();
+                vol = primaryPool.createPhysicalDisk(UUID.randomUUID()
+                        .toString(), dskch.getSize());
+            }
+            VolumeTO volume = new VolumeTO(cmd.getVolumeId(), dskch.getType(),
+                    pool.getType(), pool.getUuid(), pool.getPath(),
+                    vol.getName(), vol.getName(), disksize, null);
+            return new CreateAnswer(cmd, volume);
+        } catch (CloudRuntimeException e) {
+            s_logger.debug("Failed to create volume: " + e.toString());
+            return new CreateAnswer(cmd, e);
+        }
+    }
+
+    public Answer execute(DestroyCommand cmd) {
+        VolumeTO vol = cmd.getVolume();
+
+        try {
+            KVMStoragePool pool = _storagePoolMgr.getStoragePool(vol
+                    .getPoolUuid());
+            pool.deletePhysicalDisk(vol.getPath());
+
+            return new Answer(cmd, true, "Success");
+        } catch (CloudRuntimeException e) {
+            s_logger.debug("Failed to delete volume: " + e.toString());
+            return new Answer(cmd, false, e.toString());
+        }
+    }
+
+    private String getVlanIdFromBridge(String brName) {
+        OutputInterpreter.OneLineParser vlanIdParser = new OutputInterpreter.OneLineParser();
+        final Script cmd = new Script("/bin/bash", s_logger);
+        cmd.add("-c");
+        cmd.add("vlanid=$(brctl show |grep " + brName
+                + " |awk '{print $4}' | cut -s -d. -f 2);echo $vlanid");
+        String result = cmd.execute(vlanIdParser);
+        if (result != null) {
+            return null;
+        }
+        String vlanId = vlanIdParser.getLine();
+        if (vlanId.equalsIgnoreCase("")) {
+            return null;
+        } else {
+            return vlanId;
+        }
+    }
+
+    private void VifHotPlug(Connect conn, String vmName, String vlanId,
+            String macAddr) throws InternalErrorException, LibvirtException {
+        NicTO nicTO = new NicTO();
+        nicTO.setMac(macAddr);
+        nicTO.setType(TrafficType.Public);
+        if (vlanId == null) {
+            nicTO.setBroadcastType(BroadcastDomainType.Native);
+        } else {
+            nicTO.setBroadcastType(BroadcastDomainType.Vlan);
+            nicTO.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlanId));
+        }
+
+        InterfaceDef nic = createVif(conn, nicTO, InterfaceDef.nicModel.VIRTIO);
+        Domain vm = getDomain(conn, vmName);
+        vm.attachDevice(nic.toString());
+    }
+
+    public Answer execute(IpAssocCommand cmd) {
+        String routerName = cmd
+                .getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        String[] results = new String[cmd.getIpAddresses().length];
+        Connect conn;
+        try {
+            conn = LibvirtConnection.getConnection();
+            List<InterfaceDef> nics = getInterfaces(conn, routerName);
+            Map<String, Integer> vlanAllocatedToVM = new HashMap<String, Integer>();
+            Integer nicPos = 0;
+            for (InterfaceDef nic : nics) {
+                if (nic.getBrName().equalsIgnoreCase(_linkLocalBridgeName)) {
+                    vlanAllocatedToVM.put("LinkLocal", nicPos);
+                } else {
+                    String vlanId = getVlanIdFromBridge(nic.getBrName());
+                    if (vlanId != null) {
+                        vlanAllocatedToVM.put(vlanId, nicPos);
+                    } else {
+                        vlanAllocatedToVM.put(Vlan.UNTAGGED, nicPos);
+                    }
+                }
+                nicPos++;
+            }
+            IpAddressTO[] ips = cmd.getIpAddresses();
+            int i = 0;
+            String result = null;
+            int nicNum = 0;
+            for (IpAddressTO ip : ips) {
+                if (!vlanAllocatedToVM.containsKey(ip.getVlanId())) {
+                    /* plug a vif into router */
+                    VifHotPlug(conn, routerName, ip.getVlanId(),
+                            ip.getVifMacAddress());
+                    vlanAllocatedToVM.put(ip.getVlanId(), nicPos++);
+                }
+                nicNum = vlanAllocatedToVM.get(ip.getVlanId());
+                networkUsage(routerIp, "addVif", "eth" + nicNum);
+                result = _virtRouterResource.assignPublicIpAddress(routerName,
+                        routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(),
+                        ip.isSourceNat(), ip.getVlanId(), ip.getVlanGateway(),
+                        ip.getVlanNetmask(), ip.getVifMacAddress(),
+                        ip.getGuestIp(), nicNum);
+
+                if (result != null) {
+                    results[i++] = IpAssocAnswer.errorResult;
+                } else {
+                    results[i++] = ip.getPublicIp() + " - success";
+                    ;
+                }
+            }
+            return new IpAssocAnswer(cmd, results);
+        } catch (LibvirtException e) {
+            return new IpAssocAnswer(cmd, results);
+        } catch (InternalErrorException e) {
+            return new IpAssocAnswer(cmd, results);
+        }
+    }
+
+    protected ManageSnapshotAnswer execute(final ManageSnapshotCommand cmd) {
+        String snapshotName = cmd.getSnapshotName();
+        String snapshotPath = cmd.getSnapshotPath();
+        String vmName = cmd.getVmName();
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+            DomainInfo.DomainState state = null;
+            Domain vm = null;
+            if (vmName != null) {
+                try {
+                    vm = getDomain(conn, cmd.getVmName());
+                    state = vm.getInfo().state;
+                } catch (LibvirtException e) {
+
+                }
+            }
+
+            KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd
+                    .getPool().getUuid());
+
+            if (primaryPool.getType() == StoragePoolType.RBD) {
+                s_logger.debug("Snapshots are not supported on RBD volumes");
+                return new ManageSnapshotAnswer(cmd, false,
+                    "Snapshots are not supported on RBD volumes");
+            }
+
+            KVMPhysicalDisk disk = primaryPool.getPhysicalDisk(cmd
+                    .getVolumePath());
+            if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING
+                    && !primaryPool.isExternalSnapshot()) {
+                String vmUuid = vm.getUUIDString();
+                Object[] args = new Object[] { snapshotName, vmUuid };
+                String snapshot = SnapshotXML.format(args);
+                s_logger.debug(snapshot);
+                if (cmd.getCommandSwitch().equalsIgnoreCase(
+                        ManageSnapshotCommand.CREATE_SNAPSHOT)) {
+                    vm.snapshotCreateXML(snapshot);
+                } else {
+                    DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
+                    snap.delete(0);
+                }
+
+                /*
+                 * libvirt on RHEL6 doesn't handle resume event emitted from
+                 * qemu
+                 */
+                vm = getDomain(conn, cmd.getVmName());
+                state = vm.getInfo().state;
+                if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
+                    vm.resume();
+                }
+            } else {
+
+                /* VM is not running, create a snapshot by ourself */
+                final Script command = new Script(_manageSnapshotPath,
+                        _cmdsTimeout, s_logger);
+                if (cmd.getCommandSwitch().equalsIgnoreCase(
+                        ManageSnapshotCommand.CREATE_SNAPSHOT)) {
+                    command.add("-c", disk.getPath());
+                } else {
+                    command.add("-d", snapshotPath);
+                }
+
+                command.add("-n", snapshotName);
+                String result = command.execute();
+                if (result != null) {
+                    s_logger.debug("Failed to manage snapshot: " + result);
+                    return new ManageSnapshotAnswer(cmd, false,
+                            "Failed to manage snapshot: " + result);
+                }
+            }
+            return new ManageSnapshotAnswer(cmd, cmd.getSnapshotId(),
+                    disk.getPath() + File.separator + snapshotName, true, null);
+        } catch (LibvirtException e) {
+            s_logger.debug("Failed to manage snapshot: " + e.toString());
+            return new ManageSnapshotAnswer(cmd, false,
+                    "Failed to manage snapshot: " + e.toString());
+        }
+
+    }
+
+    protected BackupSnapshotAnswer execute(final BackupSnapshotCommand cmd) {
+        Long dcId = cmd.getDataCenterId();
+        Long accountId = cmd.getAccountId();
+        Long volumeId = cmd.getVolumeId();
+        String secondaryStoragePoolUrl = cmd.getSecondaryStorageUrl();
+        String snapshotName = cmd.getSnapshotName();
+        String snapshotPath = cmd.getVolumePath();
+        String snapshotDestPath = null;
+        String snapshotRelPath = null;
+        String vmName = cmd.getVmName();
+        KVMStoragePool secondaryStoragePool = null;
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+
+            secondaryStoragePool = _storagePoolMgr
+                    .getStoragePoolByURI(secondaryStoragePoolUrl);
+
+            String ssPmountPath = secondaryStoragePool.getLocalPath();
+            snapshotRelPath = File.separator + "snapshots" + File.separator
+                    + dcId + File.separator + accountId + File.separator
+                    + volumeId;
+
+            snapshotDestPath = ssPmountPath + File.separator + "snapshots"
+                    + File.separator + dcId + File.separator + accountId
+                    + File.separator + volumeId;
+            KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd
+                    .getPrimaryStoragePoolNameLabel());
+            KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(cmd
+                    .getVolumePath());
+            Script command = new Script(_manageSnapshotPath, _cmdsTimeout,
+                    s_logger);
+            command.add("-b", snapshotDisk.getPath());
+            command.add("-n", snapshotName);
+            command.add("-p", snapshotDestPath);
+            command.add("-t", snapshotName);
+            String result = command.execute();
+            if (result != null) {
+                s_logger.debug("Failed to backup snaptshot: " + result);
+                return new BackupSnapshotAnswer(cmd, false, result, null, true);
+            }
+            /* Delete the snapshot on primary */
+
+            DomainInfo.DomainState state = null;
+            Domain vm = null;
+            if (vmName != null) {
+                try {
+                    vm = getDomain(conn, cmd.getVmName());
+                    state = vm.getInfo().state;
+                } catch (LibvirtException e) {
+
+                }
+            }
+
+            KVMStoragePool primaryStorage = _storagePoolMgr.getStoragePool(cmd
+                    .getPool().getUuid());
+            if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING
+                    && !primaryStorage.isExternalSnapshot()) {
+                String vmUuid = vm.getUUIDString();
+                Object[] args = new Object[] { snapshotName, vmUuid };
+                String snapshot = SnapshotXML.format(args);
+                s_logger.debug(snapshot);
+                DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
+                snap.delete(0);
+
+                /*
+                 * libvirt on RHEL6 doesn't handle resume event emitted from
+                 * qemu
+                 */
+                vm = getDomain(conn, cmd.getVmName());
+                state = vm.getInfo().state;
+                if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
+                    vm.resume();
+                }
+            } else {
+                command = new Script(_manageSnapshotPath, _cmdsTimeout,
+                        s_logger);
+                command.add("-d", snapshotDisk.getPath());
+                command.add("-n", snapshotName);
+                result = command.execute();
+                if (result != null) {
+                    s_logger.debug("Failed to backup snapshot: " + result);
+                    return new BackupSnapshotAnswer(cmd, false,
+                            "Failed to backup snapshot: " + result, null, true);
+                }
+            }
+        } catch (LibvirtException e) {
+            return new BackupSnapshotAnswer(cmd, false, e.toString(), null,
+                    true);
+        } catch (CloudRuntimeException e) {
+            return new BackupSnapshotAnswer(cmd, false, e.toString(), null,
+                    true);
+        } finally {
+            if (secondaryStoragePool != null) {
+                secondaryStoragePool.delete();
+            }
+        }
+        return new BackupSnapshotAnswer(cmd, true, null, snapshotRelPath
+                + File.separator + snapshotName, true);
+    }
+
+    protected DeleteSnapshotBackupAnswer execute(
+            final DeleteSnapshotBackupCommand cmd) {
+        Long dcId = cmd.getDataCenterId();
+        Long accountId = cmd.getAccountId();
+        Long volumeId = cmd.getVolumeId();
+        KVMStoragePool secondaryStoragePool = null;
+        try {
+            secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd
+                    .getSecondaryStorageUrl());
+
+            String ssPmountPath = secondaryStoragePool.getLocalPath();
+            String snapshotDestPath = ssPmountPath + File.separator
+                    + "snapshots" + File.separator + dcId + File.separator
+                    + accountId + File.separator + volumeId;
+
+            final Script command = new Script(_manageSnapshotPath,
+                    _cmdsTimeout, s_logger);
+            command.add("-d", snapshotDestPath);
+            command.add("-n", cmd.getSnapshotName());
+
+            command.execute();
+        } catch (CloudRuntimeException e) {
+            return new DeleteSnapshotBackupAnswer(cmd, false, e.toString());
+        } finally {
+            if (secondaryStoragePool != null) {
+                secondaryStoragePool.delete();
+            }
+        }
+        return new DeleteSnapshotBackupAnswer(cmd, true, null);
+    }
+
+    protected Answer execute(DeleteSnapshotsDirCommand cmd) {
+        Long dcId = cmd.getDcId();
+        Long accountId = cmd.getAccountId();
+        Long volumeId = cmd.getVolumeId();
+        KVMStoragePool secondaryStoragePool = null;
+        try {
+            secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd
+                    .getSecondaryStorageUrl());
+
+            String ssPmountPath = secondaryStoragePool.getLocalPath();
+            String snapshotDestPath = ssPmountPath + File.separator
+                    + "snapshots" + File.separator + dcId + File.separator
+                    + accountId + File.separator + volumeId;
+
+            final Script command = new Script(_manageSnapshotPath,
+                    _cmdsTimeout, s_logger);
+            command.add("-d", snapshotDestPath);
+            command.add("-f");
+            command.execute();
+        } catch (CloudRuntimeException e) {
+            return new Answer(cmd, false, e.toString());
+        } finally {
+            if (secondaryStoragePool != null) {
+                secondaryStoragePool.delete();
+            }
+
+        }
+        return new Answer(cmd, true, null);
+    }
+
+    protected CreateVolumeFromSnapshotAnswer execute(
+            final CreateVolumeFromSnapshotCommand cmd) {
+        try {
+
+            String snapshotPath = cmd.getSnapshotUuid();
+            int index = snapshotPath.lastIndexOf("/");
+            snapshotPath = snapshotPath.substring(0, index);
+            KVMStoragePool secondaryPool = _storagePoolMgr
+                    .getStoragePoolByURI(cmd.getSecondaryStorageUrl()
+                            + snapshotPath);
+            KVMPhysicalDisk snapshot = secondaryPool.getPhysicalDisk(cmd
+                    .getSnapshotName());
+
+            String primaryUuid = cmd.getPrimaryStoragePoolNameLabel();
+            KVMStoragePool primaryPool = _storagePoolMgr
+                    .getStoragePool(primaryUuid);
+            String volUuid = UUID.randomUUID().toString();
+            KVMPhysicalDisk disk = _storagePoolMgr.copyPhysicalDisk(snapshot,
+                    volUuid, primaryPool);
+            return new CreateVolumeFromSnapshotAnswer(cmd, true, "",
+                    disk.getName());
+        } catch (CloudRuntimeException e) {
+            return new CreateVolumeFromSnapshotAnswer(cmd, false, e.toString(),
+                    null);
+        }
+    }
+
+    protected Answer execute(final UpgradeSnapshotCommand cmd) {
+
+        return new Answer(cmd, true, "success");
+    }
+
+    protected CreatePrivateTemplateAnswer execute(
+            final CreatePrivateTemplateFromSnapshotCommand cmd) {
+        String templateFolder = cmd.getAccountId() + File.separator
+                + cmd.getNewTemplateId();
+        String templateInstallFolder = "template/tmpl/" + templateFolder;
+        String tmplName = UUID.randomUUID().toString();
+        String tmplFileName = tmplName + ".qcow2";
+        KVMStoragePool secondaryPool = null;
+        KVMStoragePool snapshotPool = null;
+        try {
+            String snapshotPath = cmd.getSnapshotUuid();
+            int index = snapshotPath.lastIndexOf("/");
+            snapshotPath = snapshotPath.substring(0, index);
+            snapshotPool = _storagePoolMgr.getStoragePoolByURI(cmd
+                    .getSecondaryStorageUrl() + snapshotPath);
+            KVMPhysicalDisk snapshot = snapshotPool.getPhysicalDisk(cmd
+                    .getSnapshotName());
+
+            secondaryPool = _storagePoolMgr.getStoragePoolByURI(cmd
+                    .getSecondaryStorageUrl());
+
+            String templatePath = secondaryPool.getLocalPath() + File.separator
+                    + templateInstallFolder;
+
+            _storage.mkdirs(templatePath);
+
+            String tmplPath = templateInstallFolder + File.separator
+                    + tmplFileName;
+            Script command = new Script(_createTmplPath, _cmdsTimeout, s_logger);
+            command.add("-t", templatePath);
+            command.add("-n", tmplFileName);
+            command.add("-f", snapshot.getPath());
+            command.execute();
+
+            Map<String, Object> params = new HashMap<String, Object>();
+            params.put(StorageLayer.InstanceConfigKey, _storage);
+            Processor qcow2Processor = new QCOW2Processor();
+            qcow2Processor.configure("QCOW2 Processor", params);
+            FormatInfo info = qcow2Processor.process(templatePath, null,
+                    tmplName);
+
+            TemplateLocation loc = new TemplateLocation(_storage, templatePath);
+            loc.create(1, true, tmplName);
+            loc.addFormat(info);
+            loc.save();
+
+            return new CreatePrivateTemplateAnswer(cmd, true, "", tmplPath,
+                    info.virtualSize, info.size, tmplName, info.format);
+        } catch (ConfigurationException e) {
+            return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage());
+        } catch (InternalErrorException e) {
+            return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage());
+        } catch (IOException e) {
+            return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage());
+        } catch (CloudRuntimeException e) {
+            return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage());
+        } finally {
+            if (secondaryPool != null) {
+                secondaryPool.delete();
+            }
+            if (snapshotPool != null) {
+                snapshotPool.delete();
+            }
+        }
+    }
+
+    protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
+        try {
+            KVMStoragePool sp = _storagePoolMgr.getStoragePool(cmd
+                    .getStorageId());
+            return new GetStorageStatsAnswer(cmd, sp.getCapacity(),
+                    sp.getUsed());
+        } catch (CloudRuntimeException e) {
+            return new GetStorageStatsAnswer(cmd, e.toString());
+        }
+    }
+
+    protected CreatePrivateTemplateAnswer execute(
+            CreatePrivateTemplateFromVolumeCommand cmd) {
+        String secondaryStorageURL = cmd.getSecondaryStorageUrl();
+
+        KVMStoragePool secondaryStorage = null;
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+            String templateFolder = cmd.getAccountId() + File.separator
+                    + cmd.getTemplateId() + File.separator;
+            String templateInstallFolder = "/template/tmpl/" + templateFolder;
+
+            secondaryStorage = _storagePoolMgr
+                    .getStoragePoolByURI(secondaryStorageURL);
+
+            KVMStoragePool primary = _storagePoolMgr.getStoragePool(cmd
+                    .getPrimaryStoragePoolNameLabel());
+            KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath());
+            String tmpltPath = secondaryStorage.getLocalPath() + File.separator
+                    + templateInstallFolder;
+            _storage.mkdirs(tmpltPath);
+
+            if (primary.getType() != StoragePoolType.RBD) {
+                Script command = new Script(_createTmplPath, _cmdsTimeout, s_logger);
+                command.add("-f", disk.getPath());
+                command.add("-t", tmpltPath);
+                command.add("-n", cmd.getUniqueName() + ".qcow2");
+
+                String result = command.execute();
+
+                if (result != null) {
+                    s_logger.debug("failed to create template: " + result);
+                    return new CreatePrivateTemplateAnswer(cmd, false, result);
+                }
+            } else {
+                s_logger.debug("Converting RBD disk " + disk.getPath() + " into template " + cmd.getUniqueName());
+                Script.runSimpleBashScript("qemu-img convert"
+                                + " -f raw -O qcow2 "
+                                + KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(),
+                                                primary.getSourcePort(),
+                                                primary.getAuthUserName(),
+                                                primary.getAuthSecret(),
+                                                disk.getPath())
+                                + " " + tmpltPath + "/" + cmd.getUniqueName() + ".qcow2");
+                File templateProp = new File(tmpltPath + "/template.properties");
+                if (!templateProp.exists()) {
+                    templateProp.createNewFile();
+                }
+
+                String templateContent = "filename=" + cmd.getUniqueName() + ".qcow2" + System.getProperty("line.separator");
+
+                DateFormat dateFormat = new SimpleDateFormat("MM_dd_yyyy");
+                Date date = new Date();
+                templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator");
+
+                FileOutputStream templFo = new FileOutputStream(templateProp);
+                templFo.write(templateContent.getBytes());
+                templFo.flush();
+                templFo.close();
+            }
+
+            Map<String, Object> params = new HashMap<String, Object>();
+            params.put(StorageLayer.InstanceConfigKey, _storage);
+            Processor qcow2Processor = new QCOW2Processor();
+
+            qcow2Processor.configure("QCOW2 Processor", params);
+
+            FormatInfo info = qcow2Processor.process(tmpltPath, null,
+                    cmd.getUniqueName());
+
+            TemplateLocation loc = new TemplateLocation(_storage, tmpltPath);
+            loc.create(1, true, cmd.getUniqueName());
+            loc.addFormat(info);
+            loc.save();
+
+            return new CreatePrivateTemplateAnswer(cmd, true, null,
+                    templateInstallFolder + cmd.getUniqueName() + ".qcow2",
+                    info.virtualSize, info.size, cmd.getUniqueName(),
+                    ImageFormat.QCOW2);
+        } catch (LibvirtException e) {
+            s_logger.debug("Failed to get secondary storage pool: "
+                    + e.toString());
+            return new CreatePrivateTemplateAnswer(cmd, false, e.toString());
+        } catch (InternalErrorException e) {
+            return new CreatePrivateTemplateAnswer(cmd, false, e.toString());
+        } catch (IOException e) {
+            return new CreatePrivateTemplateAnswer(cmd, false, e.toString());
+        } catch (ConfigurationException e) {
+            return new CreatePrivateTemplateAnswer(cmd, false, e.toString());
+        } catch (CloudRuntimeException e) {
+            return new CreatePrivateTemplateAnswer(cmd, false, e.toString());
+        } finally {
+            if (secondaryStorage != null) {
+                secondaryStorage.delete();
+            }
+        }
+    }
+
+    protected PrimaryStorageDownloadAnswer execute(
+            final PrimaryStorageDownloadCommand cmd) {
+        String tmplturl = cmd.getUrl();
+        int index = tmplturl.lastIndexOf("/");
+        String mountpoint = tmplturl.substring(0, index);
+        String tmpltname = null;
+        if (index < tmplturl.length() - 1) {
+            tmpltname = tmplturl.substring(index + 1);
+        }
+
+        KVMPhysicalDisk tmplVol = null;
+        KVMStoragePool secondaryPool = null;
+        try {
+            secondaryPool = _storagePoolMgr.getStoragePoolByURI(mountpoint);
+
+            /* Get template vol */
+            if (tmpltname == null) {
+                secondaryPool.refresh();
+                List<KVMPhysicalDisk> disks = secondaryPool.listPhysicalDisks();
+                if (disks == null || disks.isEmpty()) {
+                    return new PrimaryStorageDownloadAnswer(
+                            "Failed to get volumes from pool: "
+                                    + secondaryPool.getUuid());
+                }
+                for (KVMPhysicalDisk disk : disks) {
+                    if (disk.getName().endsWith("qcow2")) {
+                        tmplVol = disk;
+                        break;
+                    }
+                }
+                if (tmplVol == null) {
+                    return new PrimaryStorageDownloadAnswer(
+                            "Failed to get template from pool: "
+                                    + secondaryPool.getUuid());
+                }
+            } else {
+                tmplVol = secondaryPool.getPhysicalDisk(tmpltname);
+            }
+
+            /* Copy volume to primary storage */
+            KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd
+                    .getPoolUuid());
+
+            KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(
+                    tmplVol, UUID.randomUUID().toString(), primaryPool);
+
+            return new PrimaryStorageDownloadAnswer(primaryVol.getName(),
+                    primaryVol.getSize());
+        } catch (CloudRuntimeException e) {
+            return new PrimaryStorageDownloadAnswer(e.toString());
+        } finally {
+            if (secondaryPool != null) {
+                secondaryPool.delete();
+            }
+        }
+    }
+
+    protected Answer execute(CreateStoragePoolCommand cmd) {
+        return new Answer(cmd, true, "success");
+    }
+
+    protected Answer execute(ModifyStoragePoolCommand cmd) {
+        KVMStoragePool storagepool = _storagePoolMgr.createStoragePool(cmd
+                .getPool().getUuid(), cmd.getPool().getHost(), cmd.getPool().getPort(),
+                cmd.getPool().getPath(), cmd.getPool().getUserInfo(), cmd.getPool().getType());
+        if (storagepool == null) {
+            return new Answer(cmd, false, " Failed to create storage pool");
+        }
+
+        Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
+        ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd,
+                storagepool.getCapacity(), storagepool.getUsed(), tInfo);
+
+        return answer;
+    }
+
+    private Answer execute(SecurityGroupRulesCmd cmd) {
+        String vif = null;
+        String brname = null;
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+            List<InterfaceDef> nics = getInterfaces(conn, cmd.getVmName());
+            vif = nics.get(0).getDevName();
+            brname = nics.get(0).getBrName();
+        } catch (LibvirtException e) {
+            return new SecurityGroupRuleAnswer(cmd, false, e.toString());
+        }
+
+        boolean result = add_network_rules(cmd.getVmName(),
+                Long.toString(cmd.getVmId()), cmd.getGuestIp(),
+                cmd.getSignature(), Long.toString(cmd.getSeqNum()),
+                cmd.getGuestMac(), cmd.stringifyRules(), vif, brname);
+
+        if (!result) {
+            s_logger.warn("Failed to program network rules for vm "
+                    + cmd.getVmName());
+            return new SecurityGroupRuleAnswer(cmd, false,
+                    "programming network rules failed");
+        } else {
+            s_logger.debug("Programmed network rules for vm " + cmd.getVmName()
+                    + " guestIp=" + cmd.getGuestIp() + ",ingress numrules="
+                    + cmd.getIngressRuleSet().length + ",egress numrules="
+                    + cmd.getEgressRuleSet().length);
+            return new SecurityGroupRuleAnswer(cmd);
+        }
+    }
+
+    private Answer execute(CleanupNetworkRulesCmd cmd) {
+        boolean result = cleanup_rules();
+        return new Answer(cmd, result, "");
+    }
+
+    protected GetVncPortAnswer execute(GetVncPortCommand cmd) {
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+            Integer vncPort = getVncPort(conn, cmd.getName());
+            return new GetVncPortAnswer(cmd, _privateIp, 5900 + vncPort);
+        } catch (Exception e) {
+            return new GetVncPortAnswer(cmd, e.toString());
+        }
+    }
+
+    protected Answer execute(final CheckConsoleProxyLoadCommand cmd) {
+        return executeProxyLoadScan(cmd, cmd.getProxyVmId(),
+                cmd.getProxyVmName(), cmd.getProxyManagementIp(),
+                cmd.getProxyCmdPort());
+    }
+
+    protected Answer execute(final WatchConsoleProxyLoadCommand cmd) {
+        return executeProxyLoadScan(cmd, cmd.getProxyVmId(),
+                cmd.getProxyVmName(), cmd.getProxyManagementIp(),
+                cmd.getProxyCmdPort());
+    }
+
+    protected MaintainAnswer execute(MaintainCommand cmd) {
+        return new MaintainAnswer(cmd);
+    }
+
+    private Answer executeProxyLoadScan(final Command cmd,
+            final long proxyVmId, final String proxyVmName,
+            final String proxyManagementIp, final int cmdPort) {
+        String result = null;
+
+        final StringBuffer sb = new StringBuffer();
+        sb.append("http://").append(proxyManagementIp).append(":" + cmdPort)
+                .append("/cmd/getstatus");
+
+        boolean success = true;
+        try {
+            final URL url = new URL(sb.toString());
+            final URLConnection conn = url.openConnection();
+
+            final InputStream is = conn.getInputStream();
+            final BufferedReader reader = new BufferedReader(
+                    new InputStreamReader(is));
+            final StringBuilder sb2 = new StringBuilder();
+            String line = null;
+            try {
+                while ((line = reader.readLine()) != null) {
+                    sb2.append(line + "\n");
+                }
+                result = sb2.toString();
+            } catch (final IOException e) {
+                success = false;
+            } finally {
+                try {
+                    is.close();
+                } catch (final IOException e) {
+                    s_logger.warn("Exception when closing , console proxy address : "
+                            + proxyManagementIp);
+                    success = false;
+                }
+            }
+        } catch (final IOException e) {
+            s_logger.warn("Unable to open console proxy command port url, console proxy address : "
+                    + proxyManagementIp);
+            success = false;
+        }
+
+        return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success,
+                result);
+    }
+
+    private Answer execute(AttachIsoCommand cmd) {
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+            attachOrDetachISO(conn, cmd.getVmName(), cmd.getIsoPath(),
+                    cmd.isAttach());
+        } catch (LibvirtException e) {
+            return new Answer(cmd, false, e.toString());
+        } catch (URISyntaxException e) {
+            return new Answer(cmd, false, e.toString());
+        } catch (InternalErrorException e) {
+            return new Answer(cmd, false, e.toString());
+        }
+
+        return new Answer(cmd);
+    }
+
+    private AttachVolumeAnswer execute(AttachVolumeCommand cmd) {
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+            KVMStoragePool primary = _storagePoolMgr.getStoragePool(cmd
+                    .getPoolUuid());
+            KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath());
+            attachOrDetachDisk(conn, cmd.getAttach(), cmd.getVmName(), disk,
+                    cmd.getDeviceId().intValue());
+        } catch (LibvirtException e) {
+            return new AttachVolumeAnswer(cmd, e.toString());
+        } catch (InternalErrorException e) {
+            return new AttachVolumeAnswer(cmd, e.toString());
+        }
+
+        return new AttachVolumeAnswer(cmd, cmd.getDeviceId());
+    }
+
+    private Answer execute(ReadyCommand cmd) {
+        return new ReadyAnswer(cmd);
+    }
+
+    protected State convertToState(DomainInfo.DomainState ps) {
+        final State state = s_statesTable.get(ps);
+        return state == null ? State.Unknown : state;
+    }
+
+    protected State getVmState(Connect conn, final String vmName) {
+        int retry = 3;
+        Domain vms = null;
+        while (retry-- > 0) {
+            try {
+                vms = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName
+                        .getBytes()));
+                State s = convertToState(vms.getInfo().state);
+                return s;
+            } catch (final LibvirtException e) {
+                s_logger.warn("Can't get vm state " + vmName + e.getMessage()
+                        + "retry:" + retry);
+            } catch (Exception e) {
+                s_logger.warn("Can't get vm state " + vmName + e.getMessage()
+                        + "retry:" + retry);
+            } finally {
+                try {
+                    if (vms != null) {
+                        vms.free();
+                    }
+                } catch (final LibvirtException e) {
+
+                }
+            }
+        }
+        return State.Stopped;
+    }
+
+    private Answer execute(CheckVirtualMachineCommand cmd) {
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+            final State state = getVmState(conn, cmd.getVmName());
+            Integer vncPort = null;
+            if (state == State.Running) {
+                vncPort = getVncPort(conn, cmd.getVmName());
+
+                synchronized (_vms) {
+                    _vms.put(cmd.getVmName(), State.Running);
+                }
+            }
+
+            return new CheckVirtualMachineAnswer(cmd, state, vncPort);
+        } catch (LibvirtException e) {
+            return new CheckVirtualMachineAnswer(cmd, e.getMessage());
+        }
+    }
+
+    private Answer execute(PingTestCommand cmd) {
+        String result = null;
+        final String computingHostIp = cmd.getComputingHostIp(); // TODO, split
+                                                                    // the
+                                                                    // command
+                                                                    // into 2
+                                                                    // types
+
+        if (computingHostIp != null) {
+            result = doPingTest(computingHostIp);
+        } else if (cmd.getRouterIp() != null && cmd.getPrivateIp() != null) {
+            result = doPingTest(cmd.getRouterIp(), cmd.getPrivateIp());
+        } else {
+            return new Answer(cmd, false, "routerip and private ip is null");
+        }
+
+        if (result != null) {
+            return new Answer(cmd, false, result);
+        }
+        return new Answer(cmd);
+    }
+
+    private String doPingTest(final String computingHostIp) {
+        final Script command = new Script(_pingTestPath, 10000, s_logger);
+        command.add("-h", computingHostIp);
+        return command.execute();
+    }
+
+    private String doPingTest(final String domRIp, final String vmIp) {
+        final Script command = new Script(_pingTestPath, 10000, s_logger);
+        command.add("-i", domRIp);
+        command.add("-p", vmIp);
+        return command.execute();
+    }
+
+    private synchronized Answer execute(MigrateCommand cmd) {
+        String vmName = cmd.getVmName();
+
+        State state = null;
+        String result = null;
+        synchronized (_vms) {
+            state = _vms.get(vmName);
+            _vms.put(vmName, State.Stopping);
+        }
+
+        Domain dm = null;
+        Connect dconn = null;
+        Domain destDomain = null;
+        Connect conn = null;
+        try {
+            conn = LibvirtConnection.getConnection();
+            dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName
+                    .getBytes()));
+            dconn = new Connect("qemu+tcp://" + cmd.getDestinationIp()
+                    + "/system");
+            /*
+             * Hard code lm flags: VIR_MIGRATE_LIVE(1<<0) and
+             * VIR_MIGRATE_PERSIST_DEST(1<<3)
+             */
+            destDomain = dm.migrate(dconn, (1 << 0) | (1 << 3), vmName, "tcp:"
+                    + cmd.getDestinationIp(), _migrateSpeed);
+        } catch (LibvirtException e) {
+            s_logger.debug("Can't migrate domain: " + e.getMessage());
+            result = e.getMessage();
+        } catch (Exception e) {
+            s_logger.debug("Can't migrate domain: " + e.getMessage());
+            result = e.getMessage();
+        } finally {
+            try {
+                if (dm != null) {
+                    dm.free();
+                }
+                if (dconn != null) {
+                    dconn.close();
+                }
+                if (destDomain != null) {
+                    destDomain.free();
+                }
+            } catch (final LibvirtException e) {
+
+            }
+        }
+
+        if (result != null) {
+            synchronized (_vms) {
+                _vms.put(vmName, state);
+            }
+        } else {
+            destroy_network_rules_for_vm(conn, vmName);
+            cleanupVM(conn, vmName,
+                    getVnetId(VirtualMachineName.getVnet(vmName)));
+        }
+
+        return new MigrateAnswer(cmd, result == null, result, null);
+    }
+
+    private synchronized Answer execute(PrepareForMigrationCommand cmd) {
+
+        VirtualMachineTO vm = cmd.getVirtualMachine();
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Preparing host for migrating " + vm);
+        }
+
+        NicTO[] nics = vm.getNics();
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+            for (NicTO nic : nics) {
+                String vlanId = null;
+                i

<TRUNCATED>