apache / apache/cloudstack

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

Ouverte
#12,765 5 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
component:kvm component:libvirt Severity:Minor type:bug
Langage dominant
Java
Étoiles
3.1k
Forks
1.4k
Merge moyen
6 j 19 h
PR mergées (30 j)
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.

Guide de contribution

Ouvrir le guide de contribution

Piste de recherche

Commencez dans plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java et suivez tous les appelants de getConnectionByVmName(), notamment LibvirtCheckVirtualMachineCommandWrapper et LibvirtStopCommandWrapper. Déterminez comment chaque wrapper obtient le type d’hyperviseur de la VM avant de modifier la recherche de connexion. C’est terminé lorsque les appelants utilisent l’hyperviseur attendu et que les domaines manquants produisent l’exception claire demandée.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
java
Domaine
backend, infrastructure
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
Calme
Clarté
Plutôt claire
Accessibilité débutants
48/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.