summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuke Bakken <lbakken@pivotal.io>2019-09-03 11:40:15 -0700
committerGitHub <noreply@github.com>2019-09-03 11:40:15 -0700
commit96cf61561e8d240e19d9c2a4a7ff1119d30fc83f (patch)
tree3d1cf9c04161481a3f7c6deb6cbaffdddb5e9615 /src
parentb51d4befd4433e68910a9392e6e6b7ddb11ba97d (diff)
parente1719f48b651dbb942c30d9a179ba476d71775c5 (diff)
downloadrabbitmq-server-git-96cf61561e8d240e19d9c2a4a7ff1119d30fc83f.tar.gz
Merge pull request #2095 from rabbitmq/disk-monitor-and-long-paths-on-windows
rabbit_disk_monitor: Tell Win32 API to not enforce path limits to dir's argument
Diffstat (limited to 'src')
-rw-r--r--src/rabbit_disk_monitor.erl23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/rabbit_disk_monitor.erl b/src/rabbit_disk_monitor.erl
index 96e90ff53e..4bc6ba09d0 100644
--- a/src/rabbit_disk_monitor.erl
+++ b/src/rabbit_disk_monitor.erl
@@ -240,7 +240,28 @@ get_disk_free(Dir, {unix, _}) ->
Df = os:find_executable("df"),
parse_free_unix(rabbit_misc:os_cmd(Df ++ " -kP " ++ Dir));
get_disk_free(Dir, {win32, _}) ->
- parse_free_win32(rabbit_misc:os_cmd("dir /-C /W \"" ++ Dir ++ "\"")).
+ %% On Windows, the Win32 API enforces a limit of 260 characters
+ %% (MAX_PATH). If we call `dir` with a path longer than that, it
+ %% fails with "File not found". Starting with Windows 10 version
+ %% 1607, this limit was removed, but the administrator has to
+ %% configure that.
+ %%
+ %% NTFS supports paths up to 32767 characters. Therefore, paths
+ %% longer than 260 characters exist but they are "inaccessible" to
+ %% `dir`.
+ %%
+ %% A workaround is to tell the Win32 API to not parse a path and
+ %% just pass it raw to the underlying filesystem. To do this, the
+ %% path must be prepended with "\\?\". That's what we do here.
+ %%
+ %% However, the underlying filesystem may not support forward
+ %% slashes transparently, as the Win32 API does. Therefore, we
+ %% convert all forward slashes to backslashes.
+ %%
+ %% See the following page to learn more about this:
+ %% https://ss64.com/nt/syntax-filenames.html
+ RawDir = "\\\\?\\" ++ string:replace(Dir, "/", "\\", all),
+ parse_free_win32(rabbit_misc:os_cmd("dir /-C /W \"" ++ RawDir ++ "\"")).
parse_free_unix(Str) ->
case string:tokens(Str, "\n") of