mirror of https://github.com/apache/cloudstack.git
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:
parent
2f491963b8
commit
9cfd434640
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue