From fc35aed2c9e64d84fff60cb1dec63b406d651106 Mon Sep 17 00:00:00 2001 From: prachi Date: Tue, 12 Apr 2011 13:46:17 -0700 Subject: [PATCH] Bug 9387 - Recreate system vms if template id changed... Changes: - Planner must reassign the storage pool if the template id for system vms has changed. StorageManager must then recreate the volume if the volume has been reassigned. This is needed to do automatic update of the system template. --- .../src/com/cloud/deploy/FirstFitPlanner.java | 12 ++--- .../com/cloud/storage/StorageManagerImpl.java | 45 ++++++++----------- .../cloud/vm/VirtualMachineManagerImpl.java | 17 +++++++ 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/com/cloud/deploy/FirstFitPlanner.java index 1fd6d7ca902..4f1cbdb0348 100644 --- a/server/src/com/cloud/deploy/FirstFitPlanner.java +++ b/server/src/com/cloud/deploy/FirstFitPlanner.java @@ -519,15 +519,17 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner { s_logger.debug("Volume is in READY state and has pool already allocated."); List suitablePools = new ArrayList(); StoragePoolVO pool = _storagePoolDao.findById(toBeCreated.getPoolId()); - suitablePools.add(pool); - suitableVolumeStoragePools.put(toBeCreated, suitablePools); - continue; + if(!avoid.shouldAvoid(pool)){ + suitablePools.add(pool); + suitableVolumeStoragePools.put(toBeCreated, suitablePools); + continue; + } } } DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId()); - DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType()); + DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType()); - boolean useLocalStorage = false; + boolean useLocalStorage = false; if (vmProfile.getType() != VirtualMachine.Type.User) { String ssvmUseLocalStorage = _configDao.getValue(Config.SystemVMUseLocalStorage.key()); if (ssvmUseLocalStorage.equalsIgnoreCase("true")) { diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 0b3910295fb..77b254da694 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -2462,38 +2462,31 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag List recreateVols = new ArrayList(vols.size()); for (VolumeVO vol : vols) { - Volume.State state = vol.getState(); - if (state == Volume.State.Ready) { - StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); - if (pool.getRemoved() != null || pool.isInMaintenance()) { - if (vol.isRecreatable()) { + if(vol.getPoolId() == null){ + recreateVols.add(vol); + }else{ + StoragePool assignedPool = dest.getStorageForDisks().get(vol); + if(vol.getPoolId() != assignedPool.getId()){ + if (vol.isRecreatable()) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Volume " + vol + " has to be recreated due to storage pool " + pool + " is unavailable"); + s_logger.debug("Volume " + vol + " has to be recreated since a different storage pool " + assignedPool + " is assigned by deploymentPlanner"); } recreateVols.add(vol); } else { - throw new StorageUnavailableException("Volume " + vol + " is not available on the storage pool.", pool.getId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Volume " + vol + " is not recreatable! Cannot create storagepool..."); + } + throw new StorageUnavailableException("Unable to create " + vol, assignedPool.getId()); + //copy volume usecase - not yet developed. } - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Volume " + vol + " is ready."); + }else{ + if (s_logger.isDebugEnabled()) { + s_logger.debug("Volume " + vol + " already has the poolId set to the assigned pool: " + assignedPool); } - vm.addDisk(new VolumeTO(vol, pool)); - } - } else if (state == Volume.State.Allocated) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating volume " + vol + " for the first time."); - } - recreateVols.add(vol); - } else if (state == Volume.State.Creating && vol.isRecreatable()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Re-creating volume " + vol + " as it was left with Creating state"); - } - recreateVols.add(vol); - } else { - // the pool id here can potentially be null if the volume was never associated with any pool id (bug: 7899) - throw new StorageUnavailableException("Volume " + vol + " can not be used", vol.getPoolId() != null ? vol.getPoolId() : null); - } + StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); + vm.addDisk(new VolumeTO(vol, pool)); + } + } } for (VolumeVO vol : recreateVols) { diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 42c2a2f4239..b8c7bccd667 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -576,6 +576,23 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene for (VolumeVO vol : vols) { Volume.State state = vol.getState(); if (state == Volume.State.Ready) { + //make sure if this is a System VM, templateId is unchanged. If it is changed, let planner + //reassign pool for the volume + if(VirtualMachine.Type.DomainRouter.equals(vm.getType()) + || VirtualMachine.Type.ConsoleProxy.equals(vm.getType()) + || VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())){ + + Long volTemplateId = vol.getTemplateId(); + if(volTemplateId != null && volTemplateId.longValue() != vm.getTemplateId()){ + if (s_logger.isDebugEnabled()) { + s_logger.debug("Root Volume " + vol + " of "+vm.getType().toString() +" System VM is ready, but volume's templateId does not match the VM, updating templateId and reassigning a new pool"); + } + vol.setTemplateId(vm.getTemplateId()); + _volsDao.update(vol.getId(), vol); + continue; + } + + } StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); if (!pool.isInMaintenance()) { long rootVolDcId = pool.getDataCenterId();