Skip to content

Commit c187d7c

Browse files
Merge pull request #7452 from snsmac/fix/no_perm_retry
Do not retry on permission errors
2 parents 270b705 + dad9965 commit c187d7c

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

src/borg/archiver/create_cmd.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import errno
12
import sys
23
import argparse
34
import logging
@@ -370,6 +371,10 @@ def _process_any(self, *, path, parent_fd, name, st, fso, cache, read_special, d
370371
self.print_warning("Unknown file type: %s", path)
371372
return
372373
except (BackupError, BackupOSError) as err:
374+
if isinstance(err, BackupOSError):
375+
if err.errno in (errno.EPERM, errno.EACCES):
376+
# Do not try again, such errors can not be fixed by retrying.
377+
raise
373378
# sleep a bit, so temporary problems might go away...
374379
sleep_s = 1000.0 / 1e6 * 10 ** (retry / 2) # retry 0: 1ms, retry 6: 1s, ...
375380
time.sleep(sleep_s)

src/borg/testsuite/archiver/create_cmd.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import shutil
66
import socket
77
import stat
8+
import subprocess
89
import time
910
import unittest
1011

@@ -208,6 +209,7 @@ def test_create_erroneous_file(self):
208209
input=flist.encode(),
209210
exit_code=0,
210211
)
212+
assert "retry: 3 of " in out
211213
assert "E input/file2" not in out # we managed to read it in the 3rd retry (after 3 failed reads)
212214
# repo looking good overall? checks for rc == 0.
213215
self.cmd(f"--repo={self.repository_location}", "check", "--debug")
@@ -217,6 +219,37 @@ def test_create_erroneous_file(self):
217219
assert "input/file2" in out
218220
assert "input/file3" in out
219221

222+
def test_create_no_permission_file(self):
223+
file_path = os.path.join(self.input_path, "file")
224+
self.create_regular_file(file_path + "1", size=1000)
225+
self.create_regular_file(file_path + "2", size=1000)
226+
self.create_regular_file(file_path + "3", size=1000)
227+
# revoke read permissions on file2 for everybody, including us:
228+
if is_win32:
229+
subprocess.run(["icacls.exe", file_path + "2", "/deny", "everyone:(R)"])
230+
else:
231+
os.chmod(file_path + "2", 0o000)
232+
self.cmd(f"--repo={self.repository_location}", "rcreate", RK_ENCRYPTION)
233+
flist = "".join(f"input/file{n}\n" for n in range(1, 4))
234+
out = self.cmd(
235+
f"--repo={self.repository_location}",
236+
"create",
237+
"--paths-from-stdin",
238+
"--list",
239+
"test",
240+
input=flist.encode(),
241+
exit_code=1, # WARNING status: could not back up file2.
242+
)
243+
assert "retry: 1 of " not in out # retries were NOT attempted!
244+
assert "E input/file2" in out # no permissions!
245+
# repo looking good overall? checks for rc == 0.
246+
self.cmd(f"--repo={self.repository_location}", "check", "--debug")
247+
# check files in created archive
248+
out = self.cmd(f"--repo={self.repository_location}", "list", "test")
249+
assert "input/file1" in out
250+
assert "input/file2" not in out # it skipped file2
251+
assert "input/file3" in out
252+
220253
def test_create_content_from_command(self):
221254
self.cmd(f"--repo={self.repository_location}", "rcreate", RK_ENCRYPTION)
222255
input_data = "some test content"

0 commit comments

Comments
 (0)