-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
path/filepath: fix EvalSymLinks documentation #40180
Comments
The background to this is that Docker misuses EvalSymlinks, so produces confusing logs and/or errors on common Windows configurations. The Windows bugs are #39786 & #40176. See also kubernetes/utils#172 |
It would be beneficial to be able to suggest against using this API on Windows and once there are alternatives which are truly portable and provide solutions to the other issues with this API, against use of this API altogether. |
Here is a list of results for It shows it may be fixing issues for many more people than introduce breaking changes having this API stop trying to resolve links on Windows and instead return one of
The list
Correct useful results are also results with errors 53 and 67 which are the result of correctly establishing that the path does not exist. Other errors are all wrong. 2 for being the wrong error code - a persistent problem accross go's
The error code -111 means that there was any go error without an error code. The paths have the following meaning:
This list is far from complete, since these tests
|
I closed #40095 on grounds that there is agreement that |
is there any progress on this? Is there on going work on replacing EvalSymlinks? Thanks! |
#42201 failed. |
I think this is still an important issue which is very hard to solve today. But there are lots of great discussion here and the other thread. So the plan is to document some of the conclusions somewhere? |
AFAIK, there is no plan. Feel free to submit a change to the docs. It should indicate that ppl who need EvalSymlinks on Windows should use the WinAPI via x/sys/windows. And perhaps reference this issue and the one I mentioned above. |
Related to #39786 (comment) as a nieth occurence |
Change https://go.dev/cl/516695 mentions this issue: |
Change https://go.dev/cl/536655 mentions this issue: |
Change https://go.dev/cl/565136 mentions this issue: |
This CL changes the behavior of os.Lstat to stop setting the os.ModeSymlink type mode bit for mount points on Windows. As a result, filepath.EvalSymlinks no longer evaluates mount points, which was the cause of many inconsistencies and bugs. Additionally, os.Lstat starts setting the os.ModeIrregular type mode bit for all reparse tags on Windows, except for those that are explicitly supported by the os package, which, since this CL, doesn't include mount points. This helps to identify files that need special handling outside of the os package. This behavior is controlled by the `winsymlink` GODEBUG setting. For Go 1.23, it defaults to `winsymlink=1`. Previous versions default to `winsymlink=0`. Fixes #39786 Fixes #40176 Fixes #61893 Updates #63703 Updates #40180 Updates #63429 Cq-Include-Trybots: luci.golang.try:gotip-windows-amd64-longtest,gotip-windows-arm64 Change-Id: I2e7372ab8862f5062667d30db6958d972bce5407 Reviewed-on: https://go-review.googlesource.com/c/go/+/565136 Reviewed-by: Bryan Mills <bcmills@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
What version of Go are you using (
go version
)?1.14.4
What operating system and processor architecture are you using (
go env
)?Windows
What did you do?
Read the docs.
What did you expect to see?
Documentation to the effect that most applications on all operating systems should not use this API, unless they write complex additional logic to resolve just those links that they are interested in (e.g. searching through one volume only, although this API cannot reliably enable this specific scenario) or responsible for (e.g. system administration software).
What did you see instead?
EvalSymLinks
intending to resolve all links in the path that it receives as argument, without any hint in the documentation that this might introduce issues due to system reconfigurations, amongst others.What do you propose to fix this?
I propose documentation changes as the best solution for
EvalSymLinks
short of deleting this API altogether, which is not possible today since deleting or no-op'ing this API as proposed in #40104 violates go policies.EvalSymLink
violates what Wikipedia calls the Fundamental Theorem of Software EngineeringEvalSymLinks is not suitable for most applications on any operating system because it unconditionally undoes all indirections for a given path. This is a violation of the principle mentioned which states (in my wording more applicable here):
EvalSymLinks
always resolves all indirections, even those that might have been introduced to fix operational issues affecting the particular application using this API, or which might have been introduced to solve administrative problems on a system that applications should generally remain unaware of - such as disk full situations.I quote from Microsoft documentation:
Mounted Folders - Win32 apps | Microsoft Docs
This API gives software no options to pick and choose to remove only those indirections that they are aware of, are designed to resolve, or have responsibility for.
Practical reasons for most developers not to use
EvalSymLinks
Certainly on Windows, the practical usefulness and applicability of this API for most applications is severely limited by the following four facts:
On the contrary, especially those users that might in some situations want to see resolved paths may configure links for the specific purpose of abbreviating paths that they frequently use, in which case resolving links and showing them to the user is a severe and annoying usability issue beyond what it in most situations normally already is. Applications should hence always remember the path they were configured or started with and generally only ever show that to the user. I champion that this point stands firmly on any operating system besides Windows.
No reboot is necessary to create, change or delete junctions or links. Such events might hence invalidate results of
EvalSymLinks
at any time. No notification is given about such changes, unless the application specifically registers for them. But this is an advanced feature which is nontrivial to implement and test, even though go has/if go would have first-class support for this scenario.The path through which files or directories on a volume are accessible might hence change at a moments notice, even while the application is using files or directories whose access path(s) changed and the application might continue to open handles to the access path(s) it was configured with on another volume, while the application remains unaware, if it does not use the
EvalSymLinks
API, or if it takes care not to cache the result ofEvalSymLinks
in any way.And if they do, they do not need to point at the root of the drive with that letter (
Z:\
). This might be surprising to any developer that is not intimately aware of Windows internals and will produce issues as soon as they do not consistently use API that is itself properly aware of and tested thoroughly to work on Windows.Similar expectations and issues may arise about paths that require the use of the
\\?\
prefix, which complicates all operations with paths further, including long paths and volume GUID paths whichEvalSymLinks
may also introduce in any application on any machine. It is fair to note thatEvalSymLinks
is not the only source of such paths and Windows applications should be prepared to deal with them regardless of whether they useEvalSymLinks
- such paths might even be introduced by user input directly, or through the operating system working directory at application start, or be intermittently visible while the system is being reconfigured.EvalSymLinks
cannot be used to identify volumes in applicable advanced scenario'sFinally, this API by design and as documented can on Windows not identify the volume on which a file or directory resides. Besides resolving UNC mappings, again only in advanced scenario's, this is - for as far as I have been able to identify - about the only situation where the above arguments against the use of
EvalSymLinks
may not always apply for all applications.Paths with a drive letter never identify volumes. Drive letters may in some trivial system configurations happen to correspond to identifiable volumes, but this can not and must never be relied upon.
EvalSymLink
definition, documentation and behavior on Windows reinforces this wrong assumption.That
EvalSymLinks
is of very limited use on Windows is strikingly evidenced by the configuration provided to reproduce issue #40176. This configuration is of particular interest, sinceEvalSymLinks
provides here exactly zero information to the caller. Any path the application requests to be resolved will result in the exact path provided toEvalSymLinks
, since the reparse point resolves to the exact same path as that of the directory that points to it. (before making the path relative and cleaning it, perhaps against statements in the documentation if the fact that an absolute link was resolved might have been lost - and a conforming result might confuse anyone)In fact, until #40095 is part of go,
EvalSymLinks
is completely unable to identify volumes on 64-bit Windows and other Windows installations that use GPT partitioning at all. With this fix, it is only able to do so if the volume happens to have its volume GUID path as its only access path. However now this is merely accidental, due to a fortunate side effect of Windows system architecture.On Windows systems that do not use GPT partitioning, or on (external) disks that do not use GPT, identifying volumes is simply not possible with a path alone, neither before nor after calling
EvalSymLinks
.How concretely do you propose to fix this?
Change the documentation of
EvalSymLinks
insrc\path\filepath\path.go
to read:The text was updated successfully, but these errors were encountered: