Repository: iterative/dvc

Issue:
doctor: unknown workspace and cache directory on some windows mapped network shares
# Bug Report

<!--
## Issue name

Issue names must follow the pattern `command: description` where the command is the dvc command that you are trying to run. The description should describe the consequence of the bug. 

Example: `repro: doesn't detect input changes`
-->

doctor: unknown workspace and cache directory on some windows mapped network shares

## Description

<!--
A clear and concise description of what the bug is.
-->

Hi everyone !
I came across the following error: https://dvc.org/doc/user-guide/troubleshooting#no-dvc-cache
, except that I have set the path to my cache folder correctly, nevertheless it is not recognized in "dvc doctor".
I think it's due to the configuration I'm using: I'm on a shared network drive mounted on Windows 10.
Maybe it is linked to this issue : https://github.com/iterative/dvc/issues/5832

### Reproduce

<!--
Step list of how to reproduce the bug
-->

<!--
Example:

1. dvc init
2. Copy dataset.zip to the directory
3. dvc add dataset.zip
4. dvc run -d dataset.zip -o model ./train.sh
5. modify dataset.zip
6. dvc repro
-->

1. Shared NAS on Windows 10 (N:/)
2. "$ dvc doctor" in a DVC repo with cache configured, inside our N:/
3. Result :
```
DVC version: 2.5.4 (pip)
Platform: Python 3.9.1 on Windows-10-10.0.17763-SP0
Supports:
        http (requests = 2.25.0),
        https (requests = 2.25.0)
Cache types:
Cache directory: ('unknown', 'none')
Caches: local
Remotes: None
Workspace directory: ('unknown', 'none')
Repo: dvc, git
```

### Expected

<!--
A clear and concise description of what you expect to happen.
-->
Expected something like this :
Cache directory: NTFS on N:\
Caches: local
Workspace directory: NTFS on N:\


<!--
Please check https://github.com/iterative/dvc/wiki/Debugging-DVC on ways to gather more information regarding the issue.

If applicable, please also provide a `--verbose` output of the command, eg: `dvc add --verbose`.
If the issue is regarding the performance, please attach the profiling information and the benchmark comparisons.
-->

Thank you! 
:)


Discussion:
Hi @AnasChetouan !

> I came across the following error: https://dvc.org/doc/user-guide/troubleshooting#no-dvc-cache

Could you show the error you are getting from a dvc command, please? E.g. `dvc status -v`

Could you show `pip freeze | grep psutil`, please?
Hi @efiop, thanks for your reply!

> Could you show `pip freeze | grep psutil`, please?

psutil==5.8.0

> I came across the following error: https://dvc.org/doc/user-guide/troubleshooting#no-dvc-cache

Sorry, I may have explained it wrong. The error is that it's printing Cache directory: ('unknown', 'none') instead of the partition type.

I have found a trail that can lead to the solution of the problem : 
I've done some tests, using code from https://github.com/iterative/dvc/blob/master/dvc/info.py and I've noticed that on line 148, the problem appears after using "Path.resolve()".

Path before resolve : N:/Projects/XX/XX/...
Path after resolve : \\<nas-name>\dfs_root\Projects\XX\XX\...

In this way, we're not able to match our partition name on line 142 because we're not using the "N:/" prefix anymore but the NAS name directly. I think that's why we're not able to get the file system type.

I can propose you to look into it further on my side and why not bring a fix if I can?


@AnasChetouan Ah, so you are not experiencing any other issues with dvc, right? Just making sure :slightly_smiling_face: 

Thanks for the investigation, makes total sense! Here is a quick explanation: https://stackoverflow.com/questions/38325636/why-does-pythons-pathlib-and-os-lib-return-different-results-for-mapped-network 

> On Windows, resolve calls os.path._getfinalpathname, which calls GetFinalPathNameByHandle. This starts from the final resolved path of the file in the NT namespace (e.g. \Device\Mup\server\share\...) and works backward as required to get the VOLUME_NAME_DOS. If the final path is a UNC share (i.e. \Device\Mup), it returns a path of the form \\?\UNC\server\share\.... pathlib translates this back to a regular UNC path of the form \\server\share\....

Had no idea resolve() behaved like that on windows :man_shrugging: So seems like we just need to also `resolve()` `partition` keys and that should fix it. Would you be interested in sending a fix? :slightly_smiling_face: 

Resolving patch:
diff --git a/dvc/info.py b/dvc/info.py
--- a/dvc/info.py
+++ b/dvc/info.py
@@ -136,11 +136,14 @@ def _get_supported_remotes():
 
 
 def get_fs_type(path):
-
-    partition = {
-        pathlib.Path(part.mountpoint): (part.fstype + " on " + part.device)
-        for part in psutil.disk_partitions(all=True)
-    }
+    partition = {}
+    for part in psutil.disk_partitions(all=True):
+        if part.fstype != "":
+            try:
+                mountpoint = pathlib.Path(part.mountpoint).resolve()
+                partition[mountpoint] = part.fstype + " on " + part.device
+            except PermissionError:
+                pass
 
     # need to follow the symlink: https://github.com/iterative/dvc/issues/5065
     path = pathlib.Path(path).resolve()


Test patch: