Repository navigation
kvm: support Host HA on Ceph RBD primary storage #14320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
806fc22
ebc71b7
a36604e
daacf3e
3d932fe
4e6ca34
dc7d14a
fcf71d1
d1fb5da
902bc58
42c5aed
ed628c0
e9b6dda
02fb3e8
324d2d8
78e4a2f
4036374
bbe5c92
e3d603c
51391aa
fe48966
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,23 +37,38 @@ public KVMHAChecker(List<HAStoragePool> pools, HostTO host, boolean reportIfHear | |
| /* | ||
| * True means heart beating is on going, or we can't get it's status. | ||
| * False means heart beating is stopped definitely. | ||
| * | ||
| * The answer comes from the heartbeats only: it is what VM HA uses (KVMInvestigator, CheckOnHostCommand), which needs no out-of-band management. | ||
| * The check of the activity of the VMs on their volumes (KVMHAVMActivityChecker) is only done by Host HA, which needs it. | ||
| * | ||
| * If the host is checked on more than one storage pool, it is dead if its heartbeat is stopped on one of them when | ||
| * reportIfHeartBeatFailedForOneStoragePool is set, or else only if its heartbeat is stopped on all of them. | ||
| */ | ||
| @Override | ||
| public Boolean hasHeartBeat() { | ||
| String hostAndPools = String.format("host IP [%s] in pools [%s]", host.getPrivateNetwork().getIp(), | ||
| storagePools.stream().map(pool -> pool.getPoolUUID()).collect(Collectors.joining(", "))); | ||
| logger.debug("Checking heart beat with KVMHAChecker for {}", hostAndPools); | ||
|
|
||
| if (storagePools.isEmpty()) { | ||
| // this host monitors no storage pool, e.g. its agent is not upgraded yet and does not monitor the pools of the type | ||
| // which a newer version does: it has nothing to tell about the host, which is not a dead host | ||
| logger.debug("KVMHAChecker has no storage pool to check the heart beat for {}, so it can not tell whether the host is alive.", hostAndPools); | ||
| return true; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional follow-up, not blocking. |
||
| } | ||
|
|
||
| boolean heartBeatCheckResult = false; | ||
| for (HAStoragePool pool : storagePools) { | ||
| heartBeatCheckResult = pool.getPool().hasHeartBeat(pool, host); | ||
| if (reportIfHeartBeatFailedForOneStoragePool && !heartBeatCheckResult) { | ||
| if (pool.getPool().hasHeartBeat(pool, host)) { | ||
| heartBeatCheckResult = true; | ||
| } else if (reportIfHeartBeatFailedForOneStoragePool) { | ||
| heartBeatCheckResult = false; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| if (!heartBeatCheckResult) { | ||
| logger.warn("All checks with KVMHAChecker for {} considered it as dead. It may cause a shutdown of the host.", hostAndPools); | ||
| logger.warn("All checks with KVMHAChecker for {} considered it as dead, which may trigger HA actions, such as fencing it and restarting its VMs on other hosts.", hostAndPools); | ||
| } | ||
|
|
||
| return heartBeatCheckResult; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,7 @@ | |
|
|
||
| import com.cloud.agent.api.to.DiskTO; | ||
| import com.cloud.agent.api.to.VirtualMachineTO; | ||
| import com.cloud.ha.HighAvailabilityManager; | ||
| import com.cloud.hypervisor.kvm.resource.KVMHABase; | ||
| import com.cloud.hypervisor.kvm.resource.KVMHABase.PoolType; | ||
| import com.cloud.hypervisor.kvm.resource.KVMHAMonitor; | ||
|
|
@@ -428,8 +429,14 @@ private synchronized KVMStoragePool createStoragePool(String name, String host, | |
|
|
||
| // LibvirtStorageAdaptor-specific statement | ||
| if (pool.isPoolSupportHA() && primaryStorage) { | ||
| KVMHABase.HAStoragePool storagePool = new KVMHABase.HAStoragePool(pool, host, path, PoolType.PrimaryStorage); | ||
| _haMonitor.addStoragePool(storagePool); | ||
| String heartBeatPrerequisiteError = pool.getHeartBeatPrerequisiteError(); | ||
| if (heartBeatPrerequisiteError == null) { | ||
| KVMHABase.HAStoragePool storagePool = new KVMHABase.HAStoragePool(pool, host, path, PoolType.PrimaryStorage); | ||
| _haMonitor.addStoragePool(storagePool); | ||
| } else { | ||
| // without the heartbeat the host would fail to write it at each cycle, and would be fenced | ||
| logger.error("The storage pool {} is not monitored for HA on this host, as its heartbeat can not be used: {}", pool.getUuid(), heartBeatPrerequisiteError); | ||
| } | ||
| } | ||
| StoragePoolInformation info = new StoragePoolInformation(name, host, port, path, userInfo, type, details, primaryStorage); | ||
| addStoragePool(pool.getUuid(), info); | ||
|
|
@@ -445,7 +452,7 @@ public boolean disconnectPhysicalDisk(StoragePoolType type, String poolUuid, Str | |
|
|
||
| public synchronized boolean deleteStoragePool(StoragePoolType type, String uuid) { | ||
| StorageAdaptor adaptor = getStorageAdaptor(type); | ||
| if (type == StoragePoolType.NetworkFilesystem) { | ||
| if (HighAvailabilityManager.LIBVIRT_STORAGE_POOL_TYPES_WITH_HA_SUPPORT.contains(type)) { | ||
| _haMonitor.unregisterStoragePool(uuid); | ||
| } | ||
| boolean deleteStatus = adaptor.deleteStoragePool(uuid); | ||
|
|
@@ -458,7 +465,7 @@ public synchronized boolean deleteStoragePool(StoragePoolType type, String uuid) | |
| public boolean deleteStoragePool(StoragePoolType type, String uuid, Map<String, String> details) { | ||
| StorageAdaptor adaptor = getStorageAdaptor(type); | ||
| boolean deleteStatus; | ||
| if (type == StoragePoolType.NetworkFilesystem) { | ||
| if (HighAvailabilityManager.LIBVIRT_STORAGE_POOL_TYPES_WITH_HA_SUPPORT.contains(type)) { | ||
| _haMonitor.unregisterStoragePool(uuid); | ||
| deleteStatus = adaptor.deleteStoragePool(uuid); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is still the delete without details for RBD and SharedMountPoint. if (HighAvailabilityManager.LIBVIRT_STORAGE_POOL_TYPES_WITH_HA_SUPPORT.contains(type)) {
_haMonitor.unregisterStoragePool(uuid);
}
if (type == StoragePoolType.NetworkFilesystem) {
deleteStatus = adaptor.deleteStoragePool(uuid);
} else {
deleteStatus = adaptor.deleteStoragePool(uuid, details);
} |
||
| } else { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.