From ad650ab36877672ee0456de1c14d6ee9e0aee36b Mon Sep 17 00:00:00 2001 From: JS Choi <77760789+jschoiRR@users.noreply.github.com> Date: Tue, 23 Jun 2026 16:22:25 +0900 Subject: [PATCH] =?UTF-8?q?*=20KVM=20HA=20activity=20check=20=EB=8C=80?= =?UTF-8?q?=EC=83=81=20=EC=8A=A4=ED=86=A0=EB=A6=AC=EC=A7=80=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=EB=A7=81=20=EA=B0=9C=EC=84=A0=20-=20KVM=20HA=20activi?= =?UTF-8?q?ty=20check=20=EC=8B=9C=20storage=20heartbeat=EA=B0=80=20?= =?UTF-8?q?=ED=99=9C=EC=84=B1=ED=99=94=EB=90=9C=20primary=20storage?= =?UTF-8?q?=EB=A7=8C=20=EA=B2=80=EC=82=AC=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=ED=96=88=EC=8A=B5=EB=8B=88=EB=8B=A4.=20-=20A?= =?UTF-8?q?gent=EC=97=90=EC=84=9C=EB=8F=84=20HA=20monitor=EC=97=90=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=EB=90=98=EC=A7=80=20=EC=95=8A=EC=9D=80=20poo?= =?UTF-8?q?l=EC=9D=80=20libvirt=20=EC=A1=B0=ED=9A=8C=20=EC=A0=84=EC=97=90?= =?UTF-8?q?=20skip=ED=95=98=EC=97=AC=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=A7=80=EC=97=B0=EA=B3=BC=20timeout=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=EC=84=B1=EC=9D=84=20=EC=A4=84=EC=98=80=EC=8A=B5?= =?UTF-8?q?=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...VMActivityOnStoragePoolCommandWrapper.java | 53 ++++++++++++------- .../kvm/ha/KVMHostActivityChecker.java | 11 ++++ 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVMActivityOnStoragePoolCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVMActivityOnStoragePoolCommandWrapper.java index 84978690ad77..9f5f35154069 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVMActivityOnStoragePoolCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVMActivityOnStoragePoolCommandWrapper.java @@ -47,28 +47,15 @@ public Answer execute(final CheckVMActivityOnStoragePoolCommand command, final L final StorageFilerTO pool = command.getPool(); final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + HAStoragePool haStoragePool = getMonitoredStoragePool(monitor, pool); + if (haStoragePool == null) { + executors.shutdownNow(); + return new Answer(command, false, "Unsupported Storage or HA pool not found"); + } + KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid()); if (primaryPool.isPoolSupportHA()){ - HAStoragePool haStoragePool = null; - String vmActivityCheckPath = ""; - if (Storage.StoragePoolType.NetworkFilesystem == pool.getType()) { - haStoragePool = monitor.getStoragePool(pool.getUuid()); - vmActivityCheckPath = libvirtComputingResource.getVmActivityCheckPath(); - } else if (Storage.StoragePoolType.SharedMountPoint == pool.getType()) { - haStoragePool = monitor.getGfsStoragePool(pool.getUuid()); - vmActivityCheckPath = libvirtComputingResource.getVmActivityCheckPathGfs(); - } else if (Storage.StoragePoolType.RBD == pool.getType()) { - haStoragePool = monitor.getRbdStoragePool(pool.getUuid()); - vmActivityCheckPath = libvirtComputingResource.getVmActivityCheckPathRbd(); - } else if (Storage.StoragePoolType.CLVM == pool.getType()) { - haStoragePool = monitor.getClvmStoragePool(pool.getUuid()); - vmActivityCheckPath = libvirtComputingResource.getVmActivityCheckPathClvm(); - } - - if (haStoragePool == null) { - executors.shutdownNow(); - return new Answer(command, false, "Unsupported Storage or HA pool not found"); - } + String vmActivityCheckPath = getVmActivityCheckPath(libvirtComputingResource, pool); final KVMHAVMActivityChecker ha = new KVMHAVMActivityChecker(haStoragePool, command.getHost(), command.getVolumeList(), vmActivityCheckPath, command.getSuspectTimeInSeconds()); final Future future = executors.submit(ha); @@ -91,4 +78,30 @@ public Answer execute(final CheckVMActivityOnStoragePoolCommand command, final L executors.shutdownNow(); return new Answer(command, false, "Unsupported Storage"); } + + protected HAStoragePool getMonitoredStoragePool(final KVMHAMonitor monitor, final StorageFilerTO pool) { + if (Storage.StoragePoolType.NetworkFilesystem == pool.getType()) { + return monitor.getStoragePool(pool.getUuid()); + } else if (Storage.StoragePoolType.SharedMountPoint == pool.getType()) { + return monitor.getGfsStoragePool(pool.getUuid()); + } else if (Storage.StoragePoolType.RBD == pool.getType()) { + return monitor.getRbdStoragePool(pool.getUuid()); + } else if (Storage.StoragePoolType.CLVM == pool.getType()) { + return monitor.getClvmStoragePool(pool.getUuid()); + } + return null; + } + + protected String getVmActivityCheckPath(final LibvirtComputingResource libvirtComputingResource, final StorageFilerTO pool) { + if (Storage.StoragePoolType.NetworkFilesystem == pool.getType()) { + return libvirtComputingResource.getVmActivityCheckPath(); + } else if (Storage.StoragePoolType.SharedMountPoint == pool.getType()) { + return libvirtComputingResource.getVmActivityCheckPathGfs(); + } else if (Storage.StoragePoolType.RBD == pool.getType()) { + return libvirtComputingResource.getVmActivityCheckPathRbd(); + } else if (Storage.StoragePoolType.CLVM == pool.getType()) { + return libvirtComputingResource.getVmActivityCheckPathClvm(); + } + return ""; + } } diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/kvm/ha/KVMHostActivityChecker.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/kvm/ha/KVMHostActivityChecker.java index 902826123096..bdfc87e488d1 100644 --- a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/kvm/ha/KVMHostActivityChecker.java +++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/kvm/ha/KVMHostActivityChecker.java @@ -189,6 +189,10 @@ private boolean isVMActivityOnHost(Host agent, DateTime suspectTime) throws HACh boolean activityStatus = true; HashMap> poolVolMap = getVolumeUuidOnHost(agent); for (StoragePool pool : poolVolMap.keySet()) { + if (!isStoragePoolHeartbeatEnabled(pool)) { + logger.debug("Skipping VM activity check for {} on storage pool [{}] because KVM HA storage heartbeat is not enabled for the pool.", agent, pool); + continue; + } activityStatus = verifyActivityOfStorageOnHost(poolVolMap, pool, agent, suspectTime, activityStatus); if (!activityStatus) { logger.warn("It seems that the storage pool [{}] does not have activity on {}.", pool, agent); @@ -199,6 +203,13 @@ private boolean isVMActivityOnHost(Host agent, DateTime suspectTime) throws HACh return activityStatus; } + protected boolean isStoragePoolHeartbeatEnabled(StoragePool pool) { + if (pool == null) { + return false; + } + return Boolean.TRUE.equals(HighAvailabilityManager.KvmHACheckOnStorage.valueIn(pool.getId())); + } + protected boolean verifyActivityOfStorageOnHost(HashMap> poolVolMap, StoragePool pool, Host agent, DateTime suspectTime, boolean activityStatus) throws HACheckerException, IllegalStateException { List volume_list = poolVolMap.get(pool); final CheckVMActivityOnStoragePoolCommand cmd = new CheckVMActivityOnStoragePoolCommand(agent, pool, volume_list, suspectTime);