danivogel90 opened a new pull request, #14331:
URL: https://github.com/apache/cloudstack/pull/14331

   ### Description
   
   This PR fixes the KVM HA heartbeat for SharedMountPoint pools whose path is 
a subdirectory of a mounted filesystem, which is common with clustered/parallel 
filesystems (IBM Storage Scale/GPFS, WEKA, Quobyte, GFS2, OCFS2, CephFS). It 
also fixes two related problems in `kvmsmpheartbeat.sh` (introduced in #12773):
   
   1. **Mount point check** – `mountpoint -q "$MountPoint"` rejects valid pools 
such as `/data01/vol01` on a GPFS filesystem mounted at `/data01`. Every 
heartbeat write fails with `Mount point is not a mounted filesystem`. A new 
helper `is_on_mounted_fs()` accepts any path on a mounted filesystem other than 
`/` (`findmnt -n -o TARGET -T`, fallback `df -P`). The safety intent is kept: 
if the shared filesystem is not mounted, the heartbeat is not written to the 
local root filesystem.
      The same helper now also replaces the `/proc/mounts` check in front of 
`deleteVMs`. **Without this, relaxing only the first check would make every 
heartbeat write call `deleteVMs`, which `kill -9`s all qemu processes using the 
pool.**
   2. **False DEAD on read** – `check_hbLog` used ``diff=`expr $now - $hb` `` 
followed by `if [ $? -ne 0 ]`. `expr` exits with 1 when the result is 0, so a 
host whose heartbeat was written in the same second as the check was reported 
as DEAD (`999997`). The timestamp is now validated and the difference computed 
with shell arithmetic.
   3. **Temp file left behind** – if the script is killed (e.g. on timeout 
while the clustered FS is recovering), the `hb-<ip>.<pid>` temp file remained. 
A `trap` now removes it.
   
   Fixes: #14326
   
   Broader context: #14327
   
   ### Types of changes
   
   - [ ] Breaking change (fix or feature that would cause existing 
functionality to change)
   - [ ] New feature (non-breaking change which adds functionality)
   - [x] Bug fix (non-breaking change which fixes an issue)
   - [ ] Enhancement (improves an existing feature and functionality)
   - [ ] Cleanup (Code refactoring and cleanup, that may add test cases)
   - [ ] Build/CI
   - [ ] Test (unit or integration test code)
   
   ### Feature/Enhancement Scale or Bug Severity
   
   #### Bug Severity
   
   - [ ] BLOCKER
   - [ ] Critical
   - [x] Major
   - [ ] Minor
   - [ ] Trivial
   
   ### How Has This Been Tested?
   
   Environment: 3 KVM hosts, Ubuntu 24.04, CloudStack 4.23.0.0 (script 
identical on 4.22 and main), hyperconverged IBM Storage Scale 5.2.3-5 (3-way 
replication). SharedMountPoint pool `/data01/vol01` (subdirectory of GPFS mount 
`/data01`), plus an NFS primary storage pool.
   
   **Script tests** (copy of the script with `kill -9` replaced by an echo):
   
   | Case | Expected | Result |
   |---|---|---|
   | unpatched, subdirectory of GPFS mount | fails | exit 1 |
   | patched, subdirectory of GPFS mount, write + read | ALIVE, no deleteVMs | 
OK |
   | patched, real mount point (tmpfs) | ALIVE | OK |
   | patched, NFS pool mount point (read) | ALIVE | OK |
   | patched, path on root FS | refuse, nothing written | exit 1, dir empty |
   | patched, path does not exist | refuse | exit 1 |
   | unpatched, read right after write (diff=0) | ALIVE | **DEAD** |
   | patched, read right after write / after 3 s, `-t 60` | ALIVE | OK / OK |
   | patched, after 3 s with `-t 1` / corrupt hb file | DEAD | OK / OK |
   | patched, SIGTERM during write | temp file removed | OK |
   
   **Live:** the patched script has been running in the agent on one host since 
2026-10-07. Heartbeat writes succeed, there are no errors in agent.log, and 
nothing was killed.
   
   **HA failover test:** HA-enabled VM (offering with `offerha=true`) on the 
SharedMountPoint pool on host A. Agent autostart disabled on A, then A 
hard-reset via sysrq. Results:
   - after ~85 s the neighbour with the patched script returned "Heart is not 
beating" for both pools (NFS + SharedMountPoint), and the host was marked Down
   - after ~110 s the VM was running on another host
   - host A rejoined normally after the agent was re-enabled
   
   #### How did you try to break this feature and the system with this change?
   
   - Path on the local root filesystem / non-existent path: refused, nothing 
written, no deleteVMs.
   - Corrupt and stale heartbeat files: reported as DEAD as before.
   - Script interrupted during write: no leftover temp file.
   - Known limitation (unchanged from before): a path on a *different local* 
filesystem (e.g. a separate `/var` LV) is not detected as "not shared". The 
previous `mountpoint -q` check did not cover this either.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to