Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backup stops on too long filename not found under Windows #236

Closed
ericzolf opened this issue Jan 11, 2020 · 24 comments · Fixed by #551
Closed

Backup stops on too long filename not found under Windows #236

ericzolf opened this issue Jan 11, 2020 · 24 comments · Fixed by #551
Labels
enhancement fixed fix is in a pull request due to be merged

Comments

@ericzolf
Copy link
Member

ericzolf commented Jan 11, 2020

The backup stopped prematurely. Below is the "end" of what was on
the screen. It appears that backup of "C:/Users/????/AppData" folder is
a problem.
The error about "filename or extension too long" appears to have
terminated the backup. 16 gigabytes of "stuff" is in the backup folder.
I will try a backup that excludes the "AppData" folders.

UpdateError:
'JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/rdiff-backup.tmp.160879'
[WinError 3] The system cannot find the path specified:
b'h:/RdiffBackup/JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/rdiff-backup.tmp.160879'
->
b'h:/RdiffBackup/JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/ms-windows-store--pdp-productId=9wzdncrdg1v9&irgwc=1&OCID=AID2000142_aff_7593_1290489&tduid=(ir__xtsgmflkwckfrjzukk0sohzg0e2xlzvjjp1gx3xe00)(7593)(1290489)(lp_upsell)&irclickid=_xtsgmflkwckfr.lnk'
OSError while renaming
h:/RdiffBackup/JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/rdiff-backup.tmp.160880
to
h:/RdiffBackup/JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/ms-windows-store--pdp-productId=9wzdncrdg1v9&irgwc=1&OCID=AID2000142_aff_7593_1290489&tduid=(ir__xtsgmflkwckfrjzukk0sohzg0e2xlzwhdd1gx3xe00)(7593)(1290489)(lp_upsell)&irclickid=_xtsgmflkwckfr.lnk
UpdateError:
'JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/rdiff-backup.tmp.160880'
[WinError 3] The system cannot find the path specified:
b'h:/RdiffBackup/JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/rdiff-backup.tmp.160880'
->
b'h:/RdiffBackup/JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/ms-windows-store--pdp-productId=9wzdncrdg1v9&irgwc=1&OCID=AID2000142_aff_7593_1290489&tduid=(ir__xtsgmflkwckfrjzukk0sohzg0e2xlzwhdd1gx3xe00)(7593)(1290489)(lp_upsell)&irclickid=_xtsgmflkwckfr.lnk'
OSError while renaming
h:/RdiffBackup/JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/rdiff-backup.tmp.160881
to
h:/RdiffBackup/JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/ms-windows-store--pdp-productId=9wzdncrdg1v9&irgwc=1&OCID=AID2000142_aff_7593_1290489&tduid=(ir__xtsgmflkwckfrjzukk0sohzg0e2xlzwlpl1gx3xe00)(7593)(1290489)(lp_upsell)&irclickid=_xtsgmflkwckfr.lnk
UpdateError:
'JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/rdiff-backup.tmp.160881'
[WinError 3] The system cannot find the path specified:
b'h:/RdiffBackup/JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/rdiff-backup.tmp.160881'
->
b'h:/RdiffBackup/JackieLahman/AppData/Roaming/Microsoft/Windows/Recent/ms-windows-store--pdp-productId=9wzdncrdg1v9&irgwc=1&OCID=AID2000142_aff_7593_1290489&tduid=(ir__xtsgmflkwckfrjzukk0sohzg0e2xlzwlpl1gx3xe00)(7593)(1290489)(lp_upsell)&irclickid=_xtsgmflkwckfr.lnk'
ListError:
'JackieLahman/AppData/Roaming/Mozilla/Firefox/Profiles/449uu6xv.default/parent.lock'
[Errno 13] Permission denied:
b'c:/Users/JackieLahman/AppData/Roaming/Mozilla/Firefox/Profiles/449uu6xv.default/parent.lock'
Exception '[WinError 206] The filename or extension is too long:
b'h:/RdiffBackup/rdiff-backup-data/increments/JackieLahman/Documents/MAIN
DATA FILES/JackieStuff/Crafts/Beads/Temari
Beads_files/TamariBeads_files/0,1158,CRHO_project_24591,FF_files/CRHO;059cat=Carol_Duvall_Show;059cat=Needle_Arts;059ord=17151440800_files''
raised of class '<class 'FileNotFoundError'>':
  File "rdiff_backup\Main.py", line 390, in error_check_Main
  File "rdiff_backup\Main.py", line 412, in Main
  File "rdiff_backup\Main.py", line 348, in take_action
  File "rdiff_backup\Main.py", line 437, in Backup
  File "rdiff_backup\backup.py", line 39, in Mirror
  File "rdiff_backup\backup.py", line 269, in patch
  File "rdiff_backup\rorpiter.py", line 313, in __call__
  File "rdiff_backup\backup.py", line 584, in fast_process
  File "rdiff_backup\longname.py", line 235, in get_mirror_inc_rps
  File "rdiff_backup\longname.py", line 221, in find_inc_pair
  File "rdiff_backup\longname.py", line 143, in check_new_index
  File "rdiff_backup\longname.py", line 125, in wrap_call
  File "rdiff_backup\longname.py", line 136, in make_parent
  File "rdiff_backup\rpath.py", line 1185, in makedirs
  File "os.py", line 221, in makedirs

Traceback (most recent call last):
  File "rdiff-backup", line 32, in <module>
  File "rdiff_backup\Main.py", line 390, in error_check_Main
  File "rdiff_backup\Main.py", line 412, in Main
  File "rdiff_backup\Main.py", line 348, in take_action
  File "rdiff_backup\Main.py", line 437, in Backup
  File "rdiff_backup\backup.py", line 39, in Mirror
  File "rdiff_backup\backup.py", line 269, in patch
  File "rdiff_backup\rorpiter.py", line 313, in __call__
  File "rdiff_backup\backup.py", line 584, in fast_process
  File "rdiff_backup\longname.py", line 235, in get_mirror_inc_rps
  File "rdiff_backup\longname.py", line 221, in find_inc_pair
  File "rdiff_backup\longname.py", line 143, in check_new_index
  File "rdiff_backup\longname.py", line 125, in wrap_call
  File "rdiff_backup\longname.py", line 136, in make_parent
  File "rdiff_backup\rpath.py", line 1185, in makedirs
  File "os.py", line 221, in makedirs
FileNotFoundError: [WinError 206] The filename or extension is too long:
b'h:/RdiffBackup/rdiff-backup-data/increments/JackieLahman/Documents/MAIN
DATA FILES/JackieStuff/Crafts/Beads/Temari
Beads_files/TamariBeads_files/0,1158,CRHO_project_24591,FF_files/CRHO;059cat=Carol_Duvall_Show;059cat=Needle_Arts;059ord=17151440800_files'
[47508] Failed to execute script rdiff-backup
@ericzolf
Copy link
Member Author

@pblahman it's a new problem, IMHO unrelated to the initial one, hence it has its place in a new issue.

The filename is indeed next to or bigger than 260 characters, which is the default limit for path sizes on Windows.

Is this an issue you did NOT have with rdiff-backup 1.2.8 or have you just started to use rdiff-backup this specific way?

@pblahman
Copy link

pblahman commented Jan 11, 2020 via email

@ericzolf
Copy link
Member Author

Fine with me, just two comments:

  1. continuing a failing backup is a tricky thing, you might corrupt even more the backup repository. You can try to plug an enhancement request but I'm not sure I'd be in favour. If you don't mind having the files not backup-ed, then just exclude them.
  2. regarding long path support in Windows, let us know the result, it could become an FAQ. In the Microsoft docs, it states that the program must also support the feature, but I don't know if it's a Python or a PyInstaller thingy to do.

@elektrocad
Copy link

The long path problem in Windows and Python can be easily solved:

  1. Path needs to be Unicode
  2. Prepend escaped \\\\?\\ prefix to the absolute paths (which is escaped version of \\?\ )
    Example path: \\\\?\\C:\\path\\to\\file
  3. Only use escaped backslashes: \\ (don't use forward slashes, because no automatic canonization, if \\?\ prefix used)
  4. It does not work for relative paths (the relative paths are always limited to a total of MAX_PATH characters)
  5. This also works with UNC paths: \\\\?\\UNC\\Server\\share\\Path

@ericzolf
Copy link
Member Author

"Easily solved" is relative, as the code is currently using bytes throughout the code and most of the time slashes instead of backslashes, so it's rather a major re-write IMHO.

@ikus060
Copy link
Contributor

ikus060 commented Feb 24, 2020 via email

@elektrocad
Copy link

elektrocad commented Feb 25, 2020

This ticket does not make sense for me. Rdiff-backup already have a way to handle long file name. What is the issue?

When the accessed path and filename total length exceeds 260 characters, get "[WinError 206] The filename or extension is too long" exception, and the backup process stops. This causes incomplete backup repository and requires special attention when the backup runs unattended.

As a result, it is currently not possible to backup long paths directly when the filename and path total length exceeds 260 characters with rdiff-backup.

This is basically Win32 API limitation: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation

Unfortunately, enabling "Enable NTFS long paths" feature in Windows 10 does not resolve this issue in Python. The only workaround currently is to use Unicode and the \\?\ prefix in paths. In this case, the internal Windows automatic path canonization does not work, so only backslash can be used in a paths. This, according to ericzolf, requires a major rewrite.

@ikus060
Copy link
Contributor

ikus060 commented Feb 25, 2020 via email

@elektrocad
Copy link

Could you provide the specific command line used to run the backup. And I would appreciate if you could provide an error log with it with a stack trace. Preferably running rdiff-backup with -v 9 would be great.

I created some sample directory structures that produces an error.

Please unpack the attachments one by one to root of drive, and run:
rdiff-backup.exe "c:/backup" "c:/backup_test"

long_path_no_error_but_incomplete_backup.zip
long_path_winerror_3.zip
long_path_winerror_206.zip

@tomasz1986
Copy link

tomasz1986 commented Apr 4, 2020

I have exactly the same problem. The operating system is Windows 10 Enterprise 2019 LTSC x64.

Exception '[WinError 206] The filename or extension is too long: b'D:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/rdiff-backup-data/increments/PortableApps/PortableApps/LibreOfficePortablePrevious/App/DefaultData/settings/user/extensions/bundled/registry/com.sun.star.comp.deployment.configuration.PackageRegistryBackend/lu23864u7l9b0.tmp'' raised of class '<class 'FileNotFoundError'>':
  File "rdiff_backup\Main.py", line 390, in error_check_Main
  File "rdiff_backup\Main.py", line 412, in Main
  File "rdiff_backup\Main.py", line 348, in take_action
  File "rdiff_backup\Main.py", line 437, in Backup
  File "rdiff_backup\backup.py", line 39, in Mirror
  File "rdiff_backup\backup.py", line 269, in patch
  File "rdiff_backup\rorpiter.py", line 313, in __call__
  File "rdiff_backup\backup.py", line 584, in fast_process
  File "rdiff_backup\longname.py", line 235, in get_mirror_inc_rps
  File "rdiff_backup\longname.py", line 221, in find_inc_pair
  File "rdiff_backup\longname.py", line 143, in check_new_index
  File "rdiff_backup\longname.py", line 125, in wrap_call
  File "rdiff_backup\longname.py", line 136, in make_parent
  File "rdiff_backup\rpath.py", line 1206, in makedirs
  File "os.py", line 221, in makedirs

Traceback (most recent call last):
  File "rdiff-backup", line 32, in <module>
  File "rdiff_backup\Main.py", line 390, in error_check_Main
  File "rdiff_backup\Main.py", line 412, in Main
  File "rdiff_backup\Main.py", line 348, in take_action
  File "rdiff_backup\Main.py", line 437, in Backup
  File "rdiff_backup\backup.py", line 39, in Mirror
  File "rdiff_backup\backup.py", line 269, in patch
  File "rdiff_backup\rorpiter.py", line 313, in __call__
  File "rdiff_backup\backup.py", line 584, in fast_process
  File "rdiff_backup\longname.py", line 235, in get_mirror_inc_rps
  File "rdiff_backup\longname.py", line 221, in find_inc_pair
  File "rdiff_backup\longname.py", line 143, in check_new_index
  File "rdiff_backup\longname.py", line 125, in wrap_call
  File "rdiff_backup\longname.py", line 136, in make_parent
  File "rdiff_backup\rpath.py", line 1206, in makedirs
  File "os.py", line 221, in makedirs
FileNotFoundError: [WinError 206] The filename or extension is too long: b'D:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/rdiff-backup-data/increments/PortableApps/PortableApps/LibreOfficePortablePrevious/App/DefaultData/settings/user/extensions/bundled/registry/com.sun.star.comp.deployment.configuration.PackageRegistryBackend/lu23864u7l9b0.tmp'
[11036] Failed to execute script rdiff-backup

Unfortunately, this makes rdiff-backup unusable here, because not only does it not copy the file in question, but it also completely stops the whole backup process on the error.

@okrasz
Copy link

okrasz commented Jul 31, 2020

Same issue for me :-(

@ericzolf
Copy link
Member Author

Short notes while I work on this topic:

reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem /v LongPathsEnabled
# 0x0
echo test > \temp\01234567890123456789012345678901234567890123456789012345678
9012345678901234567901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567
9012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345679012345678901234567
89
# The system cannot find the path specified. (the filename has 300 characters)
reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem /v LongPathsEnabled /t REG_DWORD /d 1 /f
echo test > \temp\01234567890123456789012345678901234567890123456789012345678
9012345678901234567901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567
9012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345679012345678901234567
89
# The system cannot find the path specified. (!!!)

Reboot then try again:

echo test > \temp\01234567890123456789012345678901234567890123456789012345678
9012345678901234567901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567
9012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345679012345678901234567
# The filename, directory name, or volume label syntax is incorrect. (different answer, but still wrong!)
mkdir \temp\0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
mkdir \temp\0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
echo test > \temp\0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789

I remembered too late that the registry key extends the path length but not the name length, which is still limited to 255 characters (I validated this by setting again the key to 0, rebooting and trying again).

Next step, try this stuff with Python...

@ericzolf
Copy link
Member Author

The Python stuff:

>>> path = "\\temp\\" + ("0123456789"*10+'\\')*2+"0123456789"*10 
>>> with open(path) as fd: print(fd.read())
...  
test  

>>> path = b"\\temp\\" + (b"0123456789"*10+b'\\')*2+b"0123456789"*10 
>>> path 
b'\\temp\\0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\\012345
6789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\\0123456789012345678901
234567890123456789012345678901234567890123456789012345678901234567890123456789'
>>> with open(path) as fd: print(fd.read())
...  
test  

>>> len(path) 
308 
>>> path = b"\\temp\\" + (b"0123456789"*10+b'\\')*2+b"0123456789"*20 
>>> with open(path,'w') as fd: print(fd.write('anothertest')) 
...  
11 
>>> with open(path) as fd: print(fd.read())
...  
anothertest
>>> path = b"..\\..\\temp\\" + (b"0123456789"*10+b'\\')*2+b"0123456789"*20 
>>> with open(path) as fd: print(fd.read())
...  
anothertest 
>>> path = b"../../temp/" + (b"0123456789"*10+b'/')*2+b"0123456789"*20 
>>> with open(path) as fd: print(fd.read())
...  
anothertest 
>>> path = b"/temp/" + (b"0123456789"*10+b'/')*2+b"0123456789"*20 
>>> with open(path) as fd: print(fd.read())
...
anothertest 

OK, python doesn't seem to be the issue (even with slash, and relative paths, and with bytes)... Next step, rdiff-backup itself.

@ericzolf
Copy link
Member Author

rdiff-backup -v9 \temp bak1 just seems to silently ignore all bigger files (the directories are saved, not the files).

@ericzolf
Copy link
Member Author

I've simplified the testing a little bit: the file
backup_long_win.tar.gz
can be unpacked also in root (as C:\backup) and the issues are still repeatable with something like rdiff-backup backup/rdiff_backup_testX temp/rdiff_backup_testX (so that I could do the three tests in parallel).

@ericzolf
Copy link
Member Author

OK, I have a good and a bad news: the code of rdiff-backup doesn't seem to have an issue with long names, but it seems that the result compiled with PyInstaller has an issue with those: "dist\rdiff-backup-2.0.6.dev42+g5e671d5-cp39-cp39-win_amd64.exe" -v5 \backup\rdiff_backup_testN \temp\rdiff_backup_testN fails where python build\scripts-3.9\rdiff-backup -v5 \backup\rdiff_backup_testN \temp\rdiff_backup_testN succeeds. I will create a bug report there and we'll see further.

@ericzolf
Copy link
Member Author

Issue should be solved after a rebuild with PyInstaller 4.2, assuming pyinstaller/pyinstaller#5424 is merged successfully.

@ericzolf ericzolf added the fixed fix is in a pull request due to be merged label Dec 29, 2020
@tomasz1986
Copy link

If possible, I would clearly state somewhere that the long paths are supported only in Windows 10 v1607, and also that registry or GPO modifications are required for this to work (see Enable Long Paths in Windows 10, Version 1607, and Later).

@xastor
Copy link

xastor commented Jan 1, 2021

This is wonderful news! Is there a way for me (a normal end-user) to get a hold of a test version somehow?

@ericzolf
Copy link
Member Author

ericzolf commented Jan 3, 2021

Not immediately, our pipeline is currently blocked (clarifying with Travis) and PyInstaller 4.2 isn't yet out. It should be possible to create your own binary using the Vagrant setup under tools/windows and using a development version of PyInstaller (the issue has been merged in the mean time), but it might be too much for a normal end-user, depending what you consider "normal" 😛

@ericzolf
Copy link
Member Author

ericzolf commented Apr 2, 2021

Just FYI, https://pyinstaller.readthedocs.io/en/stable/CHANGES.html 4.2 is out and has the requested fix to support long filenames. Follow the discussion on the mailing list.

ericzolf added a commit that referenced this issue Apr 8, 2021
PyInstaller doesn't support pkgutil.iter_modules out of the box
but there is a workaround:
pyinstaller/pyinstaller#1905

FIX: support long paths under Windows 10 v1607 or later, once enabled in
registry/GPO (see Windows README for details), closes #236
ericzolf added a commit that referenced this issue Apr 8, 2021
PyInstaller doesn't support pkgutil.iter_modules out of the box but there is a workaround:
pyinstaller/pyinstaller#1905

FIX: support long paths under Windows 10 v1607 or later, once enabled in registry/GPO (see Windows README for details), closes #236
@shmup
Copy link

shmup commented Aug 27, 2022

2022, checking in to say that a standard: rdiff-backup -v5 foo bar failed for too long of a file name. Yes I'm leaving this in an old ticket, I just needed to leave it here since I found comments in the scrollback like:

This ticket does not make sense for me. Rdiff-backup already have a way to handle long file name. What is the issue?

lol (psst, the issue is that it failed. no I don't have a stack trace to provide any insight. maybe next time it fails I will)

@ericzolf
Copy link
Member Author

Making fun of others doesn't help, especially as the question was valid, and constructively answered. It also seems that you didn't understand that the issue has been fixed but not yet released.

@shmup
Copy link

shmup commented Aug 27, 2022

I think that is a fair criticism. I knee-jerked 3 hours ago, unfairly

I will follow the discussion in the mailing list

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement fixed fix is in a pull request due to be merged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants