Absolute Junction Points/Symlinks

Erich E. Hoover erich.e.hoover at gmail.com
Sun May 17 12:49:09 CDT 2020


On Sat, May 16, 2020 at 8:34 PM Esme Povirk (they/them)
<vincent at codeweavers.com> wrote:
>
> I think this would be too much complexity to be worth it. By the time
> I learn as a user that my Wine-created symlinks will only work using
> some special command, and manually launch whatever program I want to
> use them in, I've already been inconvenienced more than I would be by
> a broken symlink. I'd also worry about the potential for compatibility
> problems with applications launched using wine's LD_PRELOAD (by
> winebrowser for example).

Well, a choice could be to embed the absolute path such that as long
as the prefix isn't moved that it still works.  However, this gets
back into the category of "why don't we just rewrite the symlinks if
the prefix gets moved" that we talked about at WineConf that people
didn't seem really keen on.

> I'm also not clear on why the symlinks need to resolve correctly
> *inside wine processes*. As long as we only open them using the win32
> api, the win32 api can interpret those files however we need it to.

It's not strictly necessary for Wine to be run like this, though you
would still need the wineserver to deal with the case where a path
contains an NT symlink along the way.

> Wine should control any file access that needs to work with symlinks
> it creates, especially with the push towards converting Wine's dlls to
> be built as PE. Therefore, it should be able to do the right thing in
> its own code and not have to hook itself or any native libraries it
> loads. "The right thing" might mean interpreting a special /??/ path
> differently, replacing a wineprefix embedded in the target with the
> current wineprefix, or reading the target using something other than
> readlink(), but whatever it is should be equally doable inside Wine
> without hooking.

This was meant as a demo, but if we were to do something like this
then you would implement most of the real work in the wineserver so
that the LD_PRELOAD is only needed for other programs.

On Sun, May 17, 2020 at 6:48 AM Gabriel Ivăncescu
<gabrielopcode at gmail.com> wrote:
> ...
> Can't you just make all the absolute symlinks within a prefix actually
> relative, by converting them? Then use a special pattern to recognize
> them as "absolute" so Wine knows to report them as such (any combination
> of / and . ).

We already have the "type" encoded in the staging patches, the link
target always begins with either "." (relative) or "/" (absolute)
followed by the reparse tag encoded as dots and slashes, for example:
IO_REPARSE_TAG_SYMLINK: //././/////////////////////////.//./
For symlinks this is then followed by an "is directory" flag because
of annoying Windows reasons.

> The only downside is that they will break if the symlinks themselves are
> moved within the prefix by programs outside of Wine. But then again, so
> will they with your current approach, if they don't run the 'wineprefix'
> tool.
> ...

And if they or their parent is moved by programs within Wine, unless
you modify MoveFile in a very nontrivial way.  If you move the parent
folder of the symlink then the symlink breaks, which means that
whenever you move a folder you would need to check _all_ the contents
for symlinks and then go through and rewrite them all.

I still think the easiest thing to do would be to treat these links as
absolute links and make it easy to rewrite the portion corresponding
to the prefix if the prefix is moved, but people didn't really seem to
like that.  It just seems to me like this way is easier and more
robust to external applications (doesn't require special tools unless
you move a prefix, and we could conceivably provide a tool for the
expressed purpose of moving a prefix).  If you look at how the staging
patches are doing things now:
<Relative|Absolute><Reparse Tag><Directory|File><Path to Target>
it seems like this can be extended pretty easily such that "Path to
Target" gets split into:
<Prefix><Magic Pattern><Prefix-specific Path>
Then when the wineserver opens something and it fails all we need to
do is a quick check for symlinks and rewrite the prefix portion of the
path.

Best,
Erich



More information about the wine-devel mailing list