CLOUDSTACK-4459: one more try, bypass libvirt to find volume if libvirt call failed
Conflicts: server/src/com/cloud/template/TemplateManagerImpl.java Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/49d8e444 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/49d8e444 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/49d8e444 Branch: refs/heads/master Commit: 49d8e4449166f22e30bfd13dc97827f283306e06 Parents: b695484 Author: Edison Su <sudi...@gmail.com> Authored: Wed Sep 25 16:16:10 2013 -0700 Committer: Edison Su <sudi...@gmail.com> Committed: Wed Sep 25 16:16:10 2013 -0700 ---------------------------------------------------------------------- .../kvm/storage/LibvirtStoragePool.java | 32 +++++++++++++- .../com/cloud/template/TemplateManagerImpl.java | 45 +++++++++++++------- 2 files changed, 60 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49d8e444/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java index 2ce5175..dc7981c 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java @@ -16,14 +16,19 @@ // under the License. package com.cloud.hypervisor.kvm.storage; +import java.io.File; import java.util.List; +import com.cloud.utils.exception.CloudRuntimeException; import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; +import org.apache.log4j.Logger; import org.libvirt.StoragePool; import com.cloud.storage.Storage.StoragePoolType; public class LibvirtStoragePool implements KVMStoragePool { + private static final Logger s_logger = Logger + .getLogger(LibvirtStoragePool.class); protected String uuid; protected String uri; protected long capacity; @@ -120,7 +125,32 @@ public class LibvirtStoragePool implements KVMStoragePool { @Override public KVMPhysicalDisk getPhysicalDisk(String volumeUuid) { - return this._storageAdaptor.getPhysicalDisk(volumeUuid, this); + KVMPhysicalDisk disk = null; + try { + disk = this._storageAdaptor.getPhysicalDisk(volumeUuid, this); + } catch (CloudRuntimeException e) { + if ((this.getStoragePoolType() != StoragePoolType.NetworkFilesystem) || + (this.getStoragePoolType() != StoragePoolType.Filesystem)) { + throw e; + } + } + + if (disk != null) { + return disk; + } + s_logger.debug("find volume bypass libvirt"); + //For network file system or file system, try to use java file to find the volume, instead of through libvirt. BUG:CLOUDSTACK-4459 + String localPoolPath = this.getLocalPath(); + File f = new File(localPoolPath + File.separator + volumeUuid); + if (!f.exists()) { + s_logger.debug("volume: " + volumeUuid + " not exist on storage pool"); + throw new CloudRuntimeException("Can't find volume:" + volumeUuid); + } + disk = new KVMPhysicalDisk(f.getPath(), volumeUuid, this); + disk.setFormat(PhysicalDiskFormat.QCOW2); + disk.setSize(f.length()); + disk.setVirtualSize(f.length()); + return disk; } @Override http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49d8e444/server/src/com/cloud/template/TemplateManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index e11ac0d..c52c323 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -770,29 +770,42 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } @Override + @DB public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) { - StoragePool pool = (StoragePool) _dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId()); - VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId()); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Evicting " + templatePoolVO); + //Need to hold the lock, otherwise, another thread may create a volume from the template at the same time. + //Assumption here is that, we will hold the same lock during create volume from template + VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolVO.getId()); + if (templatePoolRef == null) { + s_logger.debug("can't aquire the lock for template pool ref:" + templatePoolVO.getId()); + return; } - DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO); try { - Answer answer = _storageMgr.sendToPool(pool, cmd); + StoragePool pool = (StoragePool) this._dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId()); + VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId()); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Evicting " + templatePoolVO); + } + DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO); - if (answer != null && answer.getResult()) { - // Remove the templatePoolVO - if (_tmpltPoolDao.remove(templatePoolVO.getId())) { - s_logger.debug("Successfully evicted template: " + template.getName() + " from storage pool: " + pool.getName()); + try { + Answer answer = _storageMgr.sendToPool(pool, cmd); + + if (answer != null && answer.getResult()) { + // Remove the templatePoolVO + if (_tmpltPoolDao.remove(templatePoolVO.getId())) { + s_logger.debug("Successfully evicted template: " + template.getName() + " from storage pool: " + pool.getName()); + } + } else { + s_logger.info("Will retry evicte template: " + template.getName() + " from storage pool: " + pool.getName()); } - } else { - s_logger.info("Will retry evicte template: " + template.getName() + " from storage pool: " + pool.getName()); + } catch (StorageUnavailableException e) { + s_logger.info("Storage is unavailable currently. Will retry evicte template: " + template.getName() + " from storage pool: " + + pool.getName()); } - } catch (StorageUnavailableException e) { - s_logger.info("Storage is unavailable currently. Will retry evicte template: " + template.getName() + " from storage pool: " - + pool.getName()); + } finally { + _tmpltPoolDao.releaseFromLockTable(templatePoolRef.getId()); } }