@Override
  public boolean attachCluster(DataStore store, ClusterScope scope) {
    PrimaryDataStoreInfo primarystore = (PrimaryDataStoreInfo) store;
    // Check if there is host up in this cluster
    List<HostVO> allHosts =
        _resourceMgr.listAllUpAndEnabledHosts(
            Host.Type.Routing,
            primarystore.getClusterId(),
            primarystore.getPodId(),
            primarystore.getDataCenterId());
    if (allHosts.isEmpty()) {
      primaryDataStoreDao.expunge(primarystore.getId());
      throw new CloudRuntimeException(
          "No host up to associate a storage pool with in cluster " + primarystore.getClusterId());
    }

    if (primarystore.getPoolType() == StoragePoolType.OCFS2
        && !_ocfs2Mgr.prepareNodes(allHosts, primarystore)) {
      s_logger.warn(
          "Can not create storage pool "
              + primarystore
              + " on cluster "
              + primarystore.getClusterId());
      primaryDataStoreDao.expunge(primarystore.getId());
      return false;
    }

    boolean success = false;
    for (HostVO h : allHosts) {
      success = createStoragePool(h.getId(), primarystore);
      if (success) {
        break;
      }
    }

    s_logger.debug("In createPool Adding the pool to each of the hosts");
    List<HostVO> poolHosts = new ArrayList<HostVO>();
    for (HostVO h : allHosts) {
      try {
        storageMgr.connectHostToSharedPool(h.getId(), primarystore.getId());
        poolHosts.add(h);
      } catch (Exception e) {
        s_logger.warn("Unable to establish a connection between " + h + " and " + primarystore, e);
      }
    }

    if (poolHosts.isEmpty()) {
      s_logger.warn(
          "No host can access storage pool "
              + primarystore
              + " on cluster "
              + primarystore.getClusterId());
      primaryDataStoreDao.expunge(primarystore.getId());
      throw new CloudRuntimeException("Failed to access storage pool");
    }

    dataStoreHelper.attachCluster(store);
    return true;
  }
  @DB
  @Override
  public boolean deleteDataStore(DataStore store) {
    List<StoragePoolHostVO> hostPoolRecords = _storagePoolHostDao.listByPoolId(store.getId());
    StoragePool pool = (StoragePool) store;
    boolean deleteFlag = false;
    // find the hypervisor where the storage is attached to.
    HypervisorType hType = null;
    if (hostPoolRecords.size() > 0) {
      hType = getHypervisorType(hostPoolRecords.get(0).getHostId());
    }

    // Remove the SR associated with the Xenserver
    for (StoragePoolHostVO host : hostPoolRecords) {
      DeleteStoragePoolCommand deleteCmd = new DeleteStoragePoolCommand(pool);
      final Answer answer = agentMgr.easySend(host.getHostId(), deleteCmd);

      if (answer != null && answer.getResult()) {
        deleteFlag = true;
        // if host is KVM hypervisor then send deleteStoragepoolcmd to all the kvm hosts.
        if (HypervisorType.KVM != hType) {
          break;
        }
      } else {
        if (answer != null) {
          s_logger.debug("Failed to delete storage pool: " + answer.getResult());
        }
      }
    }

    if (!deleteFlag) {
      throw new CloudRuntimeException("Failed to delete storage pool on host");
    }

    return dataStoreHelper.deletePrimaryDataStore(store);
  }
 @Override
 public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) {
   dataStoreHelper.attachHost(store, scope, existingInfo);
   return true;
 }
  @SuppressWarnings("unchecked")
  @Override
  public DataStore initialize(Map<String, Object> dsInfos) {
    Long clusterId = (Long) dsInfos.get("clusterId");
    Long podId = (Long) dsInfos.get("podId");
    Long zoneId = (Long) dsInfos.get("zoneId");
    String url = (String) dsInfos.get("url");
    String providerName = (String) dsInfos.get("providerName");
    if (clusterId != null && podId == null) {
      throw new InvalidParameterValueException("Cluster id requires pod id");
    }

    PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters();

    URI uri = null;
    try {
      uri = new URI(UriUtils.encodeURIComponent(url));
      if (uri.getScheme() == null) {
        throw new InvalidParameterValueException(
            "scheme is null " + url + ", add nfs:// as a prefix");
      } else if (uri.getScheme().equalsIgnoreCase("nfs")) {
        String uriHost = uri.getHost();
        String uriPath = uri.getPath();
        if (uriHost == null
            || uriPath == null
            || uriHost.trim().isEmpty()
            || uriPath.trim().isEmpty()) {
          throw new InvalidParameterValueException(
              "host or path is null, should be nfs://hostname/path");
        }
      } else if (uri.getScheme().equalsIgnoreCase("sharedMountPoint")) {
        String uriPath = uri.getPath();
        if (uriPath == null) {
          throw new InvalidParameterValueException(
              "host or path is null, should be sharedmountpoint://localhost/path");
        }
      } else if (uri.getScheme().equalsIgnoreCase("rbd")) {
        String uriPath = uri.getPath();
        if (uriPath == null) {
          throw new InvalidParameterValueException(
              "host or path is null, should be rbd://hostname/pool");
        }
      }
    } catch (URISyntaxException e) {
      throw new InvalidParameterValueException(url + " is not a valid uri");
    }

    String tags = (String) dsInfos.get("tags");
    Map<String, String> details = (Map<String, String>) dsInfos.get("details");

    parameters.setTags(tags);
    parameters.setDetails(details);

    String scheme = uri.getScheme();
    String storageHost = uri.getHost();
    String hostPath = uri.getPath();
    Object localStorage = dsInfos.get("localStorage");
    if (localStorage != null) {
      hostPath = hostPath.replaceFirst("/", "");
    }
    String userInfo = uri.getUserInfo();
    int port = uri.getPort();
    if (s_logger.isDebugEnabled()) {
      s_logger.debug(
          "createPool Params @ scheme - "
              + scheme
              + " storageHost - "
              + storageHost
              + " hostPath - "
              + hostPath
              + " port - "
              + port);
    }
    if (scheme.equalsIgnoreCase("nfs")) {
      if (port == -1) {
        port = 2049;
      }
      parameters.setType(StoragePoolType.NetworkFilesystem);
      parameters.setHost(storageHost);
      parameters.setPort(port);
      parameters.setPath(hostPath);
    } else if (scheme.equalsIgnoreCase("file")) {
      if (port == -1) {
        port = 0;
      }
      parameters.setType(StoragePoolType.Filesystem);
      parameters.setHost("localhost");
      parameters.setPort(0);
      parameters.setPath(hostPath);
    } else if (scheme.equalsIgnoreCase("sharedMountPoint")) {
      parameters.setType(StoragePoolType.SharedMountPoint);
      parameters.setHost(storageHost);
      parameters.setPort(0);
      parameters.setPath(hostPath);
    } else if (scheme.equalsIgnoreCase("clvm")) {
      parameters.setType(StoragePoolType.CLVM);
      parameters.setHost(storageHost);
      parameters.setPort(0);
      parameters.setPath(hostPath.replaceFirst("/", ""));
    } else if (scheme.equalsIgnoreCase("rbd")) {
      if (port == -1) {
        port = 6789;
      }
      parameters.setType(StoragePoolType.RBD);
      parameters.setHost(storageHost);
      parameters.setPort(port);
      parameters.setPath(hostPath.replaceFirst("/", ""));
      parameters.setUserInfo(userInfo);
    } else if (scheme.equalsIgnoreCase("PreSetup")) {
      parameters.setType(StoragePoolType.PreSetup);
      parameters.setHost(storageHost);
      parameters.setPort(0);
      parameters.setPath(hostPath);
    } else if (scheme.equalsIgnoreCase("iscsi")) {
      String[] tokens = hostPath.split("/");
      int lun = NumbersUtil.parseInt(tokens[tokens.length - 1], -1);
      if (port == -1) {
        port = 3260;
      }
      if (lun != -1) {
        if (clusterId == null) {
          throw new IllegalArgumentException("IscsiLUN need to have clusters specified");
        }
        hostPath.replaceFirst("/", "");
        parameters.setType(StoragePoolType.IscsiLUN);
        parameters.setHost(storageHost);
        parameters.setPort(port);
        parameters.setPath(hostPath);
      } else {
        for (StoragePoolDiscoverer discoverer : _discoverers) {
          Map<? extends StoragePool, Map<String, String>> pools;
          try {
            pools = discoverer.find(zoneId, podId, uri, details);
          } catch (DiscoveryException e) {
            throw new IllegalArgumentException("Not enough information for discovery " + uri, e);
          }
          if (pools != null) {
            Map.Entry<? extends StoragePool, Map<String, String>> entry =
                pools.entrySet().iterator().next();
            details = entry.getValue();
            break;
          }
        }
      }
    } else if (scheme.equalsIgnoreCase("iso")) {
      if (port == -1) {
        port = 2049;
      }
      parameters.setType(StoragePoolType.ISO);
      parameters.setHost(storageHost);
      parameters.setPort(port);
      parameters.setPath(hostPath);
    } else if (scheme.equalsIgnoreCase("vmfs")) {
      parameters.setType(StoragePoolType.VMFS);
      parameters.setHost("VMFS datastore: " + hostPath);
      parameters.setPort(0);
      parameters.setPath(hostPath);
    } else if (scheme.equalsIgnoreCase("ocfs2")) {
      port = 7777;
      parameters.setType(StoragePoolType.OCFS2);
      parameters.setHost("clustered");
      parameters.setPort(port);
      parameters.setPath(hostPath);
    } else {
      StoragePoolType type = Enum.valueOf(StoragePoolType.class, scheme);

      if (type != null) {
        parameters.setType(type);
        parameters.setHost(storageHost);
        parameters.setPort(0);
        parameters.setPath(hostPath);
      } else {
        s_logger.warn("Unable to figure out the scheme for URI: " + uri);
        throw new IllegalArgumentException("Unable to figure out the scheme for URI: " + uri);
      }
    }

    if (localStorage == null) {
      List<StoragePoolVO> pools = primaryDataStoreDao.listPoolByHostPath(storageHost, hostPath);
      if (!pools.isEmpty() && !scheme.equalsIgnoreCase("sharedmountpoint")) {
        Long oldPodId = pools.get(0).getPodId();
        throw new CloudRuntimeException(
            "Storage pool " + uri + " already in use by another pod (id=" + oldPodId + ")");
      }
    }

    Object existingUuid = dsInfos.get("uuid");
    String uuid = null;

    if (existingUuid != null) {
      uuid = (String) existingUuid;
    } else if (scheme.equalsIgnoreCase("sharedmountpoint") || scheme.equalsIgnoreCase("clvm")) {
      uuid = UUID.randomUUID().toString();
    } else if (scheme.equalsIgnoreCase("PreSetup")) {
      uuid = hostPath.replace("/", "");
    } else {
      uuid = UUID.nameUUIDFromBytes(new String(storageHost + hostPath).getBytes()).toString();
    }

    List<StoragePoolVO> spHandles = primaryDataStoreDao.findIfDuplicatePoolsExistByUUID(uuid);
    if ((spHandles != null) && (spHandles.size() > 0)) {
      if (s_logger.isDebugEnabled()) {
        s_logger.debug("Another active pool with the same uuid already exists");
      }
      throw new CloudRuntimeException("Another active pool with the same uuid already exists");
    }

    String poolName = (String) dsInfos.get("name");

    parameters.setUuid(uuid);
    parameters.setZoneId(zoneId);
    parameters.setPodId(podId);
    parameters.setName(poolName);
    parameters.setClusterId(clusterId);
    parameters.setProviderName(providerName);

    return dataStoreHelper.createPrimaryDataStore(parameters);
  }