Skip to content

<fix>[externalapiadapter]: fix VM NIC driver type fallback#3933

Open
zstack-robot-1 wants to merge 1 commit into
5.4.2from
sync/boce.wang/fix-85160
Open

<fix>[externalapiadapter]: fix VM NIC driver type fallback#3933
zstack-robot-1 wants to merge 1 commit into
5.4.2from
sync/boce.wang/fix-85160

Conversation

@zstack-robot-1
Copy link
Copy Markdown
Collaborator

Persist the resolved NIC driver type during AttachVmNicToVm and narrow prepareDbInitialValue to repair only null VNIC driverType records while respecting the VM virtio tag and platform, preventing existing virtio NICs from being overwritten as e1000 after management node restart.

Resolves: ZSTAC-85160

Change-Id: I6868776c140529e5286d40c187fde99608127f7a

sync from gitlab !9822

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: http://open.zstack.ai:20001/code-reviews/zstack-cloud.yaml (via .coderabbit.yaml)

Review profile: CHILL

Plan: Pro

Run ID: 7eecb791-c73b-457c-bc1d-42208c7beee8

📥 Commits

Reviewing files that changed from the base of the PR and between c68e521 and 046e4a7.

📒 Files selected for processing (4)
  • compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java
  • compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java
  • test/src/test/groovy/org/zstack/test/integration/kvm/nic/ChangeWindowsVmNicDriverCase.groovy
  • test/src/test/groovy/org/zstack/test/integration/kvm/nic/VmNicBasicCase.groovy
🚧 Files skipped from review as they are similar to previous changes (4)
  • test/src/test/groovy/org/zstack/test/integration/kvm/nic/VmNicBasicCase.groovy
  • compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java
  • test/src/test/groovy/org/zstack/test/integration/kvm/nic/ChangeWindowsVmNicDriverCase.groovy
  • compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java

Walkthrough

此 PR 在 NIC 附加与初始化路径中:保留已有的 VmNicVO.driverType,只有为空时才基于 virtio 标签与平台类型计算并持久化;同时优化了 prepareDbInitialValue 的数据库查询与分组逻辑,并新增/扩展集成测试以覆盖这些行为。

更改内容

NIC 驱动类型处理

层/文件 摘要
NIC 附加时的驱动类型保留
compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java
attachNic 方法现在保留已有的 VmNicVO.driverType;当该字段为空时通过 nicManager.setNicDriverType() 计算,并将结果写回数据库更新和内存对象。包括末尾微小的 EOF 空白调整。
驱动类型初始化和查询优化
compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java
prepareDbInitialValue() 使用目标查询获取 driverType is null 的虚拟 NIC(带 vmInstanceUuid),按 VM 聚合并基于 virtio 系统标签与平台 para-virtualization 状态计算每个 VM 的目标驱动,使用标准 HashMap 分组后更新 NIC 的 driverType
驱动类型初始化和附加的测试覆盖
test/src/test/groovy/org/zstack/test/integration/kvm/nic/ChangeWindowsVmNicDriverCase.groovy, test/src/test/groovy/org/zstack/test/integration/kvm/nic/VmNicBasicCase.groovy
ChangeWindowsVmNicDriverCase 添加 testPrepareDbInitialValueForVirtioTaggedWindowsVm(),通过直接清空新 NIC 的 driverType 并调用 VmNicManagerImpl.prepareDbInitialValue() 验证其被恢复为 "virtio"VmNicBasicCase 验证新建 NIC 初始数据库记录无 driverType,并在 attach 后与 VM 现有 NIC 的 driverType 保持一致。

🎯 3 (中等) | ⏱️ ~25 分钟

🐰 我从洞口来报喜,
虚拟网卡换新衣,
保留旧驱动心意,
查询更快步子轻,
*测试一笑皆安心。

🚥 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 标题遵循 [scope]: 格式,包含 'fix' 类型和 'externalapiadapter' 作用域,长度为 58 字符(不超过 72 字符限制),准确描述了 VM NIC 驱动类型回退修复的主要变更。
Description check ✅ Passed 描述清晰地说明了修复的核心问题:在 AttachVmNicToVm 期间保持已解析的 NIC 驱动类型,并缩小 prepareDbInitialValue 的范围仅处理空值 VNIC driverType 记录,与 PR 变更内容直接相关。
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/boce.wang/fix-85160

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.42.2)
compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java

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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java`:
- Around line 146-147: The current vmDrivers.put call in VmNicManagerImpl
(inside prepareDbInitialValue) directly calls ImagePlatform.valueOf(vmPlatform)
which will throw on null/unknown platform; change this to safely parse the
platform string: first check if vmPlatform is null/blank, then attempt a guarded
parse (try-catch around valueOf or use a safe lookup method) and treat any
exception or unknown value as non-paravirtualized, falling back to
defaultNicDriver; ensure the put still uses virtioVmUuids.contains(vmUuid) ||
<isParaVirtualization> logic with the safe result, and log a warning/error
mentioning vmUuid and vmPlatform when falling back so startup repair tolerates
dirty/legacy data.

In
`@test/src/test/groovy/org/zstack/test/integration/kvm/nic/ChangeWindowsVmNicDriverCase.groovy`:
- Around line 116-124: After zeroing driverType with
SQL.New(VmNicVO.class)...set(VmNicVO_.driverType, null).update(), add an
immediate pre-condition assertion that Q.New(VmNicVO.class).eq(VmNicVO_.uuid,
newNic.uuid).select(VmNicVO_.driverType).findValue() == null before calling
bean(VmNicManagerImpl.class).prepareDbInitialValue(), so the test fails if the
SQL update didn't actually clear the field and avoids a false positive on the
later "virtio" assertions.
🪄 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: Path: http://open.zstack.ai:20001/code-reviews/zstack-cloud.yaml (via .coderabbit.yaml)

Review profile: CHILL

Plan: Pro

Run ID: db2f81b5-3f6e-416b-88b0-7c67dc6ca0c2

📥 Commits

Reviewing files that changed from the base of the PR and between a763663 and c68e521.

📒 Files selected for processing (4)
  • compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java
  • compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java
  • test/src/test/groovy/org/zstack/test/integration/kvm/nic/ChangeWindowsVmNicDriverCase.groovy
  • test/src/test/groovy/org/zstack/test/integration/kvm/nic/VmNicBasicCase.groovy

Comment on lines +146 to 147
vmDrivers.put(vmUuid, virtioVmUuids.contains(vmUuid) || ImagePlatform.valueOf(vmPlatform).isParaVirtualization() ?
defaultPVNicDriver : defaultNicDriver);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== 1) 检查 VmInstanceVO.platform 字段定义 =="
fd -i 'VmInstanceVO.java' | xargs -r rg -n -C3 'platform|@Column|nullable'

echo
echo "== 2) 检查 ImagePlatform 可接受取值 =="
fd -i 'ImagePlatform.java' | xargs -r rg -n -C2 'enum ImagePlatform|class ImagePlatform|\\b[A-Z0-9_]+\\b'

echo
echo "== 3) 检查平台字段历史写入/迁移路径(是否可能出现非枚举值或空值) =="
rg -n -C2 --iglob '*.{java,groovy,sql,xml}' 'vm_instance|VmInstanceVO_\\.platform|\\bplatform\\b\\s*=|insert\\s+into\\s+.*vm_instance'

Repository: MatheMatrix/zstack

Length of output: 103


🏁 Script executed:

git ls-files | grep -i "VmNicManagerImpl\|VmInstanceVO\|ImagePlatform" | head -20

Repository: MatheMatrix/zstack

Length of output: 418


🏁 Script executed:

sed -n '140,160p' compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java

Repository: MatheMatrix/zstack

Length of output: 1041


🏁 Script executed:

rg -n -C5 '@Column.*platform|private.*platform|public.*platform' header/src/main/java/org/zstack/header/vm/VmInstanceVO.java | head -30

Repository: MatheMatrix/zstack

Length of output: 44


🏁 Script executed:

wc -l header/src/main/java/org/zstack/header/vm/VmInstanceVO.java && grep -n "platform" header/src/main/java/org/zstack/header/vm/VmInstanceVO.java | head -10

Repository: MatheMatrix/zstack

Length of output: 126


🏁 Script executed:

cat -n header/src/main/java/org/zstack/header/vm/VmInstanceVO.java

Repository: MatheMatrix/zstack

Length of output: 5235


🏁 Script executed:

grep -r "class VmInstanceAO" --include="*.java" | head -5

Repository: MatheMatrix/zstack

Length of output: 279


🏁 Script executed:

rg -n "platform" header/src/main/java/org/zstack/header/vm/VmInstanceAO.java

Repository: MatheMatrix/zstack

Length of output: 256


🏁 Script executed:

sed -n '75,95p' header/src/main/java/org/zstack/header/vm/VmInstanceAO.java

Repository: MatheMatrix/zstack

Length of output: 385


🏁 Script executed:

cat -n header/src/main/java/org/zstack/header/image/ImagePlatform.java

Repository: MatheMatrix/zstack

Length of output: 946


🏁 Script executed:

rg -n "prepareDbInitialValue" compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java -B5 -A15

Repository: MatheMatrix/zstack

Length of output: 893


🏁 Script executed:

sed -n '120,170p' compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java

Repository: MatheMatrix/zstack

Length of output: 2231


避免在启动修复路径直接对平台字符串调用 valueOf,需要做安全解析

VmInstanceAO.platform 字段为可空(@Column 未设置 nullable=false),但 line 146 的 ImagePlatform.valueOf(vmPlatform) 在遇到 null 值或未知平台值时会抛 IllegalArgumentException,导致 prepareDbInitialValue() 启动修复被中断。需要安全解析:未知/空值平台降级为 defaultNicDriver 并记录告警。

建议修改(示例)
        for (Tuple vmTuple : tupleList) {
            String vmUuid = vmTuple.get(0, String.class);
            String vmPlatform = vmTuple.get(1, String.class);
-           vmDrivers.put(vmUuid, virtioVmUuids.contains(vmUuid) || ImagePlatform.valueOf(vmPlatform).isParaVirtualization() ?
-                   defaultPVNicDriver : defaultNicDriver);
+           Optional<ImagePlatform> platformOpt = Arrays.stream(ImagePlatform.values())
+                   .filter(p -> p.toString().equals(vmPlatform))
+                   .findFirst();
+           boolean isParaVirtualization = platformOpt.map(ImagePlatform::isParaVirtualization).orElse(false);
+           if (vmPlatform != null && !platformOpt.isPresent()) {
+               logger.warn(String.format("unknown vm platform[%s] for vm[uuid:%s], fallback to default nic driver",
+                       vmPlatform, vmUuid));
+           }
+           vmDrivers.put(vmUuid, virtioVmUuids.contains(vmUuid) || isParaVirtualization
+                   ? defaultPVNicDriver : defaultNicDriver);
        }

符合向后兼容原则:启动修复应容错处理历史脏数据,避免因个别异常记录导致全局启动失败。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java` around
lines 146 - 147, The current vmDrivers.put call in VmNicManagerImpl (inside
prepareDbInitialValue) directly calls ImagePlatform.valueOf(vmPlatform) which
will throw on null/unknown platform; change this to safely parse the platform
string: first check if vmPlatform is null/blank, then attempt a guarded parse
(try-catch around valueOf or use a safe lookup method) and treat any exception
or unknown value as non-paravirtualized, falling back to defaultNicDriver;
ensure the put still uses virtioVmUuids.contains(vmUuid) ||
<isParaVirtualization> logic with the safe result, and log a warning/error
mentioning vmUuid and vmPlatform when falling back so startup repair tolerates
dirty/legacy data.

Persist the resolved NIC driver type during AttachVmNicToVm and narrow prepareDbInitialValue to repair only null VNIC driverType records while respecting the VM virtio tag and platform, preventing existing virtio NICs from being overwritten as e1000 after management node restart.

Resolves: ZSTAC-85160

Change-Id: I6868776c140529e5286d40c187fde99608127f7a
@MatheMatrix MatheMatrix force-pushed the sync/boce.wang/fix-85160 branch from c68e521 to 046e4a7 Compare May 13, 2026 03:21
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