Skip to content

<fix>[kvm]: mark TPM VM host files changed on start/shutdown#3726

Open
MatheMatrix wants to merge 1 commit intofeature-zsv-5.0.0-vm-support-vtpm-and-secucebootfrom
sync/wenhao.zhang/zsv-ldap
Open

<fix>[kvm]: mark TPM VM host files changed on start/shutdown#3726
MatheMatrix wants to merge 1 commit intofeature-zsv-5.0.0-vm-support-vtpm-and-secucebootfrom
sync/wenhao.zhang/zsv-ldap

Conversation

@MatheMatrix
Copy link
Copy Markdown
Owner

When a VM with TPM starts or shuts down, NvRam/TpmState
data must have changed. Preemptively set changeDate on the
corresponding VmHostFileVO so the periodic tracker knows
to sync them, even if the direct sync fails.

Also add ResourceDestinationMaker check to all VM canonical
event handlers in KvmSecureBootManager to ensure only the
owning management node processes each event.

Resolves: ZSV-11779
Related: ZSV-11310

Change-Id: I6e6d6c6c647175716669756b75756a6f72657277

sync from gitlab !9595

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2026

Walkthrough

在 KVM 安全启动模块中:KvmSecureBootManager 注入 ResourceDestinationMaker 并在 libvirt 启动/关机事件用 isManagedByUs 门控;受管 VM 事件会提前更新对应主机文件的 changeDate(通过工厂决定的类型集合);工厂新增按 VM 决定需注册的主机文件类型查询方法,扩展改为使用该工厂判定 NvRam/TpmState 处理逻辑。

Changes

Cohort / File(s) Summary
安全启动管理器
plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java
注入 ResourceDestinationMaker;在 VM_LIBVIRT_REPORT_STARTVM_LIBVIRT_REPORT_SHUTDOWN 事件处理里用 resourceDestinationMaker.isManagedByUs(vmUuid) 门控早退;新增私有方法 markVmHostFilesChanged(String vmUuid)markVmHostFilesChanged(String vmUuid, String hostUuid),在解析到 hostUuid 后按工厂类型集合更新匹配 VmHostFileVO.changeDate 的行。
主机文件工厂与依赖注入
plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmVmHostFileFactory.java
新增注入字段 ResourceConfigFacade resourceConfigFacadeVmTpmManager vmTpmManager;新增公有方法 Set<VmHostFileType> vmHostFileTypeNeedRegisterForVm(String vmUuid)(返回需注册类型集)与 boolean needRegister(VmHostFileType type, String vmUuid);用于替代原先在多处对 TPM/资源配置的直接检测。
安全启动扩展逻辑调整
plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootExtensions.java
移除对 VmSystemTags 和直接 TPM (TpmVO) 查表的检测,注入并使用 KvmVmHostFileFactory.needRegister(NvRam, vm.getUuid()) 来决定是否处理 NvRam;在多处同步/迁移/备份路径统一使用 VmHostFileType.NvRam 常量并据工厂返回跳过或继续流程。

Sequence Diagram(s)

sequenceDiagram
    participant Libvirt as "Libvirt 事件"
    participant Manager as "KvmSecureBootManager"
    participant Factory as "KvmVmHostFileFactory"
    participant DB as "数据库 (VmHostFileVO)"
    Libvirt->>Manager: VM_LIBVIRT_REPORT_START/SHUTDOWN(vmUuid)
    Manager->>Manager: resourceDestinationMaker.isManagedByUs(vmUuid)?
    alt Managed
        Manager->>Factory: vmHostFileTypeNeedRegisterForVm(vmUuid)
        Factory-->>Manager: Set<VmHostFileType> (e.g., NvRam, TpmState)
        Manager->>DB: UPDATE VmHostFileVO.changeDate WHERE vmInstanceUuid=vmUuid AND hostUuid=resolvedHostUuid AND type IN (...)
        DB-->>Manager: 更新结果
        Manager-->>Libvirt: 继续后续事件处理(如需)
    else Not managed
        Manager-->>Libvirt: 早退/忽略事件
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 轻蹦过代码林,
门控先问谁来临,
标记时间小脚印,
NvRam 与 TPM 同吟,
兔子鼓掌庆新巡!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed 标题清晰准确地概括了主要变更:在VM启动/关闭时标记TPM VM主机文件已更改,反映了代码库中引入的核心功能。
Description check ✅ Passed 描述与变更集高度相关,解释了预设changeDate的原因、ResourceDestinationMaker检查的必要性及相关问题编号。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sync/wenhao.zhang/zsv-ldap

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java (1)

197-238: 可选优化:提取 hostUuid 获取逻辑以避免重复代码和重复查询。

hostUuid 的获取逻辑(优先取 hostUuid,若为空则取 lastHostUuid)在以下位置重复出现:

  • markVmHostFilesChanged (lines 210-224)
  • shutdown 事件处理 (lines 146-157)
  • handle(RestoreVmHostFileMsg) (lines 816-834)

此外,在 shutdown 事件路径中,markVmHostFilesChanged 和后续逻辑会对 VmInstanceVO 进行两次相同的查询,可以考虑传递查询结果以减少 DB 访问。

♻️ 建议提取辅助方法
/**
 * Get the effective host UUID for a VM (hostUuid or fallback to lastHostUuid).
 * `@return` host UUID or null if VM not found or no host
 */
private String getEffectiveHostUuid(String vmUuid) {
    Tuple tuple = Q.New(VmInstanceVO.class)
            .select(VmInstanceVO_.hostUuid, VmInstanceVO_.lastHostUuid)
            .eq(VmInstanceVO_.uuid, vmUuid)
            .findTuple();
    if (tuple == null) {
        return null;
    }
    String hostUuid = (String) tuple.get(0);
    return hostUuid != null ? hostUuid : (String) tuple.get(1);
}

然后在 shutdown 事件处理中可以复用结果:

markVmHostFilesChanged(vmUuid);

String hostUuid = getEffectiveHostUuid(vmUuid);
if (hostUuid == null) {
    return;
}
// ... rest of logic using hostUuid
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java` around
lines 197 - 238, The hostUuid selection logic (prefer hostUuid, fallback to
lastHostUuid) is duplicated in markVmHostFilesChanged, the shutdown handler, and
handle(RestoreVmHostFileMsg); extract it into a private helper (e.g.,
getEffectiveHostUuid(String vmUuid)) that returns the effective host UUID or
null, then replace the duplicated Tuple queries in markVmHostFilesChanged, the
shutdown event path, and handle(RestoreVmHostFileMsg) to call
getEffectiveHostUuid; additionally, where shutdown currently calls
markVmHostFilesChanged and then re-queries VmInstanceVO, refactor to call
getEffectiveHostUuid once and pass the result into markVmHostFilesChanged (or
provide an overload like markVmHostFilesChanged(String vmUuid, String hostUuid))
to eliminate the double DB access.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java`:
- Around line 197-238: The hostUuid selection logic (prefer hostUuid, fallback
to lastHostUuid) is duplicated in markVmHostFilesChanged, the shutdown handler,
and handle(RestoreVmHostFileMsg); extract it into a private helper (e.g.,
getEffectiveHostUuid(String vmUuid)) that returns the effective host UUID or
null, then replace the duplicated Tuple queries in markVmHostFilesChanged, the
shutdown event path, and handle(RestoreVmHostFileMsg) to call
getEffectiveHostUuid; additionally, where shutdown currently calls
markVmHostFilesChanged and then re-queries VmInstanceVO, refactor to call
getEffectiveHostUuid once and pass the result into markVmHostFilesChanged (or
provide an overload like markVmHostFilesChanged(String vmUuid, String hostUuid))
to eliminate the double DB access.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ed16abfb-1ca2-46ac-95aa-f0d9d855a8a4

📥 Commits

Reviewing files that changed from the base of the PR and between 449ef01 and 3f42ee8.

📒 Files selected for processing (1)
  • plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java

@MatheMatrix MatheMatrix force-pushed the sync/wenhao.zhang/zsv-ldap branch from 3f42ee8 to 0a5630d Compare April 11, 2026 10:16
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java (1)

208-222: 建议抽取 hostUuid 解析逻辑以减少重复。

hostUuid -> lastHostUuid 的回退解析在 shutdown 回调和 markVmHostFilesChanged() 中重复出现,建议提取成私有 helper,减少后续改动时的分支漂移风险。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java` around
lines 208 - 222, Extract the duplicated "hostUuid -> lastHostUuid" fallback
logic into a private helper in KvmSecureBootManager (e.g.,
resolveHostUuid(String vmUuid) or getEffectiveHostUuid) that performs the
Q.New(VmInstanceVO.class) select for hostUuid and lastHostUuid, applies the
fallback and returns null if none; then replace the duplicated blocks in the
shutdown callback and markVmHostFilesChanged() with calls to this helper to
centralize the resolution logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java`:
- Around line 233-234: 将 debug 日志中的“TPM vm”表述改为中性且准确的描述以免误导排障;在
KvmSecureBootManager 中找到使用 logger.debug 的那一行(当前格式化字符串包含 vmUuid, hostUuid,
updated)并将消息改为例如“preemptively marked VmHostFiles as changed for
secure-boot-related vm[uuid:%s] on host[uuid:%s], %d records updated”
或其它等效中性表述,确保仍包含 vmUuid、hostUuid 和 updated 三个占位符。

In `@plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmVmHostFileFactory.java`:
- Around line 53-55: The ternary in KvmVmHostFileFactory using
resourceConfig.getResourceConfigValue(vmUuid, Boolean.class) can NPE when the
Boolean is null; change the condition to compare with Boolean.TRUE (e.g.,
Boolean.TRUE.equals(resourceConfig.getResourceConfigValue(...)) or ==
Boolean.TRUE) to avoid auto-unboxing NPE and match the style used in
KvmSecureBootExtensions and VmTpmExtensions, keeping the returned new
HashSet<>(list(NvRam)) or Collections.emptySet() behavior unchanged.

---

Nitpick comments:
In `@plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java`:
- Around line 208-222: Extract the duplicated "hostUuid -> lastHostUuid"
fallback logic into a private helper in KvmSecureBootManager (e.g.,
resolveHostUuid(String vmUuid) or getEffectiveHostUuid) that performs the
Q.New(VmInstanceVO.class) select for hostUuid and lastHostUuid, applies the
fallback and returns null if none; then replace the duplicated blocks in the
shutdown callback and markVmHostFilesChanged() with calls to this helper to
centralize the resolution logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7ab4cfb2-44df-49e3-964e-75fb7a2aea7d

📥 Commits

Reviewing files that changed from the base of the PR and between 3f42ee8 and 0a5630d.

📒 Files selected for processing (2)
  • plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java
  • plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmVmHostFileFactory.java

@MatheMatrix MatheMatrix force-pushed the sync/wenhao.zhang/zsv-ldap branch from 0a5630d to de81066 Compare April 11, 2026 10:54
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java (1)

201-229: 建议按已注册的 VmHostFileVO 置脏,避免兜底范围和直读范围漂移。

这里用 vmHostFileFactory.vmHostFileTypeNeedRegisterForVm(vmUuid) 重新推导类型;但下面 shutdown 的即时同步是按 DB 里实际存在的 VmHostFileVO 行来读的。为了让“即时同步失败后的周期兜底”覆盖完全一致,建议这里直接基于 vmUuid + hostUuid 下已注册的文件行批量更新 changeDate,而不是再算一遍期望类型集。

♻️ 可参考的调整方向
-        final Set<VmHostFileType> types = vmHostFileFactory.vmHostFileTypeNeedRegisterForVm(vmUuid);
-        if (types.isEmpty()) {
-            return;
-        }
-
         Tuple tuple = Q.New(VmInstanceVO.class)
                 .select(VmInstanceVO_.hostUuid, VmInstanceVO_.lastHostUuid)
                 .eq(VmInstanceVO_.uuid, vmUuid)
                 .findTuple();
@@
         if (hostUuid == null) {
             return;
         }

+        List<VmHostFileType> types = Q.New(VmHostFileVO.class)
+                .eq(VmHostFileVO_.vmInstanceUuid, vmUuid)
+                .eq(VmHostFileVO_.hostUuid, hostUuid)
+                .select(VmHostFileVO_.type)
+                .listValues();
+        if (types.isEmpty()) {
+            return;
+        }
+
         Timestamp now = new Timestamp(timeHelper.getCurrentTimeMillis());
         long updated = SQL.New(VmHostFileVO.class)
                 .eq(VmHostFileVO_.vmInstanceUuid, vmUuid)
                 .eq(VmHostFileVO_.hostUuid, hostUuid)
                 .in(VmHostFileVO_.type, types)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java` around
lines 201 - 229, The current markVmHostFilesChanged method computes types via
vmHostFileFactory.vmHostFileTypeNeedRegisterForVm(vmUuid) but then updates by
that derived set, which can diverge from the actual registered VmHostFileVO rows
read by the shutdown sync; change it to query the DB for existing VmHostFileVO
entries for the resolved hostUuid and vmUuid and update those rows'
VmHostFileVO_.changeDate directly (use SQL.New(VmHostFileVO.class) filtered by
VmHostFileVO_.vmInstanceUuid and VmHostFileVO_.hostUuid to target actual rows)
instead of using the types variable derived from the factory so both immediate
sync and periodic fallback operate on the same set of DB rows.
plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootExtensions.java (1)

339-346: 建议把 VmHostFileType 到消息字段的分派收敛到一个 helper。

这几处现在都在手写 NvRam/TpmState -> setNvRamPath/setTpmStateFolder 的分支。当前 PR 已经改到 6 处,后面如果再加类型或调整路径语义,很容易漏改,而且现在不同路径里对 unsupported type 的处理也不完全一致。

♻️ 可参考的收敛方式
+    private void applyHostFilePath(SyncVmHostFilesFromHostMsg syncMsg, VmHostFileType type, String path) {
+        if (type == NvRam) {
+            syncMsg.setNvRamPath(path);
+            return;
+        }
+        if (type == VmHostFileType.TpmState) {
+            syncMsg.setTpmStateFolder(path);
+            return;
+        }
+        throw new CloudRuntimeException("unsupported vm host file type: " + type);
+    }

然后把这些分支统一替换成:

-        if (file.getType() == NvRam) {
-            syncMsg.setNvRamPath(file.getPath());
-        } else if (file.getType() == VmHostFileType.TpmState) {
-            syncMsg.setTpmStateFolder(file.getPath());
-        } else {
-            logger.warn(...);
-        }
+        applyHostFilePath(syncMsg, file.getType(), file.getPath());

As per coding guidelines,“单一职责原则:每个模块、类、方法应只承担单一的责任。若某个逻辑过于复杂,应考虑拆分出独立类来处理。”

Also applies to: 461-465, 563-572, 622-632, 688-697, 748-754

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootExtensions.java`
around lines 339 - 346, Centralize the VmHostFileType -> message-field dispatch
into a single helper to avoid duplicated branching: create a private helper
(e.g., populateSyncMsgForVmHostFile or mapVmHostFileToSync) that takes the
VmHostFile (or its type/path) and the sync message object and performs the
NvRam/TpmState switch, calling setNvRamPath or setTpmStateFolder (and throwing a
single consistent CloudRuntimeException for unsupported types); then replace the
inline branches in KvmSecureBootExtensions (locations around vmHostFile handling
including the existing blocks at the shown snippet and the other occurrences
~461-465, ~563-572, ~622-632, ~688-697, ~748-754) to call that helper so all
dispatch logic is maintained in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootExtensions.java`:
- Around line 339-346: Centralize the VmHostFileType -> message-field dispatch
into a single helper to avoid duplicated branching: create a private helper
(e.g., populateSyncMsgForVmHostFile or mapVmHostFileToSync) that takes the
VmHostFile (or its type/path) and the sync message object and performs the
NvRam/TpmState switch, calling setNvRamPath or setTpmStateFolder (and throwing a
single consistent CloudRuntimeException for unsupported types); then replace the
inline branches in KvmSecureBootExtensions (locations around vmHostFile handling
including the existing blocks at the shown snippet and the other occurrences
~461-465, ~563-572, ~622-632, ~688-697, ~748-754) to call that helper so all
dispatch logic is maintained in one place.

In `@plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java`:
- Around line 201-229: The current markVmHostFilesChanged method computes types
via vmHostFileFactory.vmHostFileTypeNeedRegisterForVm(vmUuid) but then updates
by that derived set, which can diverge from the actual registered VmHostFileVO
rows read by the shutdown sync; change it to query the DB for existing
VmHostFileVO entries for the resolved hostUuid and vmUuid and update those rows'
VmHostFileVO_.changeDate directly (use SQL.New(VmHostFileVO.class) filtered by
VmHostFileVO_.vmInstanceUuid and VmHostFileVO_.hostUuid to target actual rows)
instead of using the types variable derived from the factory so both immediate
sync and periodic fallback operate on the same set of DB rows.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 78119598-43fb-468d-a005-d3d5d6fbabf3

📥 Commits

Reviewing files that changed from the base of the PR and between 0a5630d and de81066.

📒 Files selected for processing (3)
  • plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootExtensions.java
  • plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java
  • plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmVmHostFileFactory.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmVmHostFileFactory.java

@zstack-robot-1
Copy link
Copy Markdown
Collaborator

Comment from ye.zou:

Code Review

# 严重程度 分类 文件 问题描述 修复建议
1 🟡 Major 正确性 / 语义变更 KvmVmHostFileFactory.java:48-56 vmHostFileTypeNeedRegisterForVmhasTpm=false 时直接查 ENABLE_UEFI_SECURE_BOOT resource config。但原 KvmSecureBootExtensions 中的逻辑是先检查 boot mode 是否为 UEFIisUefiBootMode(bootMode)),只有 UEFI boot mode 才查 secure boot config。新方法跳过了 boot mode 前置检查。如果管理员在 global/cluster 级别设了 ENABLE_UEFI_SECURE_BOOT=true,非 UEFI VM 也会被误判为需要注册 NvRam。实际影响有限(非 UEFI VM 不会有 VmHostFileVO 记录,markVmHostFilesChangedupdated 会是 0;迁移路径也会因找不到 NvRam 文件而跳过),但语义上与原逻辑不一致,且在迁移路径中会导致不必要的 flow chain 执行。 方案一:在 vmHostFileTypeNeedRegisterForVm 中加回 boot mode 检查(需要引入 VmSystemTags.BOOT_MODE)。方案二:如果确认上游保证只有 UEFI VM 才会设 ENABLE_UEFI_SECURE_BOOT=true,在注释中标明这个前提。
2 🟡 Major 性能 KvmSecureBootManager.java (shutdown handler) shutdown 路径中 markVmHostFilesChanged(vmUuid) 内部查了一次 VmInstanceVO(获取 hostUuid/lastHostUuid),紧接着 shutdown handler 自身又做了一模一样的 tuple 查询。每次 VM shutdown 都多一次不必要的 DB roundtrip。 markVmHostFilesChanged 重构为接受 (vmUuid, hostUuid) 参数,由调用方传入已查询到的 hostUuid 复用。或者提取 getEffectiveHostUuid(vmUuid) 公共方法(CodeRabbit 也提了同样建议)。
3 🔵 Minor 性能 KvmSecureBootManager.java (start handler) VM_LIBVIRT_REPORT_START所有 VM 都会触发,包括无 TPM/无 UEFI 的 VM。每次触发都会执行 vmHostFileTypeNeedRegisterForVm → 查一次 TpmVO + 可能查一次 resource config,对绝大多数无关 VM 是纯开销。 考虑增加更轻量级的前置检查(如先查 VM 是否存在 VmHostFileVO 记录),或者在 event 数据中携带标记来 early-return。

结论: CONDITIONAL ⚠️

统计: 🔴 0 | 🟡 2 | 🔵 1

回归风险: 低-中

总体评价

  • 重构方向正确,把 TPM/SecureBoot 检测逻辑集中到 KvmVmHostFileFactory 消除了多处重复判断
  • ResourceDestinationMaker guard 的添加是必要的,防止多 MN 环境下重复处理
  • markVmHostFilesChanged 的设计思路合理(预判性标脏,即使即时同步失败也能被周期 tracker 兜底)
  • Boolean NPE 已在后续 commit 修复 ✅
  • Test1 #1 的语义变更建议确认或补回 boot mode 检查;tao.yang/zstack-ZSV-3564@@2 #2 的重复查询建议在 follow-up 中优化

When a VM with TPM starts or shuts down, NvRam/TpmState
data must have changed. Preemptively set changeDate on the
corresponding VmHostFileVO so the periodic tracker knows
to sync them, even if the direct sync fails.

Also add ResourceDestinationMaker check to all VM canonical
event handlers in KvmSecureBootManager to ensure only the
owning management node processes each event.

Resolves: ZSV-11779
Related: ZSV-11310

Change-Id: I6e6d6c6c647175716669756b75756a6f72657277
@MatheMatrix MatheMatrix force-pushed the sync/wenhao.zhang/zsv-ldap branch from de81066 to 9ea77b9 Compare April 12, 2026 13:47
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java (1)

150-154: ⚠️ Potential issue | 🟡 Minor

缺少 hostUuid 的空值检查。

shutdown 事件处理器在调用 markVmHostFilesChanged(vmUuid, hostUuid) 前没有检查 hostUuid 是否为 null。如果 VmInstanceVO.hostUuidlastHostUuid 都为 null,会传递 null 给方法。

相比之下,markVmHostFilesChanged(String vmUuid) 重载版本(第 212-214 行)正确地做了 null 检查。建议保持一致性。

🛡️ 建议添加空值检查
 String hostUuid = (String) tuple.get(0);
 if (hostUuid == null) {
     hostUuid = (String) tuple.get(1);
 }
+if (hostUuid == null) {
+    return;
+}
 markVmHostFilesChanged(vmUuid, hostUuid);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java` around
lines 150 - 154, The shutdown handler extracts hostUuid from tuple but doesn't
null-check it before calling markVmHostFilesChanged(vmUuid, hostUuid); add a
null check on the extracted hostUuid (the value from tuple.get(0)/tuple.get(1))
and, if it is null, call the existing overload markVmHostFilesChanged(vmUuid)
instead of passing null, otherwise call markVmHostFilesChanged(vmUuid,
hostUuid); this keeps behavior consistent with the other overload that already
performs the null check.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java`:
- Around line 150-154: The shutdown handler extracts hostUuid from tuple but
doesn't null-check it before calling markVmHostFilesChanged(vmUuid, hostUuid);
add a null check on the extracted hostUuid (the value from
tuple.get(0)/tuple.get(1)) and, if it is null, call the existing overload
markVmHostFilesChanged(vmUuid) instead of passing null, otherwise call
markVmHostFilesChanged(vmUuid, hostUuid); this keeps behavior consistent with
the other overload that already performs the null check.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: fbd4eff4-b5de-4ccd-935b-48ddc80cfb1b

📥 Commits

Reviewing files that changed from the base of the PR and between de81066 and 9ea77b9.

📒 Files selected for processing (3)
  • plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootExtensions.java
  • plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java
  • plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmVmHostFileFactory.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmVmHostFileFactory.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants