Accessing file over network using WSL 2

Windows 10 allows one to create a Ubuntu machine within Windows 10 using WSL 2.

Files on the Ubuntu machine are accessed as networked drives from Windows 10.

In checking out how to run a *.pl file on Ubuntu machine from Windows 10 and accessing the file as a networked file ran into a problem using consult/1.

?- consult('//wsl$/Ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl').
ERROR: source_sink `'/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl'' does not exist
ERROR: In:
ERROR:   [34] throw(error(existence_error(source_sink,'/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl'),_4068))
ERROR:   [30] '$source_term'('/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',_4100,_4102,_4104,_4106,_4108,[],[expand(false),...]) at c:/program files/swipl/boot/init.pl:1640
ERROR:   [29] '$source_term'('/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',_4154,_4156,_4158,_4160,_4162,[expand(false),...]) at c:/program files/swipl/boot/init.pl:1619
ERROR:   [28] '$load_file'('/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl','/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',_4208,[expand(false),...]) at c:/program files/swipl/boot/init.pl:2855
ERROR:   [27] setup_call_catcher_cleanup(system:true,system:'$load_file'('/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl','/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',_4276,...),_4254,system:'$end_consult'(...,user)) at c:/program files/swipl/boot/init.pl:564
ERROR:   [23] '$do_load_file_2'('//wsl$/Ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl','/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',user,compiled,[expand(false),...]) at c:/program files/swipl/boot/init.pl:2442
ERROR:   [20] '$mt_do_load'(<clause>(000002272E105240),'//wsl$/Ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl','/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',user,[expand(false),...]) at c:/program files/swipl/boot/init.pl:2385
ERROR:   [19] setup_call_catcher_cleanup(system:with_mutex('$load_file',...),system:'$mt_do_load'(<clause>(000002272E105240),'//wsl$/Ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl','/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',user,...),_4414,system:'$mt_end_load'(<clause>(000002272E105240))) at c:/program files/swipl/boot/init.pl:564
ERROR:   [16] '$load_file'('//wsl$/Ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',user,[expand(false),...]) at c:/program files/swipl/boot/init.pl:2246
ERROR:    [9] <user>
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

Windows 10 is running

SWI-Prolog (threaded, 64 bits, version 8.1.32)

Ubuntu 18.04 is running

SWI-Prolog (threaded, 64 bits, version 8.1.32)

Steps to isolate problem using full path.

  1. On Ubuntu machine, *.pl file can be consulted and predicate executed.
eric@WINDOWS-6F874NS:~$ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.32)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- consult("/home/eric/projects/prolog/wsl2_tests/test.pl").
true.

?- test.
Hello, World!
true.
  1. On Windows 10, file can be accessed as network drive.
C:\Users\Eric>dir \\wsl$\Ubuntu-18.04\home\eric\projects\prolog\wsl2_tests\test.pl
 Volume in drive \\wsl$\Ubuntu-18.04 has no label.
 Volume Serial Number is 0000-0000

 Directory of \\wsl$\Ubuntu-18.04\home\eric\projects\prolog\wsl2_tests

05/24/2020  02:53 PM               240 test.pl
               1 File(s)            240 bytes
               0 Dir(s)  250,222,571,520 bytes free
  1. On Windows 10, Prolog can see the file.
?- exists_file('//wsl$/Ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl').
true.

Trying to resolve problem setting working directory.

?- working_directory(Old,'//wsl$/Ubuntu-18.04/home/eric/projects/prolog/wsl2_tests').
Old = '/wsl$/ubuntu-18.04/'.

?- working_directory(D,D).
D = '/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/'.

?- consult('test.pl').
ERROR: source_sink `'/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl'' does not exist
ERROR: In:
ERROR:   [34] throw(error(existence_error(source_sink,'/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl'),_8004))
ERROR:   [30] '$source_term'('/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',_8036,_8038,_8040,_8042,_8044,[],[expand(false),...]) at c:/program files/swipl/boot/init.pl:1640
ERROR:   [29] '$source_term'('/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',_8090,_8092,_8094,_8096,_8098,[expand(false),...]) at c:/program files/swipl/boot/init.pl:1619
ERROR:   [28] '$load_file'('/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl','/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',_8144,[expand(false),...]) at c:/program files/swipl/boot/init.pl:2855
ERROR:   [27] setup_call_catcher_cleanup(system:true,system:'$load_file'('/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl','/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',_8212,...),_8190,system:'$end_consult'(...,user)) at c:/program files/swipl/boot/init.pl:564
ERROR:   [23] '$do_load_file_2'('test.pl','/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',user,compiled,[expand(false),...]) at c:/program files/swipl/boot/init.pl:2442
ERROR:   [20] '$mt_do_load'(<clause>(000002272E105040),'test.pl','/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',user,[expand(false),...]) at c:/program files/swipl/boot/init.pl:2385
ERROR:   [19] setup_call_catcher_cleanup(system:with_mutex('$load_file',...),system:'$mt_do_load'(<clause>(000002272E105040),'test.pl','/wsl$/ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl',user,...),_8350,system:'$mt_end_load'(<clause>(000002272E105040))) at c:/program files/swipl/boot/init.pl:564
ERROR:   [16] '$load_file'('test.pl',user,[expand(false),...]) at c:/program files/swipl/boot/init.pl:2246
ERROR:    [9] <user>
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

One other odd thing that turned up.

On Windows 10 directory_files/2 works with a network drive when given the drive name directly.

?- directory_files('//wsl$/Ubuntu-18.04/',E).
E = [home, srv, etc, opt, root, lib, mnt, usr, media, lib64, sys, dev, sbin, boot, bin, run, init, proc, snap, tmp, var, 'lost+found', .., '.'].

but fails when being passed the directory name from working_directory/2

?- working_directory(D,D).
D = '/wsl$/ubuntu-18.04/'.

?- working_directory(D,D),directory_files(D,E).
ERROR: file `'/wsl$/ubuntu-18.04/'' does not exist
ERROR: In:
ERROR:   [11] directory_files('/wsl$/ubuntu-18.04/',_8520)
ERROR:    [9] <user>
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

Notice that the network directory path returned from working_directory/2 started with one / and not two.


EDIT

Workaround

Map the network folder to a Windows drive. See: Map a network drive

Drive: S
Folder: \\wsl$\Ubuntu-18.04

Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.32)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- consult("S:/home/eric/projects/prolog/wsl2_tests/test.pl").
true.

?- test.
Hello, World!
true.

EDIT

Fix in GitHub Commit: f5069ab

Personal Notes

SWI-Prolog C code to check for names with shares (ref)

Microsoft

Support

Naming conventions in Active Directory for computers, domains, sites, and OUs (ref)

Docs

2.2.1 NetBIOS Name Syntax (ref)
Naming Files, Paths, and Namespaces (ref)

Namespaces (ref) - same as [1] in below statement by WorldMaker

There are two main categories of namespace conventions used in the Windows APIs, commonly referred to as NT namespaces and the Win32 namespaces . The NT namespace was designed to be the lowest level namespace on which other subsystems and namespaces could exist, including the Win32 subsystem and, by extension, the Win32 namespaces. POSIX is another example of a subsystem in Windows that is built on top of the NT namespace. Early versions of Windows also defined several predefined, or reserved, names for certain special devices such as communications (serial and parallel) ports and the default display console as part of what is now called the NT device namespace, and are still supported in current versions of Windows for backward compatibility.

IETF

PROTOCOL STANDARD FOR A NetBIOS SERVICE ON A TCP/UDP TRANSPORT:

RFC 1001 - CONCEPTS AND METHODS (ref)
RFC 1002 - DETAILED SPECIFICATIONS (ref)

IBM

Personal Computer Hardware Reference Library

Technical Reference - PC Network - IBM document 6322916 (ref)

Hacker News

Windows Subsystem for Linux 2 Moving into General Availability (ref) - Discussion that often touches on some of the technical problems with getting Linux to run with Windows on the same machine.

Statement by WorldMaker

At a high level it’s much closer to a Win32 Namespace [1] that appears like a network path. UNC stands for Universal Naming Convention, there’s no “Network” in the UNC abbreviation as there are many namespaces other than just network paths. Which is why the $ was chosen for the name because it is a valid Namespace character but not a valid system name in Windows, and they wanted to avoid the problem of people with systems named “wsl” suddenly unable to be accessible over the network, because Namespaces have higher priority than network paths. You could think of it as bypassing the network, but it is maybe more accurate to view it that network access is a fallback of UNC paths after all local Namespaces have been checked if they support the path.

I don’t fully understand that statement at present but plan to look into what it means in more detail. If this is correct then wsl$ is probably not a NetBios Computer Name as I noted below.

GitHub

WSL

Issues

What is wsl$? Where are the syntax rules to parse it correctly? (ref)

It’s a UNC path. [One that happens to have a $ in the hostname component.]

References

rfc3986 - Uniform Resource Identifier (URI): Generic Syntax

1 Like

Thanks for the elaborate report. I do not have WSL installed, but your report says //wfs$/ should be recognized as a share name while share names are defined to be a valid DNS name which does not allow for $. I couldn’t find what is allowed now. I’ve added allowing for $ as last character of the share name. That may not be correct.

Should be in tomorrows daily builds (typically finished by 02.30UTC). Please check then.

1 Like

I added some personal notes in the original post that may answer this. It seems the name used by WSL2 is a NetBIOS computer name and the naming specification can be found in Naming conventions in Active Directory for computers, domains, sites, and OUs (ref)

1 Like

Thanks. Pushed a fix that is, as far as I can tell, pretty much the spec. That was a lot harder than I thought as NetBIOS names are … case sensitive! So, when canonicalizing a file for case we need to leave the NetBIOS name alone :frowning:

Anyway, please give it a try. You can test filename canonicalization separately using absolute_file_name/2, which only performs the syntactic transformation if you give it an absolute file name.

1 Like

Thanks.

I hate to say it but I could be totally wrong on it being a NetBIOS computer name. As I have never dealt with the Microsoft naming conventions at this level I am learning a lot today.

My current focus is from Microsoft Namespaces

There are two main categories of namespace conventions used in the Windows APIs, commonly referred to as NT namespaces and the Win32 namespaces . The NT namespace was designed to be the lowest level namespace on which other subsystems and namespaces could exist, including the Win32 subsystem and, by extension, the Win32 namespaces.

While I see no harm in adding NetBIOS computer name syntax rules, and the name wsl$ may pass as one, it could be of the wrong type. Something like 1 and 1.0 both are the quantity 1, but one is an integer and one is a real. It is only when looking under the covers does someone know there is a difference.

So for now I will wait till I can pull the changes down in a PPA and corresponding Windows install and check it as I still have never built a version of SWI-Prolog along the make route. If it works then there is no sense in splitting hairs.

The Windows binary will be in the daily downloads tomorrow. These patches do not affect non-Windows platforms (except for possible mistakes in the reorganization). So, please check (tomorrow) whether the Windows version can access the WSL files.

That doesn’t matter. SWI-Prolog doesn’t need to know the type. It just needs to know the syntactic simplifications that apply to a file name.

2 Likes
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.32-171-g4ba05b1cc)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- consult('//wsl$/Ubuntu-18.04/home/eric/projects/prolog/wsl2_tests/test.pl').
true.

?- test.
Hello, World!
true.

Works as expected with the daily Windows build.

2 Likes