Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,19 @@ public void removeClvmStoragePool(String uuid) {
}
}

public void removeStoragePoolFromMonitoring(String uuid) {
removeStoragePoolFromMonitoring(storagePool, uuid);
removeStoragePoolFromMonitoring(storageGfsPool, uuid);
removeStoragePoolFromMonitoring(storageRbdPool, uuid);
removeStoragePoolFromMonitoring(storageClvmPool, uuid);
}

private void removeStoragePoolFromMonitoring(Map<String, HAStoragePool> storagePools, String uuid) {
synchronized (storagePools) {
storagePools.remove(uuid);
}
}

public List<HAStoragePool> getStoragePools() {
synchronized (storagePool) {
return new ArrayList<>(storagePool.values());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

public class KVMStoragePoolManager {
protected Logger logger = LogManager.getLogger(getClass());
protected static final String KVM_HA_ON_STORAGE_HEARTBEAT = "kvm.ha.on.storage.heartbeat";

private class StoragePoolInformation {
String name;
Expand Down Expand Up @@ -392,29 +393,42 @@ private synchronized KVMStoragePool createStoragePool(String name, String host,
StorageAdaptor adaptor = getStorageAdaptor(type);
KVMStoragePool pool = adaptor.createStoragePool(name, host, port, path, userInfo, type, details, primaryStorage);

if (MapUtils.isNotEmpty(details) && details.containsKey("kvm.ha.on.storage.heartbeat") && "true".equals(details.get("kvm.ha.on.storage.heartbeat"))) {
// LibvirtStorageAdaptor-specific statement
if (type == StoragePoolType.NetworkFilesystem && primaryStorage) {
KVMHABase.HAStoragePool storagePool = new KVMHABase.HAStoragePool(pool, host, path, PoolType.PrimaryStorage);
_haMonitor.addStoragePool(storagePool);
} else if (type == StoragePoolType.SharedMountPoint && primaryStorage) {
KVMHABase.HAStoragePool gfsPool = new KVMHABase.HAStoragePool(pool, host, path, PoolType.PrimaryStorage);
_haMonitor.addGfsStoragePool(gfsPool);
} else if (type == StoragePoolType.RBD && primaryStorage) {
KVMHABase.HAStoragePool rbdPool = new KVMHABase.HAStoragePool(pool, host, path, pool.getLocalPath(), PoolType.PrimaryStorage, pool.getAuthUserName(), pool.getAuthSecret(), pool.getSourceHost());
_haMonitor.addRbdStoragePool(rbdPool);
} else if (type == StoragePoolType.CLVM && primaryStorage) {
KVMHABase.HAStoragePool clvmPool = new KVMHABase.HAStoragePool(pool, host, path, PoolType.PrimaryStorage);
_haMonitor.addClvmStoragePool(clvmPool);
}
}

syncStoragePoolHeartbeatMonitoring(pool, host, path, type, details, primaryStorage);

StoragePoolInformation info = new StoragePoolInformation(name, host, port, path, userInfo, type, details, primaryStorage);
addStoragePool(pool.getUuid(), info);
return pool;
}

protected void syncStoragePoolHeartbeatMonitoring(KVMStoragePool pool, String host, String path, StoragePoolType type, Map<String, String> details, boolean primaryStorage) {
_haMonitor.removeStoragePoolFromMonitoring(pool.getUuid());

if (!primaryStorage || MapUtils.isEmpty(details) || !details.containsKey(KVM_HA_ON_STORAGE_HEARTBEAT)) {
return;
}

if (!"true".equals(details.get(KVM_HA_ON_STORAGE_HEARTBEAT))) {
logger.info("Disabled KVM HA storage heartbeat monitoring for storage pool [{}].", pool.getUuid());
return;
}

// LibvirtStorageAdaptor-specific statement
if (type == StoragePoolType.NetworkFilesystem) {
KVMHABase.HAStoragePool storagePool = new KVMHABase.HAStoragePool(pool, host, path, PoolType.PrimaryStorage);
_haMonitor.addStoragePool(storagePool);
} else if (type == StoragePoolType.SharedMountPoint) {
KVMHABase.HAStoragePool gfsPool = new KVMHABase.HAStoragePool(pool, host, path, PoolType.PrimaryStorage);
_haMonitor.addGfsStoragePool(gfsPool);
} else if (type == StoragePoolType.RBD) {
KVMHABase.HAStoragePool rbdPool = new KVMHABase.HAStoragePool(pool, host, path, pool.getLocalPath(), PoolType.PrimaryStorage, pool.getAuthUserName(), pool.getAuthSecret(), pool.getSourceHost());
_haMonitor.addRbdStoragePool(rbdPool);
} else if (type == StoragePoolType.CLVM) {
KVMHABase.HAStoragePool clvmPool = new KVMHABase.HAStoragePool(pool, host, path, PoolType.PrimaryStorage);
_haMonitor.addClvmStoragePool(clvmPool);
}
logger.info("Enabled KVM HA storage heartbeat monitoring for storage pool [{}] of type [{}].", pool.getUuid(), type);
}

public boolean disconnectPhysicalDisk(StoragePoolType type, String poolUuid, String volPath) {
StorageAdaptor adaptor = getStorageAdaptor(type);
KVMStoragePool pool = adaptor.getStoragePool(poolUuid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@
import org.apache.commons.lang3.StringUtils;

import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ModifyStoragePoolCommand;
import com.cloud.alert.AlertManager;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.query.dao.NetworkOfferingJoinDao;
Expand Down Expand Up @@ -196,6 +198,7 @@
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.gpu.GPU;
import com.cloud.ha.HighAvailabilityManager;
import com.cloud.host.HostTagVO;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
Expand Down Expand Up @@ -263,6 +266,7 @@
import com.cloud.storage.VolumeApiServiceImpl;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.StoragePoolTagsDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao;
Expand Down Expand Up @@ -462,6 +466,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
@Inject
StoragePoolTagsDao storagePoolTagDao;
@Inject
StoragePoolHostDao storagePoolHostDao;
@Inject
private AnnotationDao annotationDao;
@Inject
UserIpv6AddressDao _ipv6Dao;
Expand Down Expand Up @@ -768,8 +774,10 @@ public String updateConfiguration(final long userId, final String name, final St
List<StoragePoolVO> childDataStores = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(resourceId);
for (StoragePoolVO childDataStore: childDataStores) {
_storagePoolDetailsDao.addDetail(childDataStore.getId(), name, value, true);
syncKvmStoragePoolHeartbeatSettingWithHosts(childDataStore, name);
}
}
syncKvmStoragePoolHeartbeatSettingWithHosts(pool, name);

break;

Expand Down Expand Up @@ -919,6 +927,29 @@ public String updateConfiguration(final long userId, final String name, final St
return _configDao.getValue(name);
}

protected void syncKvmStoragePoolHeartbeatSettingWithHosts(StoragePoolVO pool, String name) {
if (!HighAvailabilityManager.KvmHACheckOnStorage.key().equals(name)) {
return;
}

List<Long> poolIds = new ArrayList<>();
poolIds.add(pool.getId());
List<Long> hostIds = storagePoolHostDao.findHostsConnectedToPools(poolIds);
Map<String, String> details = _storagePoolDetailsDao.listDetailsKeyPairs(pool.getId());

for (Long hostId : hostIds) {
logger.info("Syncing KVM HA storage heartbeat setting [{}={}] for pool [{}] with host [{}].",
name, details.get(name), pool, _hostDao.findById(hostId));
ModifyStoragePoolCommand command = new ModifyStoragePoolCommand(true, pool, details);
Answer answer = _agentManager.easySend(hostId, command);
if (answer == null) {
logger.warn("Unable to sync KVM HA storage heartbeat setting for pool [{}] on host [{}] because the agent returned no answer.", pool, _hostDao.findById(hostId));
} else if (!answer.getResult()) {
logger.warn("Unable to sync KVM HA storage heartbeat setting for pool [{}] on host [{}] due to [{}].", pool, _hostDao.findById(hostId), answer.getDetails());
}
}
}

private boolean shouldEncryptValue(String category) {
return StringUtils.equalsAny(category, "Hidden", "Secure");
}
Expand Down
21 changes: 21 additions & 0 deletions server/src/main/java/com/cloud/storage/StorageManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageConflictException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.ha.HighAvailabilityManager;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
Expand Down Expand Up @@ -1267,12 +1268,32 @@ public PrimaryDataStoreInfo updateStoragePool(UpdateStoragePoolCmd cmd) throws I
}
_storagePoolDao.update(id, storagePool);
_storagePoolDao.updateDetails(id, details);
syncKvmStoragePoolHeartbeatSettingWithHosts(storagePool, inputDetails, details);
}
}

return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
}

protected void syncKvmStoragePoolHeartbeatSettingWithHosts(StoragePoolVO storagePool, Map<String, String> inputDetails, Map<String, String> details) {
if (MapUtils.isEmpty(inputDetails) || !inputDetails.containsKey(HighAvailabilityManager.KvmHACheckOnStorage.key())) {
return;
}

List<Long> poolIds = new ArrayList<>();
poolIds.add(storagePool.getId());
List<Long> hostIds = _storagePoolHostDao.findHostsConnectedToPools(poolIds);
for (Long hostId : hostIds) {
ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, storagePool, details);
Answer answer = _agentMgr.easySend(hostId, cmd);
if (answer == null) {
logger.warn("Unable to sync KVM HA storage heartbeat setting for pool {} on host {} because the agent returned no answer.", storagePool, _hostDao.findById(hostId));
} else if (!answer.getResult()) {
logger.warn("Unable to sync KVM HA storage heartbeat setting for pool {} on host {} due to {}.", storagePool, _hostDao.findById(hostId), answer.getDetails());
}
}
}

private void changeStoragePoolScopeToZone(StoragePoolVO primaryStorage) {
/*
* For cluster wide primary storage the hypervisor type might not be set.
Expand Down
Loading