apache / apache/cloudstack

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

Aperta
#12,765 5 commenti 0 reazioni 0 assegnatari Vedi su GitHub
component:kvm component:libvirt Severity:Minor type:bug
Lingua principale
Java
Stelle
3.1k
Fork
1.4k
Merge medio
6g 19h
PR unite (30g)
32

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia da plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java e traccia tutti i chiamanti di getConnectionByVmName(), inclusi LibvirtCheckVirtualMachineCommandWrapper e LibvirtStopCommandWrapper. Determina come ogni wrapper ottiene il tipo di hypervisor della VM prima di modificare la ricerca della connessione. Il lavoro è completato quando i chiamanti usano l’hypervisor previsto e i domini mancanti producono l’eccezione chiara richiesta.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
java
Ambito
backend, infrastructure
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
48/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.