VMI Memory Validation#
Overview#
VMI memory validation runs inside the virt-api validating admission webhook at creation time. The entry point is ValidateVirtualMachineInstanceSpec, which calls a chain of focused memory-related validators before the VMI is persisted. These validators cover resource requests/limits, guest memory sizing, and hugepages configuration.
Validator Functions#
All validators live in pkg/virt-api/webhooks/validating-webhook/admitters/vmi-create-admitter.go.
| Function | What it checks |
|---|---|
validateMemoryRequestsNegativeOrNull | Memory requests must be ≥ 0 and, if set, ≥ 1M |
validateMemoryLimitsNegativeOrNull | Memory limits must be ≥ 0; requests must not exceed limits |
validateHugepagesMemoryRequests | Hugepages page size parses cleanly; total VM memory ≥ page size and is an exact multiple |
validateGuestMemoryLimit | Guest memory ≤ resource memory limit (skipped under live-update rollout strategy) |
validateMemoryIsProvided | At least one of: requests, limits, hugepages, or guest memory is non-zero (called from validateCpuPinning when DedicatedCPUPlacement is true) |
ValidateVirtualMachineInstanceMandatoryFields | Post-defaults check: memory requests or domain.memory.guest/hugepages must be set |
The validateHugepagesMemoryRequests function resolves effective VM memory via a three-step fallback: resources.requests.memory → domain.memory.guest → resources.limits.memory. This fallback order was established as part of the memory-request rendering refactor .
Safety Issues and Fixes#
Nil Pointer Dereference in Guest Memory (PR #16665 / #17074 / #17999)#
The original validateMemoryLimitAndRequestProvided function called spec.Domain.Memory.Guest.Value() without first checking whether spec.Domain.Memory or spec.Domain.Memory.Guest was nil. Although the mutating webhook (setGuestMemory) normally populates this field, a future change to mutator behavior could expose a panic path.
Fix (PR #16665): The function was renamed to validateMemoryIsProvided and rewritten with sequential early-returns :
- Return
nilifresources.limits.memoryis non-zero. - Return
nilifresources.requests.memoryis non-zero. - Return error if
spec.Domain.Memory == nil. - Return
nilifspec.Domain.Memory.Hugepages != nil. - Return error if
spec.Domain.Memory.Guest == nil || Guest.IsZero().
This converts a single compound boolean into a fail-fast nil-safe sequence. The fix was cherry-picked to release-1.7 (PR #17074) and release-1.6 (PR #17999) .
Nil Pointer Dereference in validateHugepagesMemoryRequests#
A separate nil-safety gap exists in validateHugepagesMemoryRequests: line 1069 calls spec.Domain.Memory.Guest.Value() after checking only spec.Domain.Memory != nil, not spec.Domain.Memory.Guest != nil. A VMI with hugepages but no memory request and no domain.memory.guest can trigger a panic here.
Fix (PR #18496): Guards spec.Domain.Memory.Guest != nil before dereferencing, and adds a hugepagesSize.Value() > 0 check before the modulo operation .
Divide-by-Zero in Hugepages Modulo Check#
In validateHugepagesMemoryRequests, the modulo vmMemory % hugepagesSize.Value() assumes the page size is positive. PageSize is a free-form string; values like "0" or overflow values (e.g., "10E") parse without error but produce Value() == 0, causing an integer divide-by-zero panic at the modulo line.
Fix (PR #18496): An early guard rejects any parsed page size where hugepagesSize.Value() <= 0 with a FieldValueInvalid status cause before reaching the arithmetic .
Related Context#
- Memory request rendering refactor (PR #15896): Moved memory request auto-population from the mutating webhook to the virt-controller resource renderer. After this change,
resources.requests.memorymay be absent on a freshly admitted VMI; the validating webhook was updated to acceptdomain.memory.guestand hugepages as standalone memory specifications . - NUMA validation:
validateNUMAcross-checks thatdomain.memory.hugepagesis set whenNUMA.GuestMappingPassthroughis configured, making hugepages a hard dependency for NUMA topology passthrough.
Key Source Files#
- Webhook admitter:
pkg/virt-api/webhooks/validating-webhook/admitters/vmi-create-admitter.go - Tests:
pkg/virt-api/webhooks/validating-webhook/admitters/vmi-create-admitter_test.go(in the same package)