The Accounting Chain: From Physical Object to Reported Limit

The guest/host cgroup model and the first-touch page mechanism now support one practical diagnostic question: where did the resource become real, and which observer decided who owned it? This checkpoint connects those ideas into a single accounting chain for microVM-based containers. The useful outcome is a way to distinguish an undersized sandbox budget from a misattributed page, then carry the same reasoning into storage, where a correctly allocated object can still disappear from a path-based scan.

The distinction is more useful than another list of components. In Kata, a pod budget can intentionally include or exclude sandbox processes. In the memory findings, a guest can cause a host backend to populate a page that the pod cgroup does not receive. These situations can produce similar dashboards—a low application charge beside high host activity—but they imply different causes. The chain below keeps the causes separate.

Trace the resource, not the label

Start with the action that creates pressure. A guest process reads a file, writes data, maps a region, or starts a computation. That action crosses some interface: a guest kernel path, a virtio frontend, a VMM, a host filesystem service, or a block-device backend. The interface determines what the host must create or retain. A physical page may enter a host cache. A disk object may acquire blocks. A queue may consume memory. A process may spend CPU time.

The next question is not yet “what did the pod report?” It is “what physical state exists because of the action?” This step prevents a common error in resource accounting: treating the metric as the resource itself. A guest memory counter is a report about the guest’s accounting state. It is not a complete inventory of host page cache, VMM memory, page tables, or I/O buffers. A Kubernetes ephemeral-storage number is a report about the paths and objects its accounting mechanism can see. It is not automatically a host-wide inventory of every block retained for the guest.

Once the physical state is identified, ask who owns or first touches it in the host’s implementation. For a memory page, the answer may follow the host process that brings the page into memory. For a storage object, it may be associated with a host filesystem and an open descriptor even after a guest-visible name changes. Ownership is an implementation fact, but it is not necessarily the same as tenant responsibility. A backend can be the immediate host owner while the workload remains the cause and economic beneficiary of the resource.

Only then should we ask which observer can see that owner or object. A cgroup observer sees processes in a hierarchy. A filesystem scanner sees paths and allocated blocks within its field of view. A billing system may see declared resource requests and elapsed execution time. The observer’s scope determines the reported charge. A limit, eviction policy, or bill consumes that report and makes a decision.

The chain can be expressed as a set of decision points:

flowchart LR A["Guest action"] --> B["Physical resource state"] B --> C{"What is the relevant owner?"} C -->|"host process"| D["Process or cgroup observer"] C -->|"storage object or path"| E["Filesystem observer"] D --> F["Reported usage"] E --> F F --> G["Limit, eviction, or billing decision"] C --> H1["Sizing: budget excludes expected overhead"] C --> H2["Attribution: charge follows another process"] C --> H3["Visibility: observer misses the object"]