From a3ef692132d394f5fbb3cca17cd6286c843db10e Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sat, 2 Jul 2016 19:44:26 +0200 Subject: [PATCH] reimplement --read-special, fixes #1241 --- borg/archive.py | 16 +++++++++++++--- borg/archiver.py | 10 ++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/borg/archive.py b/borg/archive.py index ab4ddb0d9..db16240fe 100644 --- a/borg/archive.py +++ b/borg/archive.py @@ -589,9 +589,16 @@ def process_file(self, path, st, cache, ignore_inode=False): return status else: self.hard_links[st.st_ino, st.st_dev] = safe_path - path_hash = self.key.id_hash(os.path.join(self.cwd, path).encode('utf-8', 'surrogateescape')) + is_regular_file = stat.S_ISREG(st.st_mode) + if is_regular_file: + path_hash = self.key.id_hash(os.path.join(self.cwd, path).encode('utf-8', 'surrogateescape')) + ids = cache.file_known_and_unchanged(path_hash, st, ignore_inode) + else: + # in --read-special mode, we may be called for special files. + # there should be no information in the cache about special files processed in + # read-special mode, but we better play safe as this was wrong in the past: + path_hash = ids = None first_run = not cache.files - ids = cache.file_known_and_unchanged(path_hash, st, ignore_inode) if first_run: logger.debug('Processing files ...') chunks = None @@ -616,7 +623,10 @@ def process_file(self, path, st, cache, ignore_inode=False): chunks.append(cache.add_chunk(self.key.id_hash(chunk), chunk, self.stats)) if self.show_progress: self.stats.show_progress(item=item, dt=0.2) - cache.memorize_file(path_hash, st, [c[0] for c in chunks]) + if is_regular_file: + # we must not memorize special files, because the contents of e.g. a + # block or char device will change without its mtime/size/inode changing. + cache.memorize_file(path_hash, st, [c[0] for c in chunks]) status = status or 'M' # regular file, modified (if not 'A' already) item[b'chunks'] = chunks item.update(self.stat_attrs(st, path)) diff --git a/borg/archiver.py b/borg/archiver.py index 5d12bfc2d..85dc79f54 100644 --- a/borg/archiver.py +++ b/borg/archiver.py @@ -304,10 +304,16 @@ def _process(self, archive, cache, matcher, exclude_caches, exclude_if_present, status = archive.process_symlink(path, st) elif stat.S_ISFIFO(st.st_mode): if not dry_run: - status = archive.process_fifo(path, st) + if not read_special: + status = archive.process_fifo(path, st) + else: + status = archive.process_file(path, st, cache) elif stat.S_ISCHR(st.st_mode) or stat.S_ISBLK(st.st_mode): if not dry_run: - status = archive.process_dev(path, st) + if not read_special: + status = archive.process_dev(path, st) + else: + status = archive.process_file(path, st, cache) elif stat.S_ISSOCK(st.st_mode): # Ignore unix sockets return