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 2ce517504d6..dc7981c336b 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 diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index e11ac0db3c2..c52c323cb58 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 (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()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Evicting " + templatePoolVO); } - } catch (StorageUnavailableException e) { - s_logger.info("Storage is unavailable currently. Will retry evicte template: " + template.getName() + " from storage pool: " - + pool.getName()); + DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO); + + 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()); + } + } 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()); } }