Commit eb2d6eb
[9.0.0] Compensate for Windows filesystems lacking junction support (#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 <[email protected]>1 parent 634c7bd commit eb2d6eb
File tree
3 files changed
+15
-0
lines changed- src/main
- java/com/google/devtools/build/lib/windows
- native/windows
3 files changed
+15
-0
lines changedLines changed: 4 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
| 73 | + | |
73 | 74 | | |
74 | 75 | | |
75 | 76 | | |
| |||
172 | 173 | | |
173 | 174 | | |
174 | 175 | | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
175 | 179 | | |
176 | 180 | | |
177 | 181 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
456 | 456 | | |
457 | 457 | | |
458 | 458 | | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
459 | 464 | | |
460 | 465 | | |
461 | 466 | | |
| |||
587 | 592 | | |
588 | 593 | | |
589 | 594 | | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
590 | 600 | | |
591 | 601 | | |
592 | 602 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
| 116 | + | |
116 | 117 | | |
117 | 118 | | |
118 | 119 | | |
| |||
0 commit comments