diff options
| author | Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> | 2019-09-02 16:04:07 +0200 |
|---|---|---|
| committer | Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> | 2019-09-02 16:06:25 +0200 |
| commit | e1719f48b651dbb942c30d9a179ba476d71775c5 (patch) | |
| tree | 1930930d7ef23c7d3778b768d786f3383f5b9574 /src | |
| parent | cd114c44d8f0d2fdc72bb74bb0ff4fe1a1e8ddd1 (diff) | |
| download | rabbitmq-server-git-e1719f48b651dbb942c30d9a179ba476d71775c5.tar.gz | |
rabbit_disk_monitor: Tell Win32 API to not enforce path limits to dir's argument
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
This was discovered while working on the common_test testsuites on
Windows: we store RabbitMQ data files under common_test's `log_private`
directory and we can quickly reach the 260-character limit.
Diffstat (limited to 'src')
| -rw-r--r-- | src/rabbit_disk_monitor.erl | 23 |
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 |
