Commit 301ea24
Compensate for Windows filesystems lacking junction support
**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: I3751602b2bd793c1cee75b7b66fa73c955a725171 parent 961520c commit 301ea24
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