Repository navigation
vm: inotify: relay file creation, removal, rename and new directories - #1650
Open
fredericmorin-flare wants to merge 1 commit into
Open
fredericmorin-flare wants to merge 1 commit into
fredericmorin-flare wants to merge 1 commit into
Conversation
Only write events for existing files were relayed to the VM, so watchers never learned about new directories, removed files or files replaced by an atomic rename (how most editors and tools save). Pants (pantsd) kept a stale view: new files failed with "Unmatched glob" and edited files could be reported as passing from a memoized result. - Also watch create, remove and rename events on the host. - A file that still exists is synced as before (IN_ATTRIB, IN_CLOSE_WRITE). - For a directory or a path that no longer exists, a temporary file is created and removed in the parent directory in the VM, emitting IN_CREATE and IN_DELETE so watchers rescan it. Events for that temporary file are ignored on the host. - Buffer the notify channel: notify drops events when the receiver is busy, and every event is handled by running a command in the VM, so bursts such as `mkdir -p a/b/c` lost events. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Frederic Morin <frederic.morin@flare.io>
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.
Related: #1341, #1643, #1649.
Problem
With
--mount-inotify, the host watcher only subscribes to write events, and it ignores directories. Containers are never notified when:Separately, the channel passed to notify has a buffer of one. notify drops events when that channel is full, and events are handled one at a time by running a command in the VM. Bursts lose events: in 3 out of 15 runs of
mkdir -p a/b/c && echo > a/b/c/f, the event foranever arrived.Observed with Pants: pantsd caches the file system and relies on inotify to invalidate it. A new test file fails with
Unmatched glob. Worse, a test edited to fail is reported as passing from its memoized result, because the edit was an atomic save.Change
chmodand: >>, emittingIN_ATTRIBandIN_CLOSE_WRITE)..colima-inotify.XXXXXXis created and removed in it from the VM, emittingIN_CREATEandIN_DELETE. Watchers rescan the directory and pick up the added, removed or renamed entry. Host events for this temporary file are ignored, so syncing can't loop.Results
macOS 26 (Apple M3 Pro), vz + virtiofs, docker runtime. Each file operation was run on the host while
inotifywait -m -rwatched the directory in a container:echo > new, append,cpATTRIB,CLOSE_WRITEtouchnew empty fileATTRIB,CLOSE_WRITEwrite tmp && mv tmp file)ATTRIB,CLOSE_WRITEon the fileCREATE,DELETEin the directoryrmCREATE,DELETEin the directorymv a bATTRIB,CLOSE_WRITEonb,CREATE,DELETEin the directorymkdir+ file insideCREATE,DELETEin the parentmkdir -p a/b/c+ file, 30 runsalost in 3 of 15 runsWith pantsd watching the tree from a container:
Unmatched globUnmatched globTests
watch_test.go:syncTargetfor an existing file (synced, keeping its mode), a directory and a removed file (the parent is synced), a removed directory tree (skipped), and the temporary file (ignored).events_test.go: the generated command for a directory.events_linux_test.go(Linux only, runs in CI): the directory command emitsIN_CREATEandIN_DELETEand leaves no file behind.All tests pass on macOS and on Linux, and
golangci-lintreports no issues.Depends on #1649
This PR probably depends on #1649, and should land after it. It relays more events (creations, removals, renames, new directories), but each one still goes through the current sync: two
limactl shellcommands per event, about 4 events per second, and a rate limit that drops events above 50 unique paths per 500ms. On its own, it would overflow that dispatch during bursts, for example a branch switch or annpm install. #1649 batches the syncs.Both PRs change
events.go. I'll rebase this one once #1649 is merged.LLM usage disclosure
This change was written with the help of an LLM (Claude): the investigation, the fix and the tests. I reviewed every line and ran the tests and measurements above myself.
🤖 Generated with Claude Code