From 00268632acdf0dcfd20ef356a5e62862ab80de7d Mon Sep 17 00:00:00 2001 From: Edison Su Date: Tue, 7 Jun 2011 20:20:31 -0400 Subject: [PATCH] bug 10177: fix multiple local secondary storage: when we starting vm, only choose the local secondary storage that related to the planned computing host status 10177: resolved, fixed --- .../src/com/cloud/api/ApiResponseHelper.java | 13 ++++++- .../src/com/cloud/storage/StorageManager.java | 2 +- .../com/cloud/storage/StorageManagerImpl.java | 17 ++++++++- .../AbstractStoragePoolAllocator.java | 2 +- .../cloud/storage/dao/VMTemplateHostDao.java | 2 + .../storage/dao/VMTemplateHostDaoImpl.java | 37 ++++++++++++++++--- .../cloud/template/TemplateManagerImpl.java | 2 +- 7 files changed, 64 insertions(+), 11 deletions(-) diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 3a605df2268..160b7fc59fa 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1456,16 +1456,28 @@ public class ApiResponseHelper implements ResponseGenerator { VMTemplateVO template = ApiDBUtils.findTemplateById(templateZonePair.first()); for (VMTemplateHostVO templateHostRef : templateHostRefsForTemplate) { + if (readyOnly) { if (templateHostRef.getDownloadState() != Status.DOWNLOADED) { continue; } + boolean foundTheSameTemplate = false; for (TemplateResponse res : responses) { if (res.getId() == templateHostRef.getTemplateId()) { + foundTheSameTemplate = true; continue; } } + if (foundTheSameTemplate) { + continue; + } } + + HostVO host = ApiDBUtils.findHostById(templateHostRef.getHostId()); + if (host.getType() == Host.Type.LocalSecondaryStorage && host.getStatus() != com.cloud.host.Status.Up) { + continue; + } + TemplateResponse templateResponse = new TemplateResponse(); templateResponse.setId(template.getId()); templateResponse.setName(template.getName()); @@ -1501,7 +1513,6 @@ public class ApiResponseHelper implements ResponseGenerator { templateResponse.setDomainName(ApiDBUtils.findDomainById(owner.getDomainId()).getName()); } - HostVO host = ApiDBUtils.findHostById(templateHostRef.getHostId()); templateResponse.setHostId(host.getId()); templateResponse.setHostName(host.getName()); diff --git a/server/src/com/cloud/storage/StorageManager.java b/server/src/com/cloud/storage/StorageManager.java index 463e9d836d1..ec1dbd45774 100755 --- a/server/src/com/cloud/storage/StorageManager.java +++ b/server/src/com/cloud/storage/StorageManager.java @@ -79,7 +79,7 @@ public interface StorageManager extends Manager { * @param zoneId * @return secondary storage host */ - public VMTemplateHostVO findVmTemplateHost(long templateId, long dcId, Long podId); + public VMTemplateHostVO findVmTemplateHost(long templateId, StoragePool pool); /** * Moves a volume from its current storage pool to a storage pool with enough capacity in the specified zone, pod, or cluster diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 07d54421bec..5f6c17ff394 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -182,6 +182,7 @@ import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; + import java.util.Random; @Local(value = { StorageManager.class, StorageService.class }) @@ -2964,7 +2965,21 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag } @Override - public VMTemplateHostVO findVmTemplateHost(long templateId, long dcId, Long podId) { + public VMTemplateHostVO findVmTemplateHost(long templateId, StoragePool pool) { + long dcId = pool.getDataCenterId(); + Long podId = pool.getPodId(); + + //FIXME, for cloudzone, the local secondary storoge + if (pool.isLocal() && pool.getPoolType() == StoragePoolType.Filesystem) { + List sphs = _storagePoolHostDao.listByPoolId(pool.getId()); + if (!sphs.isEmpty()) { + StoragePoolHostVO localStoragePoolHost = sphs.get(0); + return _templateHostDao.findLocalSecondaryStorageByHostTemplate(localStoragePoolHost.getHostId(), templateId); + } else { + return null; + } + } + List secHosts = _hostDao.listSecondaryStorageHosts(dcId); if (secHosts.size() == 1) { VMTemplateHostVO templateHostVO = _templateHostDao.findByHostTemplate(secHosts.get(0).getId(), templateId); diff --git a/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java index 8d7f6f31db2..872a95a26c7 100755 --- a/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java +++ b/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java @@ -228,7 +228,7 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement if ((template != null) && !tmpinstalled) { // If the template that was passed into this allocator is not installed in the storage pool, // add 3 * (template size on secondary storage) to the running total - VMTemplateHostVO templateHostVO = _storageMgr.findVmTemplateHost(template.getId(), plan.getDataCenterId(), plan.getPodId()); + VMTemplateHostVO templateHostVO = _storageMgr.findVmTemplateHost(template.getId(), pool); if (templateHostVO == null) { s_logger.info("Did not find template downloaded on secondary hosts in zone " + plan.getDataCenterId()); diff --git a/server/src/com/cloud/storage/dao/VMTemplateHostDao.java b/server/src/com/cloud/storage/dao/VMTemplateHostDao.java index d03ac1322b8..9f4aba0a7f9 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateHostDao.java +++ b/server/src/com/cloud/storage/dao/VMTemplateHostDao.java @@ -59,5 +59,7 @@ public interface VMTemplateHostDao extends GenericDao { List listByZoneTemplate(long dcId, long templateId, boolean readyOnly); void deleteByHost(Long hostId); + + VMTemplateHostVO findLocalSecondaryStorageByHostTemplate(long hostId, long templateId); } diff --git a/server/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java index 15021f7f0fb..9bf79300327 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java @@ -32,6 +32,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.VMTemplateHostVO; @@ -58,6 +59,7 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase TemplateStatusSearch; protected final SearchBuilder TemplateStatesSearch; protected SearchBuilder ZONE_TEMPLATE_SEARCH; + protected SearchBuilder LOCAL_SECONDARY_STORAGE_SEARCH; protected static final String UPDATE_TEMPLATE_HOST_REF = @@ -132,6 +134,18 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase localSecondaryHost = _hostDao.createSearchBuilder(); + localSecondaryHost.and("private_ip_address", localSecondaryHost.entity().getPrivateIpAddress(), SearchCriteria.Op.EQ); + localSecondaryHost.and("state", localSecondaryHost.entity().getStatus(), SearchCriteria.Op.EQ); + localSecondaryHost.and("data_center_id", localSecondaryHost.entity().getDataCenterId(), SearchCriteria.Op.EQ); + localSecondaryHost.and("type", localSecondaryHost.entity().getType(), SearchCriteria.Op.EQ); + LOCAL_SECONDARY_STORAGE_SEARCH.join("host", localSecondaryHost, localSecondaryHost.entity().getId(), LOCAL_SECONDARY_STORAGE_SEARCH.entity().getHostId(), JoinBuilder.JoinType.INNER); + LOCAL_SECONDARY_STORAGE_SEARCH.done(); + return result; } @Override @@ -296,12 +310,9 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase tmplHost = new ArrayList(); - tmplHost.add(findOneBy(sc)); - return tmplHost; - } else { - return listBy(sc); - } + } + return listBy(sc); + } @Override @@ -330,6 +341,20 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase sc = LOCAL_SECONDARY_STORAGE_SEARCH.create(); + sc.setJoinParameters("host", "private_ip_address", computingHost.getPrivateIpAddress()); + sc.setJoinParameters("host", "state", com.cloud.host.Status.Up); + sc.setJoinParameters("host", "data_center_id", computingHost.getDataCenterId()); + sc.setJoinParameters("host", "type", Host.Type.LocalSecondaryStorage); + sc.setParameters("template_id", templateId); + sc.setParameters("state", VMTemplateHostVO.Status.DOWNLOADED); + return findOneBy(sc); + } @Override public void deleteByHost(Long hostId) { diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index c5e80bf262d..7a08f328ed9 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -350,7 +350,7 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe } } - templateHostRef = _storageMgr.findVmTemplateHost(templateId, pool.getDataCenterId(), pool.getPodId()); + templateHostRef = _storageMgr.findVmTemplateHost(templateId, pool); if (templateHostRef == null) { s_logger.debug("Unable to find a secondary storage host who has completely downloaded the template.");