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