Skip to content

Commit 49d8e44

Browse files
committed
CLOUDSTACK-4459: one more try, bypass libvirt to find volume if libvirt call failed
Conflicts: server/src/com/cloud/template/TemplateManagerImpl.java
1 parent b695484 commit 49d8e44

2 files changed

Lines changed: 60 additions & 17 deletions

File tree

plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,19 @@
1616
// under the License.
1717
package com.cloud.hypervisor.kvm.storage;
1818

19+
import java.io.File;
1920
import java.util.List;
2021

22+
import com.cloud.utils.exception.CloudRuntimeException;
2123
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
24+
import org.apache.log4j.Logger;
2225
import org.libvirt.StoragePool;
2326

2427
import com.cloud.storage.Storage.StoragePoolType;
2528

2629
public class LibvirtStoragePool implements KVMStoragePool {
30+
private static final Logger s_logger = Logger
31+
.getLogger(LibvirtStoragePool.class);
2732
protected String uuid;
2833
protected String uri;
2934
protected long capacity;
@@ -120,7 +125,32 @@ public KVMPhysicalDisk createPhysicalDisk(String name, long size) {
120125

121126
@Override
122127
public KVMPhysicalDisk getPhysicalDisk(String volumeUuid) {
123-
return this._storageAdaptor.getPhysicalDisk(volumeUuid, this);
128+
KVMPhysicalDisk disk = null;
129+
try {
130+
disk = this._storageAdaptor.getPhysicalDisk(volumeUuid, this);
131+
} catch (CloudRuntimeException e) {
132+
if ((this.getStoragePoolType() != StoragePoolType.NetworkFilesystem) ||
133+
(this.getStoragePoolType() != StoragePoolType.Filesystem)) {
134+
throw e;
135+
}
136+
}
137+
138+
if (disk != null) {
139+
return disk;
140+
}
141+
s_logger.debug("find volume bypass libvirt");
142+
//For network file system or file system, try to use java file to find the volume, instead of through libvirt. BUG:CLOUDSTACK-4459
143+
String localPoolPath = this.getLocalPath();
144+
File f = new File(localPoolPath + File.separator + volumeUuid);
145+
if (!f.exists()) {
146+
s_logger.debug("volume: " + volumeUuid + " not exist on storage pool");
147+
throw new CloudRuntimeException("Can't find volume:" + volumeUuid);
148+
}
149+
disk = new KVMPhysicalDisk(f.getPath(), volumeUuid, this);
150+
disk.setFormat(PhysicalDiskFormat.QCOW2);
151+
disk.setSize(f.length());
152+
disk.setVirtualSize(f.length());
153+
return disk;
124154
}
125155

126156
@Override

server/src/com/cloud/template/TemplateManagerImpl.java

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -770,29 +770,42 @@ public List<VMTemplateStoragePoolVO> getUnusedTemplatesInPool(StoragePoolVO pool
770770
}
771771

772772
@Override
773+
@DB
773774
public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) {
774-
StoragePool pool = (StoragePool) _dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
775-
VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
776-
777-
if (s_logger.isDebugEnabled()) {
778-
s_logger.debug("Evicting " + templatePoolVO);
775+
//Need to hold the lock, otherwise, another thread may create a volume from the template at the same time.
776+
//Assumption here is that, we will hold the same lock during create volume from template
777+
VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolVO.getId());
778+
if (templatePoolRef == null) {
779+
s_logger.debug("can't aquire the lock for template pool ref:" + templatePoolVO.getId());
780+
return;
779781
}
780-
DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO);
781782

782783
try {
783-
Answer answer = _storageMgr.sendToPool(pool, cmd);
784+
StoragePool pool = (StoragePool) this._dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
785+
VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
786+
787+
if (s_logger.isDebugEnabled()) {
788+
s_logger.debug("Evicting " + templatePoolVO);
789+
}
790+
DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO);
784791

785-
if (answer != null && answer.getResult()) {
786-
// Remove the templatePoolVO
787-
if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
788-
s_logger.debug("Successfully evicted template: " + template.getName() + " from storage pool: " + pool.getName());
792+
try {
793+
Answer answer = _storageMgr.sendToPool(pool, cmd);
794+
795+
if (answer != null && answer.getResult()) {
796+
// Remove the templatePoolVO
797+
if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
798+
s_logger.debug("Successfully evicted template: " + template.getName() + " from storage pool: " + pool.getName());
799+
}
800+
} else {
801+
s_logger.info("Will retry evicte template: " + template.getName() + " from storage pool: " + pool.getName());
789802
}
790-
} else {
791-
s_logger.info("Will retry evicte template: " + template.getName() + " from storage pool: " + pool.getName());
803+
} catch (StorageUnavailableException e) {
804+
s_logger.info("Storage is unavailable currently. Will retry evicte template: " + template.getName() + " from storage pool: "
805+
+ pool.getName());
792806
}
793-
} catch (StorageUnavailableException e) {
794-
s_logger.info("Storage is unavailable currently. Will retry evicte template: " + template.getName() + " from storage pool: "
795-
+ pool.getName());
807+
} finally {
808+
_tmpltPoolDao.releaseFromLockTable(templatePoolRef.getId());
796809
}
797810

798811
}

0 commit comments

Comments
 (0)