Bug: getConnectionByVmName() doesn't use VM's hypervisor type, causing confusing "Domain not found" errors
- 主要语言
- Java
- 星标
- 3.1k
- 派生
- 1.4k
- 平均合并
- 6 天 19 小时
- 30 天内合并 PR
- 32
描述
##### ISSUE TYPE
* Bug Report
##### COMPONENT NAME
KVM Hypervisor Plugin - LibvirtConnection
##### CLOUDSTACK VERSION
Main branch (4.22+)
##### CONFIGURATION
KVM hypervisor type configured with LXC support. VM deployment using KVM or LXC hypervisor.
##### OS / ENVIRONMENT
Linux hypervisor with libvirt installed
##### SUMMARY
`LibvirtConnection.getConnectionByVmName()` does not accept or use the VM's hypervisor type, causing it to always try KVM first, then LXC. When a VM doesn't exist, it returns a potentially wrong default connection instead of throwing a meaningful error, resulting in confusing "Domain not found" messages.
##### STEPS TO REPRODUCE
1. Create a KVM VM (e.g., instance `i-6-526-VM`)
2. Fail VM creation (VM never gets to libvirt) or remove it from the host via virsh (? actually my vm was failed to create)
3. Management server continues to send `CheckVirtualMachineCommand`, `StopCommand`, etc. for the non-existent VM
4. Agent's `LibvirtConnection.getConnectionByVmName("i-6-526-VM")` is called
5. Method tries:
- KVM connection → `domainLookupByName` returns null (VM doesn't exist)
- LXC connection → `domainLookupByName` returns null (VM doesn't exist)
6. Method logs warning and returns default connection from `getConnection()`
7. Caller calls `domainLookupByName` on potentially wrong connection → "Domain not found" error
##### EXPECTED RESULTS
When a VM doesn't exist on the expected hypervisor, `getConnectionByVmName()` should throw a clear exception:
```
Domain not found: no domain with matching name 'i-6-526-VM' on hypervisor 'KVM'
```
The method should accept the hypervisor type as a parameter and use it to determine which libvirt connection to attempt.
##### ACTUAL RESULTS
```
2026-03-09 09:09:43,713 INFO [kvm.resource.LibvirtConnection] (AgentRequest-Handler-4:[]) (logid:52f6b720) No existing libvirtd connection found. Opening a new one
2026-03-09 09:09:43,715 WARN [kvm.resource.LibvirtConnection] (AgentRequest-Handler-4:[]) (logid:52f6b720) Can not find a connection for Instance i-6-526-VM. Assuming the default connection.
[then later] Domain not found: no domain with matching name 'i-6-526-VM'
```
The method silently returns a potentially incorrect connection, masking the real problem (VM was never created).
##### PROPOSED FIX
Add `hypervisorType` parameter to `getConnectionByVmName()`:
**File: `plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java`**
```java
// Add new overload method
static public Connect getConnectionByVmName(String vmName, String hypervisorType) throws LibvirtException {
// Try the specified hypervisor type first
Connect conn = getConnectionByType(hypervisorType);
Domain dm = conn.domainLookupByName(vmName);
if (dm != null) {
dm.free();
return conn;
}
if (dm != null) dm.free();
// VM not found - throw meaningful exception instead of returning wrong connection
throw new LibvirtException("Domain not found: no domain with matching name '" + vmName + "' on hypervisor '" + hypervisorType + "'");
}
// Keep backward compatibility with existing call
static public Connect getConnectionByVmName(String vmName) throws LibvirtException {
return getConnectionByVmName(vmName, "KVM");
}
```
**Update callers to pass the correct hypervisor type:**
- `LibvirtCheckVirtualMachineCommandWrapper` - use `command.getContextParam(Command.HYPERVISOR_TYPE)`
- `LibvirtStopCommandWrapper` - get VM's hypervisor type from database or command context
- Other wrappers using `getConnectionByVmName()`
**Files to modify:**
- `plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java`
- `plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVirtualMachineCommandWrapper.java`
- `plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java`
- All other command wrappers that call `getConnectionByVmName()`
ps:
maybe it's a good idea to create separate adapter for lxc but this is more for roadmap, not for bugfix.
贡献指南
调研方向
从 plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java 开始,跟踪 getConnectionByVmName() 的所有调用方,包括 LibvirtCheckVirtualMachineCommandWrapper 和 LibvirtStopCommandWrapper。在更改连接查找之前,确定每个 wrapper 如何获取 VM hypervisor 类型。完成标准是调用方使用预期的 hypervisor,并且缺失的 domain 会产生所要求的明确异常。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- java
- 领域
- backend, infrastructure
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 冷清
- 描述清晰度
- 基本清楚
- 新手友好度
- 48/100