浏览代码

create/extract: add --noxattrs option, #3955

when given with borg create, borg will not get xattrs from input files (and thus, it will not archive xattrs).

when given with borg extract, borg will not read xattrs from archive and it will not set xattrs on extracted files.
Thomas Waldmann 4 年之前
父节点
当前提交
4545b9e54d
共有 2 个文件被更改,包括 36 次插入27 次删除
  1. 30 26
      src/borg/archive.py
  2. 6 1
      src/borg/archiver.py

+ 30 - 26
src/borg/archive.py

@@ -316,7 +316,7 @@ class Archive:
 
     def __init__(self, repository, key, manifest, name, cache=None, create=False,
                  checkpoint_interval=1800, numeric_owner=False, noatime=False, noctime=False, nobirthtime=False,
-                 nobsdflags=False, noacls=False,
+                 nobsdflags=False, noacls=False, noxattrs=False,
                  progress=False, chunker_params=CHUNKER_PARAMS, start=None, start_monotonic=None, end=None,
                  consider_part_files=False, log_json=False):
         self.cwd = os.getcwd()
@@ -337,6 +337,7 @@ class Archive:
         self.nobirthtime = nobirthtime
         self.nobsdflags = nobsdflags
         self.noacls = noacls
+        self.noxattrs = noxattrs
         assert (start is None) == (start_monotonic is None), 'Logic error: if start is given, start_monotonic must be given as well and vice versa.'
         if start is None:
             start = datetime.utcnow()
@@ -766,30 +767,31 @@ Utilization of max. archive size: {csize_max:.0%}
             pass
         if not self.noacls:
             acl_set(path, item, self.numeric_owner)
-        # chown removes Linux capabilities, so set the extended attributes at the end, after chown, since they include
-        # the Linux capabilities in the "security.capability" attribute.
-        xattrs = item.get('xattrs', {})
-        for k, v in xattrs.items():
-            try:
-                xattr.setxattr(fd or path, k, v, follow_symlinks=False)
-            except OSError as e:
-                msg_format = '%s: when setting extended attribute %s: %%s' % (path, k.decode())
-                if e.errno == errno.E2BIG:
-                    err_str = 'too big for this filesystem'
-                elif e.errno == errno.ENOTSUP:
-                    err_str = 'xattrs not supported on this filesystem'
-                elif e.errno == errno.ENOSPC:
-                    # no space left on device while setting this specific xattr
-                    # ext4 reports ENOSPC when trying to set an xattr with >4kiB while ext4 can only support 4kiB xattrs
-                    # (in this case, this is NOT a "disk full" error, just a ext4 limitation).
-                    err_str = 'no space left on device [xattr len = %d]' % (len(v), )
-                else:
-                    # generic handler
-                    # EACCES: permission denied to set this specific xattr (this may happen related to security.* keys)
-                    # EPERM: operation not permitted
-                    err_str = os.strerror(e.errno)
-                logger.warning(msg_format % err_str)
-                set_ec(EXIT_WARNING)
+        if not self.noxattrs:
+            # chown removes Linux capabilities, so set the extended attributes at the end, after chown, since they include
+            # the Linux capabilities in the "security.capability" attribute.
+            xattrs = item.get('xattrs', {})
+            for k, v in xattrs.items():
+                try:
+                    xattr.setxattr(fd or path, k, v, follow_symlinks=False)
+                except OSError as e:
+                    msg_format = '%s: when setting extended attribute %s: %%s' % (path, k.decode())
+                    if e.errno == errno.E2BIG:
+                        err_str = 'too big for this filesystem'
+                    elif e.errno == errno.ENOTSUP:
+                        err_str = 'xattrs not supported on this filesystem'
+                    elif e.errno == errno.ENOSPC:
+                        # no space left on device while setting this specific xattr
+                        # ext4 reports ENOSPC when trying to set an xattr with >4kiB while ext4 can only support 4kiB xattrs
+                        # (in this case, this is NOT a "disk full" error, just a ext4 limitation).
+                        err_str = 'no space left on device [xattr len = %d]' % (len(v), )
+                    else:
+                        # generic handler
+                        # EACCES: permission denied to set this specific xattr (this may happen related to security.* keys)
+                        # EPERM: operation not permitted
+                        err_str = os.strerror(e.errno)
+                    logger.warning(msg_format % err_str)
+                    set_ec(EXIT_WARNING)
         # bsdflags include the immutable flag and need to be set last:
         if not self.nobsdflags and 'bsdflags' in item:
             try:
@@ -911,8 +913,10 @@ Utilization of max. archive size: {csize_max:.0%}
     def stat_ext_attrs(self, st, path):
         attrs = {}
         bsdflags = 0
+        xattrs = {}
         with backup_io('extended stat'):
-            xattrs = xattr.get_all(path, follow_symlinks=False)
+            if not self.noxattrs:
+                xattrs = xattr.get_all(path, follow_symlinks=False)
             if not self.nobsdflags:
                 bsdflags = get_flags(path, st)
             if not self.noacls:

+ 6 - 1
src/borg/archiver.py

@@ -186,6 +186,7 @@ def with_archive(method):
                           numeric_owner=getattr(args, 'numeric_owner', False),
                           nobsdflags=getattr(args, 'nobsdflags', False),
                           noacls=getattr(args, 'noacls', False),
+                          noxattrs=getattr(args, 'noxattrs', False),
                           cache=kwargs.get('cache'),
                           consider_part_files=args.consider_part_files, log_json=args.log_json)
         return method(self, args, repository=repository, manifest=manifest, key=key, archive=archive, **kwargs)
@@ -588,7 +589,7 @@ class Archiver:
                 archive = Archive(repository, key, manifest, args.location.archive, cache=cache,
                                   create=True, checkpoint_interval=args.checkpoint_interval,
                                   numeric_owner=args.numeric_owner, noatime=args.noatime, noctime=args.noctime, nobirthtime=args.nobirthtime,
-                                  nobsdflags=args.nobsdflags, noacls=args.noacls, progress=args.progress,
+                                  nobsdflags=args.nobsdflags, noacls=args.noacls, noxattrs=args.noxattrs, progress=args.progress,
                                   chunker_params=args.chunker_params, start=t0, start_monotonic=t0_monotonic,
                                   log_json=args.log_json)
                 create_inner(archive, cache)
@@ -3476,6 +3477,8 @@ class Archiver:
                               help='do not read and store bsdflags (e.g. NODUMP, IMMUTABLE) into archive')
         fs_group.add_argument('--noacls', dest='noacls', action='store_true',
                               help='do not read and store ACLs into archive')
+        fs_group.add_argument('--noxattrs', dest='noxattrs', action='store_true',
+                              help='do not read and store xattrs into archive')
         fs_group.add_argument('--ignore-inode', dest='ignore_inode', action='store_true',
                               help='ignore inode data in the file metadata cache used to detect unchanged files.')
         fs_group.add_argument('--files-cache', metavar='MODE', dest='files_cache_mode',
@@ -3546,6 +3549,8 @@ class Archiver:
                                help='do not extract/set bsdflags (e.g. NODUMP, IMMUTABLE)')
         subparser.add_argument('--noacls', dest='noacls', action='store_true',
                                help='do not extract/set ACLs')
+        subparser.add_argument('--noxattrs', dest='noxattrs', action='store_true',
+                               help='do not extract/set xattrs')
         subparser.add_argument('--stdout', dest='stdout', action='store_true',
                                help='write all extracted data to stdout')
         subparser.add_argument('--sparse', dest='sparse', action='store_true',