Skip to content

Comments

Implement SunOS FileSystemWatcher using portfs event ports#124716

Open
gwr wants to merge 1 commit intodotnet:mainfrom
gwr:illumos-fswatch
Open

Implement SunOS FileSystemWatcher using portfs event ports#124716
gwr wants to merge 1 commit intodotnet:mainfrom
gwr:illumos-fswatch

Conversation

@gwr
Copy link
Contributor

@gwr gwr commented Feb 22, 2026

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 all System.IO.FileSystem.Watcher.Tests


Copilot AI review requested due to automatic review settings February 22, 2026 01:54
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Feb 22, 2026
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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)

@gwr gwr force-pushed the illumos-fswatch branch 2 times, most recently from cbe385d to 04c54a8 Compare February 22, 2026 02:19
Copilot AI review requested due to automatic review settings February 22, 2026 02:19
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 13 comments.

Copilot AI review requested due to automatic review settings February 22, 2026 02:54
@gwr gwr force-pushed the illumos-fswatch branch 2 times, most recently from 8b4f6e2 to 3c5ee5f Compare February 22, 2026 03:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 10 comments.

Copilot AI review requested due to automatic review settings February 22, 2026 03:15
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

@jkotas jkotas added the os-SunOS SunOS, currently not officially supported label Feb 22, 2026
Copilot AI review requested due to automatic review settings February 22, 2026 05:40
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

gwr added a commit to gwr/dotnet-runtime that referenced this pull request Feb 22, 2026
The github dotnet copilot keeps misundertanding the design
github.com/dotnet/pull/124716#discussion_r2838448285
Copilot AI review requested due to automatic review settings February 22, 2026 20:44
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

gwr added a commit to gwr/dotnet-runtime that referenced this pull request Feb 22, 2026
@gwr
Copy link
Contributor Author

gwr commented Feb 22, 2026

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.

@am11
Copy link
Member

am11 commented Feb 22, 2026

@tmds, could you please take a look?

Portfs is a generic I/O eventing facility in SunOS-like platforms: port_create(3C) - https://smartos.org/man/3c/port_create. I might be mistaken, but regarding time complexity: with your recent Linux inotify overhaul, the kernel:userland path is essentially O(1). On illumos/Solaris, this implemention's kernel:userland portion is O(n log n) due to the snapshot comparison required to reconstruct file-level changes. This complexity is probably unavoidable given the lack of per-file events, but (perhaps?) still better than not having any watcher support.

Copilot AI review requested due to automatic review settings February 23, 2026 03:41
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Copilot AI review requested due to automatic review settings February 23, 2026 04:22
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

gwr added a commit to gwr/dotnet-runtime that referenced this pull request Feb 23, 2026
gwr added a commit to gwr/dotnet-runtime that referenced this pull request Feb 23, 2026
github.com/dotnet/pull/124716#discussion_r2838974245
gwr added a commit to gwr/dotnet-runtime that referenced this pull request Feb 23, 2026
github.com/dotnet/pull/124716#discussion_r2839027292
gwr added a commit to gwr/dotnet-runtime that referenced this pull request Feb 23, 2026
github.com/dotnet/pull/124716#discussion_r2839027304
gwr added a commit to gwr/dotnet-runtime that referenced this pull request Feb 23, 2026
gwr added a commit to gwr/dotnet-runtime that referenced this pull request Feb 23, 2026
github.com/dotnet/pull/124716#discussion_r2840704598
gwr added a commit to gwr/dotnet-runtime that referenced this pull request Feb 23, 2026
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>
@gwr
Copy link
Contributor Author

gwr commented Feb 23, 2026

Squashed the last dozen updates to simplify local testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.IO community-contribution Indicates that the PR has been added by a community member os-SunOS SunOS, currently not officially supported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants