If the platform/filesystem doesn't appear to support hard links, fall
back to copy2(). See also:
commit daa6bf3eeabf1f50630b17b0cbbbdcbbef59c90e
fsck: switch from symlinks to hard links for par2 sandbox
Thanks to Daniel Distler for reporting the issue and Greg Troxel,
and Aaron M. Ucko for help with the errno values.
Signed-off-by: Rob Browning <
r...@defaultvalue.org>
Tested-by: Rob Browning <
r...@defaultvalue.org>
---
lib/bup/cmd/fsck.py | 19 ++++++++++++++++++-
note/main.md | 2 +-
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/lib/bup/cmd/fsck.py b/lib/bup/cmd/fsck.py
index 8dc1ccbc..14673119 100644
--- a/lib/bup/cmd/fsck.py
+++ b/lib/bup/cmd/fsck.py
@@ -1,9 +1,11 @@
+from errno import EMLINK, EOPNOTSUPP, EPERM, ERANGE, EREMOTEIO, EXDEV
from os import SEEK_END
from shutil import rmtree
from subprocess import DEVNULL, PIPE, run
from tempfile import mkdtemp
from os.path import join
+from shutil import copy2
import glob, os, sys
from bup import options, git
@@ -81,7 +83,22 @@ def par2_generate(stem):
# cf.
https://github.com/Parchive/par2cmdline/issues/84
with temp_dir(dir=parent, prefix=(base + b'-bup-tmp-')) as tmpdir:
pack = base + b'.pack'
- os.link(join(tmpdir, b'..', pack), join(tmpdir, pack))
+ pack_src = join(tmpdir, b'..', pack)
+ pack_dst = join(tmpdir, pack)
+ copy_instead = False
+ try:
+ os.link(pack_src, pack_dst)
+ except OSError as ex:
+ if ex.errno not in (EMLINK,
+ EOPNOTSUPP, # freebsd
+ EPERM, # linux
+ ERANGE, # cryfs
+ EREMOTEIO, # kafs (cross-directory)
+ EXDEV): # openafs (cross-directory)
+ raise
+ copy_instead = True
+ if copy_instead:
+ copy2(pack_src, pack_dst)
rc = par2(b'create', [b'-n1', b'-c200', b'--', base, pack],
verb_floor=2, cwd=tmpdir)
if rc == 0:
diff --git a/note/main.md b/note/main.md
index 84b0265b..3b7732d0 100644
--- a/note/main.md
+++ b/note/main.md
@@ -177,7 +177,7 @@ Bugs
* `par2` changed its behavior in 1.0 to be incompatible with `bup`'s
use of symlinks to mitigate a `par2` bug (see the [0.33.4 release
notes](
0.33.4-from-0.33.3.md) for additional information. `bup` now
- uses hardlinks instead.
+ uses hardlinks if possible, and copies the files if not.
* `bup rm some/SAVE` should now succeed even if the root metadata (the
`some/SAVE/.bupm` file) is missing. Previously it failed with
--
2.47.3