Repository: borgbackup/borg

Issue:
Argument list too long error probably due to xattrs
Reported and discussed this in IRC. Data which was originally on Windows was transferred to OSX, and from there sent to a Linux Ubuntu 14.04 machine with ext4 filesystem where the errors happened upon typing borg extract backup::<repo_name>

See log on pastebin: http://rn0.me/show/QOGX3zmqQDB2f8AMb3dD/

Seems like it has something to do with the icon files; checked the xattrs there. Note this doesn't happen when running it on OSX.

xattrs:
```
ls -l -@ google_drive/Archive/Something/Something_Finance/Monthly\ financials/Icon?
-rw-r--r--@ 1 cluelesscoder  staff  0 Feb 14 12:48 google_drive/Archive/Something/Something_Finance/Monthly financials/Icon?
	com.apple.FinderInfo	32
	com.apple.ResourceFork	340647
```

---

:moneybag: [there is a bounty for this](https://www.bountysource.com/issues/42034922-argument-list-too-long-error-probably-due-to-xattrs)


Discussion:
Proposed solution: When setting an xattr upon extraction results in E2BIG, just print a warning.
Print a warning, continue with other xattrs of same file, and the remaining files in the restore data set.
Also, exit with warning rc.

Resolving patch:
diff --git a/src/borg/archive.py b/src/borg/archive.py
--- a/src/borg/archive.py
+++ b/src/borg/archive.py
@@ -621,7 +621,10 @@ def restore_attrs(self, path, item, symlink=False, fd=None):
             try:
                 xattr.setxattr(fd or path, k, v, follow_symlinks=False)
             except OSError as e:
-                if e.errno not in (errno.ENOTSUP, errno.EACCES):
+                if e.errno == errno.E2BIG:
+                    logger.warning('%s: Value or key of extended attribute %s is too big for this filesystem' %
+                                   (path, k.decode()))
+                elif e.errno not in (errno.ENOTSUP, errno.EACCES):
                     # only raise if the errno is not on our ignore list:
                     # ENOTSUP == xattrs not supported here
                     # EACCES == permission denied to set this specific xattr
diff --git a/src/borg/testsuite/archiver.py b/src/borg/testsuite/archiver.py
--- a/src/borg/testsuite/archiver.py
+++ b/src/borg/testsuite/archiver.py
@@ -1029,6 +1029,21 @@ def patched_fchown(fd, uid, gid):
                 self.cmd('extract', self.repository_location + '::test')
             assert xattr.getxattr('input/file', 'security.capability') == capabilities
 
+    @pytest.mark.skipif(not xattr.XATTR_FAKEROOT, reason='xattr not supported on this system or on this version of'
+                                                         'fakeroot')
+    def test_extract_big_xattrs(self):
+        def patched_setxattr(*args, **kwargs):
+            raise OSError(errno.E2BIG, 'E2BIG')
+        self.create_regular_file('file')
+        xattr.setxattr('input/file', 'attribute', 'value')
+        self.cmd('init', self.repository_location, '-e' 'none')
+        self.cmd('create', self.repository_location + '::test', 'input')
+        with changedir('output'):
+            with patch.object(xattr, 'setxattr', patched_setxattr):
+                out = self.cmd('extract', self.repository_location + '::test', exit_code=EXIT_WARNING)
+                assert out == (os.path.abspath('input/file') + ': Value or key of extended attribute attribute is too big'
+                                                               'for this filesystem\n')
+
     def test_path_normalization(self):
         self.cmd('init', '--encryption=repokey', self.repository_location)
         self.create_regular_file('dir1/dir2/file', size=1024 * 80)


Test patch: