void PoolEmergencyTransitionToMaster(String slaveIp, String username, Queue<String> password) {
    if (!s_managePool) {
      if (s_logger.isDebugEnabled()) {
        s_logger.debug("Don't manage pool on error so sleeping for " + s_sleepOnError);
        try {
          Thread.sleep(s_sleepOnError);
        } catch (InterruptedException ie) {
        }
      }
      return;
    }

    Connection slaveConn = null;
    Connection c = null;
    try {
      s_logger.debug("Trying to transition master to " + slaveIp);
      slaveConn = new Connection(getURL(slaveIp), 10);
      slaveLocalLoginWithPassword(slaveConn, username, password);
      Pool.emergencyTransitionToMaster(slaveConn);
      // restart xapi in 10 sec
      forceSleep(10);
      // check if the master of this host is set correctly.
      c = new Connection(getURL(slaveIp), 10);
      for (int i = 0; i < 30; i++) {
        try {
          loginWithPassword(c, username, password, APIVersion.latest().toString());
          s_logger.debug("Succeeded to transition master to " + slaveIp);
          return;
        } catch (Types.HostIsSlave e) {
          s_logger.debug("HostIsSlave: Still waiting for the conversion to the master " + slaveIp);
        } catch (Exception e) {
          s_logger.debug("Exception: Still waiting for the conversion to the master");
        }
        forceSleep(2);
      }
      throw new RuntimeException("EmergencyTransitionToMaster failed after retry 30 times");
    } catch (Exception e) {
      throw new RuntimeException("EmergencyTransitionToMaster failed due to " + e.getMessage());
    } finally {
      localLogout(slaveConn);
      slaveConn = null;
      if (c != null) {
        try {
          Session.logout(c);
          c.dispose();
        } catch (Exception e) {
        }
      }
    }
  }
 private void localLogout(Connection conn) {
   if (conn == null) return;
   try {
     if (s_logger.isTraceEnabled()) {
       s_logger.trace("Logging out of the session " + conn.getSessionReference());
     }
     Session.localLogout(conn);
   } catch (Exception e) {
     s_logger.debug("localLogout has problem " + e.getMessage());
   } finally {
     conn.dispose();
     conn = null;
   }
 }
  protected Session loginWithPassword(
      Connection conn, String username, Queue<String> password, String version)
      throws BadServerResponse, XenAPIException, XmlRpcException {
    Session s = null;
    boolean logged_in = false;
    Exception ex = null;
    while (!logged_in) {
      try {
        s =
            Session.loginWithPassword(
                conn, username, password.peek(), APIVersion.latest().toString());
        logged_in = true;
      } catch (BadServerResponse e) {
        logged_in = false;
        ex = e;
      } catch (XenAPIException e) {
        logged_in = false;
        ex = e;
      } catch (XmlRpcException e) {
        logged_in = false;
        ex = e;
      }

      if (logged_in && conn != null) {
        break;
      } else {
        if (password.size() > 1) {
          password.remove();
          continue;
        } else {
          // the last password did not work leave it and flag error
          if (ex instanceof BadServerResponse) {
            throw (BadServerResponse) ex;
          } else if (ex instanceof XmlRpcException) {
            throw (XmlRpcException) ex;
          } else if (ex instanceof Types.SessionAuthenticationFailed) {
            throw (Types.SessionAuthenticationFailed) ex;
          } else if (ex instanceof XenAPIException) {
            throw (XenAPIException) ex;
          }
        }
      }
    }
    return s;
  }
  public void switchMaster(
      String slaveIp,
      String poolUuid,
      Connection conn,
      Host host,
      String username,
      Queue<String> password,
      int wait)
      throws XmlRpcException, XenAPIException {
    synchronized (poolUuid.intern()) {
      String masterIp = host.getAddress(conn);
      s_logger.debug("Designating the new master to " + masterIp);
      Pool.designateNewMaster(conn, host);
      Connection slaveConn = null;
      Connection masterConn = null;
      int retry = 30;
      for (int i = 0; i < retry; i++) {
        forceSleep(5);
        try {
          if (s_logger.isDebugEnabled()) {
            s_logger.debug("Logging on as the slave to " + slaveIp);
          }
          slaveConn = null;
          masterConn = null;
          Session slaveSession = null;

          slaveConn = new Connection(getURL(slaveIp), 10);
          slaveSession = slaveLocalLoginWithPassword(slaveConn, username, password);

          if (s_logger.isDebugEnabled()) {
            s_logger.debug("Slave logon successful. session= " + slaveSession);
          }

          Pool.Record pr = getPoolRecord(slaveConn);
          Host master = pr.master;
          String ma = master.getAddress(slaveConn);
          if (!ma.trim().equals(masterIp.trim())) {
            continue;
          }
          s_logger.debug("Logging on as the master to " + masterIp);
          masterConn = new Connection(getURL(masterIp), 10);
          loginWithPassword(masterConn, username, password, APIVersion.latest().toString());
          removeConnect(poolUuid);
          ensurePoolIntegrity(masterConn, masterIp, username, password, wait);
          return;
        } catch (Types.HostIsSlave e) {
          s_logger.debug("HostIsSlaveException: Still waiting for the conversion to the master");
        } catch (XmlRpcException e) {
          s_logger.debug(
              "XmlRpcException: Still waiting for the conversion to the master " + e.getMessage());
        } catch (Exception e) {
          s_logger.debug(
              "Exception: Still waiting for the conversion to the master" + e.getMessage());
        } finally {
          if (masterConn != null) {
            try {
              Session.logout(masterConn);
            } catch (Exception e) {
              s_logger.debug("Unable to log out of session: " + e.getMessage());
            }
            masterConn.dispose();
            masterConn = null;
          }
          localLogout(slaveConn);
          slaveConn = null;
        }
      }
      throw new CloudRuntimeException(
          "Unable to logon to the new master after " + retry + " retries");
    }
  }
  public boolean joinPool(
      Connection conn, String hostIp, String masterIp, String username, Queue<String> password) {
    try {
      join(conn, masterIp, username, password);
      if (s_logger.isDebugEnabled()) {
        s_logger.debug("Host(" + hostIp + ") Join the pool at " + masterIp);
      }
      try {
        // slave will restart xapi in 10 sec
        Thread.sleep(10000);
      } catch (InterruptedException e) {
      }
      for (int i = 0; i < 15; i++) {
        Connection slaveConn = null;
        Session slaveSession = null;
        try {
          if (s_logger.isDebugEnabled()) {
            s_logger.debug("Logging on as the slave to " + hostIp);
          }
          slaveConn = new Connection(getURL(hostIp), 10);
          slaveSession = slaveLocalLoginWithPassword(slaveConn, username, password);
          if (s_logger.isDebugEnabled()) {
            s_logger.debug("Slave logon successful. session= " + slaveSession);
          }
          Pool.Record pr = getPoolRecord(slaveConn);
          Host master = pr.master;
          String ma = master.getAddress(slaveConn);
          if (ma.trim().equals(masterIp.trim())) {
            if (s_logger.isDebugEnabled()) {
              s_logger.debug("Host(" + hostIp + ") Joined the pool at " + masterIp);
            }
            return true;
          }
        } catch (Exception e) {
        } finally {
          if (slaveSession != null) {
            try {
              Session.logout(slaveConn);
            } catch (Exception e) {
            }
            slaveConn.dispose();
          }
        }
        try {
          Thread.sleep(3000);
        } catch (InterruptedException e) {
        }
      }

    } catch (Exception e) {
      String msg =
          "Catch "
              + e.getClass().getName()
              + " Unable to allow host "
              + hostIp
              + " to join pool "
              + masterIp
              + " due to "
              + e.toString();
      s_logger.warn(msg, e);
    }
    if (s_logger.isDebugEnabled()) {
      s_logger.debug("Host(" + hostIp + ") unable to Join the pool at " + masterIp);
    }
    return false;
  }