Skip to content

[9.0.0] Compensate for Windows filesystems lacking junction support#27695

Merged
iancha1992 merged 1 commit intobazelbuild:release-9.0.0from
bazel-io:cp27598-9.0.0
Nov 18, 2025
Merged

[9.0.0] Compensate for Windows filesystems lacking junction support#27695
iancha1992 merged 1 commit intobazelbuild:release-9.0.0from
bazel-io:cp27598-9.0.0

Conversation

@bazel-io
Copy link
Copy Markdown
Member

Problem:
Bazel fails completely on Windows when using filesystems that don't support junction/reparse point operations (e.g., virtiofs, VirtualBox shared folders, network drives, RAM disks).

The fatal error occurs when ReadSymlinkOrJunction fails during path resolution (e.g., when Starlark code calls .realpath): "Cannot read link: DeviceIoControl: Incorrect function".
This causes build analysis to abort completely.

Additionally, CreateJunction failures when creating convenience symlinks produce cryptic error messages, though these were already non-fatal warnings.

Both fail because DeviceIoControl returns ERROR_INVALID_FUNCTION when the filesystem doesn't implement FSCTL_GET_REPARSE_POINT or FSCTL_SET_REPARSE_POINT operations.

Proposed solution:
Handle ERROR_INVALID_FUNCTION gracefully by treating it as a "not supported" condition rather than a fatal error:

  1. in ReadSymlinkOrJunction (file.cc:592): return kNotALink instead of kError when ERROR_INVALID_FUNCTION occurs. This allows path resolution to continue for non-symlink paths on unsupported filesystems.
  2. in CreateJunction (file.cc:461): return new kNotSupported result code when ERROR_INVALID_FUNCTION occurs. This produces clear "filesystem does not support junctions" warnings instead of cryptic "Incorrect function" messages. This improves UX but doesn't change behavior (these failures were already non-fatal).

This follows the try-first, fallback-on-error pattern (EAFP) used by other major projects when handling unsupported filesystem operations.

Prior art:

Impact:

  • enables Bazel to work on virtiofs, VirtualBox shared folders, RAM disks, and other filesystems that don't support Windows junction operations.
  • convenience symlinks (bazel-bin, bazel-out, etc.) still won't be created, but now with clearer error messages.

Limitations:
Full junction support would require filesystem-level changes (e.g., virtiofs driver improvements).

Testing:
Tested on Windows 11 VM with host directory mounted via virtiofs, with rules_pkg. Before change: build analysis aborted with "Cannot read link" fatal error. After change: builds complete successfully with clearer warnings about unsupported junctions for convenience symlinks.

Closes #27598.

PiperOrigin-RevId: 833360316
Change-Id: I3751602b2bd793c1cee75b7b66fa73c955a72517

Commit dab96fc

**Problem**:
Bazel fails completely on Windows when using filesystems that don't support junction/reparse point operations (e.g., virtiofs, VirtualBox shared folders, network drives, RAM disks).

The fatal error occurs when `ReadSymlinkOrJunction` fails during path resolution (e.g., when Starlark code calls `.realpath`): "Cannot read link: DeviceIoControl: Incorrect function".
This causes build analysis to abort completely.

Additionally, `CreateJunction` failures when creating convenience symlinks produce cryptic error messages, though these were already non-fatal warnings.

Both fail because `DeviceIoControl` returns `ERROR_INVALID_FUNCTION` when the filesystem doesn't implement `FSCTL_GET_REPARSE_POINT` or `FSCTL_SET_REPARSE_POINT` operations.

**Proposed solution:**
Handle `ERROR_INVALID_FUNCTION` gracefully by treating it as a "not supported" condition rather than a fatal error:
1. in `ReadSymlinkOrJunction` (`file.cc`:592): return `kNotALink` instead of `kError` when `ERROR_INVALID_FUNCTION` occurs. This allows path resolution to continue for non-symlink paths on unsupported filesystems.
2. in `CreateJunction` (`file.cc`:461): return new `kNotSupported` result code when `ERROR_INVALID_FUNCTION` occurs. This produces clear "filesystem does not support junctions" warnings instead of cryptic "Incorrect function" messages. This improves UX but doesn't change behavior (these failures were already non-fatal).

This follows the try-first, fallback-on-error pattern (EAFP) used by other major projects when handling unsupported filesystem operations.

**Prior art:**
- Rust (rust-lang/rust#138133): checks `ERROR_INVALID_FUNCTION`, `ERROR_NOT_SUPPORTED`, and `ERROR_INVALID_PARAMETER` for filesystem operation fallbacks in `std::fs::rename`.
- Microsoft STL (microsoft/STL#2077): handles junctions and reparse point errors including `ERROR_INVALID_PARAMETER` with robust fallback logic in `filesystem.cpp`.
- Go (golang/go#20506): uses fallback strategies when symlink APIs are unavailable on different Windows versions.
- WinFsp (winfsp/winfsp#88): documents that `ERROR_INVALID_FUNCTION` indicates `STATUS_NOT_IMPLEMENTED` for unsupported operations.
- Microsoft Learn: recommends checking `FILE_SUPPORTS_REPARSE_POINTS` flag via `GetVolumeInformation`, but try-catch approach is simpler and handles edge cases where detection succeeds but operations fail.

**Impact**:
- enables Bazel to work on virtiofs, VirtualBox shared folders, RAM disks, and other filesystems that don't support Windows junction operations.
- convenience symlinks (bazel-bin, bazel-out, etc.) still won't be created, but now with clearer error messages.

**Limitations**:
Full junction support would require filesystem-level changes (e.g., virtiofs driver improvements).

**Testing:**
Tested on Windows 11 VM with host directory mounted via virtiofs, with [rules_pkg](https://github.com/bazelbuild/rules_pkg/blob/6cdaba69ee76463b2b8e97e8d243dbb6115c3aee/toolchains/git/git_configure.bzl#L40). Before change: build analysis aborted with "Cannot read link" fatal error. After change: builds complete successfully with clearer warnings about unsupported junctions for convenience symlinks.

Closes bazelbuild#27598.

PiperOrigin-RevId: 833360316
Change-Id: I3751602b2bd793c1cee75b7b66fa73c955a72517
@bazel-io bazel-io requested a review from a team as a code owner November 17, 2025 16:58
@bazel-io bazel-io added the awaiting-review PR is awaiting review from an assigned reviewer label Nov 17, 2025
@bazel-io bazel-io requested a review from tjgq November 17, 2025 16:58
@iancha1992 iancha1992 enabled auto-merge November 17, 2025 21:51
@iancha1992 iancha1992 added the team-Remote-Exec Issues and PRs for the Execution (Remote) team label Nov 17, 2025
@iancha1992 iancha1992 added this pull request to the merge queue Nov 18, 2025
Merged via the queue into bazelbuild:release-9.0.0 with commit eb2d6eb Nov 18, 2025
46 checks passed
@github-actions github-actions bot removed the awaiting-review PR is awaiting review from an assigned reviewer label Nov 18, 2025
gh-worker-dd-mergequeue-cf854d bot pushed a commit to DataDog/datadog-agent that referenced this pull request Mar 24, 2026
### What does this PR do?
Upgrade `bazel` from 8.6.0 to 9.0.1.

### Motivation
Bazel 9.0.1 ships upstream fixes that directly benefit our build & developer experience:
- bazelbuild/bazel#26842: `BUILD` files and `build` directories were incorrectly treated as the same entry on case-insensitive filesystems (e.g., Linux container running on a macOS host), causing spurious build failures (esp. for `rloader` we had to `gazelle`-exclude because of that),
- bazelbuild/bazel#27695: a contribution of ours (also available in 8.6.0 as bazelbuild/bazel#28367) - nice to have when sharing a folder between a Linux host and a Windows VM through `virtiofs`,
- bazelbuild/bazel#28640: another contribution of ours (@JSGette) - critical because it what preventing us from switching to Bazel 9 (ADMS config).

### Describe how you validated your changes
`bazel test //...` passes.

### Additional Notes
Groundwork landed in advance:
- #47716
- #47745
- #47982
- #48016
- #48071
- #48082
- #48183
- #48186
- #48200 (>= Bazel 9 min)
- #48201 (>= Bazel 9 min)
- #48228 (>= Bazel 9 min)

Co-authored-by: regis.desgroppes <regis.desgroppes@datadoghq.com>
aya-shimizu24 pushed a commit to DataDog/datadog-agent that referenced this pull request Mar 24, 2026
### What does this PR do?
Upgrade `bazel` from 8.6.0 to 9.0.1.

### Motivation
Bazel 9.0.1 ships upstream fixes that directly benefit our build & developer experience:
- bazelbuild/bazel#26842: `BUILD` files and `build` directories were incorrectly treated as the same entry on case-insensitive filesystems (e.g., Linux container running on a macOS host), causing spurious build failures (esp. for `rloader` we had to `gazelle`-exclude because of that),
- bazelbuild/bazel#27695: a contribution of ours (also available in 8.6.0 as bazelbuild/bazel#28367) - nice to have when sharing a folder between a Linux host and a Windows VM through `virtiofs`,
- bazelbuild/bazel#28640: another contribution of ours (@JSGette) - critical because it what preventing us from switching to Bazel 9 (ADMS config).

### Describe how you validated your changes
`bazel test //...` passes.

### Additional Notes
Groundwork landed in advance:
- #47716
- #47745
- #47982
- #48016
- #48071
- #48082
- #48183
- #48186
- #48200 (>= Bazel 9 min)
- #48201 (>= Bazel 9 min)
- #48228 (>= Bazel 9 min)

Co-authored-by: regis.desgroppes <regis.desgroppes@datadoghq.com>
StephenWakely pushed a commit to DataDog/datadog-agent that referenced this pull request Mar 27, 2026
### What does this PR do?
Upgrade `bazel` from 8.6.0 to 9.0.1.

### Motivation
Bazel 9.0.1 ships upstream fixes that directly benefit our build & developer experience:
- bazelbuild/bazel#26842: `BUILD` files and `build` directories were incorrectly treated as the same entry on case-insensitive filesystems (e.g., Linux container running on a macOS host), causing spurious build failures (esp. for `rloader` we had to `gazelle`-exclude because of that),
- bazelbuild/bazel#27695: a contribution of ours (also available in 8.6.0 as bazelbuild/bazel#28367) - nice to have when sharing a folder between a Linux host and a Windows VM through `virtiofs`,
- bazelbuild/bazel#28640: another contribution of ours (@JSGette) - critical because it what preventing us from switching to Bazel 9 (ADMS config).

### Describe how you validated your changes
`bazel test //...` passes.

### Additional Notes
Groundwork landed in advance:
- #47716
- #47745
- #47982
- #48016
- #48071
- #48082
- #48183
- #48186
- #48200 (>= Bazel 9 min)
- #48201 (>= Bazel 9 min)
- #48228 (>= Bazel 9 min)

Co-authored-by: regis.desgroppes <regis.desgroppes@datadoghq.com>
StephenWakely pushed a commit to DataDog/datadog-agent that referenced this pull request Mar 27, 2026
### What does this PR do?
Upgrade `bazel` from 8.6.0 to 9.0.1.

### Motivation
Bazel 9.0.1 ships upstream fixes that directly benefit our build & developer experience:
- bazelbuild/bazel#26842: `BUILD` files and `build` directories were incorrectly treated as the same entry on case-insensitive filesystems (e.g., Linux container running on a macOS host), causing spurious build failures (esp. for `rloader` we had to `gazelle`-exclude because of that),
- bazelbuild/bazel#27695: a contribution of ours (also available in 8.6.0 as bazelbuild/bazel#28367) - nice to have when sharing a folder between a Linux host and a Windows VM through `virtiofs`,
- bazelbuild/bazel#28640: another contribution of ours (@JSGette) - critical because it what preventing us from switching to Bazel 9 (ADMS config).

### Describe how you validated your changes
`bazel test //...` passes.

### Additional Notes
Groundwork landed in advance:
- #47716
- #47745
- #47982
- #48016
- #48071
- #48082
- #48183
- #48186
- #48200 (>= Bazel 9 min)
- #48201 (>= Bazel 9 min)
- #48228 (>= Bazel 9 min)

Co-authored-by: regis.desgroppes <regis.desgroppes@datadoghq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

team-Remote-Exec Issues and PRs for the Execution (Remote) team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants