Skip to content

<fix>[vm]: prune stale device metadata on startVm#3836

Open
zstack-robot-2 wants to merge 2 commits intozsv_5.0.0from
sync/tao.gan/ZSV-11374@@3
Open

<fix>[vm]: prune stale device metadata on startVm#3836
zstack-robot-2 wants to merge 2 commits intozsv_5.0.0from
sync/tao.gan/ZSV-11374@@3

Conversation

@zstack-robot-2
Copy link
Copy Markdown
Collaborator

afterReceiveVmDeviceInfoResponse was upsert-only, leaving
VmInstanceResourceMetadataVO rows for devices (e.g. cdrom)
detached while the VM was stopped. Add pruneStaleDeviceMetadata
and invoke it after each start/sync so DB matches the libvirt
domain. Rows with non-null metadataClass are preserved.

Resolves: ZSV-11374

Change-Id: I687463656770616d6967746b6270767366756a64

sync from gitlab !9708

afterReceiveVmDeviceInfoResponse was upsert-only, leaving
VmInstanceResourceMetadataVO rows for devices (e.g. cdrom)
detached while the VM was stopped. Add pruneStaleDeviceMetadata
and invoke it after each start/sync so DB matches the libvirt
domain. Rows with non-null metadataClass are preserved.

Resolves: ZSV-11374

Change-Id: I687463656770616d6967746b6270767366756a64
1. hasAuthoritativeDeviceInfo now tracks actually valid entries
   observed from the agent response instead of raw list
   non-emptiness, preventing a reply with all-invalid
   VirtualDeviceInfo from triggering prune with only vmUuid
   in surviving.

2. When rsp.nicInfos is null, populate surviving with every
   known nic uuid from spec/vm so the prune step cannot drop
   their address rows as collateral damage.

3. Extract ALWAYS_KEEP_UUIDS to a static final Set.

4. Remove stray uncompilable line left in prune method.

Resolves: ZSV-11374

Change-Id: Ieb86e65494b0d957ef00267f4013605170f35adb
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

Walkthrough

通过在VmInstanceResourceMetadataManager中新增pruneStaleDeviceMetadata方法,实现虚拟机设备元数据的清理功能。该功能在KVM设备信息响应处理流程中被调用,以删除不在当前存活资源集合中的陈旧元数据记录。

Changes

Cohort / File(s) Summary
接口声明
header/src/main/java/org/zstack/header/vm/devices/VmInstanceResourceMetadataManager.java
添加了新的公共接口方法pruneStaleDeviceMetadata,用于声明设备元数据清理功能的契约,包括参数类型和返回值的文档说明。
核心实现
compute/src/main/java/org/zstack/compute/vm/devices/VmInstanceResourceMetadataManagerImpl.java
实现了pruneStaleDeviceMetadata方法,包含一个静态白名单ALWAYS_KEEP_UUIDS以保护特定元数据行不被删除,同时实现了过滤逻辑以排除存活资源和虚拟机UUID。
功能集成
plugin/kvm/src/main/java/org/zstack/kvm/VirtualPciDeviceKvmExtensionPoint.java
afterReceiveVmDeviceInfoResponse方法中集成清理流程:构建存活资源集合,添加权威标志来检测有效的设备信息,在条件满足时调用清理方法并处理异常。

Sequence Diagram(s)

sequenceDiagram
    participant Agent as KVM Agent
    participant Extension as VirtualPciDeviceKvmExtensionPoint
    participant Manager as VmInstanceResourceMetadataManager
    participant DB as Database

    Agent->>Extension: afterReceiveVmDeviceInfoResponse(rsp)
    Extension->>Extension: 从响应构建surviving集合<br/>(vmUuid, 有效设备, NIC, 气球)
    Extension->>Extension: 设置hasAuthoritativeDeviceInfo标志<br/>(基于有效设备数据)
    
    alt hasAuthoritativeDeviceInfo为true
        Extension->>Extension: 更新气球设备元数据
        Extension->>Manager: pruneStaleDeviceMetadata(vmUuid,<br/>surviving)
        Manager->>DB: 加载所有元数据行
        Manager->>Manager: 计算待删除列表<br/>(排除白名单、vmInstanceUuid、<br/>存活资源)
        Manager->>DB: 硬删除陈旧元数据
        Manager-->>Extension: 返回删除数量
        Extension->>Extension: 日志记录清理结果
    else hasAuthoritativeDeviceInfo为false
        Extension->>Extension: 跳过元数据清理<br/>(无权威设备信息)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 新的清理工具闪闪发光,
删除陈旧的设备行,
白名单保护心头好,
资源存活才安详,
虚拟机的家务也轻松!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题清晰准确地总结了主要变更:在startVm时清理过时的设备元数据,与pull request的核心目标完全对应。
Description check ✅ Passed 描述详细说明了问题背景、解决方案和相关细节,与changeset的所有修改高度相关。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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/tao.gan/ZSV-11374@@3

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/VirtualPciDeviceKvmExtensionPoint.java (1)

132-139: 简化 memBalloonInfo 的空值检查。

当前检查链中的第三个条件是冗余的。DeviceAddress.toString() 调用 JSONObjectUtil.toJsonString(this),而 toJsonString() 使用 Gson 序列化对象,对于非空对象永远不会返回空字符串(至少会返回 "{}")。因此,一旦 getDeviceAddress() != null 通过,toString() 不可能为空。

♻️ 建议简化
-        if (rsp.getMemBalloonInfo() != null
-                && rsp.getMemBalloonInfo().getDeviceAddress() != null
-                && !StringUtils.isEmpty(rsp.getMemBalloonInfo().getDeviceAddress().toString())) {
+        if (rsp.getMemBalloonInfo() != null
+                && rsp.getMemBalloonInfo().getDeviceAddress() != null) {
🤖 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/VirtualPciDeviceKvmExtensionPoint.java`
around lines 132 - 139, The null/empty check chain in
VirtualPciDeviceKvmExtensionPoint is redundant: once
rsp.getMemBalloonInfo().getDeviceAddress() is non-null, its toString() (which
delegates to JSONObjectUtil/Gson) cannot be an empty string. Simplify the if
condition to only test rsp.getMemBalloonInfo() != null &&
rsp.getMemBalloonInfo().getDeviceAddress() != null, then proceed to call
vidManager.createOrUpdateVmResourceMetadata(... DeviceAddress.fromString(...)),
add vidManager.MEM_BALLOON_UUID to surviving, and set hasAuthoritativeDeviceInfo
= true.
🤖 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/VirtualPciDeviceKvmExtensionPoint.java`:
- Around line 132-139: The null/empty check chain in
VirtualPciDeviceKvmExtensionPoint is redundant: once
rsp.getMemBalloonInfo().getDeviceAddress() is non-null, its toString() (which
delegates to JSONObjectUtil/Gson) cannot be an empty string. Simplify the if
condition to only test rsp.getMemBalloonInfo() != null &&
rsp.getMemBalloonInfo().getDeviceAddress() != null, then proceed to call
vidManager.createOrUpdateVmResourceMetadata(... DeviceAddress.fromString(...)),
add vidManager.MEM_BALLOON_UUID to surviving, and set hasAuthoritativeDeviceInfo
= true.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f3bab009-a40d-4959-b2fb-957b44ffbe96

📥 Commits

Reviewing files that changed from the base of the PR and between c040645 and 486fb4e.

📒 Files selected for processing (3)
  • compute/src/main/java/org/zstack/compute/vm/devices/VmInstanceResourceMetadataManagerImpl.java
  • header/src/main/java/org/zstack/header/vm/devices/VmInstanceResourceMetadataManager.java
  • plugin/kvm/src/main/java/org/zstack/kvm/VirtualPciDeviceKvmExtensionPoint.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