Commit 9b796f17 authored by owsla's avatar owsla

Make rdiff-backup robust to failure to read the extended attributes or ACL

because the file cannot be found.


git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup@892 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
parent 9f8b0e92
New in v1.1.16 (????/??/??) New in v1.1.16 (????/??/??)
--------------------------- ---------------------------
Don't abort if can't read extended attributes or ACL because the path is
considered bad by the EA/ACL subsystem; print a warning instead. Problem
reported by Farkas Levente. (Andrew Ferguson)
rdiff-backup-statistics enhancements suggested by James Marsh: flush stdout rdiff-backup-statistics enhancements suggested by James Marsh: flush stdout
before running other commands, and add a --quiet option to suppress printing before running other commands, and add a --quiet option to suppress printing
the "Processing statistics from session..." lines. (Andrew Ferguson) the "Processing statistics from session..." lines. (Andrew Ferguson)
......
...@@ -57,10 +57,10 @@ class ExtendedAttributes: ...@@ -57,10 +57,10 @@ class ExtendedAttributes:
def read_from_rp(self, rp): def read_from_rp(self, rp):
"""Set the extended attributes from an rpath""" """Set the extended attributes from an rpath"""
try: attr_list = rp.conn.xattr.listxattr(rp.path) try: attr_list = rp.conn.xattr.listxattr(rp.path)
except IOError, exc: except (IOError, ListError), exc:
if exc[0] == errno.EOPNOTSUPP or exc[0] == errno.EPERM: if exc[0] == errno.EOPNOTSUPP or exc[0] == errno.EPERM:
return # if not supported, consider empty return # if not supported, consider empty
if exc[0] == errno.EACCES: if exc[0] == errno.EACCES or exc[0] == errno.ENOENT:
log.Log("Warning: listattr(%s): %s" % (repr(rp.path), exc), 3) log.Log("Warning: listattr(%s): %s" % (repr(rp.path), exc), 3)
return return
raise raise
...@@ -93,9 +93,13 @@ class ExtendedAttributes: ...@@ -93,9 +93,13 @@ class ExtendedAttributes:
% (name, repr(rp.path)), 7) % (name, repr(rp.path)), 7)
continue continue
else: raise else: raise
except IOError, exc: except (IOError, ListError), exc:
if exc[0] == errno.EOPNOTSUPP or exc[0] == errno.EPERM: if exc[0] == errno.EOPNOTSUPP or exc[0] == errno.EPERM:
return # if not supported, consider empty return # if not supported, consider empty
if exc[0] == errno.ENOENT: # path is bad
log.Log("Warning: unable to clear xattrs on %s: %s" %
(repr(rp.path), exc), 3)
return
else: raise else: raise
def write_to_rp(self, rp): def write_to_rp(self, rp):
...@@ -104,10 +108,11 @@ class ExtendedAttributes: ...@@ -104,10 +108,11 @@ class ExtendedAttributes:
for (name, value) in self.attr_dict.iteritems(): for (name, value) in self.attr_dict.iteritems():
try: try:
rp.conn.xattr.setxattr(rp.path, name, value) rp.conn.xattr.setxattr(rp.path, name, value)
except IOError, exc: except (IOError, ListError), exc:
# Mac and Linux attributes have different namespaces, so # Mac and Linux attributes have different namespaces, so
# fail gracefully if can't call setxattr # fail gracefully if can't call setxattr
if exc[0] == errno.EOPNOTSUPP or exc[0] == errno.EACCES: if exc[0] == errno.EOPNOTSUPP or exc[0] == errno.EACCES \
or exc[0] == errno.ENOENT:
log.Log("Warning: unable to write xattr %s to %s" log.Log("Warning: unable to write xattr %s to %s"
% (name, repr(rp.path)), 6) % (name, repr(rp.path)), 6)
continue continue
...@@ -376,13 +381,21 @@ def get_acl_lists_from_rp(rp): ...@@ -376,13 +381,21 @@ def get_acl_lists_from_rp(rp):
"""Returns (acl_list, def_acl_list) from an rpath. Call locally""" """Returns (acl_list, def_acl_list) from an rpath. Call locally"""
assert rp.conn is Globals.local_connection assert rp.conn is Globals.local_connection
try: acl = posix1e.ACL(file=rp.path) try: acl = posix1e.ACL(file=rp.path)
except IOError, exc: except (IOError, ListError), exc:
if exc[0] == errno.EOPNOTSUPP: acl = None if exc[0] == errno.EOPNOTSUPP: acl = None
if exc[0] == errno.ENOENT:
log.Log("Warning: unable to read ACL from %s: %s"
% (repr(rp.path), exc), 3)
acl = None
else: raise else: raise
if rp.isdir(): if rp.isdir():
try: def_acl = posix1e.ACL(filedef=rp.path) try: def_acl = posix1e.ACL(filedef=rp.path)
except IOError, exc: except (IOError, ListError), exc:
if exc[0] == errno.EOPNOTSUPP: def_acl = None if exc[0] == errno.EOPNOTSUPP: def_acl = None
if exc[0] == errno.ENOENT:
log.Log("Warning: unable to read default ACL from %s: %s"
% (repr(rp.path), exc), 3)
def_acl = None
else: raise else: raise
else: def_acl = None else: def_acl = None
return (acl and acl_to_list(acl), def_acl and acl_to_list(def_acl)) return (acl and acl_to_list(acl), def_acl and acl_to_list(def_acl))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment