You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2013/10/29 04:53:17 UTC

[27/50] [abbrv] Extend support of CloudStack-managed storage to KVM

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/858ce766/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
index f1ac3b3..038e89b 100644
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
@@ -18,6 +18,8 @@
  */
 package org.apache.cloudstack.storage.datastore.lifecycle;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
 
@@ -33,54 +35,62 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
 import org.apache.cloudstack.storage.datastore.util.SolidFireUtil;
 import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
+import org.apache.log4j.Logger;
 
 import com.cloud.dc.DataCenterVO;
 import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.host.HostVO;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.resource.ResourceManager;
+import com.cloud.storage.StorageManager;
 import com.cloud.storage.StoragePoolAutomation;
 import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.utils.exception.CloudRuntimeException;
 
 public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeCycle {
-    @Inject PrimaryDataStoreDao storagePoolDao;
-    @Inject PrimaryDataStoreHelper dataStoreHelper;
-    @Inject StoragePoolAutomation storagePoolAutomation;
-    @Inject StoragePoolDetailsDao storagePoolDetailsDao;
-    @Inject DataCenterDao zoneDao;
-    
+    private static final Logger s_logger = Logger.getLogger(SolidFirePrimaryDataStoreLifeCycle.class);
+
+    @Inject private DataCenterDao zoneDao;
+    @Inject private PrimaryDataStoreDao storagePoolDao;
+    @Inject private PrimaryDataStoreHelper dataStoreHelper;
+    @Inject private ResourceManager _resourceMgr;
+    @Inject StorageManager _storageMgr;
+    @Inject private StoragePoolAutomation storagePoolAutomation;
+    @Inject private StoragePoolDetailsDao storagePoolDetailsDao;
+
     private static final int DEFAULT_MANAGEMENT_PORT = 443;
     private static final int DEFAULT_STORAGE_PORT = 3260;
-    
+
     // invoked to add primary storage that is based on the SolidFire plug-in
     @Override
     public DataStore initialize(Map<String, Object> dsInfos) {
-    	String url = (String)dsInfos.get("url");
-    	Long zoneId = (Long)dsInfos.get("zoneId");
+        String url = (String)dsInfos.get("url");
+        Long zoneId = (Long)dsInfos.get("zoneId");
         String storagePoolName = (String) dsInfos.get("name");
         String providerName = (String)dsInfos.get("providerName");
         Long capacityBytes = (Long)dsInfos.get("capacityBytes");
         Long capacityIops = (Long)dsInfos.get("capacityIops");
         String tags = (String)dsInfos.get("tags");
         Map<String, String> details = (Map<String, String>)dsInfos.get("details");
-    	
-    	String storageVip = getStorageVip(url);
-    	int storagePort = getStoragePort(url);
-    	
-    	DataCenterVO zone = zoneDao.findById(zoneId);
-    	
-    	String uuid = SolidFireUtil.PROVIDER_NAME + "_" + zone.getUuid() + "_" + storageVip;
+
+        String storageVip = getStorageVip(url);
+        int storagePort = getStoragePort(url);
+
+        DataCenterVO zone = zoneDao.findById(zoneId);
+
+        String uuid = SolidFireUtil.PROVIDER_NAME + "_" + zone.getUuid() + "_" + storageVip;
 
         if (capacityBytes == null || capacityBytes <= 0) {
             throw new IllegalArgumentException("'capacityBytes' must be present and greater than 0.");
         }
-    	
-    	if (capacityIops == null || capacityIops <= 0) {
-    	    throw new IllegalArgumentException("'capacityIops' must be present and greater than 0.");
-    	}
-    	
+
+        if (capacityIops == null || capacityIops <= 0) {
+            throw new IllegalArgumentException("'capacityIops' must be present and greater than 0.");
+        }
+
         PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters();
-        
+
         parameters.setHost(storageVip);
         parameters.setPort(storagePort);
         parameters.setPath(getModifiedUrl(url));
@@ -96,16 +106,16 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
         parameters.setHypervisorType(HypervisorType.Any);
         parameters.setTags(tags);
         parameters.setDetails(details);
-        
+
         String managementVip = getManagementVip(url);
         int managementPort = getManagementPort(url);
-        
+
         details.put(SolidFireUtil.MANAGEMENT_VIP, managementVip);
         details.put(SolidFireUtil.MANAGEMENT_PORT, String.valueOf(managementPort));
-        
+
         String clusterAdminUsername = getValue(SolidFireUtil.CLUSTER_ADMIN_USERNAME, url);
         String clusterAdminPassword = getValue(SolidFireUtil.CLUSTER_ADMIN_PASSWORD, url);
-        
+
         details.put(SolidFireUtil.CLUSTER_ADMIN_USERNAME, clusterAdminUsername);
         details.put(SolidFireUtil.CLUSTER_ADMIN_PASSWORD, clusterAdminPassword);
 
@@ -171,144 +181,158 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
         // this adds a row in the cloud.storage_pool table for this SolidFire cluster
     	return dataStoreHelper.createPrimaryDataStore(parameters);
     }
-    
+
     // remove the clusterAdmin and password key/value pairs
     private String getModifiedUrl(String originalUrl)
     {
-    	StringBuilder sb = new StringBuilder();
-    	
-    	String delimiter = ";";
-    	
-    	StringTokenizer st = new StringTokenizer(originalUrl, delimiter);
-    	
-    	while (st.hasMoreElements()) {
-			String token = st.nextElement().toString().toUpperCase();
-			
-			if (token.startsWith(SolidFireUtil.MANAGEMENT_VIP.toUpperCase()) ||
-				token.startsWith(SolidFireUtil.STORAGE_VIP.toUpperCase())) {
-				sb.append(token).append(delimiter);
-			}
-    	}
-    	
-    	String modifiedUrl = sb.toString();
-    	int lastIndexOf = modifiedUrl.lastIndexOf(delimiter);
-    	
-    	if (lastIndexOf == (modifiedUrl.length() - delimiter.length())) {
-    		return modifiedUrl.substring(0, lastIndexOf);
-    	}
-    	
-    	return modifiedUrl;
+        StringBuilder sb = new StringBuilder();
+
+        String delimiter = ";";
+
+        StringTokenizer st = new StringTokenizer(originalUrl, delimiter);
+
+        while (st.hasMoreElements()) {
+            String token = st.nextElement().toString().toUpperCase();
+
+            if (token.startsWith(SolidFireUtil.MANAGEMENT_VIP.toUpperCase()) ||
+                token.startsWith(SolidFireUtil.STORAGE_VIP.toUpperCase())) {
+                sb.append(token).append(delimiter);
+            }
+        }
+
+        String modifiedUrl = sb.toString();
+        int lastIndexOf = modifiedUrl.lastIndexOf(delimiter);
+
+        if (lastIndexOf == (modifiedUrl.length() - delimiter.length())) {
+            return modifiedUrl.substring(0, lastIndexOf);
+        }
+
+        return modifiedUrl;
     }
-    
+
     private String getManagementVip(String url)
     {
     	return getVip(SolidFireUtil.MANAGEMENT_VIP, url);
     }
-    
+
     private String getStorageVip(String url)
     {
     	return getVip(SolidFireUtil.STORAGE_VIP, url);
     }
-    
+
     private int getManagementPort(String url)
     {
     	return getPort(SolidFireUtil.MANAGEMENT_VIP, url, DEFAULT_MANAGEMENT_PORT);
     }
-    
+
     private int getStoragePort(String url)
     {
     	return getPort(SolidFireUtil.STORAGE_VIP, url, DEFAULT_STORAGE_PORT);
     }
-    
+
     private String getVip(String keyToMatch, String url)
     {
-    	String delimiter = ":";
-    	
-    	String storageVip = getValue(keyToMatch, url);
-    	
-    	int index = storageVip.indexOf(delimiter);
-    	
-    	if (index != -1)
-    	{
-    		return storageVip.substring(0, index);
-    	}
-    	
-    	return storageVip;
+        String delimiter = ":";
+
+        String storageVip = getValue(keyToMatch, url);
+
+        int index = storageVip.indexOf(delimiter);
+
+        if (index != -1)
+        {
+            return storageVip.substring(0, index);
+        }
+
+        return storageVip;
     }
-    
+
     private int getPort(String keyToMatch, String url, int defaultPortNumber)
     {
-    	String delimiter = ":";
-    	
-    	String storageVip = getValue(keyToMatch, url);
-    	
-    	int index = storageVip.indexOf(delimiter);
-    	
-    	int portNumber = defaultPortNumber;
-    	
-    	if (index != -1) {
-    		String port = storageVip.substring(index + delimiter.length());
-    		
-    		try {
-    			portNumber = Integer.parseInt(port);
-    		}
-    		catch (NumberFormatException ex) {
-    			throw new IllegalArgumentException("Invalid URL format (port is not an integer)");
-    		}
-    	}
-    	
-    	return portNumber;
+        String delimiter = ":";
+
+        String storageVip = getValue(keyToMatch, url);
+
+        int index = storageVip.indexOf(delimiter);
+
+        int portNumber = defaultPortNumber;
+
+        if (index != -1) {
+            String port = storageVip.substring(index + delimiter.length());
+
+            try {
+                portNumber = Integer.parseInt(port);
+            }
+            catch (NumberFormatException ex) {
+                throw new IllegalArgumentException("Invalid URL format (port is not an integer)");
+            }
+        }
+
+        return portNumber;
     }
-    
+
     private String getValue(String keyToMatch, String url)
     {
-    	String delimiter1 = ";";
-    	String delimiter2 = "=";
-    	
-    	StringTokenizer st = new StringTokenizer(url, delimiter1);
-    	
-    	while (st.hasMoreElements()) {
-			String token = st.nextElement().toString();
-			
-			int index = token.indexOf(delimiter2);
-			
-			if (index == -1)
-			{
-				throw new RuntimeException("Invalid URL format");
-			}
-			
-			String key = token.substring(0, index);
-			
-			if (key.equalsIgnoreCase(keyToMatch)) {
-				String valueToReturn = token.substring(index + delimiter2.length());
-				
-				return valueToReturn;
-			}
-		}
-    	
-    	throw new RuntimeException("Key not found in URL");
+        String delimiter1 = ";";
+        String delimiter2 = "=";
+
+        StringTokenizer st = new StringTokenizer(url, delimiter1);
+
+        while (st.hasMoreElements()) {
+            String token = st.nextElement().toString();
+
+            int index = token.indexOf(delimiter2);
+
+            if (index == -1)
+            {
+                throw new RuntimeException("Invalid URL format");
+            }
+
+            String key = token.substring(0, index);
+
+            if (key.equalsIgnoreCase(keyToMatch)) {
+                String valueToReturn = token.substring(index + delimiter2.length());
+
+                return valueToReturn;
+            }
+        }
+
+        throw new RuntimeException("Key not found in URL");
     }
-    
+
     // do not implement this method for SolidFire's plug-in
     @Override
     public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) {
         return true; // should be ignored for zone-wide-only plug-ins like SolidFire's
     }
-    
+
     // do not implement this method for SolidFire's plug-in
     @Override
     public boolean attachCluster(DataStore store, ClusterScope scope) {
     	return true; // should be ignored for zone-wide-only plug-ins like SolidFire's
     }
-    
+
     @Override
     public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) {
-    	dataStoreHelper.attachZone(dataStore);
-    	
+        dataStoreHelper.attachZone(dataStore);
+
+        List<HostVO> xenServerHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(HypervisorType.XenServer, scope.getScopeId());
+        List<HostVO> kvmHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(HypervisorType.KVM, scope.getScopeId());
+        List<HostVO> hosts = new ArrayList<HostVO>();
+
+        hosts.addAll(xenServerHosts);
+        hosts.addAll(kvmHosts);
+
+        for (HostVO host : hosts) {
+            try {
+                _storageMgr.connectHostToSharedPool(host.getId(), dataStore.getId());
+            } catch (Exception e) {
+                s_logger.warn("Unable to establish a connection between " + host + " and " + dataStore, e);
+            }
+        }
+
         return true;
     }
 
-    
     @Override
     public boolean maintain(DataStore dataStore) {
         storagePoolAutomation.maintain(dataStore);
@@ -316,7 +340,7 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
         
         return true;
     }
-    
+
     @Override
     public boolean cancelMaintain(DataStore store) {
         dataStoreHelper.cancelMaintain(store);
@@ -324,7 +348,7 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
         
         return true;
     }
-    
+
     // invoked to delete primary storage that is based on the SolidFire plug-in
     @Override
     public boolean deleteDataStore(DataStore store) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/858ce766/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java
new file mode 100644
index 0000000..43e9830
--- /dev/null
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java
@@ -0,0 +1,102 @@
+/*
+ * 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 org.apache.cloudstack.storage.datastore.provider;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.ModifyStoragePoolAnswer;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.alert.AlertManager;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolHostVO;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class SolidFireHostListener implements HypervisorHostListener {
+    private static final Logger s_logger = Logger.getLogger(SolidFireHostListener.class);
+
+    @Inject private AgentManager _agentMgr;
+    @Inject private AlertManager _alertMgr;
+    @Inject private DataStoreManager _dataStoreMgr;
+    @Inject private HostDao _hostDao;
+    @Inject private StoragePoolHostDao storagePoolHostDao;
+
+    @Override
+    public boolean hostConnect(long hostId, long storagePoolId) {
+        HostVO host = _hostDao.findById(hostId);
+
+        StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
+
+        if (storagePoolHost == null) {
+            storagePoolHost = new StoragePoolHostVO(storagePoolId, hostId, "");
+
+            storagePoolHostDao.persist(storagePoolHost);
+        }
+
+        // just want to send the ModifyStoragePoolCommand for KVM
+        if (host.getHypervisorType() != HypervisorType.KVM) {
+            return true;
+        }
+
+        StoragePool storagePool = (StoragePool)_dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+        ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, storagePool);
+
+        Answer answer = _agentMgr.easySend(hostId, cmd);
+
+        if (answer == null) {
+            throw new CloudRuntimeException("Unable to get an answer to the modify storage pool command (" + storagePool.getId() + ")");
+        }
+
+        if (!answer.getResult()) {
+            String msg = "Unable to attach storage pool " + storagePoolId + " to host " + hostId;
+
+            _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, storagePool.getDataCenterId(), storagePool.getPodId(), msg, msg);
+
+            throw new CloudRuntimeException("Unable to establish a connection from agent to storage pool " + storagePool.getId() +
+                    " due to " + answer.getDetails() + " (" + storagePool.getId() + ")");
+        }
+
+        assert (answer instanceof ModifyStoragePoolAnswer) : "ModifyStoragePoolAnswer expected ; Pool = " + storagePool.getId() + " Host = " + hostId;
+
+        s_logger.info("Connection established between storage pool " + storagePool + " and host + " + hostId);
+
+        return true;
+    }
+
+    @Override
+    public boolean hostDisconnected(long hostId, long storagePoolId) {
+        StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
+
+        if (storagePoolHost != null) {
+            storagePoolHostDao.deleteStoragePoolHostDetails(hostId, storagePoolId);
+        }
+
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/858ce766/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java
index 9c784ba..576d1a2 100644
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java
@@ -66,15 +66,7 @@ public class SolidfirePrimaryDataStoreProvider implements PrimaryDataStoreProvid
     public boolean configure(Map<String, Object> params) {
         lifecycle = ComponentContext.inject(SolidFirePrimaryDataStoreLifeCycle.class);
         driver = ComponentContext.inject(SolidfirePrimaryDataStoreDriver.class);
-        listener = ComponentContext.inject(new HypervisorHostListener() {
-            public boolean hostConnect(long hostId, long poolId) {
-                return true;
-            }
-
-            public boolean hostDisconnected(long hostId, long poolId) {
-                return true;
-            }
-        });
+        listener = ComponentContext.inject(SolidFireHostListener.class);
 
         return true;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/858ce766/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index e4c8264..67aa388 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.HashMap;
 import java.util.UUID;
 import java.util.concurrent.ExecutionException;
 
@@ -1231,7 +1232,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
             StoragePoolVO volumePool = _storagePoolDao.findById(volume.getPoolId());
 
             DataTO volTO = volFactory.getVolume(volume.getId()).getTO();
-            DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), null, volume.getVolumeType());
+            DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
 
             DettachCommand cmd = new DettachCommand(disk, vm.getInstanceName());
 
@@ -1605,29 +1606,41 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         if (sendCommand) {
             volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
-            long storagePoolId = volumeToAttachStoragePool.getId();
 
-            DataTO volTO = volFactory.getVolume(volumeToAttach.getId()).getTO();
-            DiskTO disk = new DiskTO(volTO, deviceId, null, volumeToAttach.getVolumeType());
+            HostVO host = _hostDao.findById(hostId);
 
-            AttachCommand cmd = new AttachCommand(disk, vm.getInstanceName());
+            if (host.getHypervisorType() == HypervisorType.KVM &&
+                volumeToAttachStoragePool.isManaged() &&
+                volumeToAttach.getPath() == null) {
+                volumeToAttach.setPath(volumeToAttach.get_iScsiName());
 
-            cmd.setManaged(volumeToAttachStoragePool.isManaged());
+                _volsDao.update(volumeToAttach.getId(), volumeToAttach);
+            }
 
-            cmd.setStorageHost(volumeToAttachStoragePool.getHostAddress());
-            cmd.setStoragePort(volumeToAttachStoragePool.getPort());
+            DataTO volTO = volFactory.getVolume(volumeToAttach.getId()).getTO();
+            DiskTO disk = new DiskTO(volTO, deviceId, volumeToAttach.getPath(), volumeToAttach.getVolumeType());
 
-            cmd.set_iScsiName(volumeToAttach.get_iScsiName());
+            AttachCommand cmd = new AttachCommand(disk, vm.getInstanceName());
 
             VolumeInfo volumeInfo = volFactory.getVolume(volumeToAttach.getId());
-            DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+            DataStore dataStore = dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary);
             ChapInfo chapInfo = volService.getChapInfo(volumeInfo, dataStore);
 
+            Map<String, String> details = new HashMap<String, String>();
+
+            disk.setDetails(details);
+
+            details.put(DiskTO.MANAGED, String.valueOf(volumeToAttachStoragePool.isManaged()));
+            details.put(DiskTO.STORAGE_HOST, volumeToAttachStoragePool.getHostAddress());
+            details.put(DiskTO.STORAGE_PORT, String.valueOf(volumeToAttachStoragePool.getPort()));
+            details.put(DiskTO.VOLUME_SIZE, String.valueOf(volumeToAttach.getSize()));
+            details.put(DiskTO.IQN, volumeToAttach.get_iScsiName());
+
             if (chapInfo != null) {
-                cmd.setChapInitiatorUsername(chapInfo.getInitiatorUsername());
-                cmd.setChapInitiatorPassword(chapInfo.getInitiatorSecret());
-                cmd.setChapTargetUsername(chapInfo.getTargetUsername());
-                cmd.setChapTargetPassword(chapInfo.getTargetSecret());
+                details.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
+                details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
+                details.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
+                details.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
             }
 
             try {
@@ -1646,7 +1659,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
                 volumeToAttach = _volsDao.findById(volumeToAttach.getId());
 
                 if (volumeToAttachStoragePool.isManaged() && volumeToAttach.getPath() == null) {
-                    volumeToAttach.setPath(answer.getDisk().getVdiUuid());
+                    volumeToAttach.setPath(answer.getDisk().getPath());
 
                     _volsDao.update(volumeToAttach.getId(), volumeToAttach);
                 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/858ce766/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
index 2be0c65..e1d0e08 100755
--- a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
+++ b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
@@ -81,6 +81,9 @@ public class StoragePoolMonitor implements Listener {
                 List<StoragePoolVO> zoneStoragePoolsByHypervisor = _poolDao.findZoneWideStoragePoolsByHypervisor(host.getDataCenterId(), scCmd.getHypervisorType());
                 zoneStoragePoolsByTags.retainAll(zoneStoragePoolsByHypervisor);
                 pools.addAll(zoneStoragePoolsByTags);
+                List<StoragePoolVO> zoneStoragePoolsByAnyHypervisor = _poolDao.findZoneWideStoragePoolsByHypervisor(host.getDataCenterId(), HypervisorType.Any);
+                pools.addAll(zoneStoragePoolsByAnyHypervisor);
+
                 for (StoragePoolVO pool : pools) {
                     if (pool.getStatus() != StoragePoolStatus.Up) {
                         continue;