From 3afc80dc4e3c0ae38ade8eeeab5f4d7ccfd25716 Mon Sep 17 00:00:00 2001 From: "lin.ma" Date: Fri, 3 Jul 2026 10:40:47 +0800 Subject: [PATCH] [compute]: avoid dual MN host tracking Backport the host tracking guard to 5.4.10. 1. Why? ZSTAC-86365 tracks dual management nodes tracking the same host. The target branch does not contain the source fix yet. 2. How? Check isManagedByUs before trackHost to avoid duplicate tracking. 3. Side effects? None. The change only skips host tracking on non-owner MNs. # Summary of changes (by module): - compute: guard host tracking by management node ownership. - test: cover host connected time tracking behavior. Source-Commit: bd5119ae0dc46eef7dcab2e5f4fc403a85574c0e Related: ZSTAC-86365, ZSTAC-76341 Change-Id: I6de8611b596a775d893d2dde91ac89410f69bf2c --- .../zstack/compute/host/HostTrackImpl.java | 5 +++ .../kvm/host/HostConnectedTimeCase.groovy | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/compute/src/main/java/org/zstack/compute/host/HostTrackImpl.java b/compute/src/main/java/org/zstack/compute/host/HostTrackImpl.java index 49394e88b78..48ed6a7dc48 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostTrackImpl.java +++ b/compute/src/main/java/org/zstack/compute/host/HostTrackImpl.java @@ -251,6 +251,11 @@ public void cancel() { public void trackHost(String hostUuid) { + if (!destMaker.isManagedByUs(hostUuid)) { + logger.debug(String.format("skip tracking host[uuid:%s], not managed by us", hostUuid)); + return; + } + Tracker t = trackers.get(hostUuid); if (t != null) { t.cancel(); diff --git a/test/src/test/groovy/org/zstack/test/integration/kvm/host/HostConnectedTimeCase.groovy b/test/src/test/groovy/org/zstack/test/integration/kvm/host/HostConnectedTimeCase.groovy index eaf774fb84f..87a06e15abd 100644 --- a/test/src/test/groovy/org/zstack/test/integration/kvm/host/HostConnectedTimeCase.groovy +++ b/test/src/test/groovy/org/zstack/test/integration/kvm/host/HostConnectedTimeCase.groovy @@ -16,6 +16,11 @@ import org.zstack.utils.gson.JSONObjectUtil import org.zstack.header.network.l2.BatchCheckNetworkPhysicalInterfaceMsg import org.zstack.header.network.l2.BatchCheckNetworkPhysicalInterfaceReply import org.zstack.core.cloudbus.CloudBus +import org.zstack.core.cloudbus.ResourceDestinationMaker +import org.zstack.compute.host.HostTrackImpl + +import static org.mockito.Mockito.mock +import static org.mockito.Mockito.when class HostConnectedTimeCase extends SubCase { @@ -34,6 +39,7 @@ class HostConnectedTimeCase extends SubCase { @Override void test() { env.create { + testSkipTrackIfNotManagedByUs() testHostConnectedTime() } } @@ -43,6 +49,31 @@ class HostConnectedTimeCase extends SubCase { env.delete() } + /** + * Test for ZSTAC-76341: check isManagedByUs before trackHost to prevent dual MN tracking + */ + void testSkipTrackIfNotManagedByUs() { + HostInventory host = env.inventoryByName("kvm") as HostInventory + HostTrackImpl tracker = bean(HostTrackImpl.class) + + ResourceDestinationMaker originalDestMaker = tracker.@destMaker + + ResourceDestinationMaker mockDestMaker = mock(ResourceDestinationMaker.class) + when(mockDestMaker.isManagedByUs(host.uuid)).thenReturn(false) + tracker.@destMaker = mockDestMaker + + tracker.untrackHost(host.uuid) + assert !tracker.trackers.containsKey(host.uuid) + + tracker.trackHost(host.uuid) + assert !tracker.trackers.containsKey(host.uuid) : "Host should NOT be tracked when isManagedByUs returns false" + + tracker.@destMaker = originalDestMaker + + tracker.trackHost(host.uuid) + assert tracker.trackers.containsKey(host.uuid) : "Host should be tracked when isManagedByUs returns true" + } + void testHostConnectedTime() { HostInventory host = env.inventoryByName("kvm")