From 75a0b0d720eaff0e68a066009061af5563b2fc92 Mon Sep 17 00:00:00 2001 From: Reiko Asakura Date: Wed, 10 Nov 2021 20:00:22 -0500 Subject: [PATCH] Workaround for volume shadow copy in WSL1 --- docs/usage/general/environment.rst.inc | 5 +++++ src/borg/archive.py | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/docs/usage/general/environment.rst.inc b/docs/usage/general/environment.rst.inc index c70d0f565..b8b5ba4dd 100644 --- a/docs/usage/general/environment.rst.inc +++ b/docs/usage/general/environment.rst.inc @@ -94,6 +94,11 @@ General: Using this does not affect data safety, but might result in a more bursty write to disk behaviour (not continuously streaming to disk). + retry_erofs + Retry opening a file without O_NOATIME if opening a file with O_NOATIME + caused EROFS. You will need this to make archives from volume shadow copies + in WSL1 (Windows Subsystem for Linux 1). + Some automatic "answerers" (if set, they automatically answer confirmation questions): BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=no (or =yes) For "Warning: Attempting to access a previously unknown unencrypted repository" diff --git a/src/borg/archive.py b/src/borg/archive.py index 93385c9d1..5843ddb9a 100644 --- a/src/borg/archive.py +++ b/src/borg/archive.py @@ -37,6 +37,7 @@ from .helpers import bin_to_hex from .helpers import safe_ns from .helpers import ellipsis_truncate, ProgressIndicatorPercent, log_multi from .helpers import msgpack +from .helpers import workarounds from .patterns import PathPrefixPattern, FnmatchPattern, IECommand from .item import Item, ArchiveItem from .platform import acl_get, acl_set, set_flags, get_flags, swidth, hostname @@ -1115,6 +1116,12 @@ Utilization of max. archive size: {csize_max:.0%} raise # Was this EPERM due to the O_NOATIME flag? Try again without it: return os.open(path, flags_normal) + except OSError as exc: + # O_NOATIME causes EROFS when accessing a volume shadow copy in WSL1 + if 'retry_erofs' in workarounds and exc.errno == errno.EROFS and flags_noatime != flags_normal: + return os.open(path, flags_normal) + else: + raise def valid_msgpacked_dict(d, keys_serialized):