Releases: billziss-gh/winfuse
WinFuse 2020 Beta - FUSE for WSL1
FUSE for WSL1
This release of WinFuse finally brings FUSE support for WSL1!
Linux FUSE file systems that use the libfuse high-level or low-level interface should work without any modifications. Linux FUSE file systems that interface with /dev/fuse
directly should still work, unless they perform their own mounting and do not use fusermount
; such file systems may need some modifications in order to work (see LIMITATIONS below).
It is recommended that you try this release in a VM. Although there are no known system stability issues, bugchecks, leaks, system hangs and other system problems are still a possibility.
In the screen cap below you can see unmodified Linux SSHFS running under WSL1 and used to browse the source code of WinFuse. The file system is presented as the Windows drive Z:
and also mounted on mnt
. (You can use a FUSE file system running under WSL1 to make a drive available to the rest of Windows.)
INSTALLATION
This installation requires Windows 10 2004 64-bit. It should also work in Windows 10 1909 64-bit. Prior versions of Windows 10 are not supported.
- Install WinFsp.
- WinFsp 2020.2 Beta2 (v1.8B2) is required.
- Installation Path:
C:\Program Files (x86)\WinFsp
- Registry Path:
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\WinFsp
- Driver:
winfsp
- Install LxDK.
- LxDK 2020 Beta2 (v0.3) is required.
- Installation Path:
C:\Program Files\LxDK
- Registry Path:
HKEY_LOCAL_MACHINE\SOFTWARE\LxDK
- Driver:
lxldr
- Install WinFuse.
- Installation Path:
C:\Program Files\WinFuse
- Registry Path:
HKEY_LOCAL_MACHINE\SOFTWARE\WinFuse
- Drivers:
winfuse
,wslfuse
- Installation Path:
- Reboot your machine to ensure that the necessary driver for WSL1 has been loaded.
- The installation process should be streamlined in later versions of WinFuse.
NOTE: Please use the indicated minimum required versions or system instability is possible.
How to use in WSL1
-
Launch a WSL1 session.
-
Execute the command below to install a custom
fusermount
and create/dev/fuse
. Unfortunately the/dev/fuse
node cannot be created permanently at this time, so you may have to execute this command at the beginning of every WSL1 session (see LIMITATIONS below).$ sudo sh '/mnt/c/Program Files/WinFuse/opt/wslfuse/install.sh' FUSE for WSL1 user space components installed
-
Start your file system. For example:
$ sshfs -d -o umask=000 USER@SERVER: mnt ...
LIMITATIONS
This release has a few limitations that are listed below. Some of these limitations may be lifted in the future.
/dev/fuse creation
Currently the /dev/fuse
node must be created in the beginning of every WSL1 session. (The easiest way to do this is to execute the command sudo sh '/mnt/c/Program Files/WinFuse/opt/wslfuse/install.sh'
.) The reasons are the following:
-
The LXCORE driver provides an (undocumented) DDI for creating file system entries (
VfsInitializeStartupEntries
). Unfortunately the WSL1init
process remounts the/dev
file system immediately after thewslfuse
driver gets a chance to create its/dev/fuse
entry. For this reason it is not possible to create/dev/fuse
from kernel mode. -
The WSL1
init
process executes/bin/sh
and passes control to the user without first attempting to execute any system-wide scripts or configuration (such assystemd
). For this reason it is not possible to create/dev/fuse
when the WSL session starts.
Mount protocol
Linux programs typically call mount(2)
to mount a file system. Unfortunately LXCORE does not provide any obvious way to intercept the mount
and umount
system calls nor does it provide any way to add a new "FUSE" file system type. For this reason, fusermount
emulates mounting and unmounting using special ioctl
's on /dev/fuse
.
The mount protocol is as follows:
- Open
/dev/fuse
for read/write. - Issue an
WSLFUSE_IOCTL_CREATEVOLUME
ioctl
. This creates a WinFsp disk or network volume (typically named\Device\Volume{GUID}
in the NTOS namespace). - Execute a Windows helper application named
/usr/bin/fusermount-helper.exe
, which uses Windows rules to assign a drive to the WinFsp volume (e.g.Z:
->\Device\Volume{GUID}
). This is needed so that the drive can be created in the correct Windows session namespace. - Issue an
WSLFUSE_IOCTL_WINMOUNT
ioctl
. This informs the wslfuse driver about the drive chosen byfusermount-helper.exe
. - Use
sendmsg(2)
to send the open file descriptor for /dev/fuse to the FUSE file system. The FUSE file system can now use the file descriptor (e.g. via libfuse) to receive/send FUSE requests/responses. Note that at this point we have not mounted the file system in WSL1 yet. - Fork a new process to perform the actual
mount(2)
usingdrvfs
as the file system type and exit the originalfusermount
process. This is done to avoid a potential deadlock. For the full details see here. It is of course possible for this mount to fail, but the FUSE file system will continue to service file system operations for the drive created earlier. - The new process will also issue an
WSLFUSE_IOCTL_LXMOUNT
ioctl
to associate the new mount id (taken from/proc/self/mountinfo
) with the newly created volume. - Please see the source code of
fusermount
for addtional details.
Obviously this protocol is rather complex and not very robust. It may be simplified in the future.
Mount options
There are additional options that can be passed to fusermount
to control the mount process. For example the option -oVolume=X:
can be used to control the drive to be created for a new FUSE file system instance. Unfortunately libfuse does not currently recognize any of these options; as a workaround I have hijacked the -ocontext=CONTEXT
option, which libfuse does accept to pass additional options. For example, to create a new network drive X: accessible via the UNC prefix \\myfs\share
, use:
$ ./myfs -ocontext=Volume=X:,context=VolumePrefix=/myfs/share ...
Permission model
The wslfuse
driver uses a scheme used by Cygwin and (in the past) Services for UNIX to map Unix UID's and permissions to Windows SID's and ACL's. Unfortunately this scheme is not compatible with WSL1, which can result in permission problems. If you experience such problems try running your file system with the option -o umask=000
.
Future versions of WinFuse should rectify this problem.
WinFuse 2020 Alpha1
This release requires WinFsp 2019.3 or later. Prior versions will not work.
WinFuse is a suite of software components that allows FUSE file systems to run on Windows. It consists of a kernel driver that exposes the low-level FUSE protocol and a Windows port of the libfuse library compiled as a DLL.
This is the first release of WinFuse and it should be considered of ALPHA quality. Although I am not aware of any such issues, bugchecks, leaks, system hangs and other system problems are a possibility. For this reason I recommend that you try WinFuse in a VM.
I would really appreciate it if you give WinFuse a try and report any problems. This is especially so if you have a low-level FUSE file system that you cannot easily port to Windows; well now you can. Your feedback is very welcome.
Finally note that this release contains the winfuse kernel driver, which exposes the FUSE protocol in the Windows kernel (via DeviceIoControl
). It does not contain the wslfuse kernel driver, which will expose the FUSE protocol in WSL1 (via /dev/fuse
).