volume-upload: Templates in uploaded error state are also accounted in resource 
limits which leads to failure during template upload even though there aren't 
any active ones
Fixed the storage GC thread to clean up templates in error/abandoned states.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c62ce3ee
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c62ce3ee
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c62ce3ee

Branch: refs/heads/master
Commit: c62ce3eecb01bda070129143a170ceb63e0f23b9
Parents: e864b93
Author: Koushik Das <kous...@apache.org>
Authored: Tue Mar 24 09:21:42 2015 +0530
Committer: Koushik Das <kous...@apache.org>
Committed: Tue Mar 24 09:21:42 2015 +0530

----------------------------------------------------------------------
 .../com/cloud/storage/StorageManagerImpl.java   | 58 +++++++++++++++++++-
 1 file changed, 56 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c62ce3ee/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java 
b/server/src/com/cloud/storage/StorageManagerImpl.java
index fb51ff5..91e4047 100755
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -70,6 +70,7 @@ import 
org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
+import 
org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
@@ -150,6 +151,7 @@ import com.cloud.storage.dao.VolumeDao;
 import com.cloud.storage.listener.StoragePoolMonitor;
 import com.cloud.storage.listener.VolumeStateListener;
 import com.cloud.template.TemplateManager;
+import com.cloud.template.VirtualMachineTemplate;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.user.ResourceLimitService;
@@ -1082,7 +1084,7 @@ public class StorageManagerImpl extends ManagerBase 
implements StorageManager, C
                         }
                     }
 
-                    // destroy uploaded volumes in UploadAbandoned/UploadError 
state
+                    // destroy uploaded volumes in abandoned/error state
                     List<VolumeDataStoreVO> volumeDataStores = 
_volumeDataStoreDao.listByVolumeState(Volume.State.UploadError, 
Volume.State.UploadAbandoned);
                     for (VolumeDataStoreVO volumeDataStore : volumeDataStores) 
{
                         VolumeVO volume = 
_volumeDao.findById(volumeDataStore.getVolumeId());
@@ -1111,7 +1113,10 @@ public class StorageManagerImpl extends ManagerBase 
implements StorageManager, C
                                     if (volOnSecondary != null) {
                                         s_logger.info("Expunging volume " + 
volume.getUuid() + " uploaded using HTTP POST from secondary data store");
                                         AsyncCallFuture<VolumeApiResult> 
future = volService.expungeVolumeAsync(volOnSecondary);
-                                        future.get();
+                                        VolumeApiResult result = future.get();
+                                        if (!result.isSuccess()) {
+                                            s_logger.warn("Failed to expunge 
volume " + volume.getUuid() + " from the image store " + dataStore.getName() + 
" due to: " + result.getResult());
+                                        }
                                     }
                                 }
                             }
@@ -1119,6 +1124,55 @@ public class StorageManagerImpl extends ManagerBase 
implements StorageManager, C
                             s_logger.warn("Unable to destroy uploaded volume " 
+ volume.getUuid() + ". Error details: " + th.getMessage());
                         }
                     }
+
+                    // destroy uploaded templates in abandoned/error state
+                    List<TemplateDataStoreVO> templateDataStores = 
_templateStoreDao.listByTemplateState(VirtualMachineTemplate.State.UploadError, 
VirtualMachineTemplate.State.UploadAbandoned);
+                    for (TemplateDataStoreVO templateDataStore : 
templateDataStores) {
+                        VMTemplateVO template = 
_templateDao.findById(templateDataStore.getTemplateId());
+                        if (template == null) {
+                            s_logger.warn("Uploaded template with id " + 
templateDataStore.getTemplateId() + " not found, so cannot be destroyed");
+                            continue;
+                        }
+                        try {
+                            DataStore dataStore = 
_dataStoreMgr.getDataStore(templateDataStore.getDataStoreId(), 
DataStoreRole.Image);
+                            EndPoint ep = _epSelector.select(dataStore, 
templateDataStore.getExtractUrl());
+                            if (ep == null) {
+                                s_logger.warn("There is no secondary storage 
VM for image store " + dataStore.getName() + ", cannot destroy uploaded 
template " + template.getUuid());
+                                continue;
+                            }
+                            Host host = _hostDao.findById(ep.getId());
+                            if (host != null && host.getManagementServerId() 
!= null) {
+                                if (_serverId == 
host.getManagementServerId().longValue()) {
+                                    AsyncCallFuture<TemplateApiResult> future 
= _imageSrv.deleteTemplateAsync(tmplFactory.getTemplate(template.getId(), 
dataStore));
+                                    TemplateApiResult result = future.get();
+                                    if (!result.isSuccess()) {
+                                        s_logger.warn("Failed to delete 
template " + template.getUuid() + " from the image store " + 
dataStore.getName() + " due to: " + result.getResult());
+                                        continue;
+                                    }
+                                    // remove from template_zone_ref
+                                    List<VMTemplateZoneVO> templateZones = 
_vmTemplateZoneDao.listByZoneTemplate(((ImageStoreEntity)dataStore).getDataCenterId(),
 template.getId());
+                                    if (templateZones != null) {
+                                        for (VMTemplateZoneVO templateZone : 
templateZones) {
+                                            
_vmTemplateZoneDao.remove(templateZone.getId());
+                                        }
+                                    }
+                                    // mark all the occurrences of this 
template in the given store as destroyed
+                                    
_templateStoreDao.removeByTemplateStore(template.getId(), dataStore.getId());
+                                    // find all eligible image stores for this 
template
+                                    List<DataStore> imageStores = 
_tmpltMgr.getImageStoreByTemplate(template.getId(), null);
+                                    if (imageStores == null || 
imageStores.size() == 0) {
+                                        
template.setState(VirtualMachineTemplate.State.Inactive);
+                                        _templateDao.update(template.getId(), 
template);
+
+                                        // decrement template resource count
+                                        
_resourceLimitMgr.decrementResourceCount(template.getAccountId(), 
ResourceType.template);
+                                    }
+                                }
+                            }
+                        } catch (Throwable th) {
+                            s_logger.warn("Unable to destroy uploaded template 
" + template.getUuid() + ". Error details: " + th.getMessage());
+                        }
+                    }
                 } finally {
                     scanLock.unlock();
                 }

Reply via email to