Skip to content

Conversation

@rdesgroppes
Copy link
Contributor

@rdesgroppes rdesgroppes commented Nov 7, 2025

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.

@rdesgroppes rdesgroppes changed the title Compensate for virtiofs lacking junction support Compensate for virtiofs lacking junction support Nov 7, 2025
@rdesgroppes rdesgroppes force-pushed the compensate-for-virtiofs-lacking-junction-support branch 2 times, most recently from a1d2b8a to aaae579 Compare November 7, 2025 18:15
@rdesgroppes rdesgroppes marked this pull request as ready for review November 7, 2025 18:16
@github-actions github-actions bot added the awaiting-review PR is awaiting review from an assigned reviewer label Nov 7, 2025
@tjgq
Copy link
Contributor

tjgq commented Nov 7, 2025

I'm supportive of this PR, but note that #17192 appears to be a different issue (that's an error in blaze_util::MakeCanonical, which has a separate implementation).

@rdesgroppes
Copy link
Contributor Author

rdesgroppes commented Nov 7, 2025

I'm supportive of this PR, but note that #17192 appears to be a different issue (that's an error in blaze_util::MakeCanonical, which has a separate implementation).

OK, I removed the "Might close #17192" assertion from the PR summary.

@rdesgroppes rdesgroppes force-pushed the compensate-for-virtiofs-lacking-junction-support branch from aaae579 to 093a02e Compare November 7, 2025 20:11
@rdesgroppes rdesgroppes changed the title Compensate for virtiofs lacking junction support Compensate for Windows filesystems lacking junction support Nov 10, 2025
**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.

**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
   clearer "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 builds 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.
@rdesgroppes rdesgroppes force-pushed the compensate-for-virtiofs-lacking-junction-support branch from 093a02e to 35d0faa Compare November 10, 2025 07:41
@tjgq tjgq added awaiting-PR-merge PR has been approved by a reviewer and is ready to be merge internally and removed awaiting-review PR is awaiting review from an assigned reviewer labels Nov 11, 2025
@fmeum
Copy link
Collaborator

fmeum commented Nov 11, 2025

@bazel-io fork 9.0.0

@github-actions github-actions bot removed the awaiting-PR-merge PR has been approved by a reviewer and is ready to be merge internally label Nov 17, 2025
bazel-io pushed a commit to bazel-io/bazel that referenced this pull request Nov 17, 2025
**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
github-merge-queue bot pushed a commit that referenced this pull request Nov 18, 2025
…27695)

**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 #27598.

PiperOrigin-RevId: 833360316
Change-Id: I3751602b2bd793c1cee75b7b66fa73c955a72517

Commit
dab96fc

Co-authored-by: Rgis Desgroppes <rdesgroppes@gmail.com>
@rdesgroppes rdesgroppes deleted the compensate-for-virtiofs-lacking-junction-support branch November 22, 2025 00:28
@iancha1992
Copy link
Member

The changes in this PR have been included in Bazel 9.0.0 RC3. Please test out the release candidate and report any issues as soon as possible.
If you're using Bazelisk, you can point to the latest RC by setting USE_BAZEL_VERSION=9.0.0rc3. Thanks!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants