Skip to content
Open
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
9 changes: 9 additions & 0 deletions plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ public static class HostFactResponse extends AgentResponse {
@GrayVersion(value = "5.0.0")
private VirtualizerInfoTO virtualizerInfo;
private String iscsiInitiatorName;
private String cpuFeatureMd5;

public String getOsDistribution() {
return osDistribution;
Expand Down Expand Up @@ -782,6 +783,14 @@ public String getDeployMode() {
public void setDeployMode(String deployMode) {
this.deployMode = deployMode;
}

public String getCpuFeatureMd5() {
return cpuFeatureMd5;
}

public void setCpuFeatureMd5(String cpuFeatureMd5) {
this.cpuFeatureMd5 = cpuFeatureMd5;
}
}

public static class HostCapacityCmd extends AgentCommand {
Expand Down
25 changes: 25 additions & 0 deletions plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java
Original file line number Diff line number Diff line change
Expand Up @@ -6206,10 +6206,35 @@ private void saveKvmHostRelatedFacts(HostFactResponse ret) {
}

deleteCpuHistoryVOIfCpuModeNameChange(ret.getCpuModelName());

// check CPU feature MD5 change
String newMd5 = ret.getCpuFeatureMd5();
if (newMd5 != null) {
String oldMd5 = KVMSystemTags.CPU_FEATURE_MD5.getTokenByResourceUuid(
self.getUuid(), KVMSystemTags.CPU_FEATURE_MD5_TOKEN);

if (oldMd5 != null && !oldMd5.equals(newMd5)) {
deleteCpuHistoryVOOnCpuFeatureChange();
logger.debug(String.format("host[uuid:%s] CPU feature changed, old MD5: %s, new MD5: %s, deleted related CpuFeaturesHistoryVO records",
self.getUuid(), oldMd5, newMd5));
}

createTagWithoutNonValue(KVMSystemTags.CPU_FEATURE_MD5,
KVMSystemTags.CPU_FEATURE_MD5_TOKEN, newMd5, true);
}
Comment on lines +6209 to +6224
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

首次写入 CPU_FEATURE_MD5 时不会清理旧历史,可能仍阻塞迁移

当前仅在 oldMd5 非空且变化时清理。升级后首次上报时 oldMd5 为空,若该主机已有旧的 CpuFeaturesHistoryVO(正是本次问题的遗留数据),迁移仍可能被阻塞。建议在首次写入 MD5 时也做一次清理(或至少在存在历史记录时清理),避免遗留数据继续影响。

🐛 建议修复
-                String newMd5 = ret.getCpuFeatureMd5();
-                if (newMd5 != null) {
-                    String oldMd5 = KVMSystemTags.CPU_FEATURE_MD5.getTokenByResourceUuid(
-                        self.getUuid(), KVMSystemTags.CPU_FEATURE_MD5_TOKEN);
-
-                    if (oldMd5 != null && !oldMd5.equals(newMd5)) {
-                        deleteCpuHistoryVOOnCpuFeatureChange();
-                        logger.debug(String.format("host[uuid:%s] CPU feature changed, old MD5: %s, new MD5: %s, deleted related CpuFeaturesHistoryVO records",
-                            self.getUuid(), oldMd5, newMd5));
-                    }
-
-                    createTagWithoutNonValue(KVMSystemTags.CPU_FEATURE_MD5,
-                        KVMSystemTags.CPU_FEATURE_MD5_TOKEN, newMd5, true);
-                }
+                String newMd5 = ret.getCpuFeatureMd5();
+                if (StringUtils.isNotBlank(newMd5)) {
+                    String oldMd5 = KVMSystemTags.CPU_FEATURE_MD5.getTokenByResourceUuid(
+                        self.getUuid(), KVMSystemTags.CPU_FEATURE_MD5_TOKEN);
+
+                    if (oldMd5 == null) {
+                        // first time after upgrade: clear possible stale history
+                        deleteCpuHistoryVOOnCpuFeatureChange();
+                        logger.debug(String.format("host[uuid:%s] CPU feature MD5 initialized to %s, cleared CpuFeaturesHistoryVO to avoid stale history",
+                                self.getUuid(), newMd5));
+                    } else if (!oldMd5.equals(newMd5)) {
+                        deleteCpuHistoryVOOnCpuFeatureChange();
+                        logger.debug(String.format("host[uuid:%s] CPU feature changed, old MD5: %s, new MD5: %s, deleted related CpuFeaturesHistoryVO records",
+                            self.getUuid(), oldMd5, newMd5));
+                    }
+
+                    createTagWithoutNonValue(KVMSystemTags.CPU_FEATURE_MD5,
+                        KVMSystemTags.CPU_FEATURE_MD5_TOKEN, newMd5, true);
+                }
🤖 Prompt for AI Agents
In `@plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java` around lines 6209 -
6224, When handling ret.getCpuFeatureMd5() in KVMHost, ensure we also clear
legacy CpuFeaturesHistoryVO when this is the first time writing the
CPU_FEATURE_MD5 tag: if newMd5 != null and oldMd5 is null, query for existing
CpuFeaturesHistoryVO records for this host (use self.getUuid()) and, if any
exist, call deleteCpuHistoryVOOnCpuFeatureChange() and log the deletion just
like when md5 changes; keep the existing
createTagWithoutNonValue(KVMSystemTags.CPU_FEATURE_MD5,
KVMSystemTags.CPU_FEATURE_MD5_TOKEN, newMd5, true) afterward so the tag is still
created.

}
};
}

private void deleteCpuHistoryVOOnCpuFeatureChange() {
SQL.New(CpuFeaturesHistoryVO.class)
.eq(CpuFeaturesHistoryVO_.srcHostUuid, self.getUuid())
.delete();
SQL.New(CpuFeaturesHistoryVO.class)
.eq(CpuFeaturesHistoryVO_.dstHostUuid, self.getUuid())
.delete();
}

private void deleteCpuHistoryVOIfCpuModeNameChange(String cpuModelName){
// delete all records that do not match the cpuModelName of the source physical machine
SQL.New(CpuFeaturesHistoryVO.class)
Expand Down
3 changes: 3 additions & 0 deletions plugin/kvm/src/main/java/org/zstack/kvm/KVMSystemTags.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ public class KVMSystemTags {
public static final String CPU_MODEL_NAME_TOKEN = "name";
public static PatternedSystemTag CPU_MODEL_NAME = new PatternedSystemTag(String.format("cpuModelName::{%s}", CPU_MODEL_NAME_TOKEN), HostVO.class);

public static final String CPU_FEATURE_MD5_TOKEN = "cpuFeatureMd5";
public static PatternedSystemTag CPU_FEATURE_MD5 = new PatternedSystemTag(String.format("cpuFeatureMd5::{%s}", CPU_FEATURE_MD5_TOKEN), HostVO.class);

public static final String CHECK_CLUSTER_CPU_MODEL_TOKEN = "enable";
public static PatternedSystemTag CHECK_CLUSTER_CPU_MODEL = new PatternedSystemTag(String.format("check::cluster::cpu::model::{%s}", CHECK_CLUSTER_CPU_MODEL_TOKEN), ClusterVO.class);

Expand Down