From 81a57b2be8f45625d38ca69bcc384a717ae56a5b Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 11 Jul 2012 12:31:08 -0700 Subject: [PATCH] bug CS-15543, resolved fixed --- .../AgentBasedConsoleProxyManager.java | 8 +++++ .../consoleproxy/ConsoleProxyManagerImpl.java | 8 +++++ .../lb/ElasticLoadBalancerManagerImpl.java | 9 ++++++ .../VirtualNetworkApplianceManagerImpl.java | 13 ++++++++ .../src/com/cloud/storage/StorageManager.java | 2 +- .../com/cloud/storage/StorageManagerImpl.java | 31 +++++++++++++++---- .../SecondaryStorageManagerImpl.java | 8 +++++ .../src/com/cloud/vm/UserVmManagerImpl.java | 7 +++++ .../src/com/cloud/vm/VirtualMachineGuru.java | 2 ++ .../cloud/vm/VirtualMachineManagerImpl.java | 9 +++++- .../com/cloud/vm/MockUserVmManagerImpl.java | 6 ++++ 11 files changed, 95 insertions(+), 8 deletions(-) diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java index 8a6a557da8b..3971589bb87 100644 --- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java @@ -347,4 +347,12 @@ public class AgentBasedConsoleProxyManager implements ConsoleProxyManager, Virtu @Override public void finalizeExpunge(ConsoleProxyVO proxy) { } + + @Override + public boolean recreateNeeded( + VirtualMachineProfile profile, long hostId, + Commands cmds, ReservationContext context) { + // TODO Auto-generated method stub + return false; + } } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 218016129ab..8e4d8887e0b 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -1798,4 +1798,12 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx @Override public void onScanEnd() { } + + @Override + public boolean recreateNeeded( + VirtualMachineProfile profile, long hostId, + Commands cmds, ReservationContext context) { + // TODO Auto-generated method stub + return false; + } } diff --git a/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java index aed34e18082..28ec26b5f42 100644 --- a/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java +++ b/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java @@ -989,4 +989,13 @@ public class ElasticLoadBalancerManagerImpl implements return VirtualMachineName.getSystemVmId(vmName); } + + + @Override + public boolean recreateNeeded( + VirtualMachineProfile profile, long hostId, + Commands cmds, ReservationContext context) { + // TODO Auto-generated method stub + return false; + } } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index f16da831a11..c3fc20d1f25 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -2829,4 +2829,17 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian public boolean processTimeout(long agentId, long seq) { return false; } + + @Override + public boolean recreateNeeded( + VirtualMachineProfile profile, long hostId, + Commands cmds, ReservationContext context) { + //asssume that if failed to ssh into router, meaning router is crashed + CheckSshAnswer answer = (CheckSshAnswer) cmds.getAnswer("checkSsh"); + if (answer == null || !answer.getResult()) { + return true; + } + + return false; + } } diff --git a/server/src/com/cloud/storage/StorageManager.java b/server/src/com/cloud/storage/StorageManager.java index 11ee7afe3ce..2d907bcd13c 100755 --- a/server/src/com/cloud/storage/StorageManager.java +++ b/server/src/com/cloud/storage/StorageManager.java @@ -177,7 +177,7 @@ public interface StorageManager extends Manager { void createCapacityEntry(StoragePoolVO storagePool, long allocated); - void prepare(VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException, InsufficientStorageCapacityException, ConcurrentOperationException; + void prepare(VirtualMachineProfile vm, DeployDestination dest, boolean recreate) throws StorageUnavailableException, InsufficientStorageCapacityException, ConcurrentOperationException; void release(VirtualMachineProfile profile); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 6330111b858..9e14751ce81 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -2744,7 +2744,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag } @Override - public void prepare(VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException, InsufficientStorageCapacityException { + public void prepare(VirtualMachineProfile vm, DeployDestination dest, boolean recreate) throws StorageUnavailableException, InsufficientStorageCapacityException { if (dest == null) { if (s_logger.isDebugEnabled()) { @@ -2764,7 +2764,11 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag if (dest.getStorageForDisks() != null) { assignedPool = dest.getStorageForDisks().get(vol); } - if (assignedPool != null) { + if (assignedPool == null && recreate) { + assignedPool = _storagePoolDao.findById(vol.getPoolId()); + + } + if (assignedPool != null || recreate) { Volume.State state = vol.getState(); if (state == Volume.State.Allocated || state == Volume.State.Creating) { recreateVols.add(vol); @@ -2796,6 +2800,12 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag for (VolumeVO vol : recreateVols) { VolumeVO newVol; + StoragePool existingPool = null; + if (recreate && (dest.getStorageForDisks() == null || dest.getStorageForDisks().get(vol) == null)) { + existingPool = _storagePoolDao.findById(vol.getPoolId()); + s_logger.debug("existing pool: " + existingPool.getId()); + } + if (vol.getState() == Volume.State.Allocated || vol.getState() == Volume.State.Creating) { newVol = vol; } else { @@ -2814,9 +2824,12 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag try { _volsDao.update(newVol, Volume.Event.Create); } catch (ConcurrentOperationException e) { + s_logger.debug("unable to update volume state: due to" + e.toString()); throw new StorageUnavailableException("Unable to create " + newVol, newVol.getPoolId()); } - Pair created = createVolume(newVol, _diskOfferingDao.findById(newVol.getDiskOfferingId()), vm, vols, dest); + + + Pair created = createVolume(newVol, _diskOfferingDao.findById(newVol.getDiskOfferingId()), vm, vols, dest, existingPool); if (created == null) { Long poolId = newVol.getPoolId(); newVol.setPoolId(null); @@ -2871,7 +2884,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag } public Pair createVolume(VolumeVO toBeCreated, DiskOfferingVO offering, VirtualMachineProfile vm, List alreadyCreated, - DeployDestination dest) throws StorageUnavailableException { + DeployDestination dest, StoragePool sPool) throws StorageUnavailableException { if (s_logger.isDebugEnabled()) { s_logger.debug("Creating volume: " + toBeCreated); } @@ -2881,9 +2894,15 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag if (toBeCreated.getTemplateId() != null) { template = _templateDao.findById(toBeCreated.getTemplateId()); } + + StoragePool pool = null; + if (sPool != null) { + pool = sPool; + } else { + pool = dest.getStorageForDisks().get(toBeCreated); + } - if (dest.getStorageForDisks() != null) { - StoragePool pool = dest.getStorageForDisks().get(toBeCreated); + if (pool != null) { if (s_logger.isDebugEnabled()) { s_logger.debug("Trying to create in " + pool); } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 6fd8d3fd554..3539a28c55f 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -1190,4 +1190,12 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V public void onScanEnd() { } + @Override + public boolean recreateNeeded( + VirtualMachineProfile profile, long hostId, + Commands cmds, ReservationContext context) { + // TODO Auto-generated method stub + return false; + } + } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 2f653a88f7f..89b733755da 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -3379,4 +3379,11 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager VMInstanceVO migratedVm = _itMgr.migrate(vm, srcHostId, dest); return migratedVm; } + + @Override + public boolean recreateNeeded(VirtualMachineProfile profile, + long hostId, Commands cmds, ReservationContext context) { + // TODO Auto-generated method stub + return false; + } } diff --git a/server/src/com/cloud/vm/VirtualMachineGuru.java b/server/src/com/cloud/vm/VirtualMachineGuru.java index 6799bbe392d..39a8acf94af 100644 --- a/server/src/com/cloud/vm/VirtualMachineGuru.java +++ b/server/src/com/cloud/vm/VirtualMachineGuru.java @@ -64,6 +64,8 @@ public interface VirtualMachineGuru { void finalizeExpunge(T vm); + boolean recreateNeeded(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context); + /** * Returns the id parsed from the name. If it cannot parse the name, * then return null. This method is used to determine if this is diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index f54703c3b2a..cb07dcd1868 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -650,6 +650,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene DataCenterDeployment originalPlan = plan; int retry = _retry; + boolean recreate = false; while (retry-- != 0) { // It's != so that it can match -1. if(reuseVolume){ @@ -740,7 +741,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } _networkMgr.prepare(vmProfile, dest, ctx); if (vm.getHypervisorType() != HypervisorType.BareMetal) { - _storageMgr.prepare(vmProfile, dest); + _storageMgr.prepare(vmProfile, dest, recreate); + recreate = false; } //since StorageMgr succeeded in volume creation, resue Volume for further tries until current cluster has capacity if(!reuseVolume){ @@ -786,6 +788,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene if (s_logger.isDebugEnabled()) { s_logger.info("The guru did not like the answers so stopping " + vm); } + StopCommand cmd = new StopCommand(vm.getInstanceName()); StopAnswer answer = (StopAnswer)_agentMgr.easySend(destHostId, cmd); if (answer == null || !answer.getResult()) { @@ -794,6 +797,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene _haMgr.scheduleStop(vm, destHostId, WorkType.ForceStop); throw new ExecutionException("Unable to stop " + vm + " so we are unable to retry the start operation"); } + + if (vmGuru.recreateNeeded(vmProfile, destHostId, cmds, ctx)) { + recreate = true; + } } } s_logger.info("Unable to start VM on " + dest.getHost() + " due to " + (startAnswer == null ? " no start answer" : startAnswer.getDetails())); diff --git a/server/test/com/cloud/vm/MockUserVmManagerImpl.java b/server/test/com/cloud/vm/MockUserVmManagerImpl.java index 2a39bc667a2..d492f76329e 100644 --- a/server/test/com/cloud/vm/MockUserVmManagerImpl.java +++ b/server/test/com/cloud/vm/MockUserVmManagerImpl.java @@ -371,5 +371,11 @@ public class MockUserVmManagerImpl implements UserVmManager, UserVmService, Mana return null; } + @Override + public boolean recreateNeeded(VirtualMachineProfile profile, + long hostId, Commands cmds, ReservationContext context) { + // TODO Auto-generated method stub + return false; + } }