浏览代码

Merge pull request #3567 from ThomasWaldmann/files-cache-exception-handling-1.1

files cache: improve exception handling, fixes #3553 (1.1)
TW 7 年之前
父节点
当前提交
19032f72da
共有 2 个文件被更改,包括 29 次插入26 次删除
  1. 26 19
      src/borg/cache.py
  2. 3 7
      src/borg/testsuite/archiver.py

+ 26 - 19
src/borg/cache.py

@@ -502,25 +502,32 @@ class LocalCache(CacheStatsMixin):
         self.files = {}
         self._newest_cmtime = None
         logger.debug('Reading files cache ...')
-
-        with IntegrityCheckedFile(path=os.path.join(self.path, 'files'), write=False,
-                                  integrity_data=self.cache_config.integrity.get('files')) as fd:
-            u = msgpack.Unpacker(use_list=True)
-            while True:
-                data = fd.read(64 * 1024)
-                if not data:
-                    break
-                u.feed(data)
-                try:
-                    for path_hash, item in u:
-                        entry = FileCacheEntry(*item)
-                        # in the end, this takes about 240 Bytes per file
-                        self.files[path_hash] = msgpack.packb(entry._replace(age=entry.age + 1))
-                except (TypeError, ValueError) as exc:
-                    logger.warning('The files cache seems corrupt, ignoring it. '
-                                   'Expect lower performance. [%s]' % str(exc))
-                    self.files = {}
-                    return
+        msg = None
+        try:
+            with IntegrityCheckedFile(path=os.path.join(self.path, 'files'), write=False,
+                                      integrity_data=self.cache_config.integrity.get('files')) as fd:
+                u = msgpack.Unpacker(use_list=True)
+                while True:
+                    data = fd.read(64 * 1024)
+                    if not data:
+                        break
+                    u.feed(data)
+                    try:
+                        for path_hash, item in u:
+                            entry = FileCacheEntry(*item)
+                            # in the end, this takes about 240 Bytes per file
+                            self.files[path_hash] = msgpack.packb(entry._replace(age=entry.age + 1))
+                    except (TypeError, ValueError) as exc:
+                        msg = "The files cache seems invalid. [%s]" % str(exc)
+                        break
+        except OSError as exc:
+            msg = "The files cache can't be read. [%s]" % str(exc)
+        except FileIntegrityError as fie:
+            msg = "The files cache is corrupted. [%s]" % str(fie)
+        if msg is not None:
+            logger.warning(msg)
+            logger.warning('Continuing without files cache - expect lower performance.')
+            self.files = {}
 
     def begin_txn(self):
         # Initialize transaction snapshot

+ 3 - 7
src/borg/testsuite/archiver.py

@@ -3331,13 +3331,9 @@ class ArchiverCorruptionTestCase(ArchiverTestCaseBase):
     def test_cache_files(self):
         self.cmd('create', self.repository_location + '::test', 'input')
         self.corrupt(os.path.join(self.cache_path, 'files'))
-
-        if self.FORK_DEFAULT:
-            out = self.cmd('create', self.repository_location + '::test1', 'input', exit_code=2)
-            assert 'failed integrity check' in out
-        else:
-            with pytest.raises(FileIntegrityError):
-                self.cmd('create', self.repository_location + '::test1', 'input')
+        out = self.cmd('create', self.repository_location + '::test1', 'input')
+        # borg warns about the corrupt files cache, but then continues without files cache.
+        assert 'files cache is corrupted' in out
 
     def test_chunks_archive(self):
         self.cmd('create', self.repository_location + '::test1', 'input')