// 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.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;

import com.cloud.hypervisor.Hypervisor;
import com.cloud.hypervisor.Hypervisor.HypervisorType;

public class LibvirtConnection {
    private static final Logger s_logger = Logger.getLogger(LibvirtConnection.class);
    static private Map<String, Connect> s_connections = new HashMap<String, Connect>();

    static private Connect s_connection;
    static private String s_hypervisorURI;

    static public Connect getConnection() throws LibvirtException {
        return getConnection(s_hypervisorURI);
    }

    static public Connect getConnection(String hypervisorURI) throws LibvirtException {
        Connect conn = s_connections.get(hypervisorURI);

        if (conn == null) {
            conn = new Connect(hypervisorURI, false);
            s_connections.put(hypervisorURI, conn);
        } else {
            try {
                conn.getVersion();
            } catch (LibvirtException e) {
                s_logger.debug("Connection with libvirtd is broken, due to " + e.getMessage());
                conn = new Connect(hypervisorURI, false);
                s_connections.put(hypervisorURI, conn);
            }
        }

        return conn;
    }

    static public Connect getConnectionByVmName(String vmName) throws LibvirtException {
        HypervisorType[] hypervisors = new HypervisorType[] {HypervisorType.KVM, Hypervisor.HypervisorType.LXC};

        for (HypervisorType hypervisor : hypervisors) {
            try {
                Connect conn = LibvirtConnection.getConnectionByType(hypervisor.toString());
                if (conn.domainLookupByName(vmName) != null) {
                    return conn;
                }
            } catch (Exception e) {
                s_logger.debug("can't find connection: " + hypervisor.toString() + ", for vm: " + vmName + ", continue");
            }
        }

        s_logger.debug("can't find which hypervisor the vm used , then use the default hypervisor");
        // return the default connection
        return getConnection();
    }

    static public Connect getConnectionByType(String hypervisorType) throws LibvirtException {
        return getConnection(getHypervisorURI(hypervisorType));
    }

    static void initialize(String hypervisorURI) {
        s_hypervisorURI = hypervisorURI;
    }

    static String getHypervisorURI(String hypervisorType) {
        if ("LXC".equalsIgnoreCase(hypervisorType)) {
            return "lxc:///";
        } else {
            return "qemu:///system";
        }
    }
}

@@ -1576,32 +1576,112 @@
 virtException %7B%0A
+        s_logger.debug(%22Looking for libvirtd connection at: %22 + hypervisorURI);%0A
         Connect 
@@ -1766,47 +1766,220 @@
     
-conn = new Connect(hypervisorURI, false
+s_logger.info(%22No existing libvirtd connection found. Opening a new one%22);%0A            conn = new Connect(hypervisorURI, false);%0A            s_logger.debug(%22Successfully connected to libvirt at: %22 + hypervisorURI
 );%0A 
@@ -2167,21 +2167,21 @@
 _logger.
-debug
+error
 (%22Connec
@@ -2212,16 +2212,9 @@
 oken
-, due to
+:
  %22 +
@@ -2227,24 +2227,114 @@
 Message());%0A
+                s_logger.debug(%22Opening a new libvirtd connection to: %22 + hypervisorURI);%0A
             
@@ -3044,30 +3044,20 @@
 ug(%22
-can't find connection:
+Can not find
  %22 +
@@ -3086,16 +3086,32 @@
  + %22
-, for vm
+ connection for Instance
 : %22 
@@ -3131,17 +3131,20 @@
  continu
-e
+ing.
 %22);%0A    
@@ -3185,65 +3185,77 @@
 ger.
-debug(%22can'
+warn(%22Can no
 t find 
-which hypervisor the vm used , then use
+a connection for Instance %22 + vmName + %22. Assuming
  the
@@ -3263,26 +3263,27 @@
 default 
-hypervisor
+connection.
 %22);%0A    

Add more verbose logging about what is happening with Libvirt connections