diff --git a/server/src/com/cloud/upgrade/dao/Upgrade227to228.java b/server/src/com/cloud/upgrade/dao/Upgrade227to228.java index e331328f901..8937e37efca 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade227to228.java +++ b/server/src/com/cloud/upgrade/dao/Upgrade227to228.java @@ -85,6 +85,7 @@ public class Upgrade227to228 implements DbUpgrade { } updateDomainLevelNetworks(conn); + updateVolumeUsageRecords(conn); } @Override @@ -128,4 +129,30 @@ public class Upgrade227to228 implements DbUpgrade { } } + //this method inserts missing volume.delete events (events were missing when vm failed to create) + private void updateVolumeUsageRecords(Connection conn) { + try { + s_logger.debug("Inserting missing usage_event records for destroyed volumes..."); + PreparedStatement pstmt = conn.prepareStatement("select id, account_id, data_center_id, name from volumes where state='Destroy' and id in (select resource_id from usage_event where type='volume.create') and id not in (select resource_id from usage_event where type='volume.delete')"); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + long volumeId = rs.getLong(1); + long accountId = rs.getLong(2); + long zoneId = rs.getLong(3); + String volumeName = rs.getString(4); + + pstmt = conn.prepareStatement("insert into usage_event (type, account_id, created, zone_id, resource_name, resource_id) values ('VOLUME.DELETE', ?, now(), ?, ?, ?)"); + pstmt.setLong(1, accountId); + pstmt.setLong(2, zoneId); + pstmt.setString(3, volumeName); + pstmt.setLong(4, volumeId); + + pstmt.executeUpdate(); + } + s_logger.debug("Successfully inserted missing usage_event records for destroyed volumes"); + } catch (SQLException e) { + s_logger.error("Failed to insert missing delete usage records ", e); + throw new CloudRuntimeException("Failed to insert missing delete usage records ", e); + } + } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index bc4bb292808..13e06915e4c 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1647,12 +1647,13 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager s_logger.warn(e1.getMessage()); } // destroy associated volumes for vm in error state - List volumesForThisVm = _volsDao.findByInstance(vm.getId()); + // get all volumes in non destroyed state + List volumesForThisVm = _volsDao.findUsableVolumesForInstance(vm.getId()); for (VolumeVO volume : volumesForThisVm) { try { - if (volume.getState() != Volume.State.Destroy) { - _storageMgr.destroyVolume(volume); - } + _storageMgr.destroyVolume(volume); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName()); + _usageEventDao.persist(usageEvent); } catch (ConcurrentOperationException e) { s_logger.warn("Unable to delete volume:" + volume.getId() + " for vm:" + vmId + " whilst transitioning to error state"); }