Skip to content

Unify filesystem storage accounting - #3728

Merged
kmatasfp merged 55 commits into
mainfrom
kaurmatas/gol-416-unify-filesystem-storage-accounting
Sep 1, 2026
Merged

Unify filesystem storage accounting#3728
kmatasfp merged 55 commits into
mainfrom
kaurmatas/gol-416-unify-filesystem-storage-accounting

Conversation

@kmatasfp

@kmatasfp kmatasfp commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Implements GOL-416.

Summary

  • replace logical filesystem byte deltas, storage permits, and custom hard-link accounting with one AgentFilesystems / AgentFilesystem lifecycle
  • use managed XFS project quotas as the authority for per-agent allocated-byte usage, filesystem-object usage, and limits, while using fresh statvfs observations for physical node capacity
  • route WASI P2 and P3 direct operations and asynchronous streams through shared lifecycle admission and failure classification
  • move filesystem creation, initial-file materialization, replay settlement, and cleanup under the AgentFilesystem lifecycle
  • meter authoritative allocated-byte observations over the same ConcurrentAgentPermit window as linear memory, with compute, memory, and filesystem metering configured independently

Behavior

AgentFilesystem now owns each resident agent's ephemeral filesystem across creation, initial-file materialization, oplog replay, execution, and unload. Startup removes and verifies stale local resources before creating an unmanaged directory or managed XFS project. Replay-owned filesystem effects settle before startup publishes the runtime. Unload seals new filesystem work, tears down runtime resources, deletes the filesystem, and verifies cleanup before publishing Unloaded.

Managed XFS validates project-quota support, project identity and inheritance, reflink support, permissions, and exclusive ownership of the managed root. Project observations supply authoritative allocated bytes and filesystem-object counts. The executor installs the public allocated-byte limit together with an internally derived object limit. Read-only and read-write initial files both count toward quota and billing. Initial-file revisions are staged, validated, and installed atomically so a failed update does not publish partial files. Reducing either limit below current usage suspends and unloads the agent until reconstruction fits the current policy.

Unmanaged filesystems remain available when project quotas are not configured, but reject finite filesystem limits because they cannot provide authoritative enforcement. Unsupported allocation observation disables only the filesystem metering dimension; compute and memory metering continue independently.

Physical capacity remains separate from project usage. The executor obtains available bytes and filesystem objects from fresh statvfs observations. On physical exhaustion it may unload only eligible loaded-idle agents, and recognizes reclaimed capacity only after deletion and another observation. Agent quota exhaustion never triggers pressure eviction.

P2 and P3 preserve errno, completed prefixes, and effect evidence until classification. Retries are bounded and apply only to a proven unwritten suffix or an operation whose postcondition proves no effect. Unknown effects and terminal infrastructure failures invalidate the disposable local runtime while leaving durable work available for reconstruction. XFS reports ENOSPC for both project-quota and physical exhaustion, so classification uses fresh quota, capacity, and backend-health observations instead of errno alone.

Enabled storage billing integrates ordered absolute allocated_bytes observations prospectively. Storage and memory start and stop together at one monotonic timestamp while the worker owns its concurrent-agent permit. Active execution, host calls, host I/O waits, and replay are billable while retaining the permit. Loaded-idle, unloaded, and durably sleeping workers accrue nothing. Unload and filesystem deletion happen outside the billing window.

Compute, memory, and filesystem usage metering are independent switches and all default to disabled for OSS and self-hosted deployments. The worker executor and standalone golem server honor GOLEM__RESOURCE_USAGE_METERING__COMPUTE, GOLEM__RESOURCE_USAGE_METERING__MEMORY, and GOLEM__RESOURCE_USAGE_METERING__FILESYSTEM. These switches affect measurement and export, not quota enforcement, memory admission, or physical-pressure recovery.

The superseded logical accounting path has been removed across oplog types, protobuf, WIT, CLI schemas, SDK bindings, documentation, and the built-in OTLP exporter. ConcurrentAgentPermit remains because it defines the execution and billing window; it is unrelated to the removed filesystem byte permits.

@kmatasfp
kmatasfp requested a review from a team August 7, 2026 23:04
@netlify

netlify Bot commented Aug 7, 2026

Copy link
Copy Markdown

Deploy Preview for golemcloud canceled.

Name Link
🔨 Latest commit 471806f
🔍 Latest deploy log https://app.netlify.com/projects/golemcloud/deploys/6a970876f3c2aa000884ebea

@vigoo

vigoo commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

You need to rebuild the built-in plugins (cargo make build-plugins) because of the WIT change

@vigoo

vigoo commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Both filesystem APIs (p2 and p3) expose hard-link creation without charging another copy (link_at), which is correct because both names refer to one inode, but unlink releases the file's entire size after any successful unlink without tracking reference counts.

@vigoo

vigoo commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

One more review finding to check:

Read-write provisioning writes directly to the destination:

  • Cache hits use tokio::fs::copy
  • Cache misses File::create the final path and stream into it

Either operation can fail after leaving a partial regular file. On a revision-update retry, update_filesystem accepts any existing regular file as NoChanges, without validating its expected size or content.

The resulting sequence is:

  1. A revision update reserves N bytes for a new read-write file.
  2. The download writes K < N bytes and fails.
  3. The reservation is rolled back because no successful growth was reported.
  4. The partial K-byte destination remains.
  5. Retry sees a regular file and reports NoChanges.
  6. The update can succeed with those K bytes absent from quota, capacity, billing, and recovery accounting.

Required fix: write/copy into a sibling temporary file, delete it on failure, and atomically rename it only after complete success. Do not accept an arbitrary pre-existing regular destination without validating that it represents a completed provisioning operation.

@kmatasfp

kmatasfp commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

All of the above you mentioned @vigoo plus some other things I ran into myself reviewing this are the reason I changed the direction and abandoned the golem internal quota/disk usage tracking/management and now building out a proper FS support I mentioned during the standup. GOL-416 issue description contains details of the new approach

@kmatasfp
kmatasfp marked this pull request as draft August 13, 2026 03:42
kmatasfp and others added 14 commits August 13, 2026 12:09
The in-process reservation, oplog delta, and storage-permit model is superseded by backend-authoritative filesystem usage and capacity accounting planned under GOL-416.
Coordinate filesystem effects during shutdown and retry cleanup of unmanaged agent storage.

Refs GOL-429
Use XFS project quotas for authoritative per-agent usage and lifecycle cleanup. Fail closed when the managed backend cannot guarantee isolation or accounting.
Route initial file creation and revision updates through the owned agent filesystem so storage accounting, immutable-path policy, and cleanup share one authoritative lifecycle.
Make managed XFS project quotas authoritative for byte and object limits across initial files and P2/P3 mutations. Suspend and reconstruct workers when downgraded limits no longer fit.
kmatasfp and others added 14 commits August 20, 2026 01:12
Move provisioning, quota, capacity, and cleanup behind backend interfaces. Preserve lifecycle ownership across cancellation and fallback cleanup.

Refs GOL-416
Centralize mutation admission, sequencing, classification, recovery, and terminal outcomes behind the AgentFilesystem seam. Add deterministic protocol and preview lifecycle regressions without migrating callers.

Refs GOL-452
Route P2 and P3 through one sandbox-backed agent filesystem lifecycle, use authoritative XFS observations for limits and billing, and separate physical pressure recovery from per-agent accounting.\n\nReplace legacy mutation and storage-meter paths with joint resource-window metering and optimized filesystem benchmarks.\n\nRefs GOL-416
Treat the registry-safe disk sentinel as effectively unlimited, keep memory billing active when filesystem observations are unsupported, and handle lost final observers without polling completed receivers.\n\nEnable memory metering in standalone mode and remove the stale Scala oplog case.
Classify unsupported filesystem allocation explicitly instead of matching diagnostic text.

Honor standalone resource metering environment flags and keep dimensions disabled by default; opt the sparse billing test in explicitly.
@kmatasfp
kmatasfp marked this pull request as ready for review August 31, 2026 03:26
Comment thread golem-worker-executor/src/sandbox_filesystem/xfs.rs Outdated
Comment thread golem-worker-executor/src/filesystem_pressure.rs
Comment thread golem-worker-executor/src/sandbox_filesystem/mod.rs Outdated
Comment thread golem-worker-executor/src/wasi_filesystem/p2/types.rs Outdated
…fy-filesystem-storage-accounting

# Conflicts:
#	golem-worker-executor/src/worker/mod.rs
Require managed XFS to own the filesystem mount root so project IDs cannot collide across executor roots. Restore cleanup leases on cancellation and apply object pressure thresholds alongside byte thresholds.

@vigoo vigoo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to go once the conflict is resolved. Make sure you use forked wit-bindgen for regenreating the moonbit bindings (there is a proper regen script for it somewhere)

…fy-filesystem-storage-accounting

# Conflicts:
#	golem-shard-manager/config/shard-manager.toml
#	golem-worker-executor/src/worker/mod.rs
@kmatasfp
kmatasfp merged commit 649e481 into main Sep 1, 2026
222 of 234 checks passed
@kmatasfp
kmatasfp deleted the kaurmatas/gol-416-unify-filesystem-storage-accounting branch September 1, 2026 23:01
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants