Error from 'tahoe cp' on Windows, due to a long path (IOError: Errno2 - no such file or dir.) #2235
Labels
No Label
0.2.0
0.3.0
0.4.0
0.5.0
0.5.1
0.6.0
0.6.1
0.7.0
0.8.0
0.9.0
1.0.0
1.1.0
1.10.0
1.10.1
1.10.2
1.10a2
1.11.0
1.12.0
1.12.1
1.13.0
1.14.0
1.15.0
1.15.1
1.2.0
1.3.0
1.4.1
1.5.0
1.6.0
1.6.1
1.7.0
1.7.1
1.7β
1.8.0
1.8.1
1.8.2
1.8.3
1.8β
1.9.0
1.9.0-s3branch
1.9.0a1
1.9.0a2
1.9.0b1
1.9.1
1.9.2
1.9.2a1
LeastAuthority.com automation
blocker
cannot reproduce
cloud-branch
code
code-dirnodes
code-encoding
code-frontend
code-frontend-cli
code-frontend-ftp-sftp
code-frontend-magic-folder
code-frontend-web
code-mutable
code-network
code-nodeadmin
code-peerselection
code-storage
contrib
critical
defect
dev-infrastructure
documentation
duplicate
enhancement
fixed
invalid
major
minor
n/a
normal
operational
packaging
somebody else's problem
supercritical
task
trivial
unknown
was already fixed
website
wontfix
worksforme
No Milestone
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Reference: tahoe-lafs/trac-2024-07-25#2235
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This may be a result of the length of the path name; Windows APIs do not normally accept paths longer than 259 Unicode characters, unless the "
\\?\
" prefix is used. The path in question has 262 characters.Most Windows software doesn't use that prefix and just breaks on long paths. I have never understood the motivation for the design that supports longer paths but requires you to jump through an obscure hoop to use them.
Error while restoring data - IOError: Errno2 - no such file or dir.to Error from 'tahoe cp' on Windows, possibly due to a long path (IOError: Errno2 - no such file or dir.)http://bugs.python.org/issue18199. This will not be fixed in Python 2.x, so the only way for us to work around it is either to:
chdir to each subdirectory in turn using relative paths (this changes the limitation to 255 characters per directory component);
on Windows, call the Win32 API functions with the "
\\?\
" prefix directly viactypes
or similar.seems like too much work.
Replying to daira:
Why can't we just prepend "
\\?\
" to the string before we pass it toopen()
on line 274 of [fileutil.py]source:trunk/src/allmydata/util/fileutil.py?rev=ff64a0fef5879d3651bc3db6ca0522d96b217d45?Replying to [zooko]comment:4:
It's not quite as simple as that:
\\?\
" must be absolute, but CLI commands accept relative paths. Also, they don't canonicalize in the same way, e.g. "..
" and ".
" are not supported.\\?\
" is only supported by the Unicode Win32 file APIs. I think Python does use those APIs (indirectly, via msvcrt) when given aunicode
string, though.Also see http://blogs.msdn.com/b/bclteam/archive/2007/02/13/long-paths-in-net-part-1-of-3-kim-hamilton.aspx. (Parts 2 and 3 are not so interesting.)
Replying to [daira]comment:5:
Given this constraint, the best place to prepend "
\\?\
" would probably be infileutil.abspath_expanduser_unicode
.Replying to [daira]comment:7:
Okay, I don't see any reason not to prepend "
\\?\
" to all paths when reading files.We should probably think about it a bit more when creating files i.e. during a
tahoe get
, because if we do this then the resulting files wouldn't be accessible via tools that don't support long paths, such as the Explorer or cmd.exe, for example, if I understand correctly.Prepending "
\\?\
" infileutil.abspath_expanduser_unicode
would also have the effect of making all file accesses underneath a node base directory use "long" paths on Windows. I don't know whether or not that is what we want.I created a branch https://github.com/daira/tahoe-lafs/commit/2235-long-paths-on-windows. It results in the following failures of existing tests, some of which are obviously shallow. The others I haven't had time to investigate.
I fixed the test failures apart from the ones in
allmydata.test.test_cli.CLI.test_catalog_shares_error
andallmydata.test.test_system.SystemTest.test_filesystem
.Error from 'tahoe cp' on Windows, possibly due to a long path (IOError: Errno2 - no such file or dir.)to Error from 'tahoe cp' on Windows, due to a long path (IOError: Errno2 - no such file or dir.)The next step on this should be to write a test, perhaps in source:trunk/src/allmydata/test/test_util.py, that attempts to create a file under a long filename in the (real, not faked) local filesystem, and if the file is successfully created then the test passes. That test should be red on current trunk when run on Windows, and go green when daira's patch or another fixit-patch is applied.
I don't understand this
not path.startswith(u"\\\\")
clause in Daira's patch, and I'd like to see a second test added to the one described above, which verifies that whatever behavior is intended by that clause is what actually happens.Other than those two additional tests, just getting all of the current tests to pass with the patch applied will be sufficient! ☺
P.S. If you don't know why that
not path.startswith(u"\\\\")
clause is in there, and Daira isn't around to explain it, then try removing that clause. If all the tests still pass, then great — you've removed unnecessary code! If tests start failing then examining the failing tests will probably show you why that clause is there.Because prepending
\\?\
is not correct for a UNC path ( http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx#maxpath ):It is also not correct for a path that already starts with
\\?\
(or, more obscurely,\\.\
).I could have written code like this to cover all cases:
but I don't actually care about long UNC paths; I just wanted to avoid doing something obviously incorrect for them.
Branch updated to use the code in comment:95019 : https://github.com/tahoe-lafs/tahoe-lafs/commits/2235-long-paths-on-windows
https://github.com/tahoe-lafs/tahoe-lafs/pull/93. Note: this doesn't pass all tests on Windows and shouldn't be merged yet.
I'm not sure this hasn't been covered but this error didn't show up during backup, but only has shown up during recovery with IIRC -CP -R shown above.
I'll start testing with a single file name with 300 char long.
Replying to CyberAxe:
CyberAxe: have you tested this yet? What did you learn?
Replying to zooko:
I agree that we need such a test.
This has been done.
The test failures on Windows have been fixed. The problem was that when using the
\\?\
prefix, Windows is pickier about path syntax and does not accept/
as a path component separator.Pull request https://github.com/tahoe-lafs/tahoe-lafs/pull/100 has a test and is now ready for review.
Replying to daira:
Please hold off merging this; there are instances of
os.path.abspath
andos.path.expanduser
that don't go throughfileutil.abspath_expanduser_unicode
and should be changed to do so. That includes the call infileutil.put_file
that motivated this ticket, so the pull request doesn't actually fix the bug. See the results ofegrep -Rn --include='*.py' 'expanduser|abspath' src |egrep -v 'abspath_expanduser_unicode|argv_to_abspath'
for other cases.Omitting some spurious hits:
Making all user-expansions go through
fileutil.abspath_expanduser_unicode
will make it easier to fix #1674.Currently working on https://github.com/tahoe-lafs/tahoe-lafs/commits/2235-long-paths-on-windows-5.
I need to rebase this and check that it is complete and passes tests.
removing
review-needed
keywordThe next step is for Daira to do the changes she described in comment:28.
Done. Review needed for https://github.com/tahoe-lafs/tahoe-lafs/pull/138 (which also fixes #1674 and #2027).
Reviewed all the patches on https://github.com/tahoe-lafs/tahoe-lafs/pull/138 and posted comments.
Fixed on the pr138 branch which was merged in [3afe827ad0cbdb41b2928d17c8bfbbaf5102acc8/trunk].
(Woohoo! This set of bugs has been irking me for some time.)