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/11/01 01:21:55 UTC

[44/50] [abbrv] Merge branch 'master' into rbac.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/projects/ProjectManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/projects/ProjectManagerImpl.java
index b4987cb,22e2020..b97f1e8
--- a/server/src/com/cloud/projects/ProjectManagerImpl.java
+++ b/server/src/com/cloud/projects/ProjectManagerImpl.java
@@@ -202,31 -205,33 +205,33 @@@ public class ProjectManagerImpl extend
          //do resource limit check
          _resourceLimitMgr.checkResourceLimit(owner, ResourceType.project);
  
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
+         final Account ownerFinal = owner;
+         return Transaction.execute(new TransactionCallback<Project>() {
+             @Override
+             public Project doInTransaction(TransactionStatus status) {
  
 -                //Create an account associated with the project
 -                StringBuilder acctNm = new StringBuilder("PrjAcct-");
 +        //Create an account associated with the project
 +        StringBuilder acctNm = new StringBuilder("PrjAcct-");
-         acctNm.append(name).append("-").append(owner.getDomainId());
+                 acctNm.append(name).append("-").append(ownerFinal.getDomainId());
 -        
 -                Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString());
 -        
 +
 +        Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString());
 +
-         Project project = _projectDao.persist(new ProjectVO(name, displayText, owner.getDomainId(), projectAccount.getId()));
+                 Project project = _projectDao.persist(new ProjectVO(name, displayText, ownerFinal.getDomainId(), projectAccount.getId()));
 -        
 -                //assign owner to the project
 +
 +        //assign owner to the project
-         assignAccountToProject(project, owner.getId(), ProjectAccount.Role.Admin);
+                 assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin);
 -        
 -                if (project != null) {
 -                    CallContext.current().setEventDetails("Project id=" + project.getId());
 -                }
 -        
 -                //Increment resource count
 +
 +        if (project != null) {
 +            CallContext.current().setEventDetails("Project id=" + project.getId());
 +        }
 +
 +        //Increment resource count
-         _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.project);
- 
-         txn.commit();
+                 _resourceLimitMgr.incrementResourceCount(ownerFinal.getId(), ResourceType.project);
  
 -                return project;
 -            }
 +        return project;
 +    }
+         });
+     }
  
  
      @Override
@@@ -269,20 -274,24 +274,24 @@@
  
      @DB
      @Override
-     public boolean deleteProject(Account caller, long callerUserId, ProjectVO project) {
+     public boolean deleteProject(Account caller, long callerUserId, final ProjectVO project) {
          //mark project as inactive first, so you can't add resources to it
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
+         boolean updateResult = Transaction.execute(new TransactionCallback<Boolean>() {
+             @Override
+             public Boolean doInTransaction(TransactionStatus status) {
 -                s_logger.debug("Marking project id=" + project.getId() + " with state " + State.Disabled + " as a part of project delete...");
 -                project.setState(State.Disabled);
 -                boolean updateResult = _projectDao.update(project.getId(), project);
 -                //owner can be already removed at this point, so adding the conditional check
 -                Account projectOwner = getProjectOwner(project.getId());
 -                if (projectOwner != null) {
 -                    _resourceLimitMgr.decrementResourceCount(projectOwner.getId(), ResourceType.project);
 -                }
 +        s_logger.debug("Marking project id=" + project.getId() + " with state " + State.Disabled + " as a part of project delete...");
 +        project.setState(State.Disabled);
 +        boolean updateResult = _projectDao.update(project.getId(), project);
 +        //owner can be already removed at this point, so adding the conditional check
 +        Account projectOwner = getProjectOwner(project.getId());
 +        if (projectOwner != null) {
 +            _resourceLimitMgr.decrementResourceCount(projectOwner.getId(), ResourceType.project);
 +        } 
  
-         txn.commit();
+                 return updateResult;
+             }
+         });
+ 
  
          if (updateResult) {
              //pass system caller when clenaup projects account
@@@ -309,20 -318,22 +318,22 @@@
  
          if (result) {
              //Unassign all users from the project
- 
-             Transaction txn = Transaction.currentTxn();
-             txn.start();
- 
+             result = Transaction.execute(new TransactionCallback<Boolean>() {
+                 @Override
+                 public Boolean doInTransaction(TransactionStatus status) {
+                     boolean result = true;
 -                    s_logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup...");
 -                    List<? extends ProjectAccount> projectAccounts = _projectAccountDao.listByProjectId(project.getId());
 -                    for (ProjectAccount projectAccount : projectAccounts) {
 -                        result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId());
 -                    }
 -        
 -                    s_logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup...");
 -                    _projectInvitationDao.cleanupInvitations(project.getId());
 -                    
 +            s_logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup...");
 +            List<? extends ProjectAccount> projectAccounts = _projectAccountDao.listByProjectId(project.getId());
 +            for (ProjectAccount projectAccount : projectAccounts) {
 +                result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId());
 +            }
 +
 +            s_logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup...");
 +            _projectInvitationDao.cleanupInvitations(project.getId());
 +
-             txn.commit();
+                     return result;
+                 }
+             });
              if (result) {
                  s_logger.debug("Accounts are unassign successfully from project " + project + " as a part of project cleanup...");
              }
@@@ -367,27 -378,29 +378,29 @@@
      }
  
      @Override @DB
-     public boolean deleteAccountFromProject(long projectId, long accountId) {
+     public boolean deleteAccountFromProject(final long projectId, final long accountId) {
+         return Transaction.execute(new TransactionCallback<Boolean>() {
+             @Override
+             public Boolean doInTransaction(TransactionStatus status) {
 -                boolean success = true;
 -
 -                //remove account
 -                ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
 -                success = _projectAccountDao.remove(projectAccount.getId());
 -
 -                //remove all invitations for account
 -                if (success) {
 -                    s_logger.debug("Removed account " + accountId + " from project " + projectId + " , cleaning up old invitations for account/project...");
 -                    ProjectInvitation invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId);
 -                    if (invite != null) {
 -                        success = success && _projectInvitationDao.remove(invite.getId());
 -                    }
 -                }
 +        boolean success = true;
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
  
 -                return success;
 +        //remove account
 +        ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
 +        success = _projectAccountDao.remove(projectAccount.getId());
 +
 +        //remove all invitations for account
 +        if (success) {
 +            s_logger.debug("Removed account " + accountId + " from project " + projectId + " , cleaning up old invitations for account/project...");
 +            ProjectInvitation invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId);
 +            if (invite != null) {
 +                success = success && _projectInvitationDao.remove(invite.getId());
              }
 +        }
 +
-         txn.commit();
 +        return success;
 +    }
+         });
+     }
  
      @Override
      public Account getProjectOwner(long projectId) {
@@@ -456,47 -469,49 +469,49 @@@
          //verify permissions
          _accountMgr.checkAccess(caller,AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
  
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
+         Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
+             @Override
+             public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
 -                if (displayText != null) {
 -                    project.setDisplayText(displayText);
 -                    _projectDao.update(projectId, project);
 +        if (displayText != null) {
 +            project.setDisplayText(displayText);
 +            _projectDao.update(projectId, project);
 +        }
 +
 +        if (newOwnerName != null) {
 +            //check that the new owner exists
 +            Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
 +            if (futureOwnerAccount == null) {
 +                throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
 +            }
 +            Account currentOwnerAccount = getProjectOwner(projectId);
 +            if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) {
 +                ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId());
 +                if (futureOwner == null) {
 +                    throw new InvalidParameterValueException("Account " + newOwnerName + " doesn't belong to the project. Add it to the project first and then change the project's ownership");
                  }
 -        
 -                if (newOwnerName != null) {
 -                    //check that the new owner exists
 -                    Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
 -                    if (futureOwnerAccount == null) {
 -                        throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
 -                    }
 -                    Account currentOwnerAccount = getProjectOwner(projectId);
 -                    if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) {
 -                        ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId());
 -                        if (futureOwner == null) {
 -                            throw new InvalidParameterValueException("Account " + newOwnerName + " doesn't belong to the project. Add it to the project first and then change the project's ownership");
 -                        }
 -        
 -                        //do resource limit check
 -                        _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project);
 -        
 -                        //unset the role for the old owner
 -                        ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
 -                        currentOwner.setAccountRole(Role.Regular);
 -                        _projectAccountDao.update(currentOwner.getId(), currentOwner);
 -                        _resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
 -        
 -                        //set new owner
 -                        futureOwner.setAccountRole(Role.Admin);
 -                        _projectAccountDao.update(futureOwner.getId(), futureOwner);
 -                        _resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
 -        
 -        
 -                    } else {
 -                        s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId);
 -                    }
 -               }
 +
 +                //do resource limit check
 +                _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project);
 +
 +                //unset the role for the old owner
 +                ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
 +                currentOwner.setAccountRole(Role.Regular);
 +                _projectAccountDao.update(currentOwner.getId(), currentOwner);
 +                _resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
 +
 +                //set new owner
 +                futureOwner.setAccountRole(Role.Admin);
 +                _projectAccountDao.update(futureOwner.getId(), futureOwner);
 +                _resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
 +
 +
 +            } else {
 +                s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId);
 +            }
 +        }
+             }
+         });
  
-         txn.commit();
  
          return _projectDao.findById(projectId);
  
@@@ -650,38 -665,41 +665,41 @@@
      }
  
      @DB
-     public boolean activeInviteExists(Project project, Long accountId, String email) {
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
+     public boolean activeInviteExists(final Project project, final Long accountId, final String email) {
+         return Transaction.execute(new TransactionCallback<Boolean>() {
+             @Override
+             public Boolean doInTransaction(TransactionStatus status) {
 -                //verify if the invitation was already generated
 -                ProjectInvitationVO invite = null;
 +        //verify if the invitation was already generated
 +        ProjectInvitationVO invite = null;
 +        if (accountId != null) {
 +            invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId());
 +        } else if (email != null) {
 +            invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId());
 +        }
 +
 +        if (invite != null) {
 +            if (invite.getState() == ProjectInvitation.State.Completed || 
 +                    (invite.getState() == ProjectInvitation.State.Pending && _projectInvitationDao.isActive(invite.getId(), _invitationTimeOut))) {
 +                return true;
 +            } else {
 +                if (invite.getState() == ProjectInvitation.State.Pending) {
 +                    expireInvitation(invite);
 +                }
 +                //remove the expired/declined invitation
                  if (accountId != null) {
 -                    invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId());
 +                    s_logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project);
                  } else if (email != null) {
 -                    invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId());
 -                }
 -
 -                if (invite != null) {
 -                    if (invite.getState() == ProjectInvitation.State.Completed || 
 -                            (invite.getState() == ProjectInvitation.State.Pending && _projectInvitationDao.isActive(invite.getId(), _invitationTimeOut))) {
 -                        return true;
 -                    } else {
 -                        if (invite.getState() == ProjectInvitation.State.Pending) {
 -                            expireInvitation(invite);
 -                        }
 -                        //remove the expired/declined invitation
 -                        if (accountId != null) {
 -                            s_logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project);
 -                        } else if (email != null) {
 -                            s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project);
 -                        }
 -
 -                        _projectInvitationDao.expunge(invite.getId());
 -                    }
 +                    s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project);
                  }
  
 -                return false;
 +                _projectInvitationDao.expunge(invite.getId());
              }
 +        }
-         txn.commit();
++
 +        return false;
 +    }
+         });
+     }
  
      public ProjectInvitation generateTokenBasedInvitation(Project project, String email, String token) {
          //verify if the invitation was already generated
@@@ -756,29 -774,37 +774,37 @@@
                  expireInvitation(invite);
                  throw new InvalidParameterValueException("Invitation is expired for account id=" + accountName + " to the project id=" + projectId);
              } else {
-                 Transaction txn = Transaction.currentTxn();
-                 txn.start();
+                 
+                 final ProjectInvitationVO inviteFinal = invite;
+                 final Long accountIdFinal = accountId;
+                 final String accountNameFinal = accountName;
+                 result = Transaction.execute(new TransactionCallback<Boolean>() {
+                     @Override
+                     public Boolean doInTransaction(TransactionStatus status) {
+                         boolean result = true;
 -                        
 -                        ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined;
 -        
 -                        //update invitation
 +
 +                ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined;
 +
 +                //update invitation
-                 s_logger.debug("Marking invitation " + invite + " with state " + newState);
-                 invite.setState(newState);
-                 result = _projectInvitationDao.update(invite.getId(), invite);
+                         s_logger.debug("Marking invitation " + inviteFinal + " with state " + newState);
+                         inviteFinal.setState(newState);
+                         result = _projectInvitationDao.update(inviteFinal.getId(), inviteFinal);
 -        
 -                        if (result && accept) {
 -                            //check if account already exists for the project (was added before invitation got accepted)
 +
 +                if (result && accept) {
 +                    //check if account already exists for the project (was added before invitation got accepted)
-                     ProjectAccount projectAccount =  _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
+                             ProjectAccount projectAccount =  _projectAccountDao.findByProjectIdAccountId(projectId, accountIdFinal);
 -                            if (projectAccount != null) {
 +                    if (projectAccount != null) {
-                         s_logger.debug("Account " + accountName + " already added to the project id=" + projectId);
+                                 s_logger.debug("Account " + accountNameFinal + " already added to the project id=" + projectId);
 -                            } else {
 +                    } else {
-                         assignAccountToProject(project, accountId, ProjectAccount.Role.Regular); 
+                                 assignAccountToProject(project, accountIdFinal, ProjectAccount.Role.Regular); 
 -                            }
 -                        } else {
 +                    }
 +                } else {
-                     s_logger.warn("Failed to update project invitation " + invite + " with state " + newState);
+                             s_logger.warn("Failed to update project invitation " + inviteFinal + " with state " + newState);
 -                        }
 -                        
 +                }
 +
-                 txn.commit();
+                         return result;
+                     }
+                 });
              }
          } else {
              throw new InvalidParameterValueException("Unable to find invitation for account name=" + accountName + " to the project id=" + projectId);
@@@ -822,15 -848,15 +848,15 @@@
              throw new InvalidParameterValueException("Can't activate the project in " + currentState + " state");
          }
  
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
- 
+         Transaction.execute(new TransactionCallbackNoReturn() {
+             @Override
+             public void doInTransactionWithoutResult(TransactionStatus status) {
 -                project.setState(Project.State.Active);
 -                _projectDao.update(projectId, project);
 -        
 -                _accountMgr.enableAccount(project.getProjectAccountId());
 +        project.setState(Project.State.Active);
 +        _projectDao.update(projectId, project);
 +
 +        _accountMgr.enableAccount(project.getProjectAccountId());
- 
-         txn.commit();
+             }
+         });
  
          return _projectDao.findById(projectId);
      }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/resource/ResourceManagerImpl.java
index b36e03a,e9d5193..5682d6f
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@@ -818,74 -820,77 +820,77 @@@ public class ResourceManagerImpl extend
              return true;
          }
  
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
+         Transaction.execute(new TransactionCallbackNoReturn() {
+             @Override
+             public void doInTransactionWithoutResult(TransactionStatus status) {
  
 -                _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null);
 -                _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove);
 -        
 -                // delete host details
 -                _hostDetailsDao.deleteDetails(hostId);
 -        
 -                host.setGuid(null);
 -                Long clusterId = host.getClusterId();
 -                host.setClusterId(null);
 -                _hostDao.update(host.getId(), host);
 -        
 -                _hostDao.remove(hostId);
 -                if (clusterId != null) {
 -                    List<HostVO> hosts = listAllHostsInCluster(clusterId);
 -                    if (hosts.size() == 0) {
 -                        ClusterVO cluster = _clusterDao.findById(clusterId);
 -                        cluster.setGuid(null);
 -                        _clusterDao.update(clusterId, cluster);
 -                    }
 -                }
 -        
 -                try {
 -                    resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId);
 -                } catch (NoTransitionException e) {
 -                    s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
 -                }
 -        
 -                // Delete the associated entries in host ref table
 -                _storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
 -        
 -                // Make sure any VMs that were marked as being on this host are cleaned up
 -                List<VMInstanceVO> vms = _vmDao.listByHostId(hostId);
 -                for (VMInstanceVO vm : vms) {
 -                    // this is how VirtualMachineManagerImpl does it when it syncs VM states
 -                    vm.setState(State.Stopped);
 -                    vm.setHostId(null);
 -                    _vmDao.persist(vm);
 -                }
 -        
 -                // For pool ids you got, delete local storage host entries in pool table
 -                // where
 -                for (StoragePoolHostVO pool : pools) {
 -                    Long poolId = pool.getPoolId();
 -                    StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
 -                    if (storagePool.isLocal() && isForceDeleteStorage) {
 -                        storagePool.setUuid(null);
 -                        storagePool.setClusterId(null);
 -                        _storagePoolDao.update(poolId, storagePool);
 -                        _storagePoolDao.remove(poolId);
 -                        s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId);
 -                    }
 -                }
 -        
 -                // delete the op_host_capacity entry
 -                Object[] capacityTypes = {Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY};
 -                SearchCriteria<CapacityVO> hostCapacitySC = _capacityDao.createSearchCriteria();
 -                hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
 -                hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes);
 -                _capacityDao.remove(hostCapacitySC);
 -                // remove from dedicated resources
 -                DedicatedResourceVO dr = _dedicatedDao.findByHostId(hostId);
 -                if (dr != null) {
 -                    _dedicatedDao.remove(dr.getId());
 -                }
 +        _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null);
 +        _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove);
 +
 +        // delete host details
 +        _hostDetailsDao.deleteDetails(hostId);
 +
 +        host.setGuid(null);
 +        Long clusterId = host.getClusterId();
 +        host.setClusterId(null);
 +        _hostDao.update(host.getId(), host);
 +
 +        _hostDao.remove(hostId);
 +        if (clusterId != null) {
 +            List<HostVO> hosts = listAllHostsInCluster(clusterId);
 +            if (hosts.size() == 0) {
 +                ClusterVO cluster = _clusterDao.findById(clusterId);
 +                cluster.setGuid(null);
 +                _clusterDao.update(clusterId, cluster);
 +            }
 +        }
 +
 +        try {
 +            resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId);
 +        } catch (NoTransitionException e) {
 +            s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
 +        }
 +
 +        // Delete the associated entries in host ref table
 +        _storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
 +
 +        // Make sure any VMs that were marked as being on this host are cleaned up
 +        List<VMInstanceVO> vms = _vmDao.listByHostId(hostId);
 +        for (VMInstanceVO vm : vms) {
 +            // this is how VirtualMachineManagerImpl does it when it syncs VM states
 +            vm.setState(State.Stopped);
 +            vm.setHostId(null);
 +            _vmDao.persist(vm);
 +        }
 +
 +        // For pool ids you got, delete local storage host entries in pool table
 +        // where
 +        for (StoragePoolHostVO pool : pools) {
 +            Long poolId = pool.getPoolId();
 +            StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
 +            if (storagePool.isLocal() && isForceDeleteStorage) {
 +                storagePool.setUuid(null);
 +                storagePool.setClusterId(null);
 +                _storagePoolDao.update(poolId, storagePool);
 +                _storagePoolDao.remove(poolId);
 +                s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId);
 +            }
 +        }
 +
 +        // delete the op_host_capacity entry
 +        Object[] capacityTypes = {Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY};
 +        SearchCriteria<CapacityVO> hostCapacitySC = _capacityDao.createSearchCriteria();
 +        hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
 +        hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes);
 +        _capacityDao.remove(hostCapacitySC);
 +        // remove from dedicated resources
 +        DedicatedResourceVO dr = _dedicatedDao.findByHostId(hostId);
 +        if (dr != null) {
 +            _dedicatedDao.remove(dr.getId());
 +        }
-         txn.commit();
+             }
+         });
+ 
          return true;
      }
  
@@@ -905,57 -910,56 +910,56 @@@
  
      @Override
      @DB
-     public boolean deleteCluster(DeleteClusterCmd cmd) {
-         Transaction txn = Transaction.currentTxn();
+     public boolean deleteCluster(final DeleteClusterCmd cmd) {
          try {
-             txn.start();
+             Transaction.execute(new TransactionCallbackNoReturn() {
+                 @Override
+                 public void doInTransactionWithoutResult(TransactionStatus status) {
 -                    ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true);
 -                    if (cluster == null) {
 -                        if (s_logger.isDebugEnabled()) {
 -                            s_logger.debug("Cluster: " + cmd.getId() + " does not even exist.  Delete call is ignored.");
 -                        }
 -                        throw new CloudRuntimeException("Cluster: " + cmd.getId() + " does not exist");
 -                    }
 -        
 -                    Hypervisor.HypervisorType hypervisorType = cluster.getHypervisorType();
 -        
 -                    List<HostVO> hosts = listAllHostsInCluster(cmd.getId());
 -                    if (hosts.size() > 0) {
 -                        if (s_logger.isDebugEnabled()) {
 -                            s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove");
 -                        }
 -                        throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts");
 -                    }
 -        
 -                    // don't allow to remove the cluster if it has non-removed storage
 -                    // pools
 -                    List<StoragePoolVO> storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId());
 -                    if (storagePools.size() > 0) {
 -                        if (s_logger.isDebugEnabled()) {
 -                            s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove");
 -                        }
 -                        throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools");
 -                    }
 -        
 -                    if (_clusterDao.remove(cmd.getId())) {
 -                        _capacityDao.removeBy(null, null, null, cluster.getId(), null);
 -                        // If this cluster is of type vmware, and if the nexus vswitch
 -                        // global parameter setting is turned
 -                        // on, remove the row in cluster_vsm_map for this cluster id.
 -                        if (hypervisorType == HypervisorType.VMware && Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) {
 -                            _clusterVSMMapDao.removeByClusterId(cmd.getId());
 -                        }
 -                        // remove from dedicated resources
 -                        DedicatedResourceVO dr = _dedicatedDao.findByClusterId(cluster.getId());
 -                        if (dr != null) {
 -                            _dedicatedDao.remove(dr.getId());
 -                        }
 -                    }
 +            ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true);
 +            if (cluster == null) {
 +                if (s_logger.isDebugEnabled()) {
 +                    s_logger.debug("Cluster: " + cmd.getId() + " does not even exist.  Delete call is ignored.");
 +                }
-                 txn.rollback();
 +                throw new CloudRuntimeException("Cluster: " + cmd.getId() + " does not exist");
 +            }
 +
 +            Hypervisor.HypervisorType hypervisorType = cluster.getHypervisorType();
 +
 +            List<HostVO> hosts = listAllHostsInCluster(cmd.getId());
 +            if (hosts.size() > 0) {
 +                if (s_logger.isDebugEnabled()) {
 +                    s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove");
 +                }
-                 txn.rollback();
 +                throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts");
 +            }
 +
 +            // don't allow to remove the cluster if it has non-removed storage
 +            // pools
 +            List<StoragePoolVO> storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId());
 +            if (storagePools.size() > 0) {
 +                if (s_logger.isDebugEnabled()) {
 +                    s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove");
 +                }
-                 txn.rollback();
 +                throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools");
 +            }
 +
 +            if (_clusterDao.remove(cmd.getId())) {
 +                _capacityDao.removeBy(null, null, null, cluster.getId(), null);
 +                // If this cluster is of type vmware, and if the nexus vswitch
 +                // global parameter setting is turned
 +                // on, remove the row in cluster_vsm_map for this cluster id.
 +                if (hypervisorType == HypervisorType.VMware && Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) {
 +                    _clusterVSMMapDao.removeByClusterId(cmd.getId());
 +                }
 +                // remove from dedicated resources
 +                DedicatedResourceVO dr = _dedicatedDao.findByClusterId(cluster.getId());
 +                if (dr != null) {
 +                    _dedicatedDao.remove(dr.getId());
 +                }
 +            }
  
-             txn.commit();
+                 }
+             });
              return true;
          } catch (CloudRuntimeException e) {
              throw e;
@@@ -1035,15 -1038,7 +1038,7 @@@
          }
  
          if (doUpdate) {
-             Transaction txn = Transaction.currentTxn();
-             try {
-                 txn.start();
 -            _clusterDao.update(cluster.getId(), cluster);
 +                _clusterDao.update(cluster.getId(), cluster);
-                 txn.commit();
-             } catch (Exception e) {
-                 s_logger.error("Unable to update cluster due to " + e.getMessage(), e);
-                 throw new CloudRuntimeException("Failed to update cluster. Please contact Cloud Support.");
-             }
          }
  
          if (newManagedState != null && !newManagedState.equals(oldManagedState)) {
@@@ -2460,30 -2448,33 +2448,33 @@@
      @Override
      @DB
      @ActionEvent(eventType = EventTypes.EVENT_HOST_RESERVATION_RELEASE, eventDescription = "releasing host reservation", async = true)
-     public boolean releaseHostReservation(Long hostId) {
-         Transaction txn = Transaction.currentTxn();
+     public boolean releaseHostReservation(final Long hostId) {
          try {
-             txn.start();
+             return Transaction.execute(new TransactionCallback<Boolean>() {
+                 @Override
+                 public Boolean doInTransaction(TransactionStatus status) {
 -                    PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
 -                    if (reservationEntry != null) {
 -                        long id = reservationEntry.getId();
 -                        PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true);
 -                        if (hostReservation == null) {
 -                            if (s_logger.isDebugEnabled()) {
 -                                s_logger.debug("Host reservation for host: " + hostId + " does not even exist.  Release reservartion call is ignored.");
 -                            }
 -                            return false;
 -                        }
 -                        hostReservation.setResourceUsage(null);
 -                        _plannerHostReserveDao.persist(hostReservation);
 -                        return true;
 -                    }
 -
 +            PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
 +            if (reservationEntry != null) {
 +                long id = reservationEntry.getId();
 +                PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true);
 +                if (hostReservation == null) {
                      if (s_logger.isDebugEnabled()) {
                          s_logger.debug("Host reservation for host: " + hostId + " does not even exist.  Release reservartion call is ignored.");
                      }
-                     txn.rollback();
 -
                      return false;
                  }
 +                hostReservation.setResourceUsage(null);
 +                _plannerHostReserveDao.persist(hostReservation);
-                 txn.commit();
 +                return true;
 +            }
++
 +            if (s_logger.isDebugEnabled()) {
 +                s_logger.debug("Host reservation for host: " + hostId + " does not even exist.  Release reservartion call is ignored.");
 +            }
++
 +            return false;
++                }
+             });
          } catch (CloudRuntimeException e) {
              throw e;
          } catch (Throwable t) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
index c0d3cb9,7417754..55097ce
--- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
+++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
@@@ -375,53 -377,53 +378,53 @@@ public class ResourceLimitManagerImpl e
              project = _projectDao.findByProjectAccountId(account.getId());
          }
  
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
-         try {
+         final Project projectFinal = project;
+         Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
+             @Override
+             public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
 -                // Lock all rows first so nobody else can read it
 -                Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(account.getId(), ResourceOwnerType.Account, type);
 -                SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
 -                sc.setParameters("id", rowIdsToLock.toArray());
 -                _resourceCountDao.lockRows(sc, null, true);
 -    
 -                // Check account limits
 -                long accountLimit = findCorrectResourceLimitForAccount(account, type);
 -                long potentialCount = _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type) + numResources;
 -                if (accountLimit != Resource.RESOURCE_UNLIMITED && potentialCount > accountLimit) {
 -                    String message = "Maximum number of resources of type '" + type + "' for account name=" + account.getAccountName()
 -                            + " in domain id=" + account.getDomainId() + " has been exceeded.";
 +            // Lock all rows first so nobody else can read it
 +            Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(account.getId(), ResourceOwnerType.Account, type);
 +            SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
 +            sc.setParameters("id", rowIdsToLock.toArray());
 +            _resourceCountDao.lockRows(sc, null, true);
 +
 +            // Check account limits
 +            long accountLimit = findCorrectResourceLimitForAccount(account, type);
 +            long potentialCount = _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type) + numResources;
 +            if (accountLimit != Resource.RESOURCE_UNLIMITED && potentialCount > accountLimit) {
 +                String message = "Maximum number of resources of type '" + type + "' for account name=" + account.getAccountName()
 +                        + " in domain id=" + account.getDomainId() + " has been exceeded.";
-                 if (project != null) {
-                     message = "Maximum number of resources of type '" + type + "' for project name=" + project.getName()
+                     if (projectFinal != null) {
+                         message = "Maximum number of resources of type '" + type + "' for project name=" + projectFinal.getName()
 -                                + " in domain id=" + account.getDomainId() + " has been exceeded.";
 -                    }
 -                    throw new ResourceAllocationException(message, type);
 +                            + " in domain id=" + account.getDomainId() + " has been exceeded.";
                  }
 -    
 -                // check all domains in the account's domain hierarchy
 -                Long domainId = null;
 +                throw new ResourceAllocationException(message, type);
 +            }
 +
 +            // check all domains in the account's domain hierarchy
 +            Long domainId = null;
-             if (project != null) {
-                 domainId = project.getDomainId();
+                 if (projectFinal != null) {
+                     domainId = projectFinal.getDomainId();
 -                } else {
 -                    domainId = account.getDomainId();
 -                }
 -    
 -                while (domainId != null) {
 -                    DomainVO domain = _domainDao.findById(domainId);
 -                    // no limit check if it is ROOT domain
 -                    if (domainId != Domain.ROOT_DOMAIN) {
 -                        ResourceLimitVO domainLimit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type);
 -                        if (domainLimit != null && domainLimit.getMax().longValue() != Resource.RESOURCE_UNLIMITED) {
 -                            long domainCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type);
 -                            if ((domainCount + numResources) > domainLimit.getMax().longValue()) {
 -                                throw new ResourceAllocationException("Maximum number of resources of type '" + type + "' for domain id=" + domainId + " has been exceeded.", type);
 -                            }
 +            } else {
 +                domainId = account.getDomainId();
 +            }
 +
 +            while (domainId != null) {
 +                DomainVO domain = _domainDao.findById(domainId);
 +                // no limit check if it is ROOT domain
 +                if (domainId != Domain.ROOT_DOMAIN) {
 +                    ResourceLimitVO domainLimit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type);
 +                    if (domainLimit != null && domainLimit.getMax().longValue() != Resource.RESOURCE_UNLIMITED) {
 +                        long domainCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type);
 +                        if ((domainCount + numResources) > domainLimit.getMax().longValue()) {
 +                            throw new ResourceAllocationException("Maximum number of resources of type '" + type + "' for domain id=" + domainId + " has been exceeded.", type);
                          }
                      }
 -                    domainId = domain.getParent();
                  }
 +                domainId = domain.getParent();
              }
-         } finally {
-             txn.commit();
 +        }
+         });
      }
  
      @Override
@@@ -717,143 -719,143 +720,143 @@@
      }
  
      @DB
-     protected boolean updateResourceCountForAccount(long accountId, ResourceType type, boolean increment, long delta) {
-         boolean result = true;
+     protected boolean updateResourceCountForAccount(final long accountId, final ResourceType type, final boolean increment, final long delta) {
          try {
-             Transaction txn = Transaction.currentTxn();
-             txn.start();
- 
+             return Transaction.execute(new TransactionCallback<Boolean>() {
+                 @Override
+                 public Boolean doInTransaction(TransactionStatus status) {
+                     boolean result = true;
 -                    Set<Long> rowsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type);
 -        
 -                    // Lock rows first
 -                    SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
 -                    sc.setParameters("id", rowsToLock.toArray());
 -                    List<ResourceCountVO> rowsToUpdate = _resourceCountDao.lockRows(sc, null, true);
 -        
 -                    for (ResourceCountVO rowToUpdate : rowsToUpdate) {
 -                        if (!_resourceCountDao.updateById(rowToUpdate.getId(), increment, delta)) {
 -                            s_logger.trace("Unable to update resource count for the row " + rowToUpdate);
 -                            result = false;
 -                        }
 -                    }
 -                    
 +            Set<Long> rowsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type);
 +
 +            // Lock rows first
 +            SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
 +            sc.setParameters("id", rowsToLock.toArray());
 +            List<ResourceCountVO> rowsToUpdate = _resourceCountDao.lockRows(sc, null, true);
 +
 +            for (ResourceCountVO rowToUpdate : rowsToUpdate) {
 +                if (!_resourceCountDao.updateById(rowToUpdate.getId(), increment, delta)) {
 +                    s_logger.trace("Unable to update resource count for the row " + rowToUpdate);
 +                    result = false;
 +                }
 +            }
 +
-             txn.commit();
+                     return result;
+                 }
+             });
          } catch (Exception ex) {
              s_logger.error("Failed to update resource count for account id=" + accountId);
-             result = false;
+             return false;
          }
      }
  
      @DB
-     protected long recalculateDomainResourceCount(long domainId, ResourceType type) {
+     protected long recalculateDomainResourceCount(final long domainId, final ResourceType type) {
+         return Transaction.execute(new TransactionCallback<Long>() {
+             @Override
+             public Long doInTransaction(TransactionStatus status) {
 -                long newCount = 0;
 -
 -                // Lock all rows first so nobody else can read it
 -                Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(domainId, ResourceOwnerType.Domain, type);
 -                SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
 -                sc.setParameters("id", rowIdsToLock.toArray());
 -                _resourceCountDao.lockRows(sc, null, true);
 -    
 -                ResourceCountVO domainRC = _resourceCountDao.findByOwnerAndType(domainId, ResourceOwnerType.Domain, type);
 -                long oldCount = domainRC.getCount();
 -    
 -                List<DomainVO> domainChildren = _domainDao.findImmediateChildrenForParent(domainId);
 -                // for each child domain update the resource count
 -                if (type.supportsOwner(ResourceOwnerType.Domain)) {
 -    
 -                    // calculate project count here
 -                    if (type == ResourceType.project) {
 -                        newCount = newCount + _projectDao.countProjectsForDomain(domainId);
 -                    }
 -    
 -                    for (DomainVO domainChild : domainChildren) {
 -                        long domainCount = recalculateDomainResourceCount(domainChild.getId(), type);
 -                        newCount = newCount + domainCount; // add the child domain count to parent domain count
 -                    }
 +        long newCount = 0;
 +
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
- 
-         try {
 +            // Lock all rows first so nobody else can read it
 +            Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(domainId, ResourceOwnerType.Domain, type);
 +            SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
 +            sc.setParameters("id", rowIdsToLock.toArray());
 +            _resourceCountDao.lockRows(sc, null, true);
 +
 +            ResourceCountVO domainRC = _resourceCountDao.findByOwnerAndType(domainId, ResourceOwnerType.Domain, type);
 +            long oldCount = domainRC.getCount();
 +
 +            List<DomainVO> domainChildren = _domainDao.findImmediateChildrenForParent(domainId);
 +            // for each child domain update the resource count
 +            if (type.supportsOwner(ResourceOwnerType.Domain)) {
 +
 +                // calculate project count here
 +                if (type == ResourceType.project) {
 +                    newCount = newCount + _projectDao.countProjectsForDomain(domainId);
                  }
 -    
 -                if (type.supportsOwner(ResourceOwnerType.Account)) {
 -                    List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domainId);
 -                    for (AccountVO account : accounts) {
 -                        long accountCount = recalculateAccountResourceCount(account.getId(), type);
 -                        newCount = newCount + accountCount; // add account's resource count to parent domain count
 -                    }
 +
 +                for (DomainVO domainChild : domainChildren) {
 +                    long domainCount = recalculateDomainResourceCount(domainChild.getId(), type);
 +                    newCount = newCount + domainCount; // add the child domain count to parent domain count
                  }
 -                _resourceCountDao.setResourceCount(domainId, ResourceOwnerType.Domain, type, newCount);
 -    
 -                if (oldCount != newCount) {
 -                    s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " +
 -                            newCount + ") for type " + type + " for domain ID " + domainId + " is fixed during resource count recalculation.");
 +            }
 +
 +            if (type.supportsOwner(ResourceOwnerType.Account)) {
 +                List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domainId);
 +                for (AccountVO account : accounts) {
 +                    long accountCount = recalculateAccountResourceCount(account.getId(), type);
 +                    newCount = newCount + accountCount; // add account's resource count to parent domain count
                  }
 -                
 -                return newCount;
              }
 +            _resourceCountDao.setResourceCount(domainId, ResourceOwnerType.Domain, type, newCount);
 +
 +            if (oldCount != newCount) {
 +                s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " +
 +                        newCount + ") for type " + type + " for domain ID " + domainId + " is fixed during resource count recalculation.");
 +            }
-         } catch (Exception e) {
-             throw new CloudRuntimeException("Failed to update resource count for domain with Id " + domainId);
-         } finally {
-             txn.commit();
-         }
 +
 +        return newCount;
 +    }
+         });
+     }
  
      @DB
-     protected long recalculateAccountResourceCount(long accountId, ResourceType type) {
+     protected long recalculateAccountResourceCount(final long accountId, final ResourceType type) {
+         Long newCount = Transaction.execute(new TransactionCallback<Long>() {
+             @Override
+             public Long doInTransaction(TransactionStatus status) {
 -                Long newCount = null;
 -
 -                // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table
 -                // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too
 -                SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
 -                sc.setParameters("accountId", accountId);
 -                _resourceCountDao.lockRows(sc, null, true);
 -        
 -                ResourceCountVO accountRC = _resourceCountDao.findByOwnerAndType(accountId, ResourceOwnerType.Account, type);
 -                long oldCount = 0;
 -                if (accountRC != null)
 -                    oldCount = accountRC.getCount();
 -        
 -                if (type == Resource.ResourceType.user_vm) {
 -                    newCount = _userVmDao.countAllocatedVMsForAccount(accountId);
 -                } else if (type == Resource.ResourceType.volume) {
 -                    newCount = _volumeDao.countAllocatedVolumesForAccount(accountId);
 -                    long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size();
 -                    newCount = newCount - virtualRouterCount; // don't count the volumes of virtual router
 -                } else if (type == Resource.ResourceType.snapshot) {
 -                    newCount = _snapshotDao.countSnapshotsForAccount(accountId);
 -                } else if (type == Resource.ResourceType.public_ip) {
 -                    newCount = calculatePublicIpForAccount(accountId);
 -                } else if (type == Resource.ResourceType.template) {
 -                    newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
 -                } else if (type == Resource.ResourceType.project) {
 -                    newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
 -                } else if (type == Resource.ResourceType.network) {
 -                    newCount = _networkDao.countNetworksUserCanCreate(accountId);
 -                } else if (type == Resource.ResourceType.vpc) {
 -                    newCount = _vpcDao.countByAccountId(accountId);
 -                } else if (type == Resource.ResourceType.cpu) {
 -                    newCount = countCpusForAccount(accountId);
 -                } else if (type == Resource.ResourceType.memory) {
 -                    newCount = calculateMemoryForAccount(accountId);
 -                } else if (type == Resource.ResourceType.primary_storage) {
 -                    List<Long> virtualRouters = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId);
 -                    newCount = _volumeDao.primaryStorageUsedForAccount(accountId, virtualRouters);
 -                } else if (type == Resource.ResourceType.secondary_storage) {
 -                    newCount = calculateSecondaryStorageForAccount(accountId);
 -                } else {
 -                    throw new InvalidParameterValueException("Unsupported resource type " + type);
 -                }
 -                _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue());
 -        
 -                if (oldCount != newCount) {
 -                    s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " +
 -                            newCount + ") for type " + type + " for account ID " + accountId + " is fixed during resource count recalculation.");
 -                }
 +        Long newCount = null;
 +
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
- 
 +        // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table
 +        // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too
 +        SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
 +        sc.setParameters("accountId", accountId);
 +        _resourceCountDao.lockRows(sc, null, true);
 +
 +        ResourceCountVO accountRC = _resourceCountDao.findByOwnerAndType(accountId, ResourceOwnerType.Account, type);
 +        long oldCount = 0;
 +        if (accountRC != null)
 +            oldCount = accountRC.getCount();
 +
 +        if (type == Resource.ResourceType.user_vm) {
 +            newCount = _userVmDao.countAllocatedVMsForAccount(accountId);
 +        } else if (type == Resource.ResourceType.volume) {
 +            newCount = _volumeDao.countAllocatedVolumesForAccount(accountId);
 +            long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size();
 +            newCount = newCount - virtualRouterCount; // don't count the volumes of virtual router
 +        } else if (type == Resource.ResourceType.snapshot) {
 +            newCount = _snapshotDao.countSnapshotsForAccount(accountId);
 +        } else if (type == Resource.ResourceType.public_ip) {
 +            newCount = calculatePublicIpForAccount(accountId);
 +        } else if (type == Resource.ResourceType.template) {
 +            newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
 +        } else if (type == Resource.ResourceType.project) {
 +            newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
 +        } else if (type == Resource.ResourceType.network) {
 +            newCount = _networkDao.countNetworksUserCanCreate(accountId);
 +        } else if (type == Resource.ResourceType.vpc) {
 +            newCount = _vpcDao.countByAccountId(accountId);
 +        } else if (type == Resource.ResourceType.cpu) {
 +            newCount = countCpusForAccount(accountId);
 +        } else if (type == Resource.ResourceType.memory) {
 +            newCount = calculateMemoryForAccount(accountId);
 +        } else if (type == Resource.ResourceType.primary_storage) {
 +            List<Long> virtualRouters = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId);
 +            newCount = _volumeDao.primaryStorageUsedForAccount(accountId, virtualRouters);
 +        } else if (type == Resource.ResourceType.secondary_storage) {
 +            newCount = calculateSecondaryStorageForAccount(accountId);
 +        } else {
 +            throw new InvalidParameterValueException("Unsupported resource type " + type);
 +        }
 +        _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue());
 +
 +        if (oldCount != newCount) {
 +            s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " +
 +                    newCount + ") for type " + type + " for account ID " + accountId + " is fixed during resource count recalculation.");
 +        }
-         txn.commit();
+                 
+                 return newCount;
+             }
+         });
  
          return (newCount == null) ? 0 : newCount.longValue();
      }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/server/ManagementServerImpl.java
index 1144330,79b20d0..5af088d
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@@ -211,7 -198,7 +212,8 @@@ import org.apache.cloudstack.api.comman
  import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd;
  import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd;
  import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
+ import org.apache.cloudstack.api.command.admin.vm.ExpungeVMCmd;
 +import org.apache.cloudstack.api.command.admin.vm.ListVMsCmdByAdmin;
  import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
  import org.apache.cloudstack.api.command.admin.vm.MigrateVirtualMachineWithVolumeCmd;
  import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
@@@ -583,6 -575,6 +587,8 @@@ import com.cloud.utils.db.JoinBuilder.J
  import com.cloud.utils.db.SearchBuilder;
  import com.cloud.utils.db.SearchCriteria;
  import com.cloud.utils.db.Transaction;
++import com.cloud.utils.db.TransactionCallbackNoReturn;
++import com.cloud.utils.db.TransactionStatus;
  import com.cloud.utils.exception.CloudRuntimeException;
  import com.cloud.utils.net.MacAddress;
  import com.cloud.utils.net.NetUtils;
@@@ -2758,9 -2762,9 +2769,10 @@@ public class ManagementServerImpl exten
          cmdList.add(AddNicToVMCmd.class);
          cmdList.add(DeployVMCmd.class);
          cmdList.add(DestroyVMCmd.class);
+         cmdList.add(ExpungeVMCmd.class);
          cmdList.add(GetVMPasswordCmd.class);
          cmdList.add(ListVMsCmd.class);
 +        cmdList.add(ListVMsCmdByAdmin.class);
          cmdList.add(ScaleVMCmd.class);
          cmdList.add(RebootVMCmd.class);
          cmdList.add(RemoveNicFromVMCmd.class);
@@@ -3893,4 -3879,21 +3901,21 @@@
  
          _dpMgr.cleanupVMReservations();
      }
+ 
+     public List<StoragePoolAllocator> getStoragePoolAllocators() {
+         return _storagePoolAllocators;
+     }
+ 
+     @Inject
+     public void setStoragePoolAllocators(List<StoragePoolAllocator> storagePoolAllocators) {
+         _storagePoolAllocators = storagePoolAllocators;
+     }
+ 
+     public LockMasterListener getLockMasterListener() {
+         return _lockMasterListener;
+     }
+ 
+     public void setLockMasterListener(LockMasterListener lockMasterListener) {
 -        this._lockMasterListener = lockMasterListener;
++        _lockMasterListener = lockMasterListener;
+     }
  }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/servlet/ConsoleProxyServlet.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/VolumeApiServiceImpl.java
index dbcb961,d445381..61422d1
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@@ -1050,8 -1066,17 +1066,17 @@@ public class VolumeApiServiceImpl exten
          HypervisorType rootDiskHyperType = vm.getHypervisorType();
  
          HypervisorType dataDiskHyperType = _volsDao.getHypervisorType(volume.getId());
+ 
+         VolumeVO dataDiskVol = _volsDao.findById(volume.getId());
+         StoragePoolVO dataDiskStoragePool = _storagePoolDao.findById(dataDiskVol.getPoolId());
+ 
+         // managed storage can be used for different types of hypervisors
+         // only perform this check if the volume's storage pool is not null and not managed
+         if (dataDiskStoragePool != null && !dataDiskStoragePool.isManaged()) {
 -            if (dataDiskHyperType != HypervisorType.None && rootDiskHyperType != dataDiskHyperType) {
 +        if (dataDiskHyperType != HypervisorType.None && rootDiskHyperType != dataDiskHyperType) {
-             throw new InvalidParameterValueException("Can't attach a volume created by: " + dataDiskHyperType + " to a " + rootDiskHyperType + " vm");
+                 throw new InvalidParameterValueException("Can't attach a volume created by: " + dataDiskHyperType +
+                     " to a " + rootDiskHyperType + " vm");
+             }
          }
  
          deviceId = getDeviceId(vmId, deviceId);
@@@ -1108,16 -1133,36 +1133,36 @@@
      }
  
      @Override
-     public Volume updateVolume(UpdateVolumeCmd cmd) {
-         Long volumeId = cmd.getId();
-         String path = cmd.getPath();
+     @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPDATE, eventDescription = "updating volume", async = true)
+     public Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume) {
+         VolumeVO volume = _volumeDao.findById(volumeId);
 -        
 +
-         if (path == null) {
-             throw new InvalidParameterValueException("Failed to update the volume as path was null");
+         if (path != null) {
+             volume.setPath(path);
+         }
+ 
+         if (displayVolume != null) {
+             volume.setDisplayVolume(displayVolume);
+         }
+         
+         if (state != null) {
+             try {
+                 Volume.State volumeState = Volume.State.valueOf(state);
+                 volume.setState(volumeState);
+             }
+             catch(IllegalArgumentException ex) {
+                 throw new InvalidParameterValueException("Invalid volume state specified");
+             }
+         }
+         
+         if (storageId != null) {
+             StoragePool pool = _storagePoolDao.findById(storageId);
+             if (pool.getDataCenterId() != volume.getDataCenterId()) {
+                 throw new InvalidParameterValueException("Invalid storageId specified; refers to the pool outside of the volume's zone");
+             }
+             volume.setPoolId(pool.getId());
          }
 -        
 +
-         VolumeVO volume = ApiDBUtils.findVolumeById(volumeId);
-         volume.setPath(path);
          _volumeDao.update(volumeId, volume);
  
          return volume;
@@@ -1519,15 -1568,25 +1568,25 @@@
          }
  
          if (storeForRootStoreScope.getScopeType() != storeForDataStoreScope.getScopeType()) {
-             if (storeForDataStoreScope.getScopeType() == ScopeType.CLUSTER && storeForRootStoreScope.getScopeType() == ScopeType.HOST) {
+             if (storeForDataStoreScope.getScopeType() == ScopeType.CLUSTER) {
+                 Long vmClusterId = null;
+                 if (storeForRootStoreScope.getScopeType() == ScopeType.HOST) {
 -                    HostScope hs = (HostScope)storeForRootStoreScope;
 +                HostScope hs = (HostScope)storeForRootStoreScope;
-                 if (storeForDataStoreScope.getScopeId().equals(hs.getClusterId())) {
-                     return false;
+                     vmClusterId = hs.getClusterId();
+                 } else if (storeForRootStoreScope.getScopeType() == ScopeType.ZONE) {
+                     Long hostId = _vmInstanceDao.findById(rootVolumeOfVm.getInstanceId()).getHostId();
+                     if (hostId != null) {
+                         HostVO host = _hostDao.findById(hostId);
+                         vmClusterId = host.getClusterId();
+                     }
                  }
+                 if (storeForDataStoreScope.getScopeId().equals(vmClusterId)) {
+                     return false;
 -                }
 +            }
-             if (storeForRootStoreScope.getScopeType() == ScopeType.CLUSTER && storeForDataStoreScope.getScopeType() == ScopeType.HOST) {
-                 HostScope hs = (HostScope)storeForDataStoreScope;
-                 if (storeForRootStoreScope.getScopeId().equals(hs.getClusterId())) {
+             } else if (storeForDataStoreScope.getScopeType() == ScopeType.HOST &&
+                     (storeForRootStoreScope.getScopeType() == ScopeType.CLUSTER || storeForRootStoreScope.getScopeType() == ScopeType.ZONE)) {
+                 Long hostId = _vmInstanceDao.findById(rootVolumeOfVm.getInstanceId()).getHostId();
+                 if (storeForDataStoreScope.getScopeId().equals(hostId)) {
                      return false;
                  }
              }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
index 69ed16e,d15393c..464f7f8
--- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@@ -197,10 -195,9 +195,9 @@@ public class SnapshotManagerImpl extend
      @Inject VolumeDataFactory volFactory;
      @Inject SnapshotDataFactory snapshotFactory;
      @Inject EndPointSelector _epSelector;
 -    @Inject
 -    private ResourceManager _resourceMgr;
 +	@Inject
 +	private ResourceManager _resourceMgr;
- 	@Inject
- 	protected List<SnapshotStrategy> snapshotStrategies;
+     @Inject StorageStrategyFactory _storageStrategyFactory;
  
  
      private int _totalRetries;
@@@ -311,119 -337,26 +337,26 @@@
          return snapshot;
      }
  
- 
- 
      @Override
      public Snapshot backupSnapshot(Long snapshotId) {
 -        SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Image);
 -        if (snapshot != null) {
 -            throw new CloudRuntimeException("Already in the backup snapshot:" + snapshotId);
 -        }
 +    	 SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Image);
 +    	 if (snapshot != null) {
 +    		 throw new CloudRuntimeException("Already in the backup snapshot:" + snapshotId);
 +    	 }
  
 -        return snapshotSrv.backupSnapshot(snapshot);
 +         return snapshotSrv.backupSnapshot(snapshot);
      }
  
-     /*
-     @Override
-     public void downloadSnapshotsFromSwift(SnapshotVO ss) {
- 
-         long volumeId = ss.getVolumeId();
-         VolumeVO volume = _volsDao.findById(volumeId);
-         Long dcId = volume.getDataCenterId();
-         Long accountId = volume.getAccountId();
-         DataStore secStore = this.dataStoreMgr.getImageStore(dcId);
- 
-         Long swiftId = ss.getSwiftId();
-         SwiftTO swift = _swiftMgr.getSwiftTO(swiftId);
-         SnapshotVO tss = ss;
-         List<String> BackupUuids = new ArrayList<String>(30);
-         while (true) {
-             BackupUuids.add(0, tss.getBackupSnapshotId());
-             if (tss.getPrevSnapshotId() == 0)
-                 break;
-             Long id = tss.getPrevSnapshotId();
-             tss = _snapshotDao.findById(id);
-             assert tss != null : " can not find snapshot " + id;
-         }
-         String parent = null;
-         try {
-             for (String backupUuid : BackupUuids) {
- <<<<<<< HEAD
-                 downloadSnapshotFromSwiftCommand cmd = new downloadSnapshotFromSwiftCommand(swift, secStore.getUri(), dcId, accountId, volumeId, parent, backupUuid, _backupsnapshotwait);
- =======
-                 DownloadSnapshotFromSwiftCommand cmd = new DownloadSnapshotFromSwiftCommand(swift, secondaryStoragePoolUrl, dcId, accountId, volumeId, parent, backupUuid, _backupsnapshotwait);
- >>>>>>> master
-                 Answer answer = _agentMgr.sendToSSVM(dcId, cmd);
-                 if ((answer == null) || !answer.getResult()) {
-                     throw new CloudRuntimeException("downloadSnapshotsFromSwift failed ");
-                 }
-                 parent = backupUuid;
-             }
-         } catch (Exception e) {
-             throw new CloudRuntimeException("downloadSnapshotsFromSwift failed due to " + e.toString());
-         }
- 
-     }
- 
-     private List<String> determineBackupUuids(final SnapshotVO snapshot) {
- 
-         final List<String> backupUuids = new ArrayList<String>();
-         backupUuids.add(0, snapshot.getBackupSnapshotId());
- 
-         SnapshotVO tempSnapshot = snapshot;
-         while (tempSnapshot.getPrevSnapshotId() != 0) {
-             tempSnapshot = _snapshotDao.findById(tempSnapshot
-                     .getPrevSnapshotId());
-             backupUuids.add(0, tempSnapshot.getBackupSnapshotId());
-         }
- 
-         return Collections.unmodifiableList(backupUuids);
-     }
- 
-     @Override
-     public void downloadSnapshotsFromS3(final SnapshotVO snapshot) {
- 
-         final VolumeVO volume = _volsDao.findById(snapshot.getVolumeId());
-         final Long zoneId = volume.getDataCenterId();
-         final DataStore secStore = this.dataStoreMgr.getImageStore(zoneId);
- 
-         final S3TO s3 = _s3Mgr.getS3TO(snapshot.getS3Id());
-         final List<String> backupUuids = determineBackupUuids(snapshot);
- 
-         try {
-             String parent = null;
-             for (final String backupUuid : backupUuids) {
-                 final DownloadSnapshotFromS3Command cmd = new DownloadSnapshotFromS3Command(
-                         s3, parent, secStore.getUri(), zoneId,
-                         volume.getAccountId(), volume.getId(), backupUuid,
-                         _backupsnapshotwait);
-                 final Answer answer = _agentMgr.sendToSSVM(zoneId, cmd);
-                 if ((answer == null) || !answer.getResult()) {
-                     throw new CloudRuntimeException(String.format(
-                             "S3 snapshot download failed due to %1$s.",
-                             answer != null ? answer.getDetails()
-                                     : "unspecified error"));
-                 }
-                 parent = backupUuid;
-             }
-         } catch (Exception e) {
-             throw new CloudRuntimeException(
-                     "Snapshot download from S3 failed due to " + e.toString(),
-                     e);
-         }
- 
-     }*/
- 
      @Override
      public SnapshotVO getParentSnapshot(VolumeInfo volume) {
 -        long preId = _snapshotDao.getLastSnapshot(volume.getId(), DataStoreRole.Primary);
 +    	 long preId = _snapshotDao.getLastSnapshot(volume.getId(), DataStoreRole.Primary);
  
 -        SnapshotVO preSnapshotVO = null;
 -        if (preId != 0 && !(volume.getLastPoolId() != null && !volume.getLastPoolId().equals(volume.getPoolId()))) {
 -            preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preId);
 -        }
 +         SnapshotVO preSnapshotVO = null;
 +         if (preId != 0 && !(volume.getLastPoolId() != null && !volume.getLastPoolId().equals(volume.getPoolId()))) {
 +             preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preId);
 +         }
  
 -        return preSnapshotVO;
 +         return preSnapshotVO;
      }
  
      private Long getSnapshotUserId() {
@@@ -463,9 -396,11 +396,11 @@@
          while (snaps.size() > maxSnaps && snaps.size() > 1) {
              SnapshotVO oldestSnapshot = snaps.get(0);
              long oldSnapId = oldestSnapshot.getId();
+             if (policy != null) {
 -                s_logger.debug("Max snaps: " + policy.getMaxSnaps() + " exceeded for snapshot policy with Id: " + policyId + ". Deleting oldest snapshot: " + oldSnapId);
 +            s_logger.debug("Max snaps: " + policy.getMaxSnaps() + " exceeded for snapshot policy with Id: " + policyId + ". Deleting oldest snapshot: " + oldSnapId);
+             }
              if(deleteSnapshot(oldSnapId)){
 -                //log Snapshot delete event
 +            	//log Snapshot delete event
                  ActionEventUtils.onCompletedActionEvent(User.UID_SYSTEM, oldestSnapshot.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_SNAPSHOT_DELETE, "Successfully deleted oldest snapshot: " + oldSnapId, 0);
              }
              snaps.remove(oldestSnapshot);
@@@ -485,21 -420,20 +420,20 @@@
          }
  
          _accountMgr.checkAccess(caller, null, true, snapshotCheck);
-         SnapshotStrategy snapshotStrategy = null;
-         for (SnapshotStrategy strategy : snapshotStrategies) {
-         	if (strategy.canHandle(snapshotCheck)) {
-         		snapshotStrategy = strategy;
-         		break;
-         	}
+         SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshotCheck, SnapshotOperation.DELETE);
+         if (snapshotStrategy == null) {
+             s_logger.error("Unable to find snaphot strategy to handle snapshot with id '"+snapshotId+"'");
+             return false;
          }
+ 
          try {
 -            boolean result = snapshotStrategy.deleteSnapshot(snapshotId);
 -            if (result) {
 +        	boolean result = snapshotStrategy.deleteSnapshot(snapshotId);
 +        	if (result) {
                  if (snapshotCheck.getState() == Snapshot.State.BackedUp) {
 -                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshotCheck.getAccountId(),
 -                            snapshotCheck.getDataCenterId(), snapshotId, snapshotCheck.getName(), null, null, 0L,
 -                            snapshotCheck.getClass().getName(), snapshotCheck.getUuid());
 -                }
 +        			UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshotCheck.getAccountId(),
 +        					snapshotCheck.getDataCenterId(), snapshotId, snapshotCheck.getName(), null, null, 0L,
 +        					snapshotCheck.getClass().getName(), snapshotCheck.getUuid());
 +        		}
                  _resourceLimitMgr.decrementResourceCount(snapshotCheck.getAccountId(), ResourceType.snapshot);
                  _resourceLimitMgr.decrementResourceCount(snapshotCheck.getAccountId(), ResourceType.secondary_storage,
                          new Long(snapshotCheck.getSize()));
@@@ -904,40 -834,38 +834,38 @@@
          return null;
      }
  
- 
- 
      private boolean hostSupportSnapsthotForVolume(HostVO host, VolumeInfo volume) {
 -        if (host.getHypervisorType() != HypervisorType.KVM) {
 -            return true;
 -        }
 +		if (host.getHypervisorType() != HypervisorType.KVM) {
 +			return true;
 +		}
  
          //Turn off snapshot by default for KVM if the volume attached to vm that is not in the Stopped/Destroyed state,
 -        //unless it is set in the global flag
 -        Long vmId = volume.getInstanceId();
 -        if (vmId != null) {
 -            VMInstanceVO vm = _vmDao.findById(vmId);
 -            if (vm.getState() != VirtualMachine.State.Stopped && vm.getState() != VirtualMachine.State.Destroyed) {
 -                boolean snapshotEnabled = Boolean.parseBoolean(_configDao.getValue("kvm.snapshot.enabled"));
 -                if (!snapshotEnabled) {
 -                    s_logger.debug("Snapshot is not supported on host " + host + " for the volume " + volume + " attached to the vm " + vm);
 -                    return false;
 -                }
 -            }
 -        }
 -
 -        // Determine host capabilities
 -        String caps = host.getCapabilities();
 -
 -        if (caps != null) {
 -            String[] tokens = caps.split(",");
 -            for (String token : tokens) {
 -                if (token.contains("snapshot")) {
 -                    return true;
 -                }
 -            }
 -        }
 -        return false;
 -    }
 +		//unless it is set in the global flag
 +		Long vmId = volume.getInstanceId();
 +		if (vmId != null) {
 +		    VMInstanceVO vm = _vmDao.findById(vmId);
 +		    if (vm.getState() != VirtualMachine.State.Stopped && vm.getState() != VirtualMachine.State.Destroyed) {
 +		        boolean snapshotEnabled = Boolean.parseBoolean(_configDao.getValue("kvm.snapshot.enabled"));
 +	            if (!snapshotEnabled) {
 +	                 s_logger.debug("Snapshot is not supported on host " + host + " for the volume " + volume + " attached to the vm " + vm);
 +	                 return false;
 +	            }
 +		    }
 +		}
 +        
 +		// Determine host capabilities
 +		String caps = host.getCapabilities();
 +
 +		if (caps != null) {
 +			String[] tokens = caps.split(",");
 +			for (String token : tokens) {
 +				if (token.contains("snapshot")) {
 +					return true;
 +				}
 +			}
 +		}
 +		return false;
 +	}
  
      private boolean supportedByHypervisor(VolumeInfo volume) {
          HypervisorType hypervisorType;
@@@ -995,39 -923,38 +923,38 @@@
                      throw new CloudRuntimeException(
                              "There is other active vm snapshot tasks on the instance to which the volume is attached, please try again later");
                  }
 -            }
 -        }
 +			}
 +		}
  
 -        return true;
 -    }
 +		return true;
 +	}
      @Override
+     @DB
      public SnapshotInfo takeSnapshot(VolumeInfo volume) throws ResourceAllocationException {
          CreateSnapshotPayload payload = (CreateSnapshotPayload)volume.getpayload();
          Long snapshotId = payload.getSnapshotId();
          Account snapshotOwner = payload.getAccount();
          SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotId, volume.getDataStore());
-         boolean processed = false;
  
          try {
-             for (SnapshotStrategy strategy : snapshotStrategies) {
-                 if (strategy.canHandle(snapshot)) {
-                     processed = true;
-                     snapshot = strategy.takeSnapshot(snapshot);
-                     break;
-                 }
-             }
-             if (!processed) {
+             SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
+ 
+             if (snapshotStrategy == null) {
                  throw new CloudRuntimeException("Can't find snapshot strategy to deal with snapshot:" + snapshotId);
              }
+ 
+             snapshotStrategy.takeSnapshot(snapshot);
+ 
+             try {
 -                postCreateSnapshot(volume.getId(), snapshotId, payload.getSnapshotPolicyId());
 +            postCreateSnapshot(volume.getId(), snapshotId, payload.getSnapshotPolicyId());
  
 -                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(),
 -                        snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null,
 -                        volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
 -                _resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
 +            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(),
 +                    snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null,
 +                    volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
- 
- 
 +            _resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
- 
+             } catch (Exception e) {
+                 s_logger.debug("post process snapshot failed", e);
+             }
          } catch(Exception e) {
              s_logger.debug("Failed to create snapshot", e);
              if (backup) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/template/TemplateAdapterBase.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/template/TemplateManagerImpl.java
index a1e20b9,50e557a..d40a01f
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@@ -770,30 -778,43 +778,43 @@@ public class TemplateManagerImpl extend
      }
  
      @Override
+     @DB
      public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) {
+         //Need to hold the lock, otherwise, another thread may create a volume from the template at the same time.
+         //Assumption here is that, we will hold the same lock during create volume from template
+         VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolVO.getId());
+         if (templatePoolRef == null) {
+            s_logger.debug("can't aquire the lock for template pool ref:" + templatePoolVO.getId());
+            return;
+         }
+ 
+         try {
 -            StoragePool pool = (StoragePool) _dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
 -            VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
 +        StoragePool pool = (StoragePool) _dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
 +        VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
  
 -            if (s_logger.isDebugEnabled()) {
 -                s_logger.debug("Evicting " + templatePoolVO);
 -            }
 -            DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO);
 +        if (s_logger.isDebugEnabled()) {
 +            s_logger.debug("Evicting " + templatePoolVO);
 +        }
 +        DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO);
  
 -            try {
 -                Answer answer = _storageMgr.sendToPool(pool, cmd);
 +        try {
 +            Answer answer = _storageMgr.sendToPool(pool, cmd);
  
 -                if (answer != null && answer.getResult()) {
 -                    // Remove the templatePoolVO
 -                    if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
 -                        s_logger.debug("Successfully evicted template: " + template.getName() + " from storage pool: " + pool.getName());
 -                    }
 -                } else {
 -                    s_logger.info("Will retry evicte template: " + template.getName() + " from storage pool: " + pool.getName());
 +            if (answer != null && answer.getResult()) {
 +                // Remove the templatePoolVO
 +                if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
 +                    s_logger.debug("Successfully evicted template: " + template.getName() + " from storage pool: " + pool.getName());
                  }
 -            } catch (StorageUnavailableException e) {
 -                s_logger.info("Storage is unavailable currently.  Will retry evicte template: " + template.getName() + " from storage pool: "
 -                        + pool.getName());
 +            } else {
 +                s_logger.info("Will retry evicte template: " + template.getName() + " from storage pool: " + pool.getName());
              }
 +        } catch (StorageUnavailableException e) {
 +            s_logger.info("Storage is unavailable currently.  Will retry evicte template: " + template.getName() + " from storage pool: "
 +                    + pool.getName());
 +        }
+         } finally {
+             _tmpltPoolDao.releaseFromLockTable(templatePoolRef.getId());
+         }
  
      }