CLOUDSTACK-2729: another try to solve libvirt storage pool missing issue: if the storage pool is missing, then recreate it

This commit is contained in:
Edison Su 2013-08-21 16:33:40 -07:00
parent 2f491963b8
commit 9cfd434640
2 changed files with 44 additions and 41 deletions

View File

@ -33,9 +33,35 @@ import com.cloud.storage.StorageLayer;
import com.cloud.utils.exception.CloudRuntimeException;
public class KVMStoragePoolManager {
private class StoragePoolInformation {
String name;
String host;
int port;
String path;
String userInfo;
boolean type;
StoragePoolType poolType;
public StoragePoolInformation(String name,
String host,
int port,
String path,
String userInfo,
StoragePoolType poolType,
boolean type) {
this.name = name;
this.host = host;
this.port = port;
this.path = path;
this.userInfo = userInfo;
this.type = type;
this.poolType = poolType;
}
}
private StorageAdaptor _storageAdaptor;
private KVMHAMonitor _haMonitor;
private final Map<String, Object> _storagePools = new ConcurrentHashMap<String, Object>();
private final Map<String, StoragePoolInformation> _storagePools = new ConcurrentHashMap<String, StoragePoolInformation>();
private final Map<String, StorageAdaptor> _storageMapper = new HashMap<String, StorageAdaptor>();
private StorageAdaptor getStorageAdaptor(StoragePoolType type) {
@ -51,10 +77,10 @@ public class KVMStoragePoolManager {
return adaptor;
}
private void addStoragePool(String uuid) {
private void addStoragePool(String uuid, StoragePoolInformation pool) {
synchronized (_storagePools) {
if (!_storagePools.containsKey(uuid)) {
_storagePools.put(uuid, new Object());
_storagePools.put(uuid, pool);
}
}
}
@ -69,7 +95,16 @@ public class KVMStoragePoolManager {
public KVMStoragePool getStoragePool(StoragePoolType type, String uuid) {
StorageAdaptor adaptor = getStorageAdaptor(type);
return adaptor.getStoragePool(uuid);
KVMStoragePool pool = null;
try {
pool = adaptor.getStoragePool(uuid);
} catch(Exception e) {
StoragePoolInformation info = _storagePools.get(uuid);
if (info != null) {
pool = createStoragePool(info.name, info.host, info.port, info.path, info.userInfo, info.poolType, info.type);
}
}
return pool;
}
public KVMStoragePool getStoragePoolByURI(String uri) {
@ -119,7 +154,8 @@ public class KVMStoragePoolManager {
PoolType.PrimaryStorage);
_haMonitor.addStoragePool(nfspool);
}
addStoragePool(pool.getUuid());
StoragePoolInformation info = new StoragePoolInformation(name, host, port, path, userInfo, type, primaryStorage);
addStoragePool(pool.getUuid(), info);
return pool;
}

View File

@ -1168,45 +1168,12 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
// However, we also need to fix the issues in CloudStack source code.
// A file lock is used to prevent deleting a volume from a KVM storage pool when refresh it.
private void refreshPool(StoragePool pool) throws LibvirtException {
Connect conn = LibvirtConnection.getConnection();
LibvirtStoragePoolDef spd = getStoragePoolDef(conn, pool);
if ((! spd.getPoolType().equals(LibvirtStoragePoolDef.poolType.NETFS))
&& (! spd.getPoolType().equals(LibvirtStoragePoolDef.poolType.DIR))) {
pool.refresh(0);
return;
}
String lockFile = spd.getTargetPath() + File.separator + _lockfile;
s_logger.debug("Attempting to lock pool " + pool.getName() + " with file " + lockFile);
if (lock(lockFile, ACQUIRE_GLOBAL_FILELOCK_TIMEOUT_FOR_KVM)) {
try {
pool.refresh(0);
} finally {
s_logger.debug("Releasing the lock on pool " + pool.getName() + " with file " + lockFile);
unlock(lockFile);
}
} else {
throw new CloudRuntimeException("Can not get file lock to refresh the pool " + pool.getName());
}
pool.refresh(0);
return;
}
private void deleteVol(LibvirtStoragePool pool, StorageVol vol) throws LibvirtException {
if ((! pool.getType().equals(StoragePoolType.NetworkFilesystem))
&& (! pool.getType().equals(StoragePoolType.Filesystem))) {
vol.delete(0);
return;
}
String lockFile = pool.getLocalPath() + File.separator + _lockfile;
s_logger.debug("Attempting to lock pool " + pool.getName() + " with file " + lockFile);
if (lock(lockFile, ACQUIRE_GLOBAL_FILELOCK_TIMEOUT_FOR_KVM)) {
try {
vol.delete(0);
} finally {
s_logger.debug("Releasing the lock on pool " + pool.getName() + " with file " + lockFile);
unlock(lockFile);
}
} else {
throw new CloudRuntimeException("Can not get file lock to delete the volume " + vol.getName());
}
vol.delete(0);
}
private boolean lock(String path, int wait) {