On Thu, Apr 23, 2026 at 12:28:40 +0200, Claudio Fontana wrote:
Hello,
at least for virDomainInterfaceStats() and virDomainMemoryStats() they actually seem to fail when called on a non active domain (for example a shutoff domain).
It would be beneficial to document clearly which domain states are allowed when calling the APIS in
https://libvirt.org/html/libvirt-libvirt-domain.html
because it can be also reasonable to assume, for example, that a call would just return empty values when the domain is not active.
IMO that depends on whether the resource that you want to report stats even exists. E.g. the bulk stats API (backing virsh domstats) reports some data even if the VM is offline. One example is some disk image statistics as the image itself exists.
It is not 100% clear from the code either, because the domain state is not enforced at the core libvirt level, but rather by the QEMU driver implementation:
liveness check must happen at the driver impl level because you need to be able to do it after obtaining lock on the VM object. If you'd use a public API (without taking the lock and possibly job) you 'd have a TOCTOU race since the VM could have stopped/started.
qemuDomainInterfaceStats(): ... if (virDomainObjCheckActive(vm) < 0) goto cleanup;
qemuDomainMemoryStatsInternal(): ... if (virDomainObjCheckActive(vm) < 0) return -1;
E.g. the interface itself doesn't exist if the VM is running there isn't much to report. Once could argue though that an offline VM uses 0 ram.
so could a different driver decide that InterfaceStats or MemoryStats calls _are_ allowed for shutoff domains, possibly returning empty values, or latest run results, or ...?
Theoretically yes. Practically it doesn't make much sense. And a hard no for reporting stale data.
If it is 100% the case that these APIs are for active domains only, I think it could be documented in the APIs; not finding it there could make one assume that these are fine to call, especially since others _are_ documented in terms of active/inactivey:
virDomainAddIOThread virDomainAttachDevice virDomainDelIOThread virDomainDelThrottleGroup virDomainGetBlockInfo virDomainGetIOThreadInfo
All of the above work on both live and inactive configs
virDomainPinVcpu
This one works only on live VMs, but the virDomainPinVcpuFlags variant works on both.
virDomainGetJobInfo (this is the best because it explicitly says "return an error if the domain is not active" virDomainGetJobStats (same virtuous description)
virDomainGetMaxVcpus
Same as virDomainPinVcpu, there's virDomainGetVcpusFlags which works everywhere.
virDomainGetSecurityLabel virDomainGetSecurityLabelList
These "work" on inactive VMs, return nothing for qemu though. Arguably other drivers could have a value, even qemu driver could report something if it's explicitly configured.
virDomainGetVcpus (not great: "This call may fail on an inactive domain" May? Depending on what? Driver?)
Well at least qemu driver does error out.
virDomainGetVcpusFlags
This one is fun though, because it depends on flags if it works on inactive VM or not :) (e.g. with VIR_DOMAIN_VCPU_GUEST your VM has to be active, without that flag you get an answer even for inactive VM :)
virDomainPinEmulator (again "may fail if domain is not alive" - is it really conditional, as opposed to "will fail for transient domains"?)
Well, because it doesn't fail for inactive qemu domains.
virDomainPinVcpu ("can only be called on an active domain" -> would be better to say "returns an error if the domain is not active")
Sure, but also use qemuDomainPinVcpuFlags which works on active VMs too.
virDomainSetMemoryFlags ("will wail if domain is not active") -Ok, clear. virDomainSetMemoryStatsPeriod (same)
virDomainSetVcpus virDomainSetVcpusFlags
Same fun with flags as with the getter.
virDomainSuspend (but not very clear: "Suspends an active domain". Does it return an error if the domain is not active? Or just do nothing?)
virDomainUndefine virDomainUndefineFlags
Both do work on inactive VMs. These have another dimension of fun, because if the VM is active, it keeps being present and active. If you shut it down it vanishes. (same as starting it without persistent config directly)
Maybe a good bite-sized task to queue that can create a lot of value. I would suggest an additional table generated for each API mentioning allowed domain states, or something to that effect.
This would also need to be per-driver because it in many cases depends on the actual implementation. I don't think there's a way around it which also makes it extremely impractical to implement.