Skip to content
Snippets Groups Projects
  • Simon McVittie's avatar
    d3ae9433
    pv-adverb: If we cannot regenerate ld.so.cache, fall back · d3ae9433
    Simon McVittie authored
    
    Before !338 (T14481), we relied on the
    LD_LIBRARY_PATH as our way to find libraries from the graphics stack
    provider (host system or Flatpak runtime), both /overrides/lib/MULTIARCH
    and /overrides/lib/MULTIARCH/aliases. However, this was not robust
    against games that (incorrectly) reset the LD_LIBRARY_PATH in their
    startup scripts, such as Dead Cells, Evoland Legendary Edition and
    Shenzhen I/O.
    
    Since !338, we maintain three separate library search paths:
    
    1. The LD_LIBRARY_PATH that is used to run pv-adverb is the same
        as before. (This is getenv("LD_LIBRARY_PATH") in pv-adverb code.)
    2. Library directories that contain libraries named by their SONAME
        (/overrides/lib/MULTIARCH) are prepended to ld.so.conf, after which
        we invoke ldconfig to regenerate ld.so.cache. This means games that
        reset the LD_LIBRARY_PATH will effectively still search
        /overrides/lib/MULTIARCH, as a result of the usual logic that reads
        ld.so.cache. (This is global_ld_so_conf_entries in pv-adverb code.)
    3. Library directories that contain libraries not named by their SONAME
        (/overrides/lib/MULTIARCH/aliases) still need to be in the
        LD_LIBRARY_PATH, because ld.so.cache only lists libraries by their
        SONAMEs, so we still need to put these library directories in the
        LD_LIBRARY_PATH before invoking the actual game.
        (This is opt_set_ld_library_path in pv-adverb code.)
    
    This worked fine on systems like Debian 11 and Arch, but is unnecessarily
    fragile: if running ldconfig failed, there was no fallback, and the game
    would simply not launch correctly. In particular, ldconfig can fail to
    run on Ubuntu and old Debian systems (prior to Debian 9), as a result of
    a workaround involving /sbin/ldconfig being made a shell script wrapper
    around /sbin/ldconfig.real.
    
    We can mitigate this failure by falling back to the old (pre-!338) logic
    if ldconfig fails, with a warning. Games like Dead Cells will still not
    launch successfully in this mode, but better-behaved games (including
    most native Linux titles and all Proton titles) will survive.
    
    A subtlety here is that when we fall back, we need to find both
    /overrides/lib/MULTIARCH and /overrides/lib/MULTIARCH/aliases in the
    LD_LIBRARY_PATH; so we discard search paths 2 and 3, and keep using
    search path 1 for the actual game, not just pv-adverb.
    
    Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
    d3ae9433
    History
    pv-adverb: If we cannot regenerate ld.so.cache, fall back
    Simon McVittie authored
    
    Before !338 (T14481), we relied on the
    LD_LIBRARY_PATH as our way to find libraries from the graphics stack
    provider (host system or Flatpak runtime), both /overrides/lib/MULTIARCH
    and /overrides/lib/MULTIARCH/aliases. However, this was not robust
    against games that (incorrectly) reset the LD_LIBRARY_PATH in their
    startup scripts, such as Dead Cells, Evoland Legendary Edition and
    Shenzhen I/O.
    
    Since !338, we maintain three separate library search paths:
    
    1. The LD_LIBRARY_PATH that is used to run pv-adverb is the same
        as before. (This is getenv("LD_LIBRARY_PATH") in pv-adverb code.)
    2. Library directories that contain libraries named by their SONAME
        (/overrides/lib/MULTIARCH) are prepended to ld.so.conf, after which
        we invoke ldconfig to regenerate ld.so.cache. This means games that
        reset the LD_LIBRARY_PATH will effectively still search
        /overrides/lib/MULTIARCH, as a result of the usual logic that reads
        ld.so.cache. (This is global_ld_so_conf_entries in pv-adverb code.)
    3. Library directories that contain libraries not named by their SONAME
        (/overrides/lib/MULTIARCH/aliases) still need to be in the
        LD_LIBRARY_PATH, because ld.so.cache only lists libraries by their
        SONAMEs, so we still need to put these library directories in the
        LD_LIBRARY_PATH before invoking the actual game.
        (This is opt_set_ld_library_path in pv-adverb code.)
    
    This worked fine on systems like Debian 11 and Arch, but is unnecessarily
    fragile: if running ldconfig failed, there was no fallback, and the game
    would simply not launch correctly. In particular, ldconfig can fail to
    run on Ubuntu and old Debian systems (prior to Debian 9), as a result of
    a workaround involving /sbin/ldconfig being made a shell script wrapper
    around /sbin/ldconfig.real.
    
    We can mitigate this failure by falling back to the old (pre-!338) logic
    if ldconfig fails, with a warning. Games like Dead Cells will still not
    launch successfully in this mode, but better-behaved games (including
    most native Linux titles and all Proton titles) will survive.
    
    A subtlety here is that when we fall back, we need to find both
    /overrides/lib/MULTIARCH and /overrides/lib/MULTIARCH/aliases in the
    LD_LIBRARY_PATH; so we discard search paths 2 and 3, and keep using
    search path 1 for the actual game, not just pv-adverb.
    
    Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>