Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows: Path.readSymbolicLink fails for junctions #7907

Closed
laszlocsomor opened this issue Apr 1, 2019 · 0 comments
Closed

Windows: Path.readSymbolicLink fails for junctions #7907

laszlocsomor opened this issue Apr 1, 2019 · 0 comments
Assignees
Labels
area-Windows Windows-specific issues and feature requests P2 We'll consider working on this in future. (Assignee optional) team-OSS Issues for the Bazel OSS team: installation, release processBazel packaging, website type: bug

Comments

@laszlocsomor
Copy link
Contributor

laszlocsomor commented Apr 1, 2019

Description of the problem / feature request:

Path.readSymbolicLink calls FileSystem.readSymbolicLink:

return fileSystem.readSymbolicLink(this);

On Windows, this calls into JavaIoFileSystem, which calls java.nio.file.Files.readSymbolicLink, which is unaware of junctions.

Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

The bug is rooted in java.nio, so here's an out-of-bazel repro:

BUILD:

java_binary(
    name = "x",
    srcs = ["ReadJunc.java"],
    main_class = "ReadJunc",
)

ReadJunc.java:

import java.nio.file.Files;
import java.nio.file.FileSystems;
import java.nio.file.Path;

public class ReadJunc {
  public static void main(String[] args) throws Exception {
    System.err.println("Hello ReadJunc");

    Path path = FileSystems.getDefault().getPath("c:\\src\\bazel-releases\\current");
    System.err.printf("path=(%s) isdir=%d%n",
        path, path.toFile().isDirectory() ? 1 : 0);

    Path path2 = Files.readSymbolicLink(path);
    System.err.printf("path2=(%s)%n", path2);
  }
}

output:

C:\src\tmp>bazel run x
...
path=(c:\src\bazel-releases\current) isdir=1
Exception in thread "main" java.nio.file.NotLinkException: Reparse point is not a symbolic link
        at sun.nio.fs.WindowsLinkSupport.readLinkImpl(WindowsLinkSupport.java:318)
        at sun.nio.fs.WindowsLinkSupport.readLink(WindowsLinkSupport.java:59)
        at sun.nio.fs.WindowsFileSystemProvider.readSymbolicLink(WindowsFileSystemProvider.java:628)
        at java.nio.file.Files.readSymbolicLink(Files.java:1432)
        at ReadJunc.main(ReadJunc.java:13)

The particular path:

C:\src\tmp>dir c:\src\bazel-releases
...
2019-03-27  11:12    <JUNCTION>     current [C:\src\bazel-releases\0.24.0]

What operating system are you running Bazel on?

Windows 10

@laszlocsomor laszlocsomor self-assigned this Apr 1, 2019
@laszlocsomor laszlocsomor added type: bug P1 I'll work on this now. (Assignee required) area-Windows Windows-specific issues and feature requests bad error messaging Issues where users get stuck because they don't understand what they did wrong P2 We'll consider working on this in future. (Assignee optional) and removed bad error messaging Issues where users get stuck because they don't understand what they did wrong P1 I'll work on this now. (Assignee required) labels Apr 1, 2019
laszlocsomor added a commit to laszlocsomor/bazel that referenced this issue Apr 1, 2019
laszlocsomor added a commit to laszlocsomor/bazel that referenced this issue Apr 1, 2019
laszlocsomor added a commit to laszlocsomor/bazel that referenced this issue Apr 3, 2019
In this PR:

- replace custom JunctionDescription definition
  with REPARSE_DATA_BUFFER from MSDN

- clean up kMaxJunctionTargetLen computation

- use already-computed offsets when creating the
  PathBuffer

Motivation:

- I'm implementing readSymbolicLink. It should
  handle junctions as well as symlinks. (There can
  be pre-existing symlink created from Admin
  shells, or the user may have enabled
  unprivileged symlink creation.)

- REPARSE_DATA_BUFFER contains structs in a union
  for junction and symlink data, and is the
  idiomatic struct definition to work with
  FSCTL_SET_REPARSE_POINT/FSCTL_GET_REPARSE_POINT.

See bazelbuild#7907
laszlocsomor added a commit to laszlocsomor/bazel that referenced this issue Apr 3, 2019
In this PR:

- Implement ReadSymlinkOrJunction in the JNI
  library, and expose it to Java code. This method
  can resolve symlinks and junctions.

- Override readSymbolicLink in WindowsFileSystem
  and use the new native method

- Add unit tests to exercise junction resolution.
  Manual testing shows the code works for symlinks
  too, however we cannot reliably create them in
  tests because that requires unprivileged symlink
  creation support (i.e. for the test to run as
  Admin, or for the OS having enabled it)

Fixes bazelbuild#7907
laszlocsomor added a commit to laszlocsomor/bazel that referenced this issue Apr 4, 2019
In this PR:

- WindowsFileSystem.createSymbolicLink attempts to
  create a symlink. This may succeed if Bazel runs
  as Administrator or if unprivileged symlink
  creation is enabled on Windows 10.

- WindowsFileSystem.fileIsSymbolicLink and
  WindowsFileSystem.isSymlinkOrJunction now
  recognize symlinks.

See bazelbuild#7907
laszlocsomor added a commit to laszlocsomor/bazel that referenced this issue Apr 4, 2019
In this PR:

- The isJunction JNI method now recognizes
  symlinks, not just junctions. The method now
  reports errors via return codes.

- WindowsFileSystem.fileIsSymbolicLink and
  WindowsFileSystem.isSymlinkOrJunction now
  recognize symlinks.

See bazelbuild#7907
bazel-io pushed a commit that referenced this issue Apr 4, 2019
In this PR:

- replace custom JunctionDescription definition
  with REPARSE_DATA_BUFFER from MSDN

- clean up kMaxJunctionTargetLen computation

- use already-computed offsets when creating the
  PathBuffer

Motivation:

- I'm implementing readSymbolicLink. It should
  handle junctions as well as symlinks. (There can
  be pre-existing symlink created from Admin
  shells, or the user may have enabled
  unprivileged symlink creation.)

- REPARSE_DATA_BUFFER contains structs in a union
  for junction and symlink data, and is the
  idiomatic struct definition to work with
  FSCTL_SET_REPARSE_POINT/FSCTL_GET_REPARSE_POINT.

See #7907

Closes #7928.

PiperOrigin-RevId: 241891547
laszlocsomor added a commit to laszlocsomor/bazel that referenced this issue Apr 4, 2019
In this PR:

- Implement ReadSymlinkOrJunction in the JNI
  library, and expose it to Java code. This method
  can resolve symlinks and junctions.

- Override readSymbolicLink in WindowsFileSystem
  and use the new native method

- Add unit tests to exercise junction resolution.
  Manual testing shows the code works for symlinks
  too, however we cannot reliably create them in
  tests because that requires unprivileged symlink
  creation support (i.e. for the test to run as
  Admin, or for the OS having enabled it)

Fixes bazelbuild#7907

Closes bazelbuild#7929.

PiperOrigin-RevId: 241892183
Change-Id: Ic9afc1f48e35bd60990d558d3a579f61f401cc4f
laszlocsomor added a commit to laszlocsomor/bazel that referenced this issue Apr 4, 2019
In this PR:

- The isJunction JNI method now recognizes
  symlinks, not just junctions. The method now
  reports errors via return codes.

- WindowsFileSystem.fileIsSymbolicLink and
  WindowsFileSystem.isSymlinkOrJunction now
  recognize symlinks.

See bazelbuild#7907
laszlocsomor added a commit to laszlocsomor/bazel that referenced this issue Apr 4, 2019
In this PR:

- The isJunction JNI method now recognizes
  symlinks, not just junctions. The method now
  reports errors via return codes.

- WindowsFileSystem.fileIsSymbolicLink and
  WindowsFileSystem.isSymlinkOrJunction now
  recognize symlinks.

See bazelbuild#7907
laszlocsomor added a commit to laszlocsomor/bazel that referenced this issue Apr 4, 2019
In this PR:

- The isJunction JNI method now recognizes
  symlinks, not just junctions. The method now
  reports errors via return codes.

- WindowsFileSystem.fileIsSymbolicLink and
  WindowsFileSystem.isSymlinkOrJunction now
  recognize symlinks.

See bazelbuild#7907
bazel-io pushed a commit that referenced this issue Apr 4, 2019
In this PR:

- The isJunction JNI method now recognizes
  symlinks, not just junctions. The method now
  reports errors via return codes.

- WindowsFileSystem.fileIsSymbolicLink and
  WindowsFileSystem.isSymlinkOrJunction now
  recognize symlinks.

See #7907

Closes #7931.

PiperOrigin-RevId: 241927717
@philwo philwo added the team-OSS Issues for the Bazel OSS team: installation, release processBazel packaging, website label Jun 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Windows Windows-specific issues and feature requests P2 We'll consider working on this in future. (Assignee optional) team-OSS Issues for the Bazel OSS team: installation, release processBazel packaging, website type: bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants