better expunge and destroy of volumes

This commit is contained in:
Alex Huang 2011-01-11 16:44:26 -08:00
parent 7f597e594c
commit 6e6e8ff876
15 changed files with 202 additions and 492 deletions

View File

@ -26,6 +26,7 @@ import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.SuccessResponse;
import com.cloud.exception.ConcurrentOperationException;
@Implementation(description="Deletes a detached disk volume.", responseObject=SuccessResponse.class)
public class DeleteVolumeCmd extends BaseCmd {
@ -63,7 +64,7 @@ public class DeleteVolumeCmd extends BaseCmd {
}
@Override
public void execute(){
public void execute() throws ConcurrentOperationException {
boolean result = _storageService.deleteVolume(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());

View File

@ -27,6 +27,7 @@ import com.cloud.api.commands.DeletePoolCmd;
import com.cloud.api.commands.DeleteVolumeCmd;
import com.cloud.api.commands.PreparePrimaryStorageForMaintenanceCmd;
import com.cloud.api.commands.UpdateStoragePoolCmd;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
@ -60,7 +61,7 @@ public interface StorageService {
*/
Volume createVolume(CreateVolumeCmd cmd);
boolean deleteVolume(DeleteVolumeCmd cmd) throws InvalidParameterValueException;
boolean deleteVolume(DeleteVolumeCmd cmd) throws ConcurrentOperationException;
/**
* Delete the storage pool
* @param cmd - the command specifying poolId

View File

@ -38,8 +38,7 @@ public interface Volume extends ControlledEntity, BasedOn {
Creating("The volume is being created. getPoolId() should reflect the pool where it is being created."),
Ready("The volume is ready to be used."),
Used("The volume is used"),
Destroy("The volume is set to be desctroyed but can be recovered."),
Destroyed("The volume is destroyed. Should be removed.");
Destroy("The volume is set to be destroyed but can be recovered.");
String _description;
@ -75,17 +74,13 @@ public interface Volume extends ControlledEntity, BasedOn {
private final static StateMachine<State, Event> s_fsm = new StateMachine<State, Event>();
static {
s_fsm.addTransition(Allocated, Event.Create, Creating);
s_fsm.addTransition(Allocated, Event.Destroy, Destroyed);
s_fsm.addTransition(Allocated, Event.Destroy, Destroy);
s_fsm.addTransition(Creating, Event.OperationRetry, Creating);
s_fsm.addTransition(Creating, Event.OperationFailed, Allocated);
s_fsm.addTransition(Creating, Event.OperationSucceeded, Ready);
s_fsm.addTransition(Creating, Event.Destroy, Destroy);
s_fsm.addTransition(Ready, Event.Destroy, Destroy);
s_fsm.addTransition(Ready, Event.Start, Used);
s_fsm.addTransition(Destroy, Event.OperationSucceeded, Destroyed);
s_fsm.addTransition(Destroy, Event.OperationFailed, Destroy);
s_fsm.addTransition(Destroy, Event.OperationRetry, Destroy);
s_fsm.addTransition(Destroy, Event.Recover, Ready);
}
}
@ -95,8 +90,7 @@ public interface Volume extends ControlledEntity, BasedOn {
OperationFailed,
OperationSucceeded,
OperationRetry,
Destroy,
Recover;
Destroy;
}
enum SourceType {

View File

@ -1557,64 +1557,13 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx
}
@Override
@DB
public boolean destroyProxy(long vmId) {
AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor();
if (asyncExecutor != null) {
AsyncJobVO job = asyncExecutor.getJob();
if (s_logger.isInfoEnabled()) {
s_logger.info("Destroy console proxy " + vmId + ", update async job-" + job.getId());
}
_asyncMgr.updateAsyncJobAttachment(job.getId(), "console_proxy", vmId);
}
ConsoleProxyVO vm = _consoleProxyDao.findById(vmId);
if (vm == null || vm.getState() == State.Destroyed) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find vm or vm is destroyed: " + vmId);
}
return true;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Destroying console proxy vm " + vmId);
}
if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.DestroyRequested, null)) {
s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vmId);
return false;
}
Transaction txn = Transaction.currentTxn();
List<VolumeVO> vols = null;
ConsoleProxyVO proxy = _consoleProxyDao.findById(vmId);
try {
vols = _volsDao.findByInstance(vmId);
if (vols.size() != 0) {
_storageMgr.destroy(vm, vols);
}
return true;
} finally {
try {
txn.start();
// release critical system resources used by the VM before we
// delete them
if (vm.getPublicIpAddress() != null) {
// freePublicIpAddress(vm.getPublicIpAddress(), vm.getDataCenterId(), vm.getPodId());
}
vm.setPublicIpAddress(null);
_consoleProxyDao.remove(vm.getId());
txn.commit();
} catch (Exception e) {
s_logger.error("Caught this error: ", e);
txn.rollback();
return false;
} finally {
s_logger.debug("console proxy vm is destroyed : " + vm.getName());
}
return _itMgr.expunge(proxy, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount());
} catch (ResourceUnavailableException e) {
s_logger.warn("Unable to expunge " + proxy, e);
return false;
}
}

View File

@ -44,10 +44,10 @@ import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
@ -108,7 +108,7 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
public boolean configure(String name, Map<String, Object> params)
throws ConfigurationException {
_name = name;
_isEnabled = _configDao.getValue(Config.OvsNetwork.key()).equalsIgnoreCase("true") ? true : false;
_isEnabled = Boolean.parseBoolean(_configDao.getValue(Config.OvsNetwork.key()));
_serverId = ((ManagementServer)ComponentLocator.getComponent(ManagementServer.Name)).getId();
_executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS"));
_cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("OVS-Cleanup"));
@ -470,8 +470,9 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
return;
}
if (delayMs == null)
delayMs = new Long(100l);
if (delayMs == null) {
delayMs = new Long(100l);
}
for (Long vmId: affectedVms) {
Transaction txn = Transaction.currentTxn();
@ -613,14 +614,14 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
@Override
public void UserVmCheckAndCreateTunnel(Commands cmds,
VirtualMachineProfile<UserVmVO> profile, DeployDestination dest) throws GreTunnelException {
CheckAndCreateTunnel((VMInstanceVO)profile.getVirtualMachine(), dest);
CheckAndCreateTunnel(profile.getVirtualMachine(), dest);
}
@Override
public void RouterCheckAndCreateTunnel(Commands cmds,
VirtualMachineProfile<DomainRouterVO> profile,
DeployDestination dest) throws GreTunnelException {
CheckAndCreateTunnel((VMInstanceVO)profile.getVirtualMachine(), dest);
CheckAndCreateTunnel(profile.getVirtualMachine(), dest);
}
@Override

View File

@ -348,51 +348,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
if (s_logger.isDebugEnabled()) {
s_logger.debug("Attempting to destroy router " + routerId);
}
DomainRouterVO router = _routerDao.acquireInLockTable(routerId);
DomainRouterVO router = _routerDao.findById(routerId);
if (router == null) {
s_logger.debug("Unable to acquire lock on router " + routerId);
return false;
return true;
}
try {
if (router.getState() == State.Destroyed || router.getState() == State.Expunging || router.getRemoved() != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find router or router is destroyed: " + routerId);
}
return true;
}
if (stopRouterInternal(router.getId())) {
return false;
}
router = _routerDao.findById(routerId);
if (!_itMgr.stateTransitTo(router, VirtualMachine.Event.DestroyRequested, router.getHostId())) {
s_logger.debug("VM " + router.toString() + " is not in a state to be destroyed.");
return false;
}
} finally {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Release lock on router " + routerId + " for stop");
}
_routerDao.releaseFromLockTable(routerId);
}
router.setPublicIpAddress(null);
router.setVlanDbId(null);
_routerDao.update(router.getId(), router);
_routerDao.remove(router.getId());
List<VolumeVO> vols = _volsDao.findByInstance(routerId);
_storageMgr.destroy(router, vols);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Successfully destroyed router: " + routerId);
}
return true;
return _itMgr.expunge(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount());
}
@Override

View File

@ -81,14 +81,6 @@ public interface StorageManager extends Manager {
*/
List<VolumeVO> unshare(VMInstanceVO vm, HostVO host);
/**
* destroy the storage volumes of a certain vm.
*
* @param vm vm to destroy.
* @param vols volumes to remove from storage pool
*/
void destroy(VMInstanceVO vm, List<VolumeVO> vols);
/**
* Creates volumes for a particular VM.
* @param account account to create volumes for.
@ -205,7 +197,7 @@ public interface StorageManager extends Manager {
* Marks the specified volume as destroyed in the management server database. The expunge thread will delete the volume from its storage pool.
* @param volume
*/
void destroyVolume(VolumeVO volume);
void destroyVolume(VolumeVO volume) throws ConcurrentOperationException;
/** Create capacity entries in the op capacity table
* @param storagePool
@ -282,5 +274,5 @@ public interface StorageManager extends Manager {
void release(VirtualMachineProfile<? extends VMInstanceVO> profile);
void cleanupVolumes(Long vmId);
void cleanupVolumes(long vmId) throws ConcurrentOperationException;
}

View File

@ -114,7 +114,6 @@ import com.cloud.host.dao.DetailsDao;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.NetworkManager;
import com.cloud.network.VirtualNetworkApplianceService;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.offering.ServiceOffering;
import com.cloud.service.ServiceOfferingVO;
@ -141,7 +140,6 @@ import com.cloud.storage.snapshot.SnapshotScheduler;
import com.cloud.template.TemplateManager;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.User;
import com.cloud.user.UserContext;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
@ -874,7 +872,11 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
s_logger.debug(e.getMessage());
}
if (rootCreated != null) {
destroyVolume(rootCreated);
try {
destroyVolume(rootCreated);
} catch (Exception e1) {
s_logger.warn("Unable to mark a volume as destroyed: " + rootCreated, e1);
}
}
throw new CloudRuntimeException("Unable to create volumes for " + vm, e);
}
@ -953,55 +955,6 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
return true;
}
@Override
public void destroy(VMInstanceVO vm, List<VolumeVO> vols) {
if (s_logger.isDebugEnabled() && vm != null) {
s_logger.debug("Destroying volumes of " + vm.toString());
}
for (VolumeVO vol : vols) {
_volsDao.detachVolume(vol.getId());
_volsDao.destroyVolume(vol.getId());
// First delete the entries in the snapshot_policy and
// snapshot_schedule table for the volume.
// They should not get executed after the volume is destroyed.
_snapshotMgr.deletePoliciesForVolume(vol.getId());
String volumePath = vol.getPath();
Long poolId = vol.getPoolId();
if (poolId != null && volumePath != null && !volumePath.trim().isEmpty()) {
Answer answer = null;
StoragePoolVO pool = _storagePoolDao.findById(poolId);
String vmName = null;
if (vm != null) {
vmName = vm.getInstanceName();
}
final DestroyCommand cmd = new DestroyCommand(pool, vol, vmName);
boolean removed = false;
List<StoragePoolHostVO> poolhosts = _storagePoolHostDao.listByPoolId(poolId);
for (StoragePoolHostVO poolhost : poolhosts) {
answer = _agentMgr.easySend(poolhost.getHostId(), cmd);
if (answer != null && answer.getResult()) {
removed = true;
break;
}
}
if (removed) {
_volsDao.remove(vol.getId());
} else {
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_STORAGE_MISC, vol.getDataCenterId(), vol.getPodId(),
"Storage cleanup required for storage pool: " + pool.getName(), "Volume folder: " + vol.getFolder() + ", Volume Path: " + vol.getPath() + ", Volume id: " +vol.getId()+ ", Volume Name: " +vol.getName()+ ", Storage PoolId: " +vol.getPoolId());
s_logger.warn("destroy volume " + vol.getFolder() + " : " + vol.getPath() + " failed for Volume id : " +vol.getId()+ " Volume Name: " +vol.getName()+ " Storage PoolId : " +vol.getPoolId());
}
} else {
_volsDao.remove(vol.getId());
}
}
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
_name = name;
@ -1597,13 +1550,13 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
String destPrimaryStorageVolumePath = cvAnswer.getVolumePath();
String destPrimaryStorageVolumeFolder = cvAnswer.getVolumeFolder();
// Delete the volume on the source storage pool
final DestroyCommand cmd = new DestroyCommand(srcPool, volume, null);
Answer destroyAnswer = _agentMgr.easySend(sourceHostId, cmd);
if (destroyAnswer == null || !destroyAnswer.getResult()) {
throw new CloudRuntimeException("Failed to delete the volume from the source primary storage pool.");
try {
destroyVolume(volume);
} catch (ConcurrentOperationException e) {
s_logger.warn("Concurrent Operation", e);
}
expungeVolume(volume);
volume.setPath(destPrimaryStorageVolumePath);
volume.setFolder(destPrimaryStorageVolumeFolder);
@ -1849,16 +1802,14 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
@Override
@DB
public void destroyVolume(VolumeVO volume) {
public void destroyVolume(VolumeVO volume) throws ConcurrentOperationException {
Transaction txn = Transaction.currentTxn();
txn.start();
Long volumeId = volume.getId();
_volsDao.destroyVolume(volumeId);
_volsDao.update(volume, Volume.Event.Destroy);
long volumeId = volume.getId();
EventUtils.saveEvent(User.UID_SYSTEM, volume.getAccountId(), EventTypes.EVENT_VOLUME_DELETE, "Volume " +volume.getName()+ " deleted");
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), null, null , null);
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volumeId, volume.getName(), null, null , null);
_usageEventDao.persist(usageEvent);
// Delete the recurring snapshot policies for this volume.
@ -1994,24 +1945,6 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
return answer;
}
protected class StorageGarbageCollector implements Runnable {
public StorageGarbageCollector() {
}
@Override
public void run() {
try {
s_logger.info("Storage Garbage Collection Thread is running.");
cleanupStorage(true);
} catch (Exception e) {
s_logger.error("Caught the following Exception", e);
}
}
}
@Override
public void cleanupStorage(boolean recurring) {
GlobalLock scanLock = GlobalLock.getInternLock(this.getClass().getName());
@ -2083,19 +2016,10 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
}
}
List<VolumeVO> vols = _volsDao.listRemovedButNotDestroyed();
List<VolumeVO> vols = _volsDao.listVolumesToBeDestroyed();
for (VolumeVO vol : vols) {
try {
Long poolId = vol.getPoolId();
Answer answer = null;
StoragePoolVO pool = _storagePoolDao.findById(poolId);
final DestroyCommand cmd = new DestroyCommand(pool, vol, null);
answer = sendToPool(pool, cmd);
if (answer != null && answer.getResult()) {
s_logger.debug("Destroyed " + vol);
vol.setDestroyed(true);
_volsDao.update(vol.getId(), vol);
}
expungeVolume(vol);
} catch (Exception e) {
s_logger.warn("Unable to destroy " + vol.getId(), e);
}
@ -2470,7 +2394,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
}
@Override
public boolean deleteVolume(DeleteVolumeCmd cmd) throws InvalidParameterValueException {
public boolean deleteVolume(DeleteVolumeCmd cmd) throws ConcurrentOperationException {
Account account = UserContext.current().getCaller();
Long volumeId = cmd.getId();
@ -2513,20 +2437,13 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
}
// Check that the volume is not already destroyed
if (volume.getDestroyed()) {
throw new InvalidParameterValueException("Please specify a volume that is not already destroyed.");
if (volume.getState() != Volume.State.Destroy) {
destroyVolume(volume);
}
try {
// Destroy the volume
destroyVolume(volume);
} catch (Exception e) {
s_logger.warn("Error destroying volume:"+e);
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Error destroying volume:"+e);
}
expungeVolume(volume);
return true;
}
private boolean validateVolumeSizeRange(long size) throws InvalidParameterValueException {
@ -2800,41 +2717,90 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
//add code here
}
@Override
public void cleanupVolumes(Long vmId) {
VMInstanceVO vm = _vmInstanceDao.findById(vmId);
List<VolumeVO> volumesForVm = _volsDao.findByInstance(vmId);
for(VolumeVO vol : volumesForVm){
if(vol.getVolumeType().equals(VolumeType.ROOT)){
if(vol.getState() != Volume.State.Destroyed) {
assert(vol.getState() == Volume.State.Destroy);
String volumePath = vol.getPath();
Long poolId = vol.getPoolId();
if (poolId != null && volumePath != null && !volumePath.trim().isEmpty()) {
Answer answer = null;
StoragePoolVO pool = _storagePoolDao.findById(poolId);
final DestroyCommand cmd = new DestroyCommand(pool, vol, vm.getName());
List<StoragePoolHostVO> poolhosts = _storagePoolHostDao.listByPoolId(poolId);
for (StoragePoolHostVO poolhost : poolhosts) {
answer = _agentMgr.easySend(poolhost.getHostId(), cmd);
if (answer != null && answer.getResult()) {
try {
_volsDao.update(vol, Volume.Event.OperationSucceeded);
} catch (ConcurrentOperationException e) {
s_logger.warn("Unable to update volume state. vm: " + vmId + ", vol: " + vol.getId() + " due to ConcurrentOperationException");
}
break;
}
}
}
}
destroyVolume(vol);
public void expungeVolume(VolumeVO vol) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Expunging " + vol);
}
String vmName = null;
if (vol.getVolumeType() == VolumeType.ROOT && vol.getInstanceId() != null) {
VirtualMachine vm = _vmInstanceDao.findById(vol.getInstanceId());
vmName = vm.getInstanceName();
}
String volumePath = vol.getPath();
Long poolId = vol.getPoolId();
if (poolId == null || volumePath == null || volumePath.trim().isEmpty()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Marking volume that was never created as destroyed: " + vol);
}
_volsDao.remove(vol.getId());
return;
}
StoragePoolVO pool = _storagePoolDao.findById(poolId);
if (pool == null) {
s_logger.debug("Removing volume as storage pool is gone: " + poolId);
_volsDao.remove(vol.getId());
return;
}
DestroyCommand cmd = new DestroyCommand(pool, vol, vmName);
Answer answer = this.sendToPool(pool, cmd);
if (answer != null && answer.getResult()) {
_volsDao.remove(vol.getId());
if (s_logger.isDebugEnabled()) {
s_logger.debug("Volume successfully expunged from " + poolId);
}
} else {
s_logger.info("Will retry delete of " + vol + " from " + poolId);
}
}
@Override @DB
public void cleanupVolumes(long vmId) throws ConcurrentOperationException {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cleaning storage for vm: " + vmId);
}
List<VolumeVO> volumesForVm = _volsDao.findByInstance(vmId);
List<VolumeVO> toBeExpunged = new ArrayList<VolumeVO>();
Transaction txn = Transaction.currentTxn();
txn.start();
for (VolumeVO vol : volumesForVm) {
if (vol.getVolumeType().equals(VolumeType.ROOT)) {
destroyVolume(vol);
toBeExpunged.add(vol);
} else {
//data volume
_volsDao.detachVolume(vol.getId());
if (s_logger.isDebugEnabled()) {
s_logger.debug("Detaching " + vol);
}
_volsDao.detachVolume(vol.getId());
}
}
txn.commit();
for (VolumeVO expunge : toBeExpunged) {
expungeVolume(expunge);
}
}
protected class StorageGarbageCollector implements Runnable {
public StorageGarbageCollector() {
}
@Override
public void run() {
try {
s_logger.trace("Storage Garbage Collection Thread is running.");
cleanupStorage(true);
} catch (Exception e) {
s_logger.error("Caught the following Exception", e);
}
}
}
}

View File

@ -36,14 +36,10 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long> {
List<VolumeVO> findByDetachedDestroyed();
List<VolumeVO> findByAccountAndPod(long accountId, long podId);
List<VolumeVO> findByTemplateAndZone(long templateId, long zoneId);
List<Long> findVMInstancesByStorageHost(long hostId, Volume.MirrorState mState);
List<VolumeVO> findStrandedMirrorVolumes();
List<Long> findVmsStoredOnHost(long hostId);
void deleteVolumesByInstance(long instanceId);
void attachVolume(long volumeId, long vmId, long deviceId);
void detachVolume(long volumeId);
void destroyVolume(long volumeId);
void recoverVolume(long volumeId);
boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId);
List<VolumeVO> listRemovedButNotDestroyed();
List<VolumeVO> findCreatedByInstance(long id);
@ -59,4 +55,6 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long> {
*/
boolean update(VolumeVO vol, Volume.Event event) throws ConcurrentOperationException;
HypervisorType getHypervisorType(long volumeId);
List<VolumeVO> listVolumesToBeDestroyed();
}

View File

@ -32,8 +32,6 @@ import com.cloud.async.AsyncInstanceCreateStatus;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.Volume;
import com.cloud.storage.Volume.Event;
import com.cloud.storage.Volume.MirrorState;
import com.cloud.storage.Volume.VolumeType;
import com.cloud.storage.VolumeVO;
import com.cloud.utils.Pair;
@ -53,22 +51,14 @@ import com.cloud.utils.exception.CloudRuntimeException;
public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements VolumeDao {
private static final Logger s_logger = Logger.getLogger(VolumeDaoImpl.class);
protected final SearchBuilder<VolumeVO> DetachedAccountIdSearch;
protected final SearchBuilder<VolumeVO> AccountIdSearch;
protected final SearchBuilder<VolumeVO> AccountPodSearch;
protected final SearchBuilder<VolumeVO> TemplateZoneSearch;
protected final GenericSearchBuilder<VolumeVO, SumCount> TotalSizeByPoolSearch;
protected final SearchBuilder<VolumeVO> InstanceIdSearch;
protected final SearchBuilder<VolumeVO> InstanceAndTypeSearch;
protected final SearchBuilder<VolumeVO> InstanceIdDestroyedSearch;
protected final SearchBuilder<VolumeVO> InstanceIdCreatedSearch;
protected final SearchBuilder<VolumeVO> DetachedDestroyedSearch;
protected final SearchBuilder<VolumeVO> MirrorSearch;
protected final GenericSearchBuilder<VolumeVO, Long> ActiveTemplateSearch;
protected final SearchBuilder<VolumeVO> RemovedButNotDestroyedSearch;
protected final SearchBuilder<VolumeVO> PoolIdSearch;
protected final SearchBuilder<VolumeVO> InstanceAndDeviceIdSearch;
protected final SearchBuilder<VolumeVO> InstanceStatesSearch;
protected final SearchBuilder<VolumeVO> IdStateSearch;
protected final SearchBuilder<VolumeVO> AllFieldsSearch;
protected final Attribute _stateAttr;
@ -116,7 +106,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
@Override
public List<VolumeVO> findByAccount(long accountId) {
SearchCriteria<VolumeVO> sc = AccountIdSearch.create();
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
sc.setParameters("accountId", accountId);
sc.setParameters("destroyed", false);
return listBy(sc);
@ -124,14 +114,14 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
@Override
public List<VolumeVO> findByInstance(long id) {
SearchCriteria<VolumeVO> sc = InstanceIdSearch.create();
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
sc.setParameters("instanceId", id);
return listBy(sc);
}
@Override
public List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId){
SearchCriteria<VolumeVO> sc = InstanceAndDeviceIdSearch.create();
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
sc.setParameters("instanceId", instanceId);
sc.setParameters("deviceId", deviceId);
return listBy(sc);
@ -139,14 +129,14 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
@Override
public List<VolumeVO> findByPoolId(long poolId) {
SearchCriteria<VolumeVO> sc = PoolIdSearch.create();
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
sc.setParameters("poolId", poolId);
return listBy(sc);
}
@Override
public List<VolumeVO> findCreatedByInstance(long id) {
SearchCriteria<VolumeVO> sc = InstanceIdCreatedSearch.create();
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
sc.setParameters("instanceId", id);
sc.setParameters("status", AsyncInstanceCreateStatus.Created);
sc.setParameters("destroyed", false);
@ -164,7 +154,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
@Override
public List<VolumeVO> findByInstanceAndType(long id, VolumeType vType) {
SearchCriteria<VolumeVO> sc = InstanceAndTypeSearch.create();
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
sc.setParameters("instanceId", id);
sc.setParameters("vType", vType.toString());
return listBy(sc);
@ -172,7 +162,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
@Override
public List<VolumeVO> findByInstanceIdDestroyed(long vmId) {
SearchCriteria<VolumeVO> sc = InstanceIdDestroyedSearch.create();
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
sc.setParameters("instanceId", vmId);
sc.setParameters("destroyed", true);
return listIncludingRemovedBy(sc);
@ -187,8 +177,8 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
@Override
public List<VolumeVO> findByAccountAndPod(long accountId, long podId) {
SearchCriteria<VolumeVO> sc = AccountPodSearch.create();
sc.setParameters("account", accountId);
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
sc.setParameters("accountId", accountId);
sc.setParameters("pod", podId);
sc.setParameters("destroyed", false);
sc.setParameters("status", AsyncInstanceCreateStatus.Created);
@ -205,38 +195,6 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
return listIncludingRemovedBy(sc);
}
@Override @DB
public List<Long> findVMInstancesByStorageHost(long hostId, Volume.MirrorState mirrState) {
Transaction txn = Transaction.currentTxn();
PreparedStatement pstmt = null;
List<Long> result = new ArrayList<Long>();
try {
String sql = SELECT_VM_SQL;
pstmt = txn.prepareAutoCloseStatement(sql);
pstmt.setLong(1, hostId);
pstmt.setString(2, mirrState.toString());
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
result.add(rs.getLong(1));
}
return result;
} catch (SQLException e) {
throw new CloudRuntimeException("DB Exception on: " + SELECT_VM_SQL, e);
} catch (Throwable e) {
throw new CloudRuntimeException("Caught: " + SELECT_VM_SQL, e);
}
}
@Override
public List<VolumeVO> findStrandedMirrorVolumes() {
SearchCriteria<VolumeVO> sc = MirrorSearch.create();
sc.setParameters("mirrorState", MirrorState.ACTIVE.toString());
return listIncludingRemovedBy(sc);
}
@Override
public boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId) {
SearchCriteria<Long> sc = ActiveTemplateSearch.create();
@ -251,7 +209,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
@Override
public void deleteVolumesByInstance(long instanceId) {
SearchCriteria<VolumeVO> sc = InstanceIdSearch.create();
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
sc.setParameters("instanceId", instanceId);
expunge(sc);
}
@ -276,34 +234,6 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
update(volumeId, volume);
}
@Override
public void destroyVolume(long volumeId) {
VolumeVO volume = createForUpdate(volumeId);
volume.setDestroyed(true);
Volume.State oldState = volume.getState();
Volume.State newState = oldState.getNextState(Event.Destroy);
assert newState != null : "Event "+ Event.Destroy + " cannot happen from " + oldState;
volume.setState(newState);
update(volumeId, volume);
}
@Override
public void recoverVolume(long volumeId) {
VolumeVO volume = createForUpdate(volumeId);
volume.setDestroyed(false);
Volume.State oldState = volume.getState();
Volume.State newState = oldState.getNextState(Event.Recover);
assert newState != null : "Event "+ Event.Recover + " cannot happen from " + oldState;
volume.setState(newState);
update(volumeId, volume);
}
@Override
public boolean update(VolumeVO vol, Volume.Event event) throws ConcurrentOperationException {
Volume.State oldState = vol.getState();
@ -314,7 +244,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
UpdateBuilder builder = getUpdateBuilder(vol);
builder.set(vol, _stateAttr, newState);
SearchCriteria<VolumeVO> sc = IdStateSearch.create();
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
sc.setParameters("id", vol.getId());
sc.setParameters("state", oldState);
@ -325,6 +255,8 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
}
return rows == 1;
}
@Override
@DB
public HypervisorType getHypervisorType(long volumeId) {
/*lookup from cluster of pool*/
@ -336,8 +268,9 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
pstmt = txn.prepareAutoCloseStatement(sql);
pstmt.setLong(1, volumeId);
ResultSet rs = pstmt.executeQuery();
if (rs.next())
return HypervisorType.getType(rs.getString(1));
if (rs.next()) {
return HypervisorType.getType(rs.getString(1));
}
return HypervisorType.None;
} catch (SQLException e) {
throw new CloudRuntimeException("DB Exception on: " + SELECT_HYPERTYPE_FROM_VOLUME, e);
@ -347,98 +280,59 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
}
protected VolumeDaoImpl() {
AccountIdSearch = createSearchBuilder();
AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
AccountIdSearch.and("destroyed", AccountIdSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
AccountIdSearch.done();
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
AllFieldsSearch.and("destroyed", AllFieldsSearch.entity().getDestroyed(), Op.EQ);
AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ);
AllFieldsSearch.and("pod", AllFieldsSearch.entity().getPodId(), Op.EQ);
AllFieldsSearch.and("status", AllFieldsSearch.entity().getStatus(), Op.EQ);
AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getInstanceId(), Op.EQ);
AllFieldsSearch.and("deviceId", AllFieldsSearch.entity().getDeviceId(), Op.EQ);
AllFieldsSearch.and("poolId", AllFieldsSearch.entity().getPoolId(), Op.EQ);
AllFieldsSearch.and("vType", AllFieldsSearch.entity().getVolumeType(), Op.EQ);
AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
AllFieldsSearch.done();
DetachedAccountIdSearch = createSearchBuilder();
DetachedAccountIdSearch.and("accountId", DetachedAccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
DetachedAccountIdSearch.and("destroyed", DetachedAccountIdSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
DetachedAccountIdSearch.and("instanceId", DetachedAccountIdSearch.entity().getInstanceId(), SearchCriteria.Op.NULL);
DetachedAccountIdSearch.and("accountId", DetachedAccountIdSearch.entity().getAccountId(), Op.EQ);
DetachedAccountIdSearch.and("destroyed", DetachedAccountIdSearch.entity().getDestroyed(), Op.EQ);
DetachedAccountIdSearch.and("instanceId", DetachedAccountIdSearch.entity().getInstanceId(), Op.NULL);
DetachedAccountIdSearch.done();
AccountPodSearch = createSearchBuilder();
AccountPodSearch.and("account", AccountPodSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
AccountPodSearch.and("pod", AccountPodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
AccountPodSearch.and("destroyed", AccountPodSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
AccountPodSearch.and("status", AccountPodSearch.entity().getStatus(), SearchCriteria.Op.EQ);
AccountPodSearch.done();
TemplateZoneSearch = createSearchBuilder();
TemplateZoneSearch.and("template", TemplateZoneSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
TemplateZoneSearch.and("zone", TemplateZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
TemplateZoneSearch.and("template", TemplateZoneSearch.entity().getTemplateId(), Op.EQ);
TemplateZoneSearch.and("zone", TemplateZoneSearch.entity().getDataCenterId(), Op.EQ);
TemplateZoneSearch.done();
TotalSizeByPoolSearch = createSearchBuilder(SumCount.class);
TotalSizeByPoolSearch.select("sum", Func.SUM, TotalSizeByPoolSearch.entity().getSize());
TotalSizeByPoolSearch.select("count", Func.COUNT, (Object[])null);
TotalSizeByPoolSearch.and("poolId", TotalSizeByPoolSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
TotalSizeByPoolSearch.and("removed", TotalSizeByPoolSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
TotalSizeByPoolSearch.and("poolId", TotalSizeByPoolSearch.entity().getPoolId(), Op.EQ);
TotalSizeByPoolSearch.and("removed", TotalSizeByPoolSearch.entity().getRemoved(), Op.NULL);
TotalSizeByPoolSearch.done();
InstanceIdCreatedSearch = createSearchBuilder();
InstanceIdCreatedSearch.and("instanceId", InstanceIdCreatedSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
InstanceIdCreatedSearch.and("status", InstanceIdCreatedSearch.entity().getStatus(), SearchCriteria.Op.EQ);
InstanceIdCreatedSearch.and("destroyed", InstanceIdCreatedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
InstanceIdCreatedSearch.done();
InstanceIdSearch = createSearchBuilder();
InstanceIdSearch.and("instanceId", InstanceIdSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
InstanceIdSearch.done();
InstanceAndDeviceIdSearch = createSearchBuilder();
InstanceAndDeviceIdSearch.and("instanceId", InstanceAndDeviceIdSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
InstanceAndDeviceIdSearch.and("deviceId", InstanceAndDeviceIdSearch.entity().getDeviceId(), SearchCriteria.Op.EQ);
InstanceAndDeviceIdSearch.done();
PoolIdSearch = createSearchBuilder();
PoolIdSearch.and("poolId", PoolIdSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
PoolIdSearch.done();
InstanceAndTypeSearch= createSearchBuilder();
InstanceAndTypeSearch.and("instanceId", InstanceAndTypeSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
InstanceAndTypeSearch.and("vType", InstanceAndTypeSearch.entity().getVolumeType(), SearchCriteria.Op.EQ);
InstanceAndTypeSearch.done();
InstanceIdDestroyedSearch = createSearchBuilder();
InstanceIdDestroyedSearch.and("instanceId", InstanceIdDestroyedSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
InstanceIdDestroyedSearch.and("destroyed", InstanceIdDestroyedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
InstanceIdDestroyedSearch.done();
DetachedDestroyedSearch = createSearchBuilder();
DetachedDestroyedSearch.and("instanceId", DetachedDestroyedSearch.entity().getInstanceId(), SearchCriteria.Op.NULL);
DetachedDestroyedSearch.and("destroyed", DetachedDestroyedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
DetachedDestroyedSearch.and("instanceId", DetachedDestroyedSearch.entity().getInstanceId(), Op.NULL);
DetachedDestroyedSearch.and("destroyed", DetachedDestroyedSearch.entity().getDestroyed(), Op.EQ);
DetachedDestroyedSearch.done();
MirrorSearch = createSearchBuilder();
MirrorSearch.and("mirrorVolume", MirrorSearch.entity().getMirrorVolume(), Op.NULL);
MirrorSearch.and("mirrorState", MirrorSearch.entity().getMirrorState(), Op.EQ);
MirrorSearch.done();
ActiveTemplateSearch = createSearchBuilder(Long.class);
ActiveTemplateSearch.and("pool", ActiveTemplateSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
ActiveTemplateSearch.and("template", ActiveTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
ActiveTemplateSearch.and("removed", ActiveTemplateSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
ActiveTemplateSearch.and("pool", ActiveTemplateSearch.entity().getPoolId(), Op.EQ);
ActiveTemplateSearch.and("template", ActiveTemplateSearch.entity().getTemplateId(), Op.EQ);
ActiveTemplateSearch.and("removed", ActiveTemplateSearch.entity().getRemoved(), Op.NULL);
ActiveTemplateSearch.select(null, Func.COUNT, null);
ActiveTemplateSearch.done();
RemovedButNotDestroyedSearch = createSearchBuilder();
RemovedButNotDestroyedSearch.and("destroyed", RemovedButNotDestroyedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
RemovedButNotDestroyedSearch.and("removed", RemovedButNotDestroyedSearch.entity().getRemoved(), SearchCriteria.Op.NNULL);
RemovedButNotDestroyedSearch.and("destroyed", RemovedButNotDestroyedSearch.entity().getDestroyed(), Op.EQ);
RemovedButNotDestroyedSearch.and("removed", RemovedButNotDestroyedSearch.entity().getRemoved(), Op.NNULL);
RemovedButNotDestroyedSearch.done();
InstanceStatesSearch = createSearchBuilder();
InstanceStatesSearch.and("instance", InstanceStatesSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
InstanceStatesSearch.and("states", InstanceStatesSearch.entity().getState(), SearchCriteria.Op.IN);
InstanceStatesSearch.and("instance", InstanceStatesSearch.entity().getInstanceId(), Op.EQ);
InstanceStatesSearch.and("states", InstanceStatesSearch.entity().getState(), Op.IN);
InstanceStatesSearch.done();
IdStateSearch = createSearchBuilder();
IdStateSearch.and("id", IdStateSearch.entity().getId(), SearchCriteria.Op.EQ);
IdStateSearch.and("state", IdStateSearch.entity().getState(), SearchCriteria.Op.EQ);
IdStateSearch.done();
_stateAttr = _allAttributes.get("state");
assert _stateAttr != null : "Couldn't get the state attribute";
}
@ -458,4 +352,12 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
public SumCount() {
}
}
@Override
public List<VolumeVO> listVolumesToBeDestroyed() {
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
sc.setParameters("state", Volume.State.Destroy);
return listBy(sc);
}
}

View File

@ -1109,68 +1109,15 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
}
@Override
@DB
public boolean destroySecStorageVm(long vmId) {
AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor();
if (asyncExecutor != null) {
AsyncJobVO job = asyncExecutor.getJob();
if (s_logger.isInfoEnabled()) {
s_logger.info("Destroy secondary storage vm " + vmId + ", update async job-" + job.getId());
}
_asyncMgr.updateAsyncJobAttachment(job.getId(), "secstorage_vm", vmId);
SecondaryStorageVmVO ssvm = _secStorageVmDao.findById(vmId);
try {
return _itMgr.expunge(ssvm, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount());
} catch (ResourceUnavailableException e) {
s_logger.warn("Unable to expunge " + ssvm, e);
return false;
}
SecondaryStorageVmVO vm = _secStorageVmDao.findById(vmId);
if (vm == null || vm.getState() == State.Destroyed) {
String msg = "Unable to find vm or vm is destroyed: " + vmId;
if (s_logger.isDebugEnabled()) {
s_logger.debug(msg);
}
return true;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Destroying secondary storage vm vm " + vmId);
}
if (! _itMgr.stateTransitTo(vm, VirtualMachine.Event.DestroyRequested, null)) {
String msg = "Unable to destroy the vm because it is not in the correct state: " + vmId;
s_logger.debug(msg);
return false;
}
Transaction txn = Transaction.currentTxn();
List<VolumeVO> vols = null;
try {
vols = _volsDao.findByInstance(vmId);
if (vols.size() != 0) {
_storageMgr.destroy(vm, vols);
}
return true;
} finally {
try {
txn.start();
// release critical system resources used by the VM before we
// delete them
if (vm.getPublicIpAddress() != null) {
freePublicIpAddress(vm.getPublicIpAddress(), vm.getDataCenterId(), vm.getPodId());
}
vm.setPublicIpAddress(null);
_secStorageVmDao.remove(vm.getId());
txn.commit();
} catch (Exception e) {
s_logger.error("Caught this error: ", e);
txn.rollback();
return false;
} finally {
s_logger.debug("secondary storage vm vm is destroyed : "
+ vm.getName());
}
}
}
@DB

View File

@ -37,12 +37,12 @@ public class ItWorkDaoImpl extends GenericDaoBase<ItWorkVO, String> implements I
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("instance", AllFieldsSearch.entity().getInstanceId(), Op.EQ);
AllFieldsSearch.and("op", AllFieldsSearch.entity().getState(), Op.EQ);
AllFieldsSearch.and("op", AllFieldsSearch.entity().getType(), Op.EQ);
AllFieldsSearch.and("step", AllFieldsSearch.entity().getStep(), Op.EQ);
AllFieldsSearch.done();
CleanupSearch = createSearchBuilder();
CleanupSearch.and("step", CleanupSearch.entity().getState(), Op.IN);
CleanupSearch.and("step", CleanupSearch.entity().getType(), Op.IN);
CleanupSearch.and("time", CleanupSearch.entity().getUpdatedAt(), Op.LT);
CleanupSearch.done();
}

View File

@ -58,7 +58,7 @@ public class ItWorkVO {
@Column(name="thread")
String threadName;
@Column(name="state")
@Column(name="step")
Step step;
@Column(name="updated_at")
@ -121,11 +121,11 @@ public class ItWorkVO {
return managementServerId;
}
public State getState() {
public State getType() {
return type;
}
public void setState(State type) {
public void setType(State type) {
this.type = type;
}
@ -137,8 +137,8 @@ public class ItWorkVO {
return step;
}
public void setStep(Step state) {
this.step = state;
public void setStep(Step step) {
this.step = step;
}
public long getUpdatedAt() {

View File

@ -1027,13 +1027,11 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
// Recover the VM's disks
List<VolumeVO> volumes = _volsDao.findByInstanceIdDestroyed(vmId);
for (VolumeVO volume : volumes) {
_volsDao.recoverVolume(volume.getId());
// Create an event
Long templateId = volume.getTemplateId();
Long diskOfferingId = volume.getDiskOfferingId();
long sizeMB = volume.getSize()/(1024*1024);
StoragePoolVO pool = _storagePoolDao.findById(volume.getPoolId());
EventUtils.saveEvent(User.UID_SYSTEM, volume.getAccountId(), EventTypes.EVENT_VOLUME_CREATE, "Created volume: "+ volume.getName() +" with size: " + sizeMB + " MB in pool: " + pool.getName());
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOfferingId, templateId , sizeMB);
_usageEventDao.persist(usageEvent);

View File

@ -98,11 +98,11 @@ DROP TABLE IF EXISTS `cloud`.`host_tags`;
CREATE TABLE `cloud`.`op_it_work` (
`id` char(40) COMMENT 'id',
`mgmt_server_id` bigint unsigned COMMENT 'management server id',
`created_on` bigint unsigned NOT NULL COMMENT 'when was this work detail created',
`created_at` bigint unsigned NOT NULL COMMENT 'when was this work detail created',
`thread` varchar(255) NOT NULL COMMENT 'thread name',
`type` char(32) NOT NULL COMMENT 'type of work',
`state` char(32) NOT NULL COMMENT 'state',
`updated_on` bigint unsigned NOT NULL COMMENT 'time it was taken over',
`step` char(32) NOT NULL COMMENT 'state',
`updated_at` bigint unsigned NOT NULL COMMENT 'time it was taken over',
`instance_id` bigint unsigned NOT NULL COMMENT 'vm instance',
`resource_type` char(32) COMMENT 'type of resource being worked on',
`resource_id` bigint unsigned COMMENT 'resource id being worked on',
@ -677,7 +677,7 @@ CREATE TABLE `cloud`.`user_ip_address` (
INDEX `i_user_ip_address__source_nat`(`source_nat`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE VIEW `cloud`.`user_ip_address_view` AS SELECT INET_NTOA(user_ip_address.public_ip_address) as public_ip_address, user_ip_address.data_center_id, user_ip_address.account_id, user_ip_address.domain_id, user_ip_address.source_nat, user_ip_address.allocated, user_ip_address.vlan_db_id, user_ip_address.one_to_one_nat, user_ip_address.state, user_ip_address.mac_address, user_ip_address.network_id as associated_network_id from user_ip_address;
CREATE VIEW `cloud`.`user_ip_address_view` AS SELECT INET_NTOA(user_ip_address.public_ip_address) as ip_address, user_ip_address.data_center_id, user_ip_address.account_id, user_ip_address.domain_id, user_ip_address.source_nat, user_ip_address.allocated, user_ip_address.vlan_db_id, user_ip_address.one_to_one_nat, user_ip_address.state, user_ip_address.mac_address, user_ip_address.network_id as associated_network_id from user_ip_address;
CREATE TABLE `cloud`.`user_statistics` (
`id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT,