apache / apache/cloudstack

Bug: getConnectionByVmName() doesn't use VM's hypervisor type, causing confusing "Domain not found" errors

Open
#12,765 5 comments 0 reactions 0 assignees View on GitHub
component:kvm component:libvirt Severity:Minor type:bug
Dominant language
Java
Stars
3.1k
Forks
1.4k
Avg merge
6d 19h
Merged PRs (30d)
32

Description

##### 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.

Contributor guide

Open the contributing guide

Research direction

Start in plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java and trace all getConnectionByVmName() callers, including LibvirtCheckVirtualMachineCommandWrapper and LibvirtStopCommandWrapper. Determine how each wrapper obtains the VM hypervisor type before changing the connection lookup. Done means callers use the expected hypervisor and missing domains produce the requested clear exception.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.