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

[Feature request] Reuse common WINE components #1011

Closed
pchome opened this issue Aug 30, 2018 · 20 comments
Closed

[Feature request] Reuse common WINE components #1011

pchome opened this issue Aug 30, 2018 · 20 comments
Labels
Feature Request New feature or request

Comments

@pchome
Copy link
Contributor

pchome commented Aug 30, 2018

This issue is partially feature request and partially answer to #919 What are the use cases for a 32bit prefix? question.

I have a lot of separate prefixes for a long time and number is only growing, and this thoughts with me from the beginning: "how to reuse everything on new prefix creation". And the simplest way I've used is to create symlinks in freshly created prefix for mono|gecko|Install|...

Imagine you have to install two copies of Windows 98 ... by copying an existing installation for every game you want to launch.

$ equery s wine-vanilla

 * app-emulation/wine-vanilla-3.14
         Total files : 4955
         Total size  : 433.02 MiB

$ equery s wine-mono

 * app-emulation/wine-mono-4.7.3
         Total files : 5
         Total size  : 53.86 MiB

$ equery s wine-gecko

 * app-emulation/wine-gecko-2.47-r1
         Total files : 6
         Total size  : 95.44 MiB

All this after extracting into actual WINE prefix:
$ WINEPREFIX=/tmp/pfx wineboot --init
$ du -hs pfx

538M    pfx

So the answer to the question "where I can get a few GiB for new game" was always the same: "check your recent prefixes ;)".

Symlinking does the trick, but required manual control. I always wanted an automated script using an overlayed FS, but was too lazy to investigate/implement such ability.

Today I decided to try userspace fuse overlayfs module, and seems it can be used (not completely sure, still playing with this) to create layered WINE prefix with common parts been reused.

$ fuse-overlayfs -o lowerdir=opfx-mono:opfx-base,upperdir=opfx-up,workdir=opfx-workdir opfx
$ WINEPREFIX=/tmp/opfx winecfg
$ fusermount3 -u opfx

All changes was made in winecfg are left in opfx-up directory.

  • opfx-base - prefix init directory
  • opfx-mono - directory where "mono|gecko|Install|..." was moved after opfx-base was created.
  • opfx-workdir AFAIK an technical directory for fuse itself.

$ du -hs opfx*

538M    opfx
45M     opfx-base
493M    opfx-mono
2.4M    opfx-up
0       opfx-workdir

Any thoughts?

@Elkasitu
Copy link
Contributor

I agree with the premise of the post; for the ~10 or so games that I have installed that use proton, I'd say 8 or 9 are vanilla prefixes and my compatdata directory is currently sitting at 5GiB which is not that much by today's standards, but it is expensive in the context of SSD space and could be reduced by ~90% by using symlinks.

However I'm not sure about using third-party dependencies for it, unless of course, you want to do so manually without expecting Steam/Proton to use fuse-overlayfs, we could draw from the idea of fuse-overlayfs and implement a minimalist version that works for wine though, but I think that's premature optimization at this point, symlinking should be enough for a while.

I think I have an idea for this issue and might cook up a POC and make a PR!

@pchome
Copy link
Contributor Author

pchome commented Aug 30, 2018

I think that's premature optimization at this point

sure

I had some ideas for Proton earlier, but this "premature optimization" stops me from sharing ;)

Anyway - it's mostly FYI.

@Elkasitu
Copy link
Contributor

Maybe I should've explained what I meant by "premature optimization":

It's not a bad idea and it should totally be implemented at some point, however I don't think the difference between a fuse-overlayfs-like solution and a symlink solution is big enough to warrant the amount of time that it would take to implement it, but again the project is OS so anyone can just do it and implement it :)

@pchome
Copy link
Contributor Author

pchome commented Aug 30, 2018

Maybe I should've explained what I meant by "premature optimization"

No you shouldn't

I believe it's due to my English knowledge. It was too aggressive (many people noticed this)?
No, it was "sure this too early, I know how thing can change in time."
Sorry.

@sir-maniac
Copy link

sir-maniac commented Aug 31, 2018

Making hard-links (perhaps with an option in the steam UI to enable it) could also be a solution for this.

I'm actually already doing this by using rdfind. (which can also make symlinks if preferred)

@pchome
Copy link
Contributor Author

pchome commented Aug 31, 2018

Hardlinks is also an alternative, but overlay is much more simpler solution, IMHO.

It's new for me, and I can't say it's safe, but It looks like you can redistribute all parts separately and combine all of them with one command (fuse-overlayfs):

  • opfx-base-3.14 - should be created for every new WINE version
  • opfx-mono-4.7.3 - ok, put only mono here, it have known version for every WINE version
  • opfx-gecko-2.47 - ok, put only gecko here, it have known version for every WINE version
  • opfx-dx9 - ok, we'll improvize
  • opfx-up - this part can be loaded over steam cloud (for example), cause it contains only changes user made during gameplay

Also there is some differences between 32bit and 64bit prefixes to note.

Anyway sym/hard-linking is good-enough alternative for early stage.

@Elkasitu
Copy link
Contributor

Elkasitu commented Aug 31, 2018

Well you can't hard-link an entire directory, so proton would have to recreate the entire directory structure and hard-link each file individually which would be less efficient the first time any game is run (when the hard/soft-link is being created)

I will try doing both and maybe benchmark it

Edit: Actually, after looking at the code, the function mergedirs can be modified slightly to use hardlinks instead of copying files

@sir-maniac
Copy link

sir-maniac commented Aug 31, 2018

@pchome

It just sounds like a can of worms for OS compatibility to use something like fuse in the proton project. Haven't people gotten steam-linux to work on BSD? What about macOS compatibility?

A more compatible option would be to implement overlays directly into wine, or possibly in a libc wrapper. But that might be as great a scope as supporting overlay filesystems on each OS.

Although hard-links might be an issue as well for compatibility. ( I don't know if all POSIX-compliant file systems behave the same when hard links are involved. COW filesystems might also be an issue. )

@sir-maniac
Copy link

sir-maniac commented Aug 31, 2018

@Elkasitu hard-link clones can be made with 'cp -l' for you to test, but my experience is that they are much faster than actually copying all the files.

@Ruedii
Copy link

Ruedii commented Sep 12, 2018

I think #136 is the best implementation choice.

Overlayfs with COW would save a LOT of disk space.

Using a COW registry patch would also be a good idea to reduce registry size AND allow updating of the base registry.

The best way to do this is to just use the standard Windows tree method if Wine supports it of putting system-wide options in [hkey:localmachine] and game specific options in [hkey:localuser] (That Windows 2000 certification study is really coming in handy on this one.)

@kisak-valve kisak-valve added the Feature Request New feature or request label Oct 23, 2018
@kisak-valve
Copy link
Member

Save space by using a generic prefix

Issue transferred from #1806.
@Rabcor posted on 2018-10-23T06:53:49:

Feature Request

I would like it if proton had a generic proton prefix (something like compatdata/proton/pfx) which it would use as the default prefix for all games that don't need prefix specific workarounds. This way potentially large amounts of disk space could be saved.

I confirm:

  • that I haven't found another request for this feature.
  • that I have checked whether there are updates for my system available that
    contain this feature already.

Description

As things stand, proton doesn't seem to do anything on a per-prefix basis for any game, so the compatdata directory with all the per-game prefixes is mostly just a collection of duplicate prefixes.

On average these prefixes seem to add 1GB+ to space needed for installed games. Additionally, sometimes prefixes will be created with unrelated user files (for example save-games for other titles than the one the prefix is used for) further adding to this space use.

This should be an option, whether it should be the default can be debated. As things stand it is better to have per-game prefixes because it allows for better testing (if users need to modify their prefix, let's say by installing .NET Framework or some DX redists, they may as a side effect be able to run other games out of the box too.) but when proton is more mature, having one generic prefix that can be used for all games that don't need specific workarounds would be highly preferable.

I would suggest looking into how lutris handles prefixes (sometimes referred to by them as runners) for insights into better ways for implementing multiple prefixes while still using one (or few) prefixes for most games.

Justification

Excessive use of disk space for no real gain to the end-user. (With just 14 games installed I am using 15gb of disk space for proton prefixes alone)

Risks

False compatibility reports from users who have modified their prefix. (This may be avoidable if steam/proton will install with a configuration utility, something similar to winetricks/protontricks, which would create a separate prefix for a target game when the user wants to make changes, preferably with an option to override the generic/main proton prefix as an option for advanced users/people who don't intend to make compatibility reports)


@dlove67 commented on 2018-10-23T12:47:16

Symlinks could be a better option, since you could then keep the prefixes for each AppID, but push changes when needed.


@lucifertdark commented on 2018-10-23T13:00:29

Proton already has a default prefix in the main Proton folder, for me it's in "Proton 3.16/dist/share/default_pfx" it's copying the contents of that to the compatdata folder for each game.

@Rabcor
Copy link

Rabcor commented Oct 23, 2018

Symlinks could be a better option, since you could then keep the prefixes for each AppID, but push changes when needed.

Well I would have suggested that but both wine and steam seem to have issues with symlinks. I recall not being able to use proton if I symlinked my steam library to a different location for example. I believe it's because wine cannot follow symlinks to executables, or something like that.

@pchome
Copy link
Contributor Author

pchome commented Feb 23, 2019

A little bit off-topic, but here is the similar thing for modular dist:
modular-wine.example.sh

#!/bin/sh

# [FUSE-3](https://github.com/libfuse/libfuse)
# [fuse-overlayfs](https://github.com/containers/fuse-overlayfs)

if [ -z "$1" ]; then
  echo "Usage: $0 <module1> [module2 ...]"
  exit
fi

DISTDIR=dist
UPDIR=/tmp/fuse-t/updir
WRKDIR=/tmp/fuse-t/workdir
MODDIR=pmod

# umount if still mounted
fusermount3 -u "${DISTDIR}"

# WINE tree should be readonly
# so safely discard all changes made by user
rm -r "${UPDIR}" "${WRKDIR}"

# Recreate work dirs
mkdir -p "${UPDIR}" "${WRKDIR}"


# Module list
# reverse order, the left one "mounted" on top of the right one
MOD=${DISTDIR}
for m in $@; do
  MOD="${MODDIR}/${m}:${MOD}"
done

# Create new "dist" tree
fuse-overlayfs -o lowerdir="${MOD}",upperdir="${UPDIR}",workdir="${WRKDIR}" "${DISTDIR}"

$ sh modular-wine.example.sh dxvk faudio nvapi-dx9 pba

Module tree example:

pmod/pba/lib/wine/wined3d.dll.so
pmod/pba/lib64/wine/wined3d.dll.so

DXVK winelib module is safe between WINE versions, but e.g. PBA should be built for specific version to avoid conflicts and breakage.


Well, the same thing, but w/o fuse-overlayfs : HACK-WINEMODPATH.patch.txt
to give a module higher priority over dlldir and WINEDLLPATH through WINEMODPATH env var.

#!/bin/sh
export WINEPREFIX=/tmp/wtst

# safe
DXVK="/usr/lib64/dxvk-9999:/usr/lib/dxvk-9999"
DXUP="/usr/lib64/dxup-9999:/usr/lib/dxup-9999"

# not safe
PBA="$HOME/.local/lib64/pba-3.16-7:$HOME/.local/lib/pba-3.16-7"
STAGING_PARTS="$HOME/.local/lib64/st-3.16-7:$HOME/.local/lib/st-3.16-7"

export WINEMODPATH="$DXVK:$STAGING_PARTS"
export DXVK_HUD=full

wine /usr/bin/d3d11-triangle.exe.so

Module tree example:

lib64/pba-3.16-7/wined3d.dll.so
lib/pba-3.16-7/wined3d.dll.so

@pchome
Copy link
Contributor Author

pchome commented May 7, 2019

Partially resolved by recent WINE/Proton updates.

@pchome pchome closed this as completed May 7, 2019
@Lucki
Copy link

Lucki commented May 10, 2019

Partially resolved by recent WINE/Proton updates.

Could you provide some reference or elaborate a bit more on this? I've played a bit around with overlayfs but it's in no way practical.

@pchome
Copy link
Contributor Author

pchome commented May 10, 2019

https://www.winehq.org/pipermail/wine-devel/2019-April/143379.html
https://github.com/madewokherd/wine-mono/releases/tag/wine-mono-4.8.1 (see "Notes for packagers:" part)
TL;DR: WINE can use shared wine-mono installation for all prefixes. This saves disk space.

AFAIK >=wine-mono-4.8.1 used by Proton-4.2.

Hope same will happen to wine-gecko soon.

@Lucki
Copy link

Lucki commented May 10, 2019

Yes, looks like it uses 4.8.2 for proton 4.2-3: update to wine-mono 4.8.2

Thank you for digging that links out.

@jomarocas
Copy link

ok this is partially, but a function that make in all games, or a easy mode that put a game in a same prefix because latest proton update works for me in various games without make nothing to install depedents, a esay mode or a recommendation without use opfx

@Ruedii
Copy link

Ruedii commented Jul 3, 2019

I think some sort of FUSE based COW mount might be most effective for this.

However, this does mean insuring that FUSE and Wine will play nice about this.

@pchome
Copy link
Contributor Author

pchome commented Feb 4, 2020

Since version 5.0 WINE can use shared wine-gecko (2.47.1) installation for all prefixes.
Clean prefix size now reduced to ~75MB.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Request New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants