diff options
| author | Aravinda VK <avishwan@redhat.com> | 2015-12-29 11:20:39 +0530 | 
|---|---|---|
| committer | Venky Shankar <vshankar@redhat.com> | 2016-02-26 02:12:16 -0800 | 
| commit | 656a0e64e5f465561ed29297421ec150de32f2a1 (patch) | |
| tree | 1e3a784b8f40b7aa2ab675637540c1f8294f1e79 /geo-replication/syncdaemon/libcxattr.py | |
| parent | 1b897c39ba8c0f1bf180316637cc2d87e6920800 (diff) | |
geo-rep: Handle ERANGE error during listxattr
llistxattr in Geo-rep is two syscall instead of one
SIZE = llistxattr(PATH, &BUF, 0);
BUF = create_buf(SIZE);
_ = llistxattr(PATH, &BUF, SIZE);
So if any new xattrs added just after first call by any other worker,
second syscall will fail with ERANGE error.
Now Geo-rep sends BUF with large size(256*100) and gets value
with only one syscall. Raises OSError if fails with ERANGE error
even after sending large BUF.
Change-Id: I8ade4bbe9a0a8ea908ed9dedcd3f2ff4c6fe6f51
Signed-off-by: Aravinda VK <avishwan@redhat.com>
BUG: 1294588
Reviewed-on: http://review.gluster.org/13106
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Kotresh HR <khiremat@redhat.com>
Diffstat (limited to 'geo-replication/syncdaemon/libcxattr.py')
| -rw-r--r-- | geo-replication/syncdaemon/libcxattr.py | 28 | 
1 files changed, 21 insertions, 7 deletions
diff --git a/geo-replication/syncdaemon/libcxattr.py b/geo-replication/syncdaemon/libcxattr.py index b69773df469..553d8f13424 100644 --- a/geo-replication/syncdaemon/libcxattr.py +++ b/geo-replication/syncdaemon/libcxattr.py @@ -68,7 +68,8 @@ class Xattr(object):      def llistxattr(cls, path, siz=0):          ret = cls._query_xattr(path, siz, 'llistxattr')          if isinstance(ret, str): -            ret = ret.split('\0') +            ret = ret.strip('\0') +            ret = ret.split('\0') if ret else []          return ret      @classmethod @@ -86,9 +87,22 @@ class Xattr(object):      @classmethod      def llistxattr_buf(cls, path):          """listxattr variant with size discovery""" -        size = cls.llistxattr(path) -        if size == -1: -            cls.raise_oserr() -        if size == 0: -            return [] -        return cls.llistxattr(path, size) +        try: +            # Assuming no more than 100 xattrs in a file/directory and +            # each xattr key length will be less than 256 bytes +            # llistxattr will be called with bigger size so that +            # listxattr will not fail with ERANGE. OSError will be +            # raised if fails even with the large size specified. +            size = 256 * 100 +            return cls.llistxattr(path, size) +        except OSError: +            # If fixed length failed for getting list of xattrs then +            # use the llistxattr call to get the size and use that +            # size to get the list of xattrs. +            size = cls.llistxattr(path) +            if size == -1: +                cls.raise_oserr() +            if size == 0: +                return [] + +            return cls.llistxattr(path, size)  | 
