Skip to content

incusd/instance/qemu: Report disk usage for all disk devices in state - #4078

Merged
stgraber merged 3 commits into
lxc:mainfrom
stgraber:fixes
Sep 26, 2026
Merged

stgraber merged 3 commits into
lxc:mainfrom
stgraber:fixes

Conversation

@stgraber

Copy link
Copy Markdown
Member

Closes #4057

speijnik and others added 3 commits September 25, 2026 22:02
lxc.diskState() tested for the root disk device with the inline
predicate dev.Config["path"] == "/", while internal/instance already
provides IsRootDiskDevice() to name exactly this concept. Use it instead
of repeating the predicate.

This is behaviour-preserving. IsRootDiskDevice() is
type == "disk" && path == "/" && source == "", but the loop this check
lives in has already filtered on type == "disk" immediately above, and
internal/server/device/disk.go:634 rejects any disk device that has
both path == "/" and a non-empty source. So neither of the two extra
conjuncts IsRootDiskDevice() adds can change which device matches: for
a device that reaches this point, path == "/" and IsRootDiskDevice(dev.Config)
agree.

Signed-off-by: Stephan Peijnik-Steinwender <speijnik@eoscloud.io>
qemu.diskState() only reported usage for the root disk device, unlike
lxc.diskState() which reports usage for every disk device, including
attached custom storage volumes. This meant GET /1.0/instances/<name>/state
under-reported disk consumption for VMs with attached custom volumes.

Mirror the lxc driver structurally, not just in behaviour: iterate all
expanded disk devices, identify the root disk with
internalInstance.IsRootDiskDevice(dev.Config) — the same predicate
getRootDiskDevice() resolves through, so the root disk is identified
exactly as before, without the extra call and the error path it
introduced — use pool.GetInstanceUsage() for it and
pool.GetCustomVolumeUsage() for pool-backed custom volumes. Devices
that are neither the root disk nor pool-backed (host-path shares,
ISOs, ...) are skipped, as they have no usage to report. Per-device
failures are logged and skipped rather than failing the whole call,
using the same messages, logger.Ctx keys, and
storageDrivers.ErrNotSupported suppression that lxc.diskState() uses.

qemu.diskState() now returns a bare map[string]api.InstanceStateDisk
instead of (map[string]api.InstanceStateDisk, error), matching every
other per-driver state helper (cpuState(), memoryState(),
networkState(), and lxc's own diskState()), all of which return a bare
value and log internally. Both renderState() call sites are updated to
a plain "status.Disk = d.diskState()" assignment, as lxc.renderState()
already does; the log level for a failed usage lookup moves from a Warn
at the call site to an Error inside diskState() itself, again matching
lxc.

Behaviour change: previously, a failure to get disk usage made
diskState() return an error, and renderState() would then assign a nil
disk map, so no disk information at all was reported for the instance.
Now such a failure drops only that one device's entry while every other
entry is still returned, i.e. partial disk information instead of none.
This matches how the lxc driver already behaves.

Note that a storage driver which does not implement usage reporting
does not reach that path. Both backend.GetInstanceUsage() and
backend.GetCustomVolumeUsage() absorb drivers.ErrNotSupported into a
Used of -1 and return a nil error, so on such a driver every disk
device is still reported, with a usage of -1, exactly as before. The
ErrNotSupported checks in diskState() are therefore defensive only,
mirroring lxc.diskState(); entries are dropped solely for genuine
errors, such as a pool that fails to load or a missing volume record.

Signed-off-by: Stephan Peijnik-Steinwender <speijnik@eoscloud.io>
Attached volumes live in the default project unless the project has features.storage.volumes.

Signed-off-by: Stéphane Graber <stgraber@stgraber.org>
@stgraber
stgraber merged commit 2565564 into lxc:main Sep 26, 2026
182 of 183 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants