Serve the Session world to views over the File protocol - #349
Merged
Merged
Conversation
This was referenced Oct 1, 2026
SaladDay
force-pushed
the
aos/world-frontend
branch
3 times, most recently
from
October 1, 2026 03:03
46f234e to
cc2aebd
Compare
Add apps/daemon/internal/worldfs, a go-fuse raw-API frontend that maps each kernel request to at most one File request with the uncached profile, one errno table, view identity mapping, synthetic presentation of mountpoints and link-loss handling. Extend the sessionview World contract to return a Presentation: the launcher mounts private directories, overlays and shims at the symlink-free targets the world resolved. Add apps/sandboxio/fileservicetest to serve the Linux file service over in-memory streams for tests outside apps/sandboxio.
Stop drains and detaches under one deadline and returns within 15 seconds. An interrupted SETLK waits for the request's own outcome; an acquisition that stays uncertain is unlocked, or the handle fails. Releases a failed stream never sent are queued and drained after redial. An Attach with an unknown outcome is detached on abort. Non-retryable Link failures end the world. Presented directories keep every offset until ReleaseDir, list each sandbox entry at its own position, send at most one ReadDir per READDIR and report a pinned entry a complete enumeration does not find. The mmap note now matches the kernel.
Lock requests of one owner on one handle take turns, so a recovery unlock never removes a lock another request reported. A Release or Forget the service refused with ResourceExhausted and EffectNone is retried with backoff, and queuing wakes the drainer in the same step. sessionview.World takes Start's context, which bounds dialing, attaching and presenting, and an interrupt reaches a request still waiting for the stream or a redial. A Serve that cannot show its attachment is clean fails with ErrAttachmentDirty for the Link attachment's owner to end.
… without the turn Start joins its cancellation with the World's error, so ErrAttachmentDirty reaches the attachment's owner. A waiting lock request records its answer without retaking its owner's turn, which a non-blocking request may hold while it waits for the stream, and a request that needs recovery checks which acquisitions registered after it or were waiting when it registered. A request whose recovery is unsafe or fails returns EIO. The drainer records the generation a failed cleanup ran on, so its own redial does not cut the backoff short.
This was referenced Oct 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lane L1b of the agent-outside-sandbox workstream. A Session view sees the sandbox's
worldexport as its filesystem.worldfsserves that filesystem with FUSE, and each kernel request becomes at most one File protocol request.Changes
apps/daemon/internal/worldfs: a go-fuse v2 raw-API frontend (Linux; other platforms get a stub that returnsErrUnsupported).doc.goholds the mapping table. The profile is uncached: zero TTLs andFOPEN_DIRECT_IO, with only the declared capabilities negotiated.Walk/Readlink, at most 40 hops.ErrTopologyChanged.ServerInstanceIDis unchanged. A request is re-sent only if it was never sent; a new incarnation or an ended attachment marks the world lost.ResourceExhausted/EffectNone, are queued. They retry after the next redial or after a bounded backoff (20 ms to 2 s), and a request that may have reached the service is never re-sent.Servefails withErrAttachmentDirty. The owner of the Link attachment (the agent host, L5a) then ends that attachment.Servefailed or never ran stops at once.sessionview:Worldtakes Start's context and returns(WorldServer, Presentation, error), andWorldMountcarries the view UID/GID. A Start cancelled during construction keeps the World's error (for exampleErrAttachmentDirty).StagingParentthat Declare agent-host Session views in the Runtime–Harness protocol #350 made required.RESOLVE_NO_SYMLINKS.View.Presentation()is added.apps/sandboxio/fileservicetest: a fixture that serves the file service over a temp dir throughnet.Pipe, withBreak(),Restart()and anIntercepthook for deterministic tests.Declared gaps:
Two defects need the File protocol change in L1c, which also moves this frontend onto it:
fcntl(F_SETFL)togglingO_APPENDon an open file is ignored, because append is fixed at Open;L1c gives per-write append, client-chosen handle IDs and a fence on stream succession. M1 qualification waits for it.
Checks
OAC_TEST_WORLDFS=1): PASS, five runs./bin -> usr/bin, the shim at/usr/bin/sh), symlink loops, topology changes, instance changes, and a real launcher view editing the workspace.TestLockRecoveryKeepsLaterLock;TestRefusedReleaseIsRetried;TestReleaseQueuedAfterRedial;TestServeEndsWithItsContext;TestLockInterruptedWhileRedialing;TestStartEndsDuringAttach;TestUnsentLockInterruptedBehindTurn;TestRefusalAfterOwnRedialWaits;TestUnsafeLockRecoveryFails.