From d8d93363c9a58964adfcba6cec68df4ab142b284 Mon Sep 17 00:00:00 2001 From: Alexander 'Leo' Bergolth Date: Sat, 20 Jan 2018 14:41:14 +0100 Subject: [PATCH] ignore exceptions in scandir_inorder() that might be raised by an implicit syscall inside a DirEntry --- src/borg/helpers/fs.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/borg/helpers/fs.py b/src/borg/helpers/fs.py index 543429409..b189a2be6 100644 --- a/src/borg/helpers/fs.py +++ b/src/borg/helpers/fs.py @@ -11,6 +11,9 @@ from ..constants import * # NOQA +from ..logger import create_logger +logger = create_logger() + def get_base_dir(): """Get home directory / base directory for borg: @@ -128,8 +131,21 @@ def hardlinkable(mode): return stat.S_ISREG(mode) or stat.S_ISBLK(mode) or stat.S_ISCHR(mode) or stat.S_ISFIFO(mode) +def scandir_keyfunc(dirent): + try: + return (0, dirent.inode()) + except OSError as e: + # maybe a permission denied error while doing a stat() on the dirent + logger.debug('scandir_inorder: Unable to stat %s: %s', dirent.path, e) + # order this dirent after all the others lexically by file name + # we may not break the whole scandir just because of an exception in one dirent + # ignore the exception for now, since another stat will be done later anyways + # (or the entry will be skipped by an exclude pattern) + return (1, dirent.name) + + def scandir_inorder(path='.'): - return sorted(os.scandir(path), key=lambda dirent: dirent.inode()) + return sorted(os.scandir(path), key=scandir_keyfunc) def secure_erase(path):