This is an experimental library to workaround incompatibilities in WSL1.
The idea is to patch binaries that use unimplemented functionality with "polyfills", user-space implementations of the missing functionality.
Just type make, then make install.
First, verify that this library will fix your program
$ LD_PRELOAD=/usr/local/lib/libwslcompat.so program
If that works, you can make the change permanent
$ patchelf --add-needed /usr/local/lib/libwslcompat.so $(which program)
Note: The
patchelfutility is available in most package managers.
If this doesn't fix your binary, or causes any problems, please open an issue.
If you're trying to fix a script, you need to patchelf the interpreter, such
as python or ruby.
For example, the multiprocessing python module does not work on WSL1:
$ python multiproc.py
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3.12/multiprocessing/forkserver.py", line 207, in main
with socket.socket(socket.AF_UNIX, fileno=listener_fd) as listener, \
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/socket.py", line 233, in __init__
_socket.socket.__init__(self, family, type, proto, fileno)
OSError: [Errno 22] Invalid argument
However, we correctly polyfill the necessary socket options.
$ LD_PRELOAD=libwslcompat.so python multiproc.py
hello
If you want this to be permanent, simply try this:
$ sudo patchelf --add-needed libwslcompat.so /usr/bin/python
This library supports preloading via /etc/ld.so.preload, making it apply
systemwide.
$ echo /usr/local/lib/libwslcompat.so | sudo tee -a /etc/ld.so.preload
If necessary, you can use tunables to configure individual programs.
There are a variety of tests in the tests directory that verify the polyfills are functioning.
Type make test to run them.
MAP_FIXED_NOREPLACEis unimplemented.getsockopt(SO_PROTOCOL)is unimplemented forAF_UNIX.getsockopt(SO_DOMAIN)is unimplemented forAF_UNIX.mincore()is unimplemented.F_OFD_SETLK/F_OFD_GETLKare unimplemented.F_SETLKexclusive locks are process scoped.VMINandVTIMEare ignored by non-canonical terminals.STATX_MNT_IDis unimplemented.STATX_ATTR_MOUNT_ROOTis unimplemented.STATX_BTIMEis unimplemented.MAP_LOCKEDis unimplemented.RENAME_NOREPLACEis unimplemented.execve()rejects ELF64 binaries with mixedPT_LOADp_align.execveat()is unimplemented.
You can configure wslcompat using extended attributes, called tunables.
Tunables let you change the behavior of each binary by enabling or disabling
polyfills and features, which is particularly useful when wslcompat is
loaded via /etc/ld.so.preload.
For the full reference of every tunable and how to set them, see TUNABLES.md.
A few common ones:
$ setfattr -n user.wslcompat.disabled -v "fcntl,mmap" $(which program)
$ setfattr -n user.wslcompat.debug -v 2 $(which program)
The file locking primitives available on WSL1 are extremely limited.
This library makes an attempt to improve the consistency of locking, but does so by mapping all lock types onto the one reliable locking mechanism.
For further discussion on the problem please see LOCKS.md.
The Elf64 loader in WSL1 will reject any binary that has PT_LOAD program
headers with non-uniform alignment. These are perfectly valid and common
programs, so an execve polyfill attempts to detect this case.
The polyfill can re-exec binaries via their interpreter, but this only works for dynamically linked binaries.
For static binaries, you can use elfclamp to patch the binary in place.
$ elfclamp /path/to/program
This unifies every PT_LOAD p_align to the smallest value observed, which
preserves the ELF congruence rule. Already-uniform binaries are left alone.
We can polyfill these in future.
kcmp- For the
pid1==pid2andKCMP_FILEcase, we can use toggle flags withF_GETFL/F_SETFLto see if a file is the same.
- For the
SO_TIMESTAMPonAF_UNIX- Needs
setsockopt/getsockoptto track per-fd state andrecvmsgto splice anSCM_TIMESTAMPcmsg captured around the underlying recv.
- Needs
- Path redirection via a
user.wslcompat.redirtunable?