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:54 UTC

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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/usage/UsageServiceImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/usage/UsageServiceImpl.java
index c96e036,d16d36d..f7cfe31
--- a/server/src/com/cloud/usage/UsageServiceImpl.java
+++ b/server/src/com/cloud/usage/UsageServiceImpl.java
@@@ -153,14 -151,17 +154,17 @@@ public class UsageServiceImpl extends M
          } 
  
          boolean isAdmin = false;
+         boolean isDomainAdmin = false;
 - 
 +        
          //If accountId couldn't be found using accountName and domainId, get it from userContext
          if(accountId == null){
              accountId = caller.getId();
              //List records for all the accounts if the caller account is of type admin. 
              //If account_id or account_name is explicitly mentioned, list records for the specified account only even if the caller is of type admin
 -            if(caller.getType() == Account.ACCOUNT_TYPE_ADMIN){
 +            if (_accountService.isRootAdmin(caller.getId())) {
                  isAdmin = true;
+             } else if(caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN){
+                 isDomainAdmin = true;
              }
              s_logger.debug("Account details not available. Using userContext accountId: " + accountId);
          }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/user/AccountManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/user/AccountManagerImpl.java
index 03b51f4,27fd66a..a88b614
--- a/server/src/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/com/cloud/user/AccountManagerImpl.java
@@@ -513,18 -483,20 +516,20 @@@ public class AccountManagerImpl extend
      }
  
      @DB
-     public void updateLoginAttempts(Long id, int attempts, boolean toDisable) {
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
+     public void updateLoginAttempts(final Long id, final int attempts, final boolean toDisable) {
          try {
+             Transaction.execute(new TransactionCallbackNoReturn() {
+                 @Override
+                 public void doInTransactionWithoutResult(TransactionStatus status) {
 -                    UserAccountVO user = null;
 -                    user = _userAccountDao.lockRow(id, true);
 -                    user.setLoginAttempts(attempts);
 -                    if(toDisable) {
 -                        user.setState(State.disabled.toString());
 -                    }
 -                    _userAccountDao.update(id, user);
 +            UserAccountVO user = null;
 +            user = _userAccountDao.lockRow(id, true);
 +            user.setLoginAttempts(attempts);
 +            if(toDisable) {
 +                user.setState(State.disabled.toString());
 +            }
 +            _userAccountDao.update(id, user);
-              txn.commit();
+                 }
+             });
          } catch (Exception e) {
              s_logger.error("Failed to update login attempts for user with id " + id );
          }
@@@ -938,33 -906,35 +942,42 @@@
              }
          }
  
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
+         final String accountNameFinal = accountName;
+         final Long domainIdFinal = domainId;
+         final String accountUUIDFinal = accountUUID;
+         Pair<Long, Account> pair = Transaction.execute(new TransactionCallback<Pair<Long, Account>>() {
+             @Override
+             public Pair<Long, Account> doInTransaction(TransactionStatus status) {
+                 // create account
+                 String accountUUID = accountUUIDFinal;
 -                if(accountUUID == null){
++                if (accountUUID == null) {
+                     accountUUID = UUID.randomUUID().toString();
+                 }
+                 AccountVO account = createAccount(accountNameFinal, accountType, domainIdFinal, networkDomain, details, accountUUID);
+                 long accountId = account.getId();
 -        
 +
-         // create account
-         if(accountUUID == null){
-             accountUUID = UUID.randomUUID().toString();
-         }
-         AccountVO account = createAccount(accountName, accountType, domainId, networkDomain, details, accountUUID);
-         long accountId = account.getId();
+                 // create the first user for the account
+                 UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone, userUUID);
 -        
 +
-         // create the first user for the account
-         UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone, userUUID);
+                 if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
+                     // set registration token
+                     byte[] bytes = (domainIdFinal + accountNameFinal + userName + System.currentTimeMillis()).getBytes();
+                     String registrationToken = UUID.nameUUIDFromBytes(bytes).toString();
+                     user.setRegistrationToken(registrationToken);
+                 }
 +
-         if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
-             // set registration token
-             byte[] bytes = (domainId + accountName + userName + System.currentTimeMillis()).getBytes();
-             String registrationToken = UUID.nameUUIDFromBytes(bytes).toString();
-             user.setRegistrationToken(registrationToken);
-         }
++                // create correct account and group association based on accountType
++                if (accountType != Account.ACCOUNT_TYPE_PROJECT) {
++                    AclGroupAccountMapVO grpAcct = new AclGroupAccountMapVO(accountType + 1, accountId);
++                    _aclGroupAccountDao.persist(grpAcct);
++                }
 +
-         // create correct account and group association based on accountType
-         if (accountType != Account.ACCOUNT_TYPE_PROJECT) {
-             AclGroupAccountMapVO grpAcct = new AclGroupAccountMapVO(accountType + 1, accountId);
-             _aclGroupAccountDao.persist(grpAcct);
-         }
+                 return new Pair<Long, Account>(user.getId(), account);
+             }
+         });
  
-         txn.commit();
+         long userId = pair.first();
+         Account account = pair.second();
  
          CallContext.current().putContextParameter(Account.class, account.getUuid());
  
@@@ -1198,15 -1168,18 +1211,18 @@@
  
          checkAccess(caller, null, true, account);
  
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
- 
+         boolean success = Transaction.execute(new TransactionCallback<Boolean>() {
+             @Override
+             public Boolean doInTransaction(TransactionStatus status) {
 -                boolean success = doSetUserStatus(userId, State.enabled);
 -        
 -                // make sure the account is enabled too
 -                success = success && enableAccount(user.getAccountId());
 -                
 +        boolean success = doSetUserStatus(userId, State.enabled);
 +
 +        // make sure the account is enabled too
 +        success = success && enableAccount(user.getAccountId());
 +
-         txn.commit();
+                 return success;
+             }
+         });
+ 
  
          if (success) {
              // whenever the user is successfully enabled, reset the login attempts to zero
@@@ -1488,16 -1461,19 +1504,19 @@@
              }
          }
  
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
- 
-         success = _accountDao.update(account.getId(), acctForUpdate);
+         final Account accountFinal = account;
+         success = Transaction.execute(new TransactionCallback<Boolean>() {
+             @Override
+             public Boolean doInTransaction(TransactionStatus status) {
+                 boolean success = _accountDao.update(accountFinal.getId(), acctForUpdate);
  
 -                if (details != null && success) {
 +        if (details != null && success) {
-             _accountDetailsDao.update(account.getId(), details);
+                     _accountDetailsDao.update(accountFinal.getId(), details);
 -                }
 +        }
  
-         txn.commit();
+                 return success;
+             }
+         });
  
          if (success) {
              CallContext.current().putContextParameter(Account.class, account.getUuid());
@@@ -1799,30 -1766,31 +1809,31 @@@
          }
  
          // Create the account
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
- 
+         return Transaction.execute(new TransactionCallback<AccountVO>() {
+             @Override
+             public AccountVO doInTransaction(TransactionStatus status) {
 -                AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, uuid));
 -        
 -                if (account == null) {
 -                    throw new CloudRuntimeException("Failed to create account name " + accountName + " in domain id=" + domainId);
 -                }
 -        
 -                Long accountId = account.getId();
 -        
 -                if (details != null) {
 -                    _accountDetailsDao.persist(accountId, details);
 -                }
 -        
 -                // Create resource count records for the account
 -                _resourceCountDao.createResourceCounts(accountId, ResourceLimit.ResourceOwnerType.Account);
 -        
 -                // Create default security group
 -                _networkGroupMgr.createDefaultSecurityGroup(accountId);
 +        AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, uuid));
  
 -                return account;
 -            }
 +        if (account == null) {
 +            throw new CloudRuntimeException("Failed to create account name " + accountName + " in domain id=" + domainId);
 +        }
 +
 +        Long accountId = account.getId();
 +
 +        if (details != null) {
 +            _accountDetailsDao.persist(accountId, details);
 +        }
 +
 +        // Create resource count records for the account
 +        _resourceCountDao.createResourceCounts(accountId, ResourceLimit.ResourceOwnerType.Account);
 +
 +        // Create default security group
 +        _networkGroupMgr.createDefaultSecurityGroup(accountId);
-         txn.commit();
 +
 +        return account;
 +    }
+         });
+     }
  
      protected UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone, String userUUID) {
          if (s_logger.isDebugEnabled()) {
@@@ -2071,12 -2039,14 +2082,14 @@@
          }
  
          // generate both an api key and a secret key, update the user table with the keys, return the keys to the user
-         String[] keys = new String[2];
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
+         final String[] keys = new String[2];
+         Transaction.execute(new TransactionCallbackNoReturn() {
+             @Override
+             public void doInTransactionWithoutResult(TransactionStatus status) {
 -                keys[0] = createUserApiKey(userId);
 -                keys[1] = createUserSecretKey(userId);
 +        keys[0] = createUserApiKey(userId);
 +        keys[1] = createUserSecretKey(userId);
-         txn.commit();
+             }
+         });
  
          return keys;
      }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/user/DomainManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/user/DomainManagerImpl.java
index 58e8017,8416645..fa53b03
--- a/server/src/com/cloud/user/DomainManagerImpl.java
+++ b/server/src/com/cloud/user/DomainManagerImpl.java
@@@ -181,11 -192,16 +192,16 @@@ public class DomainManagerImpl extends 
              domainUUID = UUID.randomUUID().toString();
          }
  
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
-         DomainVO domain = _domainDao.create(new DomainVO(name, ownerId, parentId, networkDomain, domainUUID));
+         final String domainUUIDFinal = domainUUID;
+         DomainVO domain = Transaction.execute(new TransactionCallback<DomainVO>() {
+             @Override
+             public DomainVO doInTransaction(TransactionStatus status) {
+                 DomainVO domain = _domainDao.create(new DomainVO(name, ownerId, parentId, networkDomain, domainUUIDFinal));
 -                _resourceCountDao.createResourceCounts(domain.getId(), ResourceLimit.ResourceOwnerType.Domain);
 +        _resourceCountDao.createResourceCounts(domain.getId(), ResourceLimit.ResourceOwnerType.Domain);
-         txn.commit();
+                 return domain;
+             }
+         });
+ 
          CallContext.current().putContextParameter(Domain.class, domain.getUuid());
          return domain;
      }
@@@ -587,27 -603,28 +603,28 @@@
              }
          }
  
-         Transaction txn = Transaction.currentTxn();
- 
-         txn.start();
- 
+         Transaction.execute(new TransactionCallbackNoReturn() {
+             @Override
+             public void doInTransactionWithoutResult(TransactionStatus status) {
 -                if (domainName != null) {
 -                    String updatedDomainPath = getUpdatedDomainPath(domain.getPath(), domainName);
 -                    updateDomainChildren(domain, updatedDomainPath);
 -                    domain.setName(domainName);
 -                    domain.setPath(updatedDomainPath);
 -                }
 -        
 -                if (networkDomain != null) {
 -                    if (networkDomain.isEmpty()) {
 -                        domain.setNetworkDomain(null);
 -                    } else {
 -                        domain.setNetworkDomain(networkDomain);
 -                    }
 -                }
 -                _domainDao.update(domainId, domain);
 -                CallContext.current().putContextParameter(Domain.class, domain.getUuid());
 +        if (domainName != null) {
 +            String updatedDomainPath = getUpdatedDomainPath(domain.getPath(), domainName);
 +            updateDomainChildren(domain, updatedDomainPath);
 +            domain.setName(domainName);
 +            domain.setPath(updatedDomainPath);
 +        }
 +
 +        if (networkDomain != null) {
 +            if (networkDomain.isEmpty()) {
 +                domain.setNetworkDomain(null);
 +            } else {
 +                domain.setNetworkDomain(networkDomain);
 +            }
 +        }
 +        _domainDao.update(domainId, domain);
 +        CallContext.current().putContextParameter(Domain.class, domain.getUuid());
-         txn.commit();
+             }
+         });
+ 
  
          return _domainDao.findById(domainId);
  

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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/vm/UserVmManagerImpl.java
index fb00f91,a0c7151..2f1c6c0
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@@ -68,10 -68,15 +69,15 @@@ import org.apache.cloudstack.engine.orc
  import org.apache.cloudstack.engine.service.api.OrchestrationService;
  import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
  import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
++import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
++import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
++import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
++import org.apache.cloudstack.framework.async.AsyncCallFuture;
  import org.apache.cloudstack.framework.config.ConfigKey;
  import org.apache.cloudstack.framework.config.Configurable;
  import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
  import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+ import org.apache.cloudstack.managed.context.ManagedContextRunnable;
 -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
 -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
 -import org.apache.cloudstack.framework.async.AsyncCallFuture;
  import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
  import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
  import org.apache.cloudstack.storage.to.TemplateObjectTO;
@@@ -210,7 -220,7 +216,6 @@@ import com.cloud.template.VirtualMachin
  import com.cloud.user.Account;
  import com.cloud.user.AccountManager;
  import com.cloud.user.AccountService;
--import com.cloud.user.AccountVO;
  import com.cloud.user.ResourceLimitService;
  import com.cloud.user.SSHKeyPair;
  import com.cloud.user.SSHKeyPairVO;
@@@ -232,9 -242,17 +237,13 @@@ import com.cloud.utils.concurrency.Name
  import com.cloud.utils.crypt.RSAHelper;
  import com.cloud.utils.db.DB;
  import com.cloud.utils.db.EntityManager;
 -import com.cloud.utils.db.Filter;
  import com.cloud.utils.db.GlobalLock;
 -import com.cloud.utils.db.SearchBuilder;
  import com.cloud.utils.db.SearchCriteria;
 -import com.cloud.utils.db.TransactionCallback;
 -import com.cloud.utils.db.TransactionCallbackNoReturn;
 -import com.cloud.utils.db.SearchCriteria.Func;
  import com.cloud.utils.db.Transaction;
++import com.cloud.utils.db.TransactionCallbackNoReturn;
+ import com.cloud.utils.db.TransactionCallbackWithException;
+ import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
+ import com.cloud.utils.db.TransactionStatus;
  import com.cloud.utils.exception.CloudRuntimeException;
  import com.cloud.utils.exception.ExecutionException;
  import com.cloud.utils.fsm.NoTransitionException;
@@@ -1403,68 -1425,70 +1416,70 @@@ public class UserVmManagerImpl extends 
              s_logger.debug("Recovering vm " + vmId);
          }
  
-         Transaction txn = Transaction.currentTxn();
-         AccountVO account = null;
-         txn.start();
+         Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
+             @Override
+             public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
 -        
 +
-         account = _accountDao.lockRow(vm.getAccountId(), true);
+                 Account account = _accountDao.lockRow(vm.getAccountId(), true);
 -        
 -                // if the account is deleted, throw error
 -                if (account.getRemoved() != null) {
 -                    throw new CloudRuntimeException(
 -                            "Unable to recover VM as the account is deleted");
 -                }
 -        
 -                // Get serviceOffering for Virtual Machine
 -                ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(vm.getServiceOfferingId());
 -        
 -                // First check that the maximum number of UserVMs, CPU and Memory limit for the given
 -                // accountId will not be exceeded
 -                resourceLimitCheck(account, new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize()));
 -        
 -                _haMgr.cancelDestroy(vm, vm.getHostId());
 -        
 -                try {
 -                    if (!_itMgr.stateTransitTo(vm,
 -                            VirtualMachine.Event.RecoveryRequested, null)) {
 -                        s_logger.debug("Unable to recover the vm because it is not in the correct state: "
 +
 +        // if the account is deleted, throw error
 +        if (account.getRemoved() != null) {
 +            throw new CloudRuntimeException(
 +                    "Unable to recover VM as the account is deleted");
 +        }
 +
 +        // Get serviceOffering for Virtual Machine
 +        ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(vm.getServiceOfferingId());
 +
 +        // First check that the maximum number of UserVMs, CPU and Memory limit for the given
 +        // accountId will not be exceeded
 +        resourceLimitCheck(account, new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize()));
 +
 +        _haMgr.cancelDestroy(vm, vm.getHostId());
 +
 +        try {
 +            if (!_itMgr.stateTransitTo(vm,
 +                    VirtualMachine.Event.RecoveryRequested, null)) {
 +                s_logger.debug("Unable to recover the vm because it is not in the correct state: "
 +                        + vmId);
 +                throw new InvalidParameterValueException(
 +                        "Unable to recover the vm because it is not in the correct state: "
                                  + vmId);
 -                        throw new InvalidParameterValueException(
 -                                "Unable to recover the vm because it is not in the correct state: "
 -                                        + vmId);
 -                    }
 -                } catch (NoTransitionException e) {
 -                    throw new InvalidParameterValueException(
 -                            "Unable to recover the vm because it is not in the correct state: "
 -                                    + vmId);
 -                }
 -        
 -                // Recover the VM's disks
 -                List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
 -                for (VolumeVO volume : volumes) {
 -                    if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
 -                        // Create an event
 -                        Long templateId = volume.getTemplateId();
 -                        Long diskOfferingId = volume.getDiskOfferingId();
 -                        Long offeringId = null;
 -                        if (diskOfferingId != null) {
 -                            DiskOfferingVO offering = _diskOfferingDao
 -                                    .findById(diskOfferingId);
 -                            if (offering != null
 -                                    && (offering.getType() == DiskOfferingVO.Type.Disk)) {
 -                                offeringId = offering.getId();
 -                            }
 -                        }
 -                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(),
 -                                volume.getDataCenterId(), volume.getId(), volume.getName(), offeringId, templateId,
 -                                volume.getSize(), Volume.class.getName(), volume.getUuid());
 +            }
 +        } catch (NoTransitionException e) {
 +            throw new InvalidParameterValueException(
 +                    "Unable to recover the vm because it is not in the correct state: "
 +                            + vmId);
 +        }
 +
 +        // Recover the VM's disks
 +        List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
 +        for (VolumeVO volume : volumes) {
 +            if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
 +                // Create an event
 +                Long templateId = volume.getTemplateId();
 +                Long diskOfferingId = volume.getDiskOfferingId();
 +                Long offeringId = null;
 +                if (diskOfferingId != null) {
 +                    DiskOfferingVO offering = _diskOfferingDao
 +                            .findById(diskOfferingId);
 +                    if (offering != null
 +                            && (offering.getType() == DiskOfferingVO.Type.Disk)) {
 +                        offeringId = offering.getId();
                      }
                  }
 -        
 -                //Update Resource Count for the given account
 -                resourceCountIncrement(account.getId(), new Long(serviceOffering.getCpu()),
 -                        new Long(serviceOffering.getRamSize()));
 +                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(),
 +                        volume.getDataCenterId(), volume.getId(), volume.getName(), offeringId, templateId,
 +                        volume.getSize(), Volume.class.getName(), volume.getUuid());
 +            }
 +        }
 +
 +        //Update Resource Count for the given account
 +        resourceCountIncrement(account.getId(), new Long(serviceOffering.getCpu()),
 +                new Long(serviceOffering.getRamSize()));
-         txn.commit();
+             }
+         });
+ 
  
          return _vmDao.findById(vmId);
      }
@@@ -1773,28 -1791,11 +1782,11 @@@
                      "unable to find virtual machine with id " + id);
          }
  
-         ServiceOffering offering = _serviceOfferingDao.findById(vmInstance
-                 .getServiceOfferingId());
-         if (!offering.getOfferHA() && ha != null && ha) {
-             throw new InvalidParameterValueException(
-                     "Can't enable ha for the vm as it's created from the Service offering having HA disabled");
-         }
- 
          _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true,
                  vmInstance);
 -        
 +
-         if (displayName == null) {
-             displayName = vmInstance.getDisplayName();
-         }
- 
-         if (ha == null) {
-             ha = vmInstance.isHaEnabled();
-         }
- 
-         if (isDisplayVmEnabled == null) {
-             isDisplayVmEnabled = vmInstance.isDisplayVm();
-         } else{
-             if(!_accountMgr.isRootAdmin(caller.getId())){
+         if (isDisplayVmEnabled != null) {
+             if(!_accountMgr.isRootAdmin(caller.getType())){
                  throw new PermissionDeniedException( "Cannot update parameter displayvm, only admin permitted ");
              }
          }
@@@ -1810,7 -1818,25 +1809,25 @@@
              throw new InvalidParameterValueException("Vm with id " + id
                      + " is not in the right state");
          }
 -        
 +
+         if (displayName == null) {
+             displayName = vm.getDisplayName();
+         }
+ 
+         if (ha == null) {
+             ha = vm.isHaEnabled();
+         }
+ 
+         ServiceOffering offering = _serviceOfferingDao.findById(vm.getServiceOfferingId());
+         if (!offering.getOfferHA() && ha) {
+             throw new InvalidParameterValueException(
+                     "Can't enable ha for the vm as it's created from the Service offering having HA disabled");
+         }
+         
+         if (isDisplayVmEnabled == null) {
+             isDisplayVmEnabled = vm.isDisplayVm();
+         }
+ 
          boolean updateUserdata = false;
          if (userData != null) {
              // check and replace newlines
@@@ -1819,26 -1845,15 +1836,15 @@@
              // update userData on domain router.
              updateUserdata = true;
          } else {
-             userData = vmInstance.getUserData();
+             userData = vm.getUserData();
          }
  
-         String description = "";
- 
-         if (displayName != null && !displayName.equals(vmInstance.getDisplayName())) {
-             description += "New display name: " + displayName + ". ";
+         if (isDynamicallyScalable == null) {
+             isDynamicallyScalable = vm.isDynamicallyScalable();
          }
 -        
 +
-         if (ha != vmInstance.isHaEnabled()) {
-             if (ha) {
-                 description += "Enabled HA. ";
-             } else {
-                 description += "Disabled HA. ";
-             }
-         }
          if (osTypeId == null) {
-             osTypeId = vmInstance.getGuestOSId();
-         } else {
-             description += "Changed Guest OS Type to " + osTypeId + ". ";
+             osTypeId = vm.getGuestOSId();
          }
  
          if (group != null) {
@@@ -2056,35 -2087,41 +2078,41 @@@
                          + userVmId);
              }
              try {
+                 final InstanceGroupVO groupFinal = group;
+                 Transaction.execute(new TransactionCallbackNoReturn() {
+                     @Override
+                     public void doInTransactionWithoutResult(TransactionStatus status) {
 -                        // don't let the group be deleted when we are assigning vm to
 -                        // it.
 +                // don't let the group be deleted when we are assigning vm to
 +                // it.
-                 InstanceGroupVO ngrpLock = _vmGroupDao.lockRow(group.getId(),
+                         InstanceGroupVO ngrpLock = _vmGroupDao.lockRow(groupFinal.getId(),
 -                                false);
 -                        if (ngrpLock == null) {
 -                            s_logger.warn("Failed to acquire lock on vm group id="
 +                        false);
 +                if (ngrpLock == null) {
 +                    s_logger.warn("Failed to acquire lock on vm group id="
-                             + group.getId() + " name=" + group.getName());
-                     txn.rollback();
-                     return false;
+                                     + groupFinal.getId() + " name=" + groupFinal.getName());
+                             throw new CloudRuntimeException("Failed to acquire lock on vm group id="
+                                     + groupFinal.getId() + " name=" + groupFinal.getName());
 -                        }
 -        
 -                        // Currently don't allow to assign a vm to more than one group
 -                        if (_groupVMMapDao.listByInstanceId(userVmId) != null) {
 -                            // Delete all mappings from group_vm_map table
 -                            List<InstanceGroupVMMapVO> groupVmMaps = _groupVMMapDao
 -                                    .listByInstanceId(userVmId);
 -                            for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
 -                                SearchCriteria<InstanceGroupVMMapVO> sc = _groupVMMapDao
 -                                        .createSearchCriteria();
 -                                sc.addAnd("instanceId", SearchCriteria.Op.EQ,
 -                                        groupMap.getInstanceId());
 -                                _groupVMMapDao.expunge(sc);
 -                            }
 -                        }
 -                        InstanceGroupVMMapVO groupVmMapVO = new InstanceGroupVMMapVO(
 +                }
 +
 +                // Currently don't allow to assign a vm to more than one group
 +                if (_groupVMMapDao.listByInstanceId(userVmId) != null) {
 +                    // Delete all mappings from group_vm_map table
 +                    List<InstanceGroupVMMapVO> groupVmMaps = _groupVMMapDao
 +                            .listByInstanceId(userVmId);
 +                    for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
 +                        SearchCriteria<InstanceGroupVMMapVO> sc = _groupVMMapDao
 +                                .createSearchCriteria();
 +                        sc.addAnd("instanceId", SearchCriteria.Op.EQ,
 +                                groupMap.getInstanceId());
 +                        _groupVMMapDao.expunge(sc);
 +                    }
 +                }
 +                InstanceGroupVMMapVO groupVmMapVO = new InstanceGroupVMMapVO(
-                         group.getId(), userVmId);
+                                 groupFinal.getId(), userVmId);
 -                        _groupVMMapDao.persist(groupVmMapVO);
 +                _groupVMMapDao.persist(groupVmMapVO);
  
-                 txn.commit();
+                     }
+                 });
+ 
                  return true;
              } finally {
                  if (userVm != null) {
@@@ -2459,7 -2496,11 +2487,11 @@@
              throw new PermissionDeniedException(
                      "The owner of vm to deploy is disabled: " + owner);
          }
+         VMTemplateVO template = _templateDao.findById(tmplt.getId());
+         if (template != null) {
+             _templateDao.loadDetails(template);
+         }
 -        
 +
          long accountId = owner.getId();
  
          assert !(requestedIps != null && (defaultIps.getIp4Address() != null || defaultIps.getIp6Address() != null)) : "requestedIp list and defaultNetworkIp should never be specified together";
@@@ -2749,121 -2790,139 +2781,139 @@@
              hypervisorType = template.getHypervisorType();
          }
  
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
+         UserVmVO vm = commitUserVm(zone, template, hostName, displayName, owner, diskOfferingId, diskSize, userData,
+                 hypervisor, caller, isDisplayVmEnabled, keyboard, accountId, offering, isIso, sshPublicKey,
+                 networkNicMap, id, instanceName, uuidName, hypervisorType);
+ 
+         // Assign instance to the group
+         try {
+             if (group != null) {
+                 boolean addToGroup = addInstanceToGroup(Long.valueOf(id), group);
+                 if (!addToGroup) {
+                     throw new CloudRuntimeException(
+                             "Unable to assign Vm to the group " + group);
+                 }
+             }
+         } catch (Exception ex) {
+             throw new CloudRuntimeException("Unable to assign Vm to the group "
+                     + group);
+         }
+ 
+         _securityGroupMgr.addInstanceToGroups(vm.getId(), securityGroupIdList);
+ 
+         if (affinityGroupIdList != null && !affinityGroupIdList.isEmpty()) {
+             _affinityGroupVMMapDao.updateMap(vm.getId(), affinityGroupIdList);
+         }
+ 
+         return vm;
+     }
+ 
+     private UserVmVO commitUserVm(final DataCenter zone, final VirtualMachineTemplate template, final String hostName,
+             final String displayName, final Account owner, final Long diskOfferingId, final Long diskSize, final String userData,
+             final HypervisorType hypervisor, final Account caller, final Boolean isDisplayVmEnabled, final String keyboard, final long accountId,
+             final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey,
+             final LinkedHashMap<String, NicProfile> networkNicMap, final long id, final String instanceName, final String uuidName,
+             final HypervisorType hypervisorType) throws InsufficientCapacityException {
+         return Transaction.execute(new TransactionCallbackWithException<UserVmVO,InsufficientCapacityException>() {
+             @Override
+             public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException {
 -                UserVmVO vm = new UserVmVO(id, instanceName, displayName,
 -                        template.getId(), hypervisorType, template.getGuestOSId(),
 -                        offering.getOfferHA(), offering.getLimitCpuUse(),
 -                        owner.getDomainId(), owner.getId(), offering.getId(), userData,
 -                        hostName, diskOfferingId);
 -                vm.setUuid(uuidName);
 -                vm.setDynamicallyScalable(template.isDynamicallyScalable());
 -                if (sshPublicKey != null) {
 -                    vm.setDetail("SSH.PublicKey", sshPublicKey);
 -                }
 -        
 -                if (keyboard != null && !keyboard.isEmpty())
 -                    vm.setDetail(VmDetailConstants.KEYBOARD, keyboard);
 -        
 -                if (isIso) {
 -                    vm.setIsoId(template.getId());
 -                }
 -        
 -                if(isDisplayVmEnabled != null){
 -                    if(!_accountMgr.isRootAdmin(caller.getType())){
 -                        throw new PermissionDeniedException( "Cannot update parameter displayvm, only admin permitted ");
 -                    }
 -                    vm.setDisplayVm(isDisplayVmEnabled);
 -                }else {
 -                    vm.setDisplayVm(true);
 -                }
 -        
 -                // If hypervisor is vSphere, check for clone type setting.
 -                if (hypervisorType.equals(HypervisorType.VMware)) {
 -                    // retrieve clone flag.
 -                    UserVmCloneType cloneType = UserVmCloneType.linked;
 -                    String value = _configDao.getValue(Config.VmwareCreateFullClone.key());
 -                    if (value != null) {
 -                        if (Boolean.parseBoolean(value) == true)
 -                            cloneType = UserVmCloneType.full;
 -                    }
 -                    UserVmCloneSettingVO vmCloneSettingVO = new UserVmCloneSettingVO(id, cloneType.toString());
 -                    _vmCloneSettingDao.persist(vmCloneSettingVO);
 -                }
 -        
 -                long guestOSId = template.getGuestOSId();
 -                GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
 -                long guestOSCategoryId = guestOS.getCategoryId();
 -                GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId);
 -        
 -        
 -                // If hypervisor is vSphere and OS is OS X, set special settings.
 -                if (hypervisorType.equals(HypervisorType.VMware)) {
 -                    if (guestOS.getDisplayName().toLowerCase().contains("apple mac os")){
 -                        vm.setDetail("smc.present", "TRUE");
 -                        vm.setDetail(VmDetailConstants.ROOK_DISK_CONTROLLER, "scsi");
 -                        vm.setDetail("firmware", "efi");
 -                        s_logger.info("guestOS is OSX : overwrite root disk controller to scsi, use smc and efi");
 -                    }
 -               }
 -        
 +        UserVmVO vm = new UserVmVO(id, instanceName, displayName,
 +                template.getId(), hypervisorType, template.getGuestOSId(),
 +                offering.getOfferHA(), offering.getLimitCpuUse(),
 +                owner.getDomainId(), owner.getId(), offering.getId(), userData,
 +                hostName, diskOfferingId);
 +        vm.setUuid(uuidName);
 +        vm.setDynamicallyScalable(template.isDynamicallyScalable());
 +        if (sshPublicKey != null) {
 +            vm.setDetail("SSH.PublicKey", sshPublicKey);
 +        }
 +
 +        if (keyboard != null && !keyboard.isEmpty())
 +            vm.setDetail(VmDetailConstants.KEYBOARD, keyboard);
 +
 +        if (isIso) {
 +            vm.setIsoId(template.getId());
 +        }
 +
 +        if(isDisplayVmEnabled != null){
 +            if(!_accountMgr.isRootAdmin(caller.getId())){
 +                throw new PermissionDeniedException( "Cannot update parameter displayvm, only admin permitted ");
 +            }
 +            vm.setDisplayVm(isDisplayVmEnabled);
 +        }else {
 +            vm.setDisplayVm(true);
 +        }
 +
 +        // If hypervisor is vSphere, check for clone type setting.
 +        if (hypervisorType.equals(HypervisorType.VMware)) {
 +            // retrieve clone flag.
 +            UserVmCloneType cloneType = UserVmCloneType.linked;
 +            String value = _configDao.getValue(Config.VmwareCreateFullClone.key());
 +            if (value != null) {
 +                if (Boolean.parseBoolean(value) == true)
 +                    cloneType = UserVmCloneType.full;
 +            }
 +            UserVmCloneSettingVO vmCloneSettingVO = new UserVmCloneSettingVO(id, cloneType.toString());
 +            _vmCloneSettingDao.persist(vmCloneSettingVO);
 +        }
 +
 +        long guestOSId = template.getGuestOSId();
 +        GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
 +        long guestOSCategoryId = guestOS.getCategoryId();
 +        GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId);
 +
 +
 +        // If hypervisor is vSphere and OS is OS X, set special settings.
 +        if (hypervisorType.equals(HypervisorType.VMware)) {
 +            if (guestOS.getDisplayName().toLowerCase().contains("apple mac os")){
 +                vm.setDetail("smc.present", "TRUE");
 +                vm.setDetail(VmDetailConstants.ROOK_DISK_CONTROLLER, "scsi");
 +                vm.setDetail("firmware", "efi");
 +                s_logger.info("guestOS is OSX : overwrite root disk controller to scsi, use smc and efi");
 +            }
 +       }
 +
+                 Map<String, String> details = template.getDetails();
+                 if ( details != null && !details.isEmpty() ) {
+                     vm.details.putAll(details);
+                 }
+ 
 -                _vmDao.persist(vm);
 -                _vmDao.saveDetails(vm);
 -        
 -                s_logger.debug("Allocating in the DB for vm");
 -                DataCenterDeployment plan = new DataCenterDeployment(zone.getId());
 -        
 -                List<String> computeTags = new ArrayList<String>();
 -                computeTags.add(offering.getHostTag());
 -        
 -                List<String> rootDiskTags =	new ArrayList<String>();
 -                rootDiskTags.add(offering.getTags());
 -        
 -                if(isIso){
 +        _vmDao.persist(vm);
 +        _vmDao.saveDetails(vm);
 +
 +        s_logger.debug("Allocating in the DB for vm");
 +        DataCenterDeployment plan = new DataCenterDeployment(zone.getId());
 +
 +        List<String> computeTags = new ArrayList<String>();
 +        computeTags.add(offering.getHostTag());
 +
 +        List<String> rootDiskTags =	new ArrayList<String>();
 +        rootDiskTags.add(offering.getTags());
 +
 +        if(isIso){
-             VirtualMachineEntity vmEntity = _orchSrvc.createVirtualMachineFromScratch(vm.getUuid(), new Long(owner.getAccountId()).toString(), vm.getIsoId().toString(), hostName, displayName, hypervisor.name(), guestOSCategory.getName(), offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize,  computeTags, rootDiskTags, networkNicMap, plan);
+                     VirtualMachineEntity vmEntity = _orchSrvc.createVirtualMachineFromScratch(vm.getUuid(), Long.toString(owner.getAccountId()), vm.getIsoId().toString(), hostName, displayName, hypervisor.name(), guestOSCategory.getName(), offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize,  computeTags, rootDiskTags, networkNicMap, plan);
 -                }else {
 +        }else {
-             VirtualMachineEntity vmEntity = _orchSrvc.createVirtualMachine(vm.getUuid(), new Long(owner.getAccountId()).toString(), new Long(template.getId()).toString(), hostName, displayName, hypervisor.name(), offering.getCpu(),  offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan);
+                     VirtualMachineEntity vmEntity = _orchSrvc.createVirtualMachine(vm.getUuid(), Long.toString(owner.getAccountId()), Long.toString(template.getId()), hostName, displayName, hypervisor.name(), offering.getCpu(),  offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan);
 -                }
 -        
 -        
 -        
 -                if (s_logger.isDebugEnabled()) {
 -                    s_logger.debug("Successfully allocated DB entry for " + vm);
 -                }
 -                CallContext.current().setEventDetails("Vm Id: " + vm.getId());
 -        
 -                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(),
 -                        vm.getHostName(), offering.getId(), template.getId(), hypervisorType.toString(),
 -                        VirtualMachine.class.getName(), vm.getUuid());
 -        
 -                //Update Resource Count for the given account
 -                resourceCountIncrement(accountId, new Long(offering.getCpu()),
 -                        new Long(offering.getRamSize()));
 -                return vm;
 -            }
 +        }
 +
 +
 +
 +        if (s_logger.isDebugEnabled()) {
 +            s_logger.debug("Successfully allocated DB entry for " + vm);
 +        }
 +        CallContext.current().setEventDetails("Vm Id: " + vm.getId());
 +
 +        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(),
 +                vm.getHostName(), offering.getId(), template.getId(), hypervisorType.toString(),
 +                VirtualMachine.class.getName(), vm.getUuid());
 +
 +        //Update Resource Count for the given account
 +        resourceCountIncrement(accountId, new Long(offering.getCpu()),
 +                new Long(offering.getRamSize()));
- 
-         txn.commit();
- 
-         // Assign instance to the group
-         try {
-             if (group != null) {
-                 boolean addToGroup = addInstanceToGroup(Long.valueOf(id), group);
-                 if (!addToGroup) {
-                     throw new CloudRuntimeException(
-                             "Unable to assign Vm to the group " + group);
-                 }
-             }
-         } catch (Exception ex) {
-             throw new CloudRuntimeException("Unable to assign Vm to the group "
-                     + group);
-         }
- 
-         _securityGroupMgr.addInstanceToGroups(vm.getId(), securityGroupIdList);
- 
-         if (affinityGroupIdList != null && !affinityGroupIdList.isEmpty()) {
-             _affinityGroupVMMapDao.updateMap(vm.getId(), affinityGroupIdList);
-         }
- 
 +        return vm;
 +    }
+         });
+     }
  
      private void validateUserData(String userData, HTTPMethod httpmethod) {
          byte[] decodedUserData = null;
@@@ -3444,104 -3503,324 +3494,145 @@@
                  s_logger.warn("Error while collecting disk stats vm: " + userVm.getHostName() + " from host: " + host.getName() + "; details: " + diskStatsAnswer.getDetails());
                  return;
              }
-             Transaction txn = Transaction.open(Transaction.CLOUD_DB);
              try {
-                 txn.start();
-                 HashMap<String, List<VmDiskStatsEntry>> vmDiskStatsByName = diskStatsAnswer.getVmDiskStatsMap();
+                 final GetVmDiskStatsAnswer diskStatsAnswerFinal = diskStatsAnswer;
+                 Transaction.execute(new TransactionCallbackNoReturn() {
+                     @Override
+                     public void doInTransactionWithoutResult(TransactionStatus status) {
+                         HashMap<String, List<VmDiskStatsEntry>> vmDiskStatsByName = diskStatsAnswerFinal.getVmDiskStatsMap();
 -                        if (vmDiskStatsByName == null)
 -                            return;
 -                        List<VmDiskStatsEntry> vmDiskStats = vmDiskStatsByName.get(userVm.getInstanceName());
 -                        if (vmDiskStats == null)
 -                            return;
 -        
 -            	        for (VmDiskStatsEntry vmDiskStat:vmDiskStats) {
 -                                SearchCriteria<VolumeVO> sc_volume = _volsDao.createSearchCriteria();
 -                                sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath());
 -                                VolumeVO volume = _volsDao.search(sc_volume, null).get(0);
 -            	            VmDiskStatisticsVO previousVmDiskStats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId());
 -            	            VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId());
 -        
 -        	                if ((vmDiskStat.getIORead() == 0) && (vmDiskStat.getIOWrite() == 0) && (vmDiskStat.getBytesRead() == 0) && (vmDiskStat.getBytesWrite() == 0)) {
 -        	                    s_logger.debug("Read/Write of IO and Bytes are both 0. Not updating vm_disk_statistics");
 -        	                    continue;
 -        	                }
 -        
 -        	                if (vmDiskStat_lock == null) {
 -        	                    s_logger.warn("unable to find vm disk stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and volumeId:" + volume.getId());
 -        	                    continue;
 -        	                }
 -        
 -        	                if (previousVmDiskStats != null
 -        	                        && ((previousVmDiskStats.getCurrentIORead() != vmDiskStat_lock.getCurrentIORead())
 -        	                        || ((previousVmDiskStats.getCurrentIOWrite() != vmDiskStat_lock.getCurrentIOWrite())
 -        	                        || (previousVmDiskStats.getCurrentBytesRead() != vmDiskStat_lock.getCurrentBytesRead())
 -        	    	                || (previousVmDiskStats.getCurrentBytesWrite() != vmDiskStat_lock.getCurrentBytesWrite())))) {
 -        	                    s_logger.debug("vm disk stats changed from the time GetVmDiskStatsCommand was sent. " +
 -        	                            "Ignoring current answer. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
 -        	                            " IO Read: " + vmDiskStat.getIORead() + " IO Write: " + vmDiskStat.getIOWrite() +
 -        	                            " Bytes Read: " + vmDiskStat.getBytesRead() + " Bytes Write: " + vmDiskStat.getBytesWrite());
 -        	                    continue;
 -        	                }
 -        
 -        	                if (vmDiskStat_lock.getCurrentIORead() > vmDiskStat.getIORead()) {
 -        	                    if (s_logger.isDebugEnabled()) {
 -        	                        s_logger.debug("Read # of IO that's less than the last one.  " +
 -        	                                "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
 -        	                                " Reported: " + vmDiskStat.getIORead() + " Stored: " + vmDiskStat_lock.getCurrentIORead());
 -        	                    }
 -        	                    vmDiskStat_lock.setNetIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
 -        	                }
 -        	                vmDiskStat_lock.setCurrentIORead(vmDiskStat.getIORead());
 -        	                if (vmDiskStat_lock.getCurrentIOWrite() > vmDiskStat.getIOWrite()) {
 -        	                    if (s_logger.isDebugEnabled()) {
 -        	                        s_logger.debug("Write # of IO that's less than the last one.  " +
 -        	                                "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
 -        	                                " Reported: " + vmDiskStat.getIOWrite() + " Stored: " + vmDiskStat_lock.getCurrentIOWrite());
 -        	                    }
 -        	                    vmDiskStat_lock.setNetIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
 -        	                }
 -        	                vmDiskStat_lock.setCurrentIOWrite(vmDiskStat.getIOWrite());
 -        	                if (vmDiskStat_lock.getCurrentBytesRead() > vmDiskStat.getBytesRead()) {
 -        	                    if (s_logger.isDebugEnabled()) {
 -        	                        s_logger.debug("Read # of Bytes that's less than the last one.  " +
 -        	                                "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
 -        	                                " Reported: " + vmDiskStat.getBytesRead() + " Stored: " + vmDiskStat_lock.getCurrentBytesRead());
 -        	                    }
 -        	                    vmDiskStat_lock.setNetBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
 -        	                }
 -        	                vmDiskStat_lock.setCurrentBytesRead(vmDiskStat.getBytesRead());
 -        	                if (vmDiskStat_lock.getCurrentBytesWrite() > vmDiskStat.getBytesWrite()) {
 -        	                    if (s_logger.isDebugEnabled()) {
 -        	                        s_logger.debug("Write # of Bytes that's less than the last one.  " +
 -        	                                "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
 -        	                                " Reported: " + vmDiskStat.getBytesWrite() + " Stored: " + vmDiskStat_lock.getCurrentBytesWrite());
 -        	                    }
 -        	                    vmDiskStat_lock.setNetBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
 -        	                }
 -        	                vmDiskStat_lock.setCurrentBytesWrite(vmDiskStat.getBytesWrite());
 -        
 -        	                if (! _dailyOrHourly) {
 -        	                    //update agg bytes
 -        	                	vmDiskStat_lock.setAggIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
 -        	                	vmDiskStat_lock.setAggIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
 -        	                	vmDiskStat_lock.setAggBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
 -        	                	vmDiskStat_lock.setAggBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
 -        	                }
 -        
 -        	                _vmDiskStatsDao.update(vmDiskStat_lock.getId(), vmDiskStat_lock);
 -        	        	}
 +                if (vmDiskStatsByName == null)
 +                    return;
 +                List<VmDiskStatsEntry> vmDiskStats = vmDiskStatsByName.get(userVm.getInstanceName());
 +                if (vmDiskStats == null)
 +		    return;
 +
 +	        for (VmDiskStatsEntry vmDiskStat:vmDiskStats) {
 +                    SearchCriteria<VolumeVO> sc_volume = _volsDao.createSearchCriteria();
 +                    sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath());
 +                    VolumeVO volume = _volsDao.search(sc_volume, null).get(0);
 +	            VmDiskStatisticsVO previousVmDiskStats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId());
 +	            VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId());
 +
 +	                if ((vmDiskStat.getIORead() == 0) && (vmDiskStat.getIOWrite() == 0) && (vmDiskStat.getBytesRead() == 0) && (vmDiskStat.getBytesWrite() == 0)) {
 +	                    s_logger.debug("Read/Write of IO and Bytes are both 0. Not updating vm_disk_statistics");
 +	                    continue;
 +	                }
 +
 +	                if (vmDiskStat_lock == null) {
 +	                    s_logger.warn("unable to find vm disk stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and volumeId:" + volume.getId());
 +	                    continue;
 +	                }
 +
 +	                if (previousVmDiskStats != null
 +	                        && ((previousVmDiskStats.getCurrentIORead() != vmDiskStat_lock.getCurrentIORead())
 +	                        || ((previousVmDiskStats.getCurrentIOWrite() != vmDiskStat_lock.getCurrentIOWrite())
 +	                        || (previousVmDiskStats.getCurrentBytesRead() != vmDiskStat_lock.getCurrentBytesRead())
 +	    	                || (previousVmDiskStats.getCurrentBytesWrite() != vmDiskStat_lock.getCurrentBytesWrite())))) {
 +	                    s_logger.debug("vm disk stats changed from the time GetVmDiskStatsCommand was sent. " +
 +	                            "Ignoring current answer. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
 +	                            " IO Read: " + vmDiskStat.getIORead() + " IO Write: " + vmDiskStat.getIOWrite() +
 +	                            " Bytes Read: " + vmDiskStat.getBytesRead() + " Bytes Write: " + vmDiskStat.getBytesWrite());
 +	                    continue;
 +	                }
 +
 +	                if (vmDiskStat_lock.getCurrentIORead() > vmDiskStat.getIORead()) {
 +	                    if (s_logger.isDebugEnabled()) {
 +	                        s_logger.debug("Read # of IO that's less than the last one.  " +
 +	                                "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
 +	                                " Reported: " + vmDiskStat.getIORead() + " Stored: " + vmDiskStat_lock.getCurrentIORead());
 +	                    }
 +	                    vmDiskStat_lock.setNetIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
 +	                }
 +	                vmDiskStat_lock.setCurrentIORead(vmDiskStat.getIORead());
 +	                if (vmDiskStat_lock.getCurrentIOWrite() > vmDiskStat.getIOWrite()) {
 +	                    if (s_logger.isDebugEnabled()) {
 +	                        s_logger.debug("Write # of IO that's less than the last one.  " +
 +	                                "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
 +	                                " Reported: " + vmDiskStat.getIOWrite() + " Stored: " + vmDiskStat_lock.getCurrentIOWrite());
 +	                    }
 +	                    vmDiskStat_lock.setNetIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
 +	                }
 +	                vmDiskStat_lock.setCurrentIOWrite(vmDiskStat.getIOWrite());
 +	                if (vmDiskStat_lock.getCurrentBytesRead() > vmDiskStat.getBytesRead()) {
 +	                    if (s_logger.isDebugEnabled()) {
 +	                        s_logger.debug("Read # of Bytes that's less than the last one.  " +
 +	                                "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
 +	                                " Reported: " + vmDiskStat.getBytesRead() + " Stored: " + vmDiskStat_lock.getCurrentBytesRead());
 +	                    }
 +	                    vmDiskStat_lock.setNetBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
 +	                }
 +	                vmDiskStat_lock.setCurrentBytesRead(vmDiskStat.getBytesRead());
 +	                if (vmDiskStat_lock.getCurrentBytesWrite() > vmDiskStat.getBytesWrite()) {
 +	                    if (s_logger.isDebugEnabled()) {
 +	                        s_logger.debug("Write # of Bytes that's less than the last one.  " +
 +	                                "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
 +	                                " Reported: " + vmDiskStat.getBytesWrite() + " Stored: " + vmDiskStat_lock.getCurrentBytesWrite());
 +	                    }
 +	                    vmDiskStat_lock.setNetBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
 +	                }
 +	                vmDiskStat_lock.setCurrentBytesWrite(vmDiskStat.getBytesWrite());
 +
 +	                if (! _dailyOrHourly) {
 +	                    //update agg bytes
 +	                	vmDiskStat_lock.setAggIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
 +	                	vmDiskStat_lock.setAggIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
 +	                	vmDiskStat_lock.setAggBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
 +	                	vmDiskStat_lock.setAggBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
 +	                }
 +
 +	                _vmDiskStatsDao.update(vmDiskStat_lock.getId(), vmDiskStat_lock);
 +	        	}
- 	        	txn.commit();
+                     }
+                 });
              } catch (Exception e) {
-                 txn.rollback();
                  s_logger.warn("Unable to update vm disk statistics for vm: " + userVm.getId() + " from host: " + hostId, e);
-             } finally {
-                 txn.close();
              }
          }
      }
  
+     @Override
+     public UserVm expungeVm(long vmId) throws ResourceUnavailableException,
+     ConcurrentOperationException {
+         Account caller = CallContext.current().getCallingAccount();
+         Long userId = caller.getId();
+ 
+         // Verify input parameters
+         UserVmVO vm = _vmDao.findById(vmId);
+         if (vm == null) {
+             InvalidParameterValueException ex = new InvalidParameterValueException(
+                     "Unable to find a virtual machine with specified vmId");
+             ex.addProxyObject(String.valueOf(vmId), "vmId");
+             throw ex;
+         }
  
+         if (vm.getRemoved() != null) {
+             s_logger.trace("Vm id=" + vmId + " is already expunged");
+             return vm;
+         }
+ 
+         if ((vm.getState() != State.Destroyed) && (vm.getState() != State.Expunging)) {
+             CloudRuntimeException ex = new CloudRuntimeException(
+                     "Please destroy vm with specified vmId before expunge");
+             ex.addProxyObject(String.valueOf(vmId), "vmId");
+             throw ex;
+         }
+ 
+         _accountMgr.checkAccess(caller, null, true, vm);
+ 
+         boolean status;
+ 
+         status = expunge(vm, userId, caller);    
+         if (status) {
+             return  _vmDao.findByIdIncludingRemoved(vmId);
+         } else {
+             CloudRuntimeException ex = new CloudRuntimeException(
+                     "Failed to expunge vm with specified vmId");
+             ex.addProxyObject(String.valueOf(vmId), "vmId");
+             throw ex;
+         }
+ 
+     }
  
 -    @Override
 -    public Pair<List<UserVmJoinVO>, Integer> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive,
 -            List<Long> permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags) {
 -        Filter searchFilter = new Filter(UserVmJoinVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit());
 -
 -        //first search distinct vm id by using query criteria and pagination
 -        SearchBuilder<UserVmJoinVO> sb = _vmJoinDao.createSearchBuilder();
 -        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct ids
 -        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
 -
 -        Object id = c.getCriteria(Criteria.ID);
 -        Object name = c.getCriteria(Criteria.NAME);
 -        Object state = c.getCriteria(Criteria.STATE);
 -        Object notState = c.getCriteria(Criteria.NOTSTATE);
 -        Object zone = c.getCriteria(Criteria.DATACENTERID);
 -        Object pod = c.getCriteria(Criteria.PODID);
 -        Object hostId = c.getCriteria(Criteria.HOSTID);
 -        Object hostName = c.getCriteria(Criteria.HOSTNAME);
 -        Object keyword = c.getCriteria(Criteria.KEYWORD);
 -        Object isAdmin = c.getCriteria(Criteria.ISADMIN);
 -        assert c.getCriteria(Criteria.IPADDRESS) == null : "We don't support search by ip address on VM any more.  If you see this assert, it means we have to find a different way to search by the nic table.";
 -        Object groupId = c.getCriteria(Criteria.GROUPID);
 -        Object networkId = c.getCriteria(Criteria.NETWORKID);
 -        Object hypervisor = c.getCriteria(Criteria.HYPERVISOR);
 -        Object storageId = c.getCriteria(Criteria.STORAGE_ID);
 -        Object templateId = c.getCriteria(Criteria.TEMPLATE_ID);
 -        Object isoId = c.getCriteria(Criteria.ISO_ID);
 -        Object vpcId = c.getCriteria(Criteria.VPC_ID);
 -
 -        sb.and("displayName", sb.entity().getDisplayName(),
 -                SearchCriteria.Op.LIKE);
 -        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
 -        sb.and("name", sb.entity().getHostName(), SearchCriteria.Op.LIKE);
 -        sb.and("stateEQ", sb.entity().getState(), SearchCriteria.Op.EQ);
 -        sb.and("stateNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ);
 -        sb.and("stateNIN", sb.entity().getState(), SearchCriteria.Op.NIN);
 -        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
 -        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
 -        sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
 -        sb.and("hostIdEQ", sb.entity().getHostId(), SearchCriteria.Op.EQ);
 -        sb.and("hostName", sb.entity().getHostName(), SearchCriteria.Op.LIKE);
 -        sb.and("templateId", sb.entity().getTemplateId(), SearchCriteria.Op.EQ);
 -        sb.and("isoId", sb.entity().getIsoId(), SearchCriteria.Op.EQ);
 -        sb.and("instanceGroupId", sb.entity().getInstanceGroupId(), SearchCriteria.Op.EQ);
 -
 -        if (groupId != null && (Long) groupId != -1) {
 -            sb.and("instanceGroupId", sb.entity().getInstanceGroupId(), SearchCriteria.Op.EQ);
 -        }
 -
 -        if (tags != null && !tags.isEmpty()) {
 -            for (int count=0; count < tags.size(); count++) {
 -                sb.or().op("key" + String.valueOf(count), sb.entity().getTagKey(), SearchCriteria.Op.EQ);
 -                sb.and("value" + String.valueOf(count), sb.entity().getTagValue(), SearchCriteria.Op.EQ);
 -                sb.cp();
 -            }
 -        }
 -
 -        if (networkId != null) {
 -            sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ);
 -        }
 -
 -        if(vpcId != null && networkId == null){
 -            sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ);
 -        }
 -
 -        if (storageId != null) {
 -            sb.and("poolId", sb.entity().getPoolId(), SearchCriteria.Op.EQ);
 -        }
 -
 -        // populate the search criteria with the values passed in
 -        SearchCriteria<UserVmJoinVO> sc = sb.create();
 -
 -        // building ACL condition
 -        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
 -
 -        if (tags != null && !tags.isEmpty()) {
 -            int count = 0;
 -            for (String key : tags.keySet()) {
 -                sc.setParameters("key" + String.valueOf(count), key);
 -                sc.setParameters("value" + String.valueOf(count), tags.get(key));
 -                count++;
 -            }
 -        }
 -
 -        if (groupId != null && (Long)groupId != -1) {
 -            sc.setParameters("instanceGroupId", groupId);
 -        }
 -
 -        if (keyword != null) {
 -            SearchCriteria<UserVmJoinVO> ssc = _vmJoinDao.createSearchCriteria();
 -            ssc.addOr("displayName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
 -            ssc.addOr("hostName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
 -            ssc.addOr("instanceName", SearchCriteria.Op.LIKE, "%" + keyword
 -                    + "%");
 -            ssc.addOr("state", SearchCriteria.Op.EQ, keyword);
 -
 -            sc.addAnd("displayName", SearchCriteria.Op.SC, ssc);
 -        }
 -
 -        if (id != null) {
 -            sc.setParameters("id", id);
 -        }
 -
 -        if (templateId != null) {
 -            sc.setParameters("templateId", templateId);
 -        }
 -
 -        if (isoId != null) {
 -            sc.setParameters("isoId", isoId);
 -        }
 -
 -        if (networkId != null) {
 -            sc.setParameters("networkId", networkId);
 -        }
 -
 -        if(vpcId != null && networkId == null){
 -            sc.setParameters("vpcId", vpcId);
 -        }
 -
 -        if (name != null) {
 -            sc.setParameters("name", "%" + name + "%");
 -        }
 -
 -        if (state != null) {
 -            if (notState != null && (Boolean) notState == true) {
 -                sc.setParameters("stateNEQ", state);
 -            } else {
 -                sc.setParameters("stateEQ", state);
 -            }
 -        }
 -
 -        if (hypervisor != null) {
 -            sc.setParameters("hypervisorType", hypervisor);
 -        }
 -
 -        // Don't show Destroyed and Expunging vms to the end user
 -        if ((isAdmin != null) && ((Boolean) isAdmin != true)) {
 -            sc.setParameters("stateNIN", "Destroyed", "Expunging");
 -        }
 -
 -        if (zone != null) {
 -            sc.setParameters("dataCenterId", zone);
 -        }
 -        if (pod != null) {
 -            sc.setParameters("podId", pod);
 -
 -            if (state == null) {
 -                sc.setParameters("stateNEQ", "Destroyed");
 -            }
 -        }
 -
 -        if (hostId != null) {
 -            sc.setParameters("hostIdEQ", hostId);
 -        } else {
 -            if (hostName != null) {
 -                sc.setParameters("hostName", hostName);
 -            }
 -        }
 -
 -        if (storageId != null) {
 -            sc.setParameters("poolId", storageId);
 -        }
 -
 -        // search vm details by ids
 -        Pair<List<UserVmJoinVO>, Integer> uniqueVmPair =  _vmJoinDao.searchAndCount(sc, searchFilter);
 -        Integer count = uniqueVmPair.second();
 -        if ( count.intValue() == 0 ){
 -            // handle empty result cases
 -            return uniqueVmPair;
 -        }
 -        List<UserVmJoinVO> uniqueVms = uniqueVmPair.first();
 -        Long[] vmIds = new Long[uniqueVms.size()];
 -        int i = 0;
 -        for (UserVmJoinVO v : uniqueVms ){
 -            vmIds[i++] = v.getId();
 -        }
 -        List<UserVmJoinVO> vms = _vmJoinDao.searchByIds(vmIds);
 -        return new Pair<List<UserVmJoinVO>, Integer>(vms, count);
 -    }
  
      @Override
      public HypervisorType getHypervisorTypeOfUserVM(long vmId) {
@@@ -4233,55 -4512,57 +4324,57 @@@
          DomainVO domain = _domainDao.findById(cmd.getDomainId());
          _accountMgr.checkAccess(newAccount, domain);
  
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
+         Transaction.execute(new TransactionCallbackNoReturn() {
+             @Override
+             public void doInTransactionWithoutResult(TransactionStatus status) {
 -                //generate destroy vm event for usage
 -                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
 -                        vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
 -                        VirtualMachine.class.getName(), vm.getUuid());
 -        
 -                // update resource counts for old account
 -                resourceCountDecrement(oldAccount.getAccountId(), new Long(offering.getCpu()),
 -                        new Long(offering.getRamSize()));
 -        
 -                // OWNERSHIP STEP 1: update the vm owner
 -                vm.setAccountId(newAccount.getAccountId());
 -                vm.setDomainId(cmd.getDomainId());
 -                _vmDao.persist(vm);
 -        
 -                // OS 2: update volume
 -                for (VolumeVO volume : volumes) {
 -                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(),
 -                            volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(), volume.getUuid());
 -                    _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume);
 -                    _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage,
 -                            new Long(volume.getSize()));
 -                    volume.setAccountId(newAccount.getAccountId());
 -                    volume.setDomainId(newAccount.getDomainId());
 -                    _volsDao.persist(volume);
 -                    _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume);
 -                    _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage,
 -                            new Long(volume.getSize()));
 -                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(),
 -                            volume.getDataCenterId(), volume.getId(), volume.getName(),
 -                            volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(),
 -                            volume.getUuid());
 -                    //snapshots: mark these removed in db
 -                    List<SnapshotVO> snapshots = _snapshotDao.listByVolumeIdIncludingRemoved(volume.getId());
 -                    for (SnapshotVO snapshot: snapshots){
 -                        _snapshotDao.remove(snapshot.getId());
 -                    }
 -                }
 -        
 -                //update resource count of new account
 -                resourceCountIncrement(newAccount.getAccountId(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
 -        
 -                //generate usage events to account for this change
 -                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
 -                        vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
 -                        VirtualMachine.class.getName(), vm.getUuid());
 +        //generate destroy vm event for usage
 +        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
 +                vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
 +                VirtualMachine.class.getName(), vm.getUuid());
 +
 +        // update resource counts for old account
 +        resourceCountDecrement(oldAccount.getAccountId(), new Long(offering.getCpu()),
 +                new Long(offering.getRamSize()));
 +
 +        // OWNERSHIP STEP 1: update the vm owner
 +        vm.setAccountId(newAccount.getAccountId());
 +        vm.setDomainId(cmd.getDomainId());
 +        _vmDao.persist(vm);
 +
 +        // OS 2: update volume
 +        for (VolumeVO volume : volumes) {
 +            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(),
 +                    volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(), volume.getUuid());
 +            _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume);
 +            _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage,
 +                    new Long(volume.getSize()));
 +            volume.setAccountId(newAccount.getAccountId());
 +            volume.setDomainId(newAccount.getDomainId());
 +            _volsDao.persist(volume);
 +            _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume);
 +            _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage,
 +                    new Long(volume.getSize()));
 +            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(),
 +                    volume.getDataCenterId(), volume.getId(), volume.getName(),
 +                    volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(),
 +                    volume.getUuid());
 +            //snapshots: mark these removed in db
 +            List<SnapshotVO> snapshots = _snapshotDao.listByVolumeIdIncludingRemoved(volume.getId());
 +            for (SnapshotVO snapshot: snapshots){
 +                _snapshotDao.remove(snapshot.getId());
 +            }
 +        }
 +
 +        //update resource count of new account
 +        resourceCountIncrement(newAccount.getAccountId(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
 +
 +        //generate usage events to account for this change
 +        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
 +                vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
 +                VirtualMachine.class.getName(), vm.getUuid());
+             }
+         });
  
-         txn.commit();
  
          VirtualMachine vmoi = _itMgr.findById(vm.getId());
          VirtualMachineProfileImpl vmOldProfile = new VirtualMachineProfileImpl(vmoi);