Implement SunOS FileSystemWatcher using portfs event ports#124716
Implement SunOS FileSystemWatcher using portfs event ports#124716gwr wants to merge 1 commit intodotnet:mainfrom
Conversation
|
Tagging subscribers to this area: @dotnet/area-system-io |
There was a problem hiding this comment.
Pull request overview
This PR implements FileSystemWatcher support for SunOS (Solaris/illumos) using the portfs (event ports) API. Unlike Linux's inotify which reports specific file changes, portfs only signals that a directory has changed, requiring the implementation to maintain snapshots and perform comparisons to determine what actually changed.
Changes:
- Native interop layer for portfs operations (port_create, port_associate, port_get, port_send, port_dissociate)
- SunOS-specific FileSystemWatcher implementation using snapshot-based change detection
- Hybrid monitoring mode that watches both directories (for name changes) and individual files (for attribute changes)
- Support for recursive subdirectory monitoring with resource limits (50 subdirs, 1000 files per directory)
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 18 comments.
Show a summary per file
| File | Description |
|---|---|
| src/native/libs/configure.cmake | CMake configuration for portfs feature detection (has critical bug) |
| src/native/libs/System.Native/pal_io.h | Header declarations for portfs native functions (has spelling errors) |
| src/native/libs/System.Native/pal_io.c | Native implementation of portfs wrapper functions (has critical string lifetime bug) |
| src/native/libs/System.Native/entrypoints.c | Export table entries for new portfs functions |
| src/native/libs/Common/pal_config.h.in | Configuration flag for HAVE_SUNOS_PORTFS |
| src/libraries/System.IO.FileSystem.Watcher/tests/System.IO.FileSystem.Watcher.Tests.csproj | Added illumos and solaris to test target frameworks |
| src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs | Main SunOS implementation with snapshot comparison and event generation (multiple issues) |
| src/libraries/System.IO.FileSystem.Watcher/src/System.IO.FileSystem.Watcher.csproj | Added SunOS-specific source files and target frameworks |
| src/libraries/Common/src/Interop/SunOS/portfs/Interop.portfs.cs | Managed P/Invoke declarations for portfs (has hardcoded struct size issue) |
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
cbe385d to
04c54a8
Compare
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
8b4f6e2 to
3c5ee5f
Compare
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/Common/src/Interop/SunOS/portfs/Interop.portfs.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/Common/src/Interop/SunOS/portfs/Interop.portfs.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/Common/src/Interop/SunOS/portfs/Interop.portfs.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
The github dotnet copilot keeps misundertanding the design github.com/dotnet/pull/124716#discussion_r2838448285
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
github.com/dotnet/pull/124716#discussion_r2838494096
|
Now that I seem to be caught-up with Copilot feedback, I've squashed so I can more easily cherry pick this into a local branch with other necessary fixes so I can re-test. |
|
@tmds, could you please take a look? Portfs is a generic I/O eventing facility in SunOS-like platforms: |
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.SunOS.cs
Outdated
Show resolved
Hide resolved
github.com/dotnet/pull/124716#discussion_r2838974229
github.com/dotnet/pull/124716#discussion_r2838974245
github.com/dotnet/pull/124716#discussion_r2839027292
github.com/dotnet/pull/124716#discussion_r2839027304
github.com/dotnet/pull/124716#discussion_r2840704581
github.com/dotnet/pull/124716#discussion_r2840704598
github.com/dotnet/pull/124716#discussion_r2840704624
This implementation uses SunOS portfs (event ports) to watch for directory changes. Unlike Linux inotify, portfs can only detect WHEN a directory changes, not WHAT changed. Therefore, this implementation: 1. Maintains a snapshot of each watched directory's contents 2. When portfs signals a change, re-reads the directory 3. Compares new vs old snapshots to detect creates/deletes/modifications 4. Generates appropriate FileSystemWatcher events Key implementation details: - Uses pinned GC.AllocateArray for file_obj structures required by portfs - When watching attributes or timestamps watches directory contents too - Each watched objct gets a unique cookie for identification - port_get returns the cookie to indicate which object changed - Optimized snapshot comparison with sorted single-pass algorithm - Supports IncludeSubdirectories by recursively watching child directories - Track mtime of the watched directory to avoid missing changes - Implement graceful cancellation using PortSend Native changes (pal_io.c): - SystemNative_PortCreate: Opens event port file descriptor - SystemNative_PortAssociate: Associates directory with port using file_obj - SystemNative_PortGet: Waits for events, returns cookie identifying directory - SystemNative_PortSend: Send an event (used in cancellation) - SystemNative_PortDissociate: Removes directory association Performance notes: - Less efficient than inotify (must re-read directories on each change) - Better than polling (blocks until change occurs) - Memory overhead for directory snapshots Passes 99% of System.IO.FileSystem.Watcher.Tests --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
Squashed the last dozen updates to simplify local testing. |
This implementation uses SunOS portfs (event ports) to watch for directory changes. Unlike Linux inotify, portfs can only detect WHEN a directory changes, not WHAT changed. Therefore, this implementation:
Key implementation details:
Native changes (pal_io.c):
Performance notes:
Passes all System.IO.FileSystem.Watcher.Tests